1
0
mirror of https://github.com/goreleaser/goreleaser.git synced 2025-03-25 21:29:14 +02:00

refactor: evaluate archive files in another package (#3101)

* refactor: evaluate archive files in another package

would be used in #2911

Signed-off-by: Carlos A Becker <caarlos0@users.noreply.github.com>

* test: fixes

Signed-off-by: Carlos A Becker <caarlos0@users.noreply.github.com>
This commit is contained in:
Carlos Alexandro Becker 2022-05-11 22:56:25 -03:00 committed by GitHub
parent 5d9110ab43
commit 9c426a7b16
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 209 additions and 187 deletions

View File

@ -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)
}

View File

@ -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)
})
}

View File

View File

View File

View File

@ -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) {

View File

@ -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()