Skip to content

Commit

Permalink
refactor: evaluate archive files in another package
Browse files Browse the repository at this point in the history
would be used in #2911

Signed-off-by: Carlos A Becker <caarlos0@users.noreply.github.com>
  • Loading branch information
caarlos0 committed May 12, 2022
1 parent 5d9110a commit 9e9c5b3
Show file tree
Hide file tree
Showing 4 changed files with 209 additions and 187 deletions.
74 changes: 74 additions & 0 deletions 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)
}
133 changes: 133 additions & 0 deletions 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)
})
}
65 changes: 2 additions & 63 deletions internal/pipe/archive/archive.go
Expand Up @@ -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"
Expand Down Expand Up @@ -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)
}
Expand Down Expand Up @@ -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) {
Expand Down

0 comments on commit 9e9c5b3

Please sign in to comment.