From 5200c491555ab1665cf280523f97bf92401c0415 Mon Sep 17 00:00:00 2001 From: Randolph Chung <112228989+avx-rchung@users.noreply.github.com> Date: Mon, 21 Nov 2022 06:47:38 -0800 Subject: [PATCH] fix: handle subdirectors and exclusions (#1012) (#1446) --- pkg/exprparser/functions.go | 32 +++++++++++++------ pkg/exprparser/functions_test.go | 6 +++- .../testdata/for-hashing-3/data.txt | 1 + .../for-hashing-3/nested/nested-data.txt | 1 + 4 files changed, 30 insertions(+), 10 deletions(-) create mode 100644 pkg/exprparser/testdata/for-hashing-3/data.txt create mode 100644 pkg/exprparser/testdata/for-hashing-3/nested/nested-data.txt diff --git a/pkg/exprparser/functions.go b/pkg/exprparser/functions.go index 37a38db..047a0e3 100644 --- a/pkg/exprparser/functions.go +++ b/pkg/exprparser/functions.go @@ -6,12 +6,14 @@ import ( "encoding/json" "fmt" "io" + "io/fs" "os" "path/filepath" "reflect" "strconv" "strings" + "github.com/go-git/go-git/v5/plumbing/format/gitignore" "github.com/nektos/act/pkg/model" "github.com/rhysd/actionlint" ) @@ -178,25 +180,37 @@ func (impl *interperterImpl) fromJSON(value reflect.Value) (interface{}, error) } func (impl *interperterImpl) hashFiles(paths ...reflect.Value) (string, error) { - var filepaths []string + var ps []gitignore.Pattern + const cwdPrefix = "." + string(filepath.Separator) + const excludeCwdPrefix = "!" + cwdPrefix for _, path := range paths { if path.Kind() == reflect.String { - filepaths = append(filepaths, path.String()) + cleanPath := path.String() + if strings.HasPrefix(cleanPath, cwdPrefix) { + cleanPath = cleanPath[len(cwdPrefix):] + } else if strings.HasPrefix(cleanPath, excludeCwdPrefix) { + cleanPath = "!" + cleanPath[len(excludeCwdPrefix):] + } + ps = append(ps, gitignore.ParsePattern(cleanPath, nil)) } else { return "", fmt.Errorf("Non-string path passed to hashFiles") } } + matcher := gitignore.NewMatcher(ps) + var files []string - - for i := range filepaths { - newFiles, err := filepath.Glob(filepath.Join(impl.config.WorkingDir, filepaths[i])) - if err != nil { - return "", fmt.Errorf("Unable to glob.Glob: %v", err) + if err := filepath.Walk(impl.config.WorkingDir, func(path string, fi fs.FileInfo, err error) error { + sansPrefix := strings.TrimPrefix(path, impl.config.WorkingDir+string(filepath.Separator)) + parts := strings.Split(sansPrefix, string(filepath.Separator)) + if fi.IsDir() || !matcher.Match(parts, fi.IsDir()) { + return nil } - - files = append(files, newFiles...) + files = append(files, path) + return nil + }); err != nil { + return "", fmt.Errorf("Unable to filepath.Walk: %v", err) } if len(files) == 0 { diff --git a/pkg/exprparser/functions_test.go b/pkg/exprparser/functions_test.go index 009e911..3c6392c 100644 --- a/pkg/exprparser/functions_test.go +++ b/pkg/exprparser/functions_test.go @@ -188,7 +188,11 @@ func TestFunctionHashFiles(t *testing.T) { {"hashFiles('**/non-extant-files') }}", "", "hash-non-existing-file"}, {"hashFiles('**/non-extant-files', '**/more-non-extant-files') }}", "", "hash-multiple-non-existing-files"}, {"hashFiles('./for-hashing-1.txt') }}", "66a045b452102c59d840ec097d59d9467e13a3f34f6494e539ffd32c1bb35f18", "hash-single-file"}, - {"hashFiles('./for-hashing-*') }}", "8e5935e7e13368cd9688fe8f48a0955293676a021562582c7e848dafe13fb046", "hash-multiple-files"}, + {"hashFiles('./for-hashing-*.txt') }}", "8e5935e7e13368cd9688fe8f48a0955293676a021562582c7e848dafe13fb046", "hash-multiple-files"}, + {"hashFiles('./for-hashing-*.txt', '!./for-hashing-2.txt') }}", "66a045b452102c59d840ec097d59d9467e13a3f34f6494e539ffd32c1bb35f18", "hash-negative-pattern"}, + {"hashFiles('./for-hashing-**') }}", "c418ba693753c84115ced0da77f876cddc662b9054f4b129b90f822597ee2f94", "hash-multiple-files-and-directories"}, + {"hashFiles('./for-hashing-3/**') }}", "6f5696b546a7a9d6d42a449dc9a56bef244aaa826601ef27466168846139d2c2", "hash-nested-directories"}, + {"hashFiles('./for-hashing-3/**/nested-data.txt') }}", "8ecadfb49f7f978d0a9f3a957e9c8da6cc9ab871f5203b5d9f9d1dc87d8af18c", "hash-nested-directories-2"}, } env := &EvaluationEnvironment{} diff --git a/pkg/exprparser/testdata/for-hashing-3/data.txt b/pkg/exprparser/testdata/for-hashing-3/data.txt new file mode 100644 index 0000000..5ac7bf9 --- /dev/null +++ b/pkg/exprparser/testdata/for-hashing-3/data.txt @@ -0,0 +1 @@ +Knock knock! diff --git a/pkg/exprparser/testdata/for-hashing-3/nested/nested-data.txt b/pkg/exprparser/testdata/for-hashing-3/nested/nested-data.txt new file mode 100644 index 0000000..ebe288b --- /dev/null +++ b/pkg/exprparser/testdata/for-hashing-3/nested/nested-data.txt @@ -0,0 +1 @@ +Anybody home?