diff --git a/add.go b/add.go index 3e7a8f3937b..266ef7d801e 100644 --- a/add.go +++ b/add.go @@ -112,6 +112,9 @@ type AddAndCopyOptions struct { // inheritAnnotations, newAnnotations). This field is internally managed and should // not be set by external API users. BuildMetadata string + // DirCopyContents copies the directory's contents instead of the + // directory with its contents below it, default true. + DirCopyContents types.OptionalBool } // gitURLFragmentSuffix matches fragments to use as Git reference and build @@ -610,18 +613,19 @@ func (b *Builder) Add(destination string, extract bool, options AddAndCopyOption return } getOptions := copier.GetOptions{ - UIDMap: srcUIDMap, - GIDMap: srcGIDMap, - Excludes: options.Excludes, - ExpandArchives: extract, - ChownDirs: chownDirs, - ChmodDirs: chmodDirsFiles, - ChownFiles: chownFiles, - ChmodFiles: chmodDirsFiles, - StripSetuidBit: options.StripSetuidBit, - StripSetgidBit: options.StripSetgidBit, - StripStickyBit: options.StripStickyBit, - Timestamp: options.Timestamp, + UIDMap: srcUIDMap, + GIDMap: srcGIDMap, + Excludes: options.Excludes, + ExpandArchives: extract, + ChownDirs: chownDirs, + ChmodDirs: chmodDirsFiles, + ChownFiles: chownFiles, + ChmodFiles: chmodDirsFiles, + KeepDirectoryNames: options.DirCopyContents == types.OptionalBoolFalse, + StripSetuidBit: options.StripSetuidBit, + StripSetgidBit: options.StripSetgidBit, + StripStickyBit: options.StripStickyBit, + Timestamp: options.Timestamp, } writer := io.WriteCloser(pipeWriter) repositoryDir := filepath.Join(cloneDir, subdir) @@ -777,19 +781,20 @@ func (b *Builder) Add(destination string, extract bool, options AddAndCopyOption return false, false, nil }) getOptions := copier.GetOptions{ - UIDMap: srcUIDMap, - GIDMap: srcGIDMap, - Excludes: options.Excludes, - ExpandArchives: extract, - ChownDirs: chownDirs, - ChmodDirs: chmodDirsFiles, - ChownFiles: chownFiles, - ChmodFiles: chmodDirsFiles, - StripSetuidBit: options.StripSetuidBit, - StripSetgidBit: options.StripSetgidBit, - StripStickyBit: options.StripStickyBit, - Parents: options.Parents, - Timestamp: options.Timestamp, + UIDMap: srcUIDMap, + GIDMap: srcGIDMap, + Excludes: options.Excludes, + ExpandArchives: extract, + ChownDirs: chownDirs, + ChmodDirs: chmodDirsFiles, + ChownFiles: chownFiles, + ChmodFiles: chmodDirsFiles, + KeepDirectoryNames: options.DirCopyContents == types.OptionalBoolFalse, + StripSetuidBit: options.StripSetuidBit, + StripSetgidBit: options.StripSetgidBit, + StripStickyBit: options.StripStickyBit, + Parents: options.Parents, + Timestamp: options.Timestamp, } getErr = copier.Get(contextDir, contextDir, getOptions, []string{globbedToGlobbable(globbed)}, writer) closeErr = writer.Close() diff --git a/add_test.go b/add_test.go new file mode 100644 index 00000000000..45622259fe9 --- /dev/null +++ b/add_test.go @@ -0,0 +1,38 @@ +package buildah + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "go.podman.io/image/v5/types" +) + +func TestDirCopyContentsToKeepDirectoryNames(t *testing.T) { + for _, tc := range []struct { + name string + dirCopyContents types.OptionalBool + keepDirectoryNames bool + }{ + { + name: "undefined defaults to not keeping directory names", + dirCopyContents: types.OptionalBoolUndefined, + keepDirectoryNames: false, + }, + { + name: "true means copy contents, don't keep directory names", + dirCopyContents: types.OptionalBoolTrue, + keepDirectoryNames: false, + }, + { + name: "false means keep directory names", + dirCopyContents: types.OptionalBoolFalse, + keepDirectoryNames: true, + }, + } { + t.Run(tc.name, func(t *testing.T) { + options := AddAndCopyOptions{DirCopyContents: tc.dirCopyContents} + got := options.DirCopyContents == types.OptionalBoolFalse + assert.Equal(t, tc.keepDirectoryNames, got) + }) + } +}