diff --git a/internal/pipe/archive/archive.go b/internal/pipe/archive/archive.go index 458e97e0d..6bab5c43a 100644 --- a/internal/pipe/archive/archive.go +++ b/internal/pipe/archive/archive.go @@ -103,12 +103,11 @@ func create(ctx *context.Context, binaries []artifact.Artifact) error { defer archiveFile.Close() // nolint: errcheck var log = log.WithField("archive", archivePath) log.Info("creating") - var a = EnhancedArchive{ - a: archive.New(archiveFile), - } + var wrap string if ctx.Config.Archive.WrapInDirectory { - a.wrap = folder + wrap = folder } + var a = NewEnhancedArchive(archive.New(archiveFile), wrap) defer a.Close() // nolint: errcheck files, err := findFiles(ctx) @@ -176,22 +175,37 @@ func packageFormat(ctx *context.Context, platform string) string { return ctx.Config.Archive.Format } +// NewEnhancedArchive enhances a pre-existing archive.Archive instance +// with this pipe specifics. +func NewEnhancedArchive(a archive.Archive, wrap string) archive.Archive { + return EnhancedArchive{ + a: a, + wrap: wrap, + files: map[string]string{}, + } +} + // EnhancedArchive is an archive.Archive implementation which decorates an // archive.Archive adding wrap directory support, logging and windows // backslash fixes. type EnhancedArchive struct { - a archive.Archive - wrap string + a archive.Archive + wrap string + files map[string]string } // Add adds a file func (d EnhancedArchive) Add(name, path string) error { name = strings.Replace(filepath.Join(d.wrap, name), "\\", "/", -1) log.Debugf("adding file: %s as %s", path, name) + if _, ok := d.files[name]; ok { + return fmt.Errorf("file %s already exists in the archive", name) + } + d.files[name] = path return d.a.Add(name, path) } -// Close closes a file +// Close closes the underlying archive func (d EnhancedArchive) Close() error { return d.a.Close() } diff --git a/internal/pipe/archive/archive_test.go b/internal/pipe/archive/archive_test.go index e9c880757..439eafc94 100644 --- a/internal/pipe/archive/archive_test.go +++ b/internal/pipe/archive/archive_test.go @@ -5,12 +5,14 @@ import ( "archive/zip" "compress/gzip" "io" + "io/ioutil" "os" "path/filepath" "testing" "github.com/goreleaser/goreleaser/internal/artifact" "github.com/goreleaser/goreleaser/internal/testlib" + "github.com/goreleaser/goreleaser/pkg/archive" "github.com/goreleaser/goreleaser/pkg/config" "github.com/goreleaser/goreleaser/pkg/context" "github.com/stretchr/testify/require" @@ -501,3 +503,20 @@ func TestRunPipeSameArchiveFilename(t *testing.T) { require.Error(t, err) require.Contains(t, err.Error(), "same-filename.tar.gz already exists. Check your archive name template") } + +func TestDuplicateFilesInsideArchive(t *testing.T) { + f, err := ioutil.TempFile("", "") + require.NoError(t, err) + defer f.Close() + defer os.Remove(f.Name()) + + ff, err := ioutil.TempFile("", "") + require.NoError(t, err) + defer ff.Close() + defer os.Remove(ff.Name()) + + a := NewEnhancedArchive(archive.New(f), "") + defer a.Close() + require.NoError(t, a.Add("foo", ff.Name())) + require.EqualError(t, a.Add("foo", ff.Name()), "file foo already exists in the archive") +}