From d259da72ec678c3377bdd95049f369c9a2956279 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Wed, 5 Aug 2026 09:51:36 +0200 Subject: [PATCH] user: MkdirAllAndChown, MkdirAndChown: DRY Signed-off-by: Sebastiaan van Stijn --- user/idtools.go | 13 ++----------- user/idtools_unix.go | 9 +++++++-- user/idtools_unix_test.go | 11 ++++++----- user/idtools_windows.go | 2 +- 4 files changed, 16 insertions(+), 19 deletions(-) diff --git a/user/idtools.go b/user/idtools.go index 0bed31ea..62f6d2c9 100644 --- a/user/idtools.go +++ b/user/idtools.go @@ -31,12 +31,7 @@ func WithOnlyNew(o *mkdirOptions) { // reapplies the requested permission bits after creation, so the resulting // permissions are not affected by the process umask. func MkdirAllAndChown(path string, mode os.FileMode, uid, gid int, opts ...MkdirOpt) error { - var options mkdirOptions - for _, opt := range opts { - opt(&options) - } - - return mkdirAs(path, mode, uid, gid, true, options.onlyNew) + return mkdirAs(path, mode, uid, gid, true, opts...) } // MkdirAndChown creates a directory named path and applies the requested @@ -49,11 +44,7 @@ func MkdirAllAndChown(path string, mode os.FileMode, uid, gid int, opts ...Mkdir // exists as a directory. The resulting permission bits are not affected by // the process umask. func MkdirAndChown(path string, mode os.FileMode, uid, gid int, opts ...MkdirOpt) error { - var options mkdirOptions - for _, opt := range opts { - opt(&options) - } - return mkdirAs(path, mode, uid, gid, false, options.onlyNew) + return mkdirAs(path, mode, uid, gid, false, opts...) } // getRootUIDGID retrieves the remapped root uid/gid pair from the set of maps. diff --git a/user/idtools_unix.go b/user/idtools_unix.go index 4e39d244..679aaa3a 100644 --- a/user/idtools_unix.go +++ b/user/idtools_unix.go @@ -10,7 +10,12 @@ import ( "syscall" ) -func mkdirAs(path string, mode os.FileMode, uid, gid int, mkAll, onlyNew bool) error { +func mkdirAs(path string, mode os.FileMode, uid, gid int, mkAll bool, opts ...MkdirOpt) error { + var options mkdirOptions + for _, opt := range opts { + opt(&options) + } + path, err := filepath.Abs(path) if err != nil { return err @@ -21,7 +26,7 @@ func mkdirAs(path string, mode os.FileMode, uid, gid int, mkAll, onlyNew bool) e if !stat.IsDir() { return &os.PathError{Op: "mkdir", Path: path, Err: syscall.ENOTDIR} } - if onlyNew { + if options.onlyNew { return nil } diff --git a/user/idtools_unix_test.go b/user/idtools_unix_test.go index db7fc42e..5e0bcce5 100644 --- a/user/idtools_unix_test.go +++ b/user/idtools_unix_test.go @@ -376,17 +376,18 @@ func TestToContainer(t *testing.T) { } } -// TestMkdirIsNotDir checks that mkdirAs() function (used by MkdirAll...) -// returns a correct error in case a directory which it is about to create -// already exists but is a file (rather than a directory). +// TestMkdirIsNotDir checks that MkdirAndChown returns a correct error in case +// a directory which it is about to create already exists but is a file (rather +// than a directory). func TestMkdirIsNotDir(t *testing.T) { file, err := os.CreateTemp(t.TempDir(), t.Name()) if err != nil { t.Fatalf("Couldn't create temp dir: %v", err) } - err = mkdirAs(file.Name(), 0o755, 0, 0, false, false) - if expected := "mkdir " + file.Name() + ": not a directory"; err.Error() != expected { + expected := "mkdir " + file.Name() + ": not a directory" + err = MkdirAndChown(file.Name(), 0o755, 0, 0) + if err == nil || err.Error() != expected { t.Fatalf("expected error: %v, got: %v", expected, err) } } diff --git a/user/idtools_windows.go b/user/idtools_windows.go index 9de730ca..d83ec902 100644 --- a/user/idtools_windows.go +++ b/user/idtools_windows.go @@ -8,6 +8,6 @@ import ( // permissions aren't set through this path, the identity isn't utilized. // Ownership is handled elsewhere, but in the future could be support here // too. -func mkdirAs(path string, _ os.FileMode, _, _ int, _, _ bool) error { +func mkdirAs(path string, _ os.FileMode, _, _ int, _ bool, _ ...MkdirOpt) error { return os.MkdirAll(path, 0) }