From af9bceb00028e69b59108fd1f8f7ab0dbf922eb9 Mon Sep 17 00:00:00 2001 From: jhancock93 Date: Thu, 13 Jan 2022 21:03:31 -0500 Subject: [PATCH] Add archive_dir property to be used with source_dir that will prefix all content --- internal/provider/archiver.go | 2 +- internal/provider/data_source_archive_file.go | 12 +++++-- .../test-fixtures/test-dir/sub-dir1/file4.txt | 1 + internal/provider/zip_archiver.go | 5 +-- internal/provider/zip_archiver_test.go | 33 ++++++++++++++----- website/docs/d/archive_file.html.markdown | 2 ++ 6 files changed, 42 insertions(+), 13 deletions(-) create mode 100644 internal/provider/test-fixtures/test-dir/sub-dir1/file4.txt diff --git a/internal/provider/archiver.go b/internal/provider/archiver.go index 66faafb0..bb318211 100644 --- a/internal/provider/archiver.go +++ b/internal/provider/archiver.go @@ -8,7 +8,7 @@ import ( type Archiver interface { ArchiveContent(content []byte, infilename string) error ArchiveFile(infilename string) error - ArchiveDir(indirname string, excludes []string) error + ArchiveDir(indirname string, excludes []string, archiveDirs string) error ArchiveMultiple(content map[string][]byte) error SetOutputFileMode(outputFileMode string) } diff --git a/internal/provider/data_source_archive_file.go b/internal/provider/data_source_archive_file.go index f0df0dd9..e0293b1e 100644 --- a/internal/provider/data_source_archive_file.go +++ b/internal/provider/data_source_archive_file.go @@ -77,6 +77,11 @@ func dataSourceFile() *schema.Resource { ForceNew: true, ConflictsWith: []string{"source_content", "source_content_filename", "source_file"}, }, + "archive_dir": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, "excludes": { Type: schema.TypeSet, Optional: true, @@ -181,15 +186,18 @@ func archive(d *schema.ResourceData) error { archiver.SetOutputFileMode(outputFileMode) } + archiveDirs := d.Get("archive_dir").(string) + if dir, ok := d.GetOk("source_dir"); ok { + if excludes, ok := d.GetOk("excludes"); ok { excludeList := expandStringList(excludes.(*schema.Set).List()) - if err := archiver.ArchiveDir(dir.(string), excludeList); err != nil { + if err := archiver.ArchiveDir(dir.(string), excludeList, archiveDirs); err != nil { return fmt.Errorf("error archiving directory: %s", err) } } else { - if err := archiver.ArchiveDir(dir.(string), []string{""}); err != nil { + if err := archiver.ArchiveDir(dir.(string), []string{""}, archiveDirs); err != nil { return fmt.Errorf("error archiving directory: %s", err) } } diff --git a/internal/provider/test-fixtures/test-dir/sub-dir1/file4.txt b/internal/provider/test-fixtures/test-dir/sub-dir1/file4.txt new file mode 100644 index 00000000..1f094c0f --- /dev/null +++ b/internal/provider/test-fixtures/test-dir/sub-dir1/file4.txt @@ -0,0 +1 @@ +This is sub-dir1/file4.txt \ No newline at end of file diff --git a/internal/provider/zip_archiver.go b/internal/provider/zip_archiver.go index 087d0d9f..6e1c1de9 100644 --- a/internal/provider/zip_archiver.go +++ b/internal/provider/zip_archiver.go @@ -13,6 +13,7 @@ import ( type ZipArchiver struct { filepath string + archiveDirs string outputFileMode string // Default value "" means unset filewriter *os.File writer *zip.Writer @@ -94,7 +95,7 @@ func checkMatch(fileName string, excludes []string) (value bool) { return false } -func (a *ZipArchiver) ArchiveDir(indirname string, excludes []string) error { +func (a *ZipArchiver) ArchiveDir(indirname string, excludes []string, archiveDirs string) error { _, err := assertValidDir(indirname) if err != nil { return err @@ -142,7 +143,7 @@ func (a *ZipArchiver) ArchiveDir(indirname string, excludes []string) error { if err != nil { return fmt.Errorf("error creating file header: %s", err) } - fh.Name = filepath.ToSlash(relname) + fh.Name = filepath.Join(archiveDirs, filepath.ToSlash(relname)) fh.Method = zip.Deflate // fh.Modified alone isn't enough when using a zero value fh.SetModTime(time.Time{}) diff --git a/internal/provider/zip_archiver_test.go b/internal/provider/zip_archiver_test.go index 2c5b0133..f5299598 100644 --- a/internal/provider/zip_archiver_test.go +++ b/internal/provider/zip_archiver_test.go @@ -99,34 +99,51 @@ func TestZipArchiver_FileModified(t *testing.T) { func TestZipArchiver_Dir(t *testing.T) { zipfilepath := "archive-dir.zip" archiver := NewZipArchiver(zipfilepath) - if err := archiver.ArchiveDir("./test-fixtures/test-dir", []string{""}); err != nil { + if err := archiver.ArchiveDir("./test-fixtures/test-dir", []string{""}, ""); err != nil { t.Fatalf("unexpected error: %s", err) } ensureContents(t, zipfilepath, map[string][]byte{ - "file1.txt": []byte("This is file 1"), - "file2.txt": []byte("This is file 2"), - "file3.txt": []byte("This is file 3"), + "file1.txt": []byte("This is file 1"), + "file2.txt": []byte("This is file 2"), + "file3.txt": []byte("This is file 3"), + "sub-dir1/file4.txt": []byte("This is sub-dir1/file4.txt"), + }) +} + +func TestZipArchiver_Dir_WithArchiveDirs(t *testing.T) { + zipfilepath := "archive-dir.zip" + archiver := NewZipArchiver(zipfilepath) + if err := archiver.ArchiveDir("./test-fixtures/test-dir", []string{""}, "root/test-dir"); err != nil { + t.Fatalf("unexpected error: %s", err) + } + + ensureContents(t, zipfilepath, map[string][]byte{ + "root/test-dir/file1.txt": []byte("This is file 1"), + "root/test-dir/file2.txt": []byte("This is file 2"), + "root/test-dir/file3.txt": []byte("This is file 3"), + "root/test-dir/sub-dir1/file4.txt": []byte("This is sub-dir1/file4.txt"), }) } func TestZipArchiver_Dir_Exclude(t *testing.T) { zipfilepath := "archive-dir.zip" archiver := NewZipArchiver(zipfilepath) - if err := archiver.ArchiveDir("./test-fixtures/test-dir", []string{"file2.txt"}); err != nil { + if err := archiver.ArchiveDir("./test-fixtures/test-dir", []string{"file2.txt"}, "root"); err != nil { t.Fatalf("unexpected error: %s", err) } ensureContents(t, zipfilepath, map[string][]byte{ - "file1.txt": []byte("This is file 1"), - "file3.txt": []byte("This is file 3"), + "root/file1.txt": []byte("This is file 1"), + "root/file3.txt": []byte("This is file 3"), + "root/sub-dir1/file4.txt": []byte("This is sub-dir1/file4.txt"), }) } func TestZipArchiver_Dir_Exclude_With_Directory(t *testing.T) { zipfilepath := "archive-dir.zip" archiver := NewZipArchiver(zipfilepath) - if err := archiver.ArchiveDir("./test-fixtures/", []string{"test-dir", "test-dir2/file2.txt"}); err != nil { + if err := archiver.ArchiveDir("./test-fixtures/", []string{"test-dir", "test-dir2/file2.txt"}, ""); err != nil { t.Fatalf("unexpected error: %s", err) } diff --git a/website/docs/d/archive_file.html.markdown b/website/docs/d/archive_file.html.markdown index 161609de..ee9a6f8d 100644 --- a/website/docs/d/archive_file.html.markdown +++ b/website/docs/d/archive_file.html.markdown @@ -78,6 +78,8 @@ NOTE: One of `source`, `source_content_filename` (with `source_content`), `sourc * `source_dir` - (Optional) Package entire contents of this directory into the archive. +* `archive_dir` - (Optional) When used with source_dir, the top-level directories inside the archive that will contain all the contents + * `source` - (Optional) Specifies attributes of a single source file to include into the archive. * `excludes` - (Optional) Specify files to ignore when reading the `source_dir`.