mirror of
https://github.com/goreleaser/nfpm
synced 2024-05-23 13:16:23 +02:00
fix: destinations for files containing matchers when globbing is disabled (#410)
* Fix destinations for files containing matchers when globbing is disabled. * Change test case to be compatible with Windows filesystem
This commit is contained in:
parent
e959f1d7c3
commit
206d797843
|
@ -8,7 +8,6 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/goreleaser/fileglob"
|
||||
"github.com/goreleaser/nfpm/v2/internal/glob"
|
||||
)
|
||||
|
||||
|
@ -143,11 +142,6 @@ func (c *Content) Sys() interface{} {
|
|||
|
||||
// ExpandContentGlobs gathers all of the real files to be copied into the package.
|
||||
func ExpandContentGlobs(contents Contents, disableGlobbing bool) (files Contents, err error) {
|
||||
options := []fileglob.OptFunc{fileglob.MatchDirectoryIncludesContents}
|
||||
if disableGlobbing {
|
||||
options = append(options, fileglob.QuoteMeta)
|
||||
}
|
||||
|
||||
for _, f := range contents {
|
||||
var globbed map[string]string
|
||||
|
||||
|
@ -157,7 +151,7 @@ func ExpandContentGlobs(contents Contents, disableGlobbing bool) (files Contents
|
|||
// them because they do not really exist
|
||||
files = append(files, f.WithFileInfoDefaults())
|
||||
default:
|
||||
globbed, err = glob.Glob(f.Source, f.Destination, options...)
|
||||
globbed, err = glob.Glob(f.Source, f.Destination, disableGlobbing)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package files_test
|
|||
|
||||
import (
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
|
@ -198,3 +199,52 @@ func TestCollision(t *testing.T) {
|
|||
require.ErrorIs(t, err, files.ErrContentCollision)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDisableGlobbing(t *testing.T) {
|
||||
testCases := []files.Content{
|
||||
{
|
||||
Source: "testdata/{test}/bar",
|
||||
Destination: "/etc/{test}/bar",
|
||||
},
|
||||
{
|
||||
Source: "testdata/{test}/[f]oo",
|
||||
Destination: "testdata/{test}/[f]oo",
|
||||
},
|
||||
{
|
||||
Source: "testdata/globtest/a.txt",
|
||||
Destination: "testdata/globtest/a.txt",
|
||||
},
|
||||
{
|
||||
Source: "testdata/globtest/a.txt",
|
||||
Destination: "/etc/a.txt",
|
||||
},
|
||||
}
|
||||
|
||||
disableGlobbing := true
|
||||
|
||||
for i, testCase := range testCases {
|
||||
content := testCase
|
||||
|
||||
t.Run(strconv.Itoa(i), func(t *testing.T) {
|
||||
result, err := files.ExpandContentGlobs(files.Contents{&content}, disableGlobbing)
|
||||
if err != nil {
|
||||
t.Fatalf("expand content globs: %v", err)
|
||||
}
|
||||
|
||||
if len(result) != 1 {
|
||||
t.Fatalf("unexpected result length: %d, expected one", len(result))
|
||||
}
|
||||
|
||||
actualContent := result[0]
|
||||
|
||||
// we expect the result content to be identical to the input content
|
||||
if actualContent.Source != content.Source {
|
||||
t.Fatalf("unexpected content source: %q, expected %q", actualContent.Source, content.Source)
|
||||
}
|
||||
|
||||
if actualContent.Destination != content.Destination {
|
||||
t.Fatalf("unexpected content destination: %q, expected %q", actualContent.Destination, content.Destination)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,7 +51,12 @@ func (e ErrGlobNoMatch) Error() string {
|
|||
// Glob returns a map with source file path as keys and destination as values.
|
||||
// First the longest common prefix (lcp) of all globbed files is found. The destination
|
||||
// for each globbed file is then dst joined with src with the lcp trimmed off.
|
||||
func Glob(pattern, dst string, options ...fileglob.OptFunc) (map[string]string, error) {
|
||||
func Glob(pattern, dst string, ignoreMatchers bool) (map[string]string, error) {
|
||||
options := []fileglob.OptFunc{fileglob.MatchDirectoryIncludesContents}
|
||||
if ignoreMatchers {
|
||||
options = append(options, fileglob.QuoteMeta)
|
||||
}
|
||||
|
||||
if strings.HasPrefix(pattern, "../") {
|
||||
p, err := filepath.Abs(pattern)
|
||||
if err != nil {
|
||||
|
@ -59,21 +64,24 @@ func Glob(pattern, dst string, options ...fileglob.OptFunc) (map[string]string,
|
|||
}
|
||||
pattern = filepath.ToSlash(p)
|
||||
}
|
||||
|
||||
matches, err := fileglob.Glob(pattern, append(options, fileglob.MaybeRootFS)...)
|
||||
if err != nil {
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
return nil, err
|
||||
}
|
||||
if err != nil {
|
||||
|
||||
return nil, fmt.Errorf("glob failed: %s: %w", pattern, err)
|
||||
}
|
||||
|
||||
if len(matches) == 0 {
|
||||
return nil, ErrGlobNoMatch{pattern}
|
||||
}
|
||||
|
||||
files := make(map[string]string)
|
||||
prefix := pattern
|
||||
// the prefix may not be a complete path or may use glob patterns, in that case use the parent directory
|
||||
if _, err := os.Stat(prefix); os.IsNotExist(err) || fileglob.ContainsMatchers(pattern) {
|
||||
if _, err := os.Stat(prefix); os.IsNotExist(err) || (fileglob.ContainsMatchers(pattern) && !ignoreMatchers) {
|
||||
prefix = filepath.Dir(longestCommonPrefix(matches))
|
||||
}
|
||||
|
||||
|
@ -82,13 +90,16 @@ func Glob(pattern, dst string, options ...fileglob.OptFunc) (map[string]string,
|
|||
if f, err := os.Stat(src); err == nil && f.Mode().IsDir() {
|
||||
continue
|
||||
}
|
||||
|
||||
relpath, err := filepath.Rel(prefix, src)
|
||||
if err != nil {
|
||||
// since prefix is a prefix of src a relative path should always be found
|
||||
panic(err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
globdst := filepath.ToSlash(filepath.Join(dst, relpath))
|
||||
files[src] = globdst
|
||||
}
|
||||
|
||||
return files, nil
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ func TestLongestCommonPrefix(t *testing.T) {
|
|||
|
||||
func TestGlob(t *testing.T) {
|
||||
t.Run("simple", func(t *testing.T) {
|
||||
files, err := Glob("./testdata/dir_a/dir_*/*", "/foo/bar")
|
||||
files, err := Glob("./testdata/dir_a/dir_*/*", "/foo/bar", false)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, files, 2)
|
||||
require.Equal(t, "/foo/bar/dir_b/test_b.txt", files["testdata/dir_a/dir_b/test_b.txt"])
|
||||
|
@ -51,47 +51,47 @@ func TestGlob(t *testing.T) {
|
|||
pattern := "../../testdata/fake"
|
||||
abs, err := filepath.Abs(pattern)
|
||||
require.NoError(t, err)
|
||||
files, err := Glob(pattern, "/foo/fake")
|
||||
files, err := Glob(pattern, "/foo/fake", false)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, files, 1)
|
||||
require.Equal(t, "/foo/fake", files[filepath.ToSlash(abs)])
|
||||
})
|
||||
|
||||
t.Run("single file", func(t *testing.T) {
|
||||
files, err := Glob("testdata/dir_a/dir_b/*", "/foo/bar")
|
||||
files, err := Glob("testdata/dir_a/dir_b/*", "/foo/bar", false)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, files, 1)
|
||||
require.Equal(t, "/foo/bar/test_b.txt", files["testdata/dir_a/dir_b/test_b.txt"])
|
||||
})
|
||||
|
||||
t.Run("double star", func(t *testing.T) {
|
||||
files, err := Glob("testdata/**/test*.txt", "/foo/bar")
|
||||
files, err := Glob("testdata/**/test*.txt", "/foo/bar", false)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, files, 3)
|
||||
require.Equal(t, "/foo/bar/dir_a/dir_b/test_b.txt", files["testdata/dir_a/dir_b/test_b.txt"])
|
||||
})
|
||||
|
||||
t.Run("nil value", func(t *testing.T) {
|
||||
files, err := Glob("does/not/exist", "/foo/bar")
|
||||
files, err := Glob("does/not/exist", "/foo/bar", false)
|
||||
require.EqualError(t, err, "matching \"./does/not/exist\": file does not exist")
|
||||
require.Nil(t, files)
|
||||
})
|
||||
|
||||
t.Run("no matches", func(t *testing.T) {
|
||||
files, err := Glob("testdata/nothing*", "/foo/bar")
|
||||
files, err := Glob("testdata/nothing*", "/foo/bar", false)
|
||||
require.Nil(t, files)
|
||||
require.EqualError(t, err, "glob failed: testdata/nothing*: no matching files")
|
||||
})
|
||||
|
||||
t.Run("escaped brace", func(t *testing.T) {
|
||||
files, err := Glob("testdata/\\{dir_d\\}/*", "/foo/bar")
|
||||
files, err := Glob("testdata/\\{dir_d\\}/*", "/foo/bar", false)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, files, 1)
|
||||
require.Equal(t, "/foo/bar/test_brace.txt", files["testdata/{dir_d}/test_brace.txt"])
|
||||
})
|
||||
|
||||
t.Run("no glob", func(t *testing.T) {
|
||||
files, err := Glob("testdata/dir_a/dir_b/test_b.txt", "/foo/bar/dest.dat")
|
||||
files, err := Glob("testdata/dir_a/dir_b/test_b.txt", "/foo/bar/dest.dat", false)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, files, 1)
|
||||
require.Equal(t, "/foo/bar/dest.dat", files["testdata/dir_a/dir_b/test_b.txt"])
|
||||
|
|
Loading…
Reference in New Issue