From d9cfebb97482769495b38d8e14920a4b79b17c95 Mon Sep 17 00:00:00 2001 From: Justin Chadwell Date: Mon, 19 Feb 2024 14:12:50 +0000 Subject: [PATCH] filter: ensure MapResult is followed for parent directories Similar to the previous commit, we weren't properly respecting MapResult return values for parent directories. To resolve this, we just store into `skipFn` just like previously, and return `SkipDir` instead of `continue`ing on. After these changes, the new test passes, and we don't end up including entries that were in excluded directories, as was happening before: Error: Not equal: expected: "dir y\nfile y/b.txt\n" actual : "file x/a.txt\ndir y\nfile y/b.txt\n" Signed-off-by: Justin Chadwell --- filter.go | 5 ++++- filter_test.go | 27 +++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/filter.go b/filter.go index 989dd178..9cee8ad2 100644 --- a/filter.go +++ b/filter.go @@ -356,8 +356,11 @@ func (fs *filterFS) Walk(ctx context.Context, target string, fn gofs.WalkDirFunc } if fs.mapFn != nil { result := fs.mapFn(parentStat.Path, parentStat) - if result == MapResultSkipDir || result == MapResultExclude { + if result == MapResultExclude { continue + } else if result == MapResultSkipDir { + parentDirs[i].skipFn = true + return filepath.SkipDir } } diff --git a/filter_test.go b/filter_test.go index d3231675..406425da 100644 --- a/filter_test.go +++ b/filter_test.go @@ -332,6 +332,33 @@ file includeDir/a.txt assert.Equal(t, []string{"excludeDir", "includeDir", filepath.FromSlash("includeDir/a.txt")}, walked) } +func TestWalkerMapSkipDirWithPattern(t *testing.T) { + d, err := tmpDir(changeStream([]string{ + "ADD x dir", + "ADD x/a.txt file", + "ADD y dir", + "ADD y/b.txt file", + })) + assert.NoError(t, err) + defer os.RemoveAll(d) + + b := &bytes.Buffer{} + err = Walk(context.Background(), d, &FilterOpt{ + IncludePatterns: []string{"**/*.txt"}, + Map: func(_ string, s *types.Stat) MapResult { + if filepath.Base(s.Path) == "x" { + return MapResultSkipDir + } + return MapResultKeep + }, + }, bufWalk(b)) + assert.NoError(t, err) + + assert.Equal(t, filepath.FromSlash(`dir y +file y/b.txt +`), b.String()) +} + func TestWalkerPermissionDenied(t *testing.T) { if runtime.GOOS == "windows" { t.Skip("os.Chmod not fully supported on Windows")