Repository: goreleaser/goreleaser
Pull request #870 (2018-11-11 21:03:14)

fix: uniq files inside archive
refs #836

<!--

Hi, thanks for contributing!

Please make sure you read our CONTRIBUTING guide.

Please fill the fields above:

-->

<!-- If applied, this commit will... -->

<!-- Why is this change being made? -->

<!-- # Provide links to any relevant tickets, URLs or other resources -->


codecov-io: # [Codecov](https://codecov.io/gh/goreleaser/goreleaser/pull/870?src=pr&el=h1) Report
> Merging [#870](https://codecov.io/gh/goreleaser/goreleaser/pull/870?src=pr&el=desc) into [master](https://codecov.io/gh/goreleaser/goreleaser/commit/7a6de727dd8f690bf799f31f1dc6b1f47be49e8d?src=pr&el=desc) will **increase** coverage by `0.04%`.
> The diff coverage is `100%`.

[![Impacted file tree graph](https://codecov.io/gh/goreleaser/goreleaser/pull/870/graphs/tree.svg?width=650&token=3bJvv6b7hN&height=150&src=pr)](https://codecov.io/gh/goreleaser/goreleaser/pull/870?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master     #870      +/-   ##
==========================================
+ Coverage   88.29%   88.33%   +0.04%     
==========================================
  Files          48       48              
  Lines        2332     2340       +8     
==========================================
+ Hits         2059     2067       +8     
  Misses        217      217              
  Partials       56       56
```


| [Impacted Files](https://codecov.io/gh/goreleaser/goreleaser/pull/870?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [internal/pipe/archive/archive.go](https://codecov.io/gh/goreleaser/goreleaser/pull/870/diff?src=pr&el=tree#diff-aW50ZXJuYWwvcGlwZS9hcmNoaXZlL2FyY2hpdmUuZ28=) | `93.1% <100%> (+0.51%)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/goreleaser/goreleaser/pull/870?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/goreleaser/goreleaser/pull/870?src=pr&el=footer). Last update [7a6de72...271833c](https://codecov.io/gh/goreleaser/goreleaser/pull/870?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/internal/pipe/archive/archive.go b/internal/pipe/archive/archive.go
index 458e97e0..6bab5c43 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()
 }


Test patch:
diff --git a/internal/pipe/archive/archive_test.go b/internal/pipe/archive/archive_test.go
index e9c88075..439eafc9 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")
+}