diff --git a/.changes/unreleased/BUG FIXES-20240117-101851.yaml b/.changes/unreleased/BUG FIXES-20240117-101851.yaml new file mode 100644 index 00000000..99e4f247 --- /dev/null +++ b/.changes/unreleased/BUG FIXES-20240117-101851.yaml @@ -0,0 +1,5 @@ +kind: BUG FIXES +body: 'resource/archive_file: Return error when generated archive would be empty' +time: 2024-01-17T10:18:51.941981Z +custom: + Issue: "298" diff --git a/.changes/unreleased/BUG FIXES-20240117-101923.yaml b/.changes/unreleased/BUG FIXES-20240117-101923.yaml new file mode 100644 index 00000000..c51c97e1 --- /dev/null +++ b/.changes/unreleased/BUG FIXES-20240117-101923.yaml @@ -0,0 +1,5 @@ +kind: BUG FIXES +body: 'data-source/archive_file: Return error when generated archive would be empty' +time: 2024-01-17T10:19:23.907477Z +custom: + Issue: "298" diff --git a/internal/provider/data_source_archive_file_test.go b/internal/provider/data_source_archive_file_test.go index ddfec65e..3a78a59d 100644 --- a/internal/provider/data_source_archive_file_test.go +++ b/internal/provider/data_source_archive_file_test.go @@ -980,12 +980,7 @@ func TestAccArchiveFile_SymlinkDirectory_Relative_ExcludeSymlinkDirectories(t *t exclude_symlink_directories = true } `, filepath.ToSlash("test-fixtures/test-symlink-dir"), filepath.ToSlash(f)), - Check: r.ComposeTestCheckFunc( - r.TestCheckResourceAttrWith("data.archive_file.foo", "output_path", func(value string) error { - ensureContents(t, value, map[string][]byte{}) - return nil - }), - ), + ExpectError: regexp.MustCompile(`.*error creating archive: error archiving directory: archive has not been\ncreated as it would be empty`), }, }, }) @@ -1016,12 +1011,7 @@ func TestAccArchiveFile_SymlinkDirectory_Absolute_ExcludeSymlinkDirectories(t *t exclude_symlink_directories = true } `, filepath.ToSlash(symlinkDirWithRegularFilesAbs), filepath.ToSlash(f)), - Check: r.ComposeTestCheckFunc( - r.TestCheckResourceAttrWith("data.archive_file.foo", "output_path", func(value string) error { - ensureContents(t, value, map[string][]byte{}) - return nil - }), - ), + ExpectError: regexp.MustCompile(`.*error creating archive: error archiving directory: archive has not been\ncreated as it would be empty`), }, }, }) @@ -1210,12 +1200,7 @@ func TestAccArchiveFile_DirectoryWithSymlinkDirectory_Relative_ExcludeSymlinkDir exclude_symlink_directories = true } `, filepath.ToSlash("test-fixtures/test-dir-with-symlink-dir"), filepath.ToSlash(f)), - Check: r.ComposeTestCheckFunc( - r.TestCheckResourceAttrWith("data.archive_file.foo", "output_path", func(value string) error { - ensureContents(t, value, map[string][]byte{}) - return nil - }), - ), + ExpectError: regexp.MustCompile(`.*error creating archive: error archiving directory: archive has not been\ncreated as it would be empty`), }, }, }) @@ -1245,12 +1230,7 @@ func TestAccArchiveFile_IncludeDirectoryWithSymlinkDirectory_Absolute_ExcludeSym exclude_symlink_directories = true } `, filepath.ToSlash(symlinkDirInRegularDirAbs), filepath.ToSlash(f)), - Check: r.ComposeTestCheckFunc( - r.TestCheckResourceAttrWith("data.archive_file.foo", "output_path", func(value string) error { - ensureContents(t, value, map[string][]byte{}) - return nil - }), - ), + ExpectError: regexp.MustCompile(`.*error creating archive: error archiving directory: archive has not been\ncreated as it would be empty`), }, }, }) diff --git a/internal/provider/zip_archiver.go b/internal/provider/zip_archiver.go index c5248444..d4c00121 100644 --- a/internal/provider/zip_archiver.go +++ b/internal/provider/zip_archiver.go @@ -107,15 +107,28 @@ func (a *ZipArchiver) ArchiveDir(indirname string, opts ArchiveDirOpts) error { opts.Excludes[i] = filepath.FromSlash(opts.Excludes[i]) } + // Determine whether an empty archive would be generated. + isArchiveEmpty := true + + err = filepath.Walk(indirname, a.createWalkFunc("", indirname, opts, &isArchiveEmpty, true)) + if err != nil { + return err + } + + // Return an error if an empty archive would be generated. + if isArchiveEmpty { + return fmt.Errorf("archive has not been created as it would be empty") + } + if err := a.open(); err != nil { return err } defer a.close() - return filepath.Walk(indirname, a.createWalkFunc("", indirname, opts)) + return filepath.Walk(indirname, a.createWalkFunc("", indirname, opts, &isArchiveEmpty, false)) } -func (a *ZipArchiver) createWalkFunc(basePath string, indirname string, opts ArchiveDirOpts) func(path string, info os.FileInfo, err error) error { +func (a *ZipArchiver) createWalkFunc(basePath, indirname string, opts ArchiveDirOpts, isArchiveEmpty *bool, dryRun bool) func(path string, info os.FileInfo, err error) error { return func(path string, info os.FileInfo, err error) error { if err != nil { return fmt.Errorf("error encountered during file walk: %s", err) @@ -158,7 +171,7 @@ func (a *ZipArchiver) createWalkFunc(basePath string, indirname string, opts Arc if realInfo.IsDir() { if !opts.ExcludeSymlinkDirectories { - return filepath.Walk(realPath, a.createWalkFunc(archivePath, realPath, opts)) + return filepath.Walk(realPath, a.createWalkFunc(archivePath, realPath, opts, isArchiveEmpty, dryRun)) } else { return filepath.SkipDir } @@ -167,6 +180,12 @@ func (a *ZipArchiver) createWalkFunc(basePath string, indirname string, opts Arc info = realInfo } + *isArchiveEmpty = false + + if dryRun { + return nil + } + fh, err := zip.FileInfoHeader(info) if err != nil { return fmt.Errorf("error creating file header: %s", err)