Repository: goreleaser/goreleaser
Pull request #3101 (2022-05-12 01:18:46)

refactor: evaluate archive files in another package
will be used in #2911

codecov[bot]: # [Codecov](https://codecov.io/gh/goreleaser/goreleaser/pull/3101?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser) Report
> Merging [#3101](https://codecov.io/gh/goreleaser/goreleaser/pull/3101?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser) (5230021) into [main](https://codecov.io/gh/goreleaser/goreleaser/commit/5d9110ab43870a8431e94b811087a795ee12c4f2?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser) (5d9110a) will **not change** coverage.
> The diff coverage is `100.00%`.

```diff
@@           Coverage Diff           @@
##             main    #3101   +/-   ##
=======================================
  Coverage   84.41%   84.41%           
=======================================
  Files         112      113    +1     
  Lines        9295     9295           
=======================================
  Hits         7846     7846           
  Misses       1176     1176           
  Partials      273      273           
```


| [Impacted Files](https://codecov.io/gh/goreleaser/goreleaser/pull/3101?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser) | Coverage Δ | |
|---|---|---|
| [internal/archivefiles/archivefiles.go](https://codecov.io/gh/goreleaser/goreleaser/pull/3101/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser#diff-aW50ZXJuYWwvYXJjaGl2ZWZpbGVzL2FyY2hpdmVmaWxlcy5nbw==) | `100.00% <100.00%> (ø)` | |
| [internal/pipe/archive/archive.go](https://codecov.io/gh/goreleaser/goreleaser/pull/3101/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser#diff-aW50ZXJuYWwvcGlwZS9hcmNoaXZlL2FyY2hpdmUuZ28=) | `93.57% <100.00%> (-1.10%)` | :arrow_down: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/goreleaser/goreleaser/pull/3101?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/goreleaser/goreleaser/pull/3101?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser). Last update [5d9110a...5230021](https://codecov.io/gh/goreleaser/goreleaser/pull/3101?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser).


Patch:
diff --git a/internal/archivefiles/archivefiles.go b/internal/archivefiles/archivefiles.go
new file mode 100644
index 00000000..84e61968
--- /dev/null
+++ b/internal/archivefiles/archivefiles.go
@@ -0,0 +1,74 @@
+// Package archivefiles can evaluate a list of config.Files into their final form.
+package archivefiles
+
+import (
+	"fmt"
+	"path/filepath"
+	"sort"
+
+	"github.com/apex/log"
+	"github.com/goreleaser/fileglob"
+	"github.com/goreleaser/goreleaser/internal/tmpl"
+	"github.com/goreleaser/goreleaser/pkg/config"
+)
+
+// Eval evaluates the given list of files to their final form.
+func Eval(template *tmpl.Template, files []config.File) ([]config.File, error) {
+	var result []config.File
+	for _, f := range files {
+		replaced, err := template.Apply(f.Source)
+		if err != nil {
+			return result, fmt.Errorf("failed to apply template %s: %w", f.Source, err)
+		}
+
+		files, err := fileglob.Glob(replaced)
+		if err != nil {
+			return result, fmt.Errorf("globbing failed for pattern %s: %w", f.Source, err)
+		}
+
+		for _, file := range files {
+			result = append(result, config.File{
+				Source:      file,
+				Destination: destinationFor(f, file),
+				Info:        f.Info,
+			})
+		}
+	}
+
+	sort.Slice(result, func(i, j int) bool {
+		return result[i].Destination < result[j].Destination
+	})
+
+	return unique(result), nil
+}
+
+// remove duplicates
+func unique(in []config.File) []config.File {
+	var result []config.File
+	exist := map[string]string{}
+	for _, f := range in {
+		if current := exist[f.Destination]; current != "" {
+			log.Warnf(
+				"file '%s' already exists in archive as '%s' - '%s' will be ignored",
+				f.Destination,
+				current,
+				f.Source,
+			)
+			continue
+		}
+		exist[f.Destination] = f.Source
+		result = append(result, f)
+	}
+
+	return result
+}
+
+func destinationFor(f config.File, path string) string {
+	if f.Destination == "" {
+		return path
+	}
+	if f.StripParent {
+		return filepath.Join(f.Destination, filepath.Base(path))
+	}
+	return filepath.Join(f.Destination, path)
+}
diff --git a/internal/archivefiles/testdata/a/a.txt b/internal/archivefiles/testdata/a/a.txt
new file mode 100644
index 00000000..e69de29b
diff --git a/internal/archivefiles/testdata/a/b/a.txt b/internal/archivefiles/testdata/a/b/a.txt
new file mode 100644
index 00000000..e69de29b
diff --git a/internal/archivefiles/testdata/a/b/c/d.txt b/internal/archivefiles/testdata/a/b/c/d.txt
new file mode 100644
index 00000000..e69de29b
diff --git a/internal/pipe/archive/archive.go b/internal/pipe/archive/archive.go
index d2297d58..566f4a21 100644
--- a/internal/pipe/archive/archive.go
+++ b/internal/pipe/archive/archive.go
@@ -8,12 +8,11 @@ import (
 	"fmt"
 	"os"
 	"path/filepath"
-	"sort"
 	"strings"
 	"sync"
 
 	"github.com/apex/log"
-	"github.com/goreleaser/fileglob"
+	"github.com/goreleaser/goreleaser/internal/archivefiles"
 	"github.com/goreleaser/goreleaser/internal/artifact"
 	"github.com/goreleaser/goreleaser/internal/ids"
 	"github.com/goreleaser/goreleaser/internal/semerrgroup"
@@ -171,7 +170,7 @@ func doCreate(ctx *context.Context, arch config.Archive, binaries []*artifact.Ar
 	a = NewEnhancedArchive(a, wrap)
 	defer a.Close()
 
-	files, err := findFiles(template, arch.Files)
+	files, err := archivefiles.Eval(template, arch.Files)
 	if err != nil {
 		return fmt.Errorf("failed to find files to archive: %w", err)
 	}
@@ -262,66 +261,6 @@ func skip(ctx *context.Context, archive config.Archive, binaries []*artifact.Art
 	return nil
 }
 
-func findFiles(template *tmpl.Template, files []config.File) ([]config.File, error) {
-	var result []config.File
-	for _, f := range files {
-		replaced, err := template.Apply(f.Source)
-		if err != nil {
-			return result, fmt.Errorf("failed to apply template %s: %w", f.Source, err)
-		}
-
-		files, err := fileglob.Glob(replaced)
-		if err != nil {
-			return result, fmt.Errorf("globbing failed for pattern %s: %w", f.Source, err)
-		}
-
-		for _, file := range files {
-			result = append(result, config.File{
-				Source:      file,
-				Destination: destinationFor(f, file),
-				Info:        f.Info,
-			})
-		}
-	}
-
-	sort.Slice(result, func(i, j int) bool {
-		return result[i].Destination < result[j].Destination
-	})
-
-	return unique(result), nil
-}
-
-// remove duplicates
-func unique(in []config.File) []config.File {
-	var result []config.File
-	exist := map[string]string{}
-	for _, f := range in {
-		if current := exist[f.Destination]; current != "" {
-			log.Warnf(
-				"file '%s' already exists in archive as '%s' - '%s' will be ignored",
-				f.Destination,
-				current,
-				f.Source,
-			)
-			continue
-		}
-		exist[f.Destination] = f.Source
-		result = append(result, f)
-	}
-
-	return result
-}
-
-func destinationFor(f config.File, path string) string {
-	if f.Destination == "" {
-		return path
-	}
-	if f.StripParent {
-		return filepath.Join(f.Destination, filepath.Base(path))
-	}
-	return filepath.Join(f.Destination, path)
-}
-
 func packageFormat(archive config.Archive, platform string) string {
 	for _, override := range archive.FormatOverrides {
 		if strings.HasPrefix(platform, override.Goos) {


Test patch:
diff --git a/internal/archivefiles/archivefiles_test.go b/internal/archivefiles/archivefiles_test.go
new file mode 100644
index 00000000..a67cf4e6
--- /dev/null
+++ b/internal/archivefiles/archivefiles_test.go
@@ -0,0 +1,133 @@
+package archivefiles
+
+import (
+	"testing"
+	"time"
+
+	"github.com/goreleaser/goreleaser/internal/tmpl"
+	"github.com/goreleaser/goreleaser/pkg/config"
+	"github.com/goreleaser/goreleaser/pkg/context"
+	"github.com/stretchr/testify/require"
+)
+
+func TestEval(t *testing.T) {
+	now := time.Now().Truncate(time.Second)
+	tmpl := tmpl.New(context.New(config.Project{}))
+
+	t.Run("single file", func(t *testing.T) {
+		result, err := Eval(tmpl, []config.File{
+			{
+				Source:      "./testdata/**/d.txt",
+				Destination: "var/foobar/d.txt",
+			},
+		})
+
+		require.NoError(t, err)
+		require.Equal(t, []config.File{
+			{
+				Source:      "testdata/a/b/c/d.txt",
+				Destination: "var/foobar/d.txt/testdata/a/b/c/d.txt",
+			},
+		}, result)
+	})
+
+	t.Run("match multiple files within tree without destination", func(t *testing.T) {
+		result, err := Eval(tmpl, []config.File{{Source: "./testdata/a"}})
+
+		require.NoError(t, err)
+		require.Equal(t, []config.File{
+			{Source: "testdata/a/a.txt", Destination: "testdata/a/a.txt"},
+			{Source: "testdata/a/b/a.txt", Destination: "testdata/a/b/a.txt"},
+			{Source: "testdata/a/b/c/d.txt", Destination: "testdata/a/b/c/d.txt"},
+		}, result)
+	})
+
+	t.Run("match multiple files within tree specific destination", func(t *testing.T) {
+		result, err := Eval(tmpl, []config.File{
+			{
+				Source:      "./testdata/a",
+				Destination: "usr/local/test",
+				Info: config.FileInfo{
+					Owner: "carlos",
+					Group: "users",
+					Mode:  0o755,
+					MTime: now,
+				},
+			},
+		})
+
+		require.NoError(t, err)
+		require.Equal(t, []config.File{
+			{
+				Source:      "testdata/a/a.txt",
+				Destination: "usr/local/test/testdata/a/a.txt",
+				Info: config.FileInfo{
+					Owner: "carlos",
+					Group: "users",
+					Mode:  0o755,
+					MTime: now,
+				},
+			},
+			{
+				Source:      "testdata/a/b/a.txt",
+				Destination: "usr/local/test/testdata/a/b/a.txt",
+				Info: config.FileInfo{
+					Owner: "carlos",
+					Group: "users",
+					Mode:  0o755,
+					MTime: now,
+				},
+			},
+			{
+				Source:      "testdata/a/b/c/d.txt",
+				Destination: "usr/local/test/testdata/a/b/c/d.txt",
+				Info: config.FileInfo{
+					Owner: "carlos",
+					Group: "users",
+					Mode:  0o755,
+					MTime: now,
+				},
+			},
+		}, result)
+	})
+
+	t.Run("match multiple files within tree specific destination stripping parents", func(t *testing.T) {
+		result, err := Eval(tmpl, []config.File{
+			{
+				Source:      "./testdata/a",
+				Destination: "usr/local/test",
+				StripParent: true,
+				Info: config.FileInfo{
+					Owner: "carlos",
+					Group: "users",
+					Mode:  0o755,
+					MTime: now,
+				},
+			},
+		})
+
+		require.NoError(t, err)
+		require.Equal(t, []config.File{
+			{
+				Source:      "testdata/a/a.txt",
+				Destination: "usr/local/test/a.txt",
+				Info: config.FileInfo{
+					Owner: "carlos",
+					Group: "users",
+					Mode:  0o755,
+					MTime: now,
+				},
+			},
+			{
+				Source:      "testdata/a/b/c/d.txt",
+				Destination: "usr/local/test/d.txt",
+				Info: config.FileInfo{
+					Owner: "carlos",
+					Group: "users",
+					Mode:  0o755,
+					MTime: now,
+				},
+			},
+		}, result)
+	})
+}
diff --git a/internal/pipe/archive/archive_test.go b/internal/pipe/archive/archive_test.go
index dab315b7..fa3685f1 100644
--- a/internal/pipe/archive/archive_test.go
+++ b/internal/pipe/archive/archive_test.go
@@ -9,11 +9,9 @@ import (
 	"os"
 	"path/filepath"
 	"testing"
-	"time"
 
 	"github.com/goreleaser/goreleaser/internal/artifact"
 	"github.com/goreleaser/goreleaser/internal/testlib"
-	"github.com/goreleaser/goreleaser/internal/tmpl"
 	"github.com/goreleaser/goreleaser/pkg/archive"
 	"github.com/goreleaser/goreleaser/pkg/config"
 	"github.com/goreleaser/goreleaser/pkg/context"
@@ -953,128 +951,6 @@ func TestSeveralArchivesWithTheSameID(t *testing.T) {
 	require.EqualError(t, Pipe{}.Default(ctx), "found 2 archives with the ID 'a', please fix your config")
 }
 
-func TestFindFiles(t *testing.T) {
-	now := time.Now().Truncate(time.Second)
-	tmpl := tmpl.New(context.New(config.Project{}))
-
-	t.Run("single file", func(t *testing.T) {
-		result, err := findFiles(tmpl, []config.File{
-			{
-				Source:      "./testdata/**/d.txt",
-				Destination: "var/foobar/d.txt",
-			},
-		})
-
-		require.NoError(t, err)
-		require.Equal(t, []config.File{
-			{
-				Source:      "testdata/a/b/c/d.txt",
-				Destination: "var/foobar/d.txt/testdata/a/b/c/d.txt",
-			},
-		}, result)
-	})
-
-	t.Run("match multiple files within tree without destination", func(t *testing.T) {
-		result, err := findFiles(tmpl, []config.File{{Source: "./testdata/a"}})
-
-		require.NoError(t, err)
-		require.Equal(t, []config.File{
-			{Source: "testdata/a/a.txt", Destination: "testdata/a/a.txt"},
-			{Source: "testdata/a/b/a.txt", Destination: "testdata/a/b/a.txt"},
-			{Source: "testdata/a/b/c/d.txt", Destination: "testdata/a/b/c/d.txt"},
-		}, result)
-	})
-
-	t.Run("match multiple files within tree specific destination", func(t *testing.T) {
-		result, err := findFiles(tmpl, []config.File{
-			{
-				Source:      "./testdata/a",
-				Destination: "usr/local/test",
-				Info: config.FileInfo{
-					Owner: "carlos",
-					Group: "users",
-					Mode:  0o755,
-					MTime: now,
-				},
-			},
-		})
-
-		require.NoError(t, err)
-		require.Equal(t, []config.File{
-			{
-				Source:      "testdata/a/a.txt",
-				Destination: "usr/local/test/testdata/a/a.txt",
-				Info: config.FileInfo{
-					Owner: "carlos",
-					Group: "users",
-					Mode:  0o755,
-					MTime: now,
-				},
-			},
-			{
-				Source:      "testdata/a/b/a.txt",
-				Destination: "usr/local/test/testdata/a/b/a.txt",
-				Info: config.FileInfo{
-					Owner: "carlos",
-					Group: "users",
-					Mode:  0o755,
-					MTime: now,
-				},
-			},
-			{
-				Source:      "testdata/a/b/c/d.txt",
-				Destination: "usr/local/test/testdata/a/b/c/d.txt",
-				Info: config.FileInfo{
-					Owner: "carlos",
-					Group: "users",
-					Mode:  0o755,
-					MTime: now,
-				},
-			},
-		}, result)
-	})
-
-	t.Run("match multiple files within tree specific destination stripping parents", func(t *testing.T) {
-		result, err := findFiles(tmpl, []config.File{
-			{
-				Source:      "./testdata/a",
-				Destination: "usr/local/test",
-				StripParent: true,
-				Info: config.FileInfo{
-					Owner: "carlos",
-					Group: "users",
-					Mode:  0o755,
-					MTime: now,
-				},
-			},
-		})
-
-		require.NoError(t, err)
-		require.Equal(t, []config.File{
-			{
-				Source:      "testdata/a/a.txt",
-				Destination: "usr/local/test/a.txt",
-				Info: config.FileInfo{
-					Owner: "carlos",
-					Group: "users",
-					Mode:  0o755,
-					MTime: now,
-				},
-			},
-			{
-				Source:      "testdata/a/b/c/d.txt",
-				Destination: "usr/local/test/d.txt",
-				Info: config.FileInfo{
-					Owner: "carlos",
-					Group: "users",
-					Mode:  0o755,
-					MTime: now,
-				},
-			},
-		}, result)
-	})
-}
-
 func TestArchive_globbing(t *testing.T) {
 	assertGlob := func(t *testing.T, files []config.File, expected []string) {
 		t.Helper()