diff --git a/internal/fsext/fileutil.go b/internal/fsext/fileutil.go index 462dcc6761f261a5be02658317884eb64fb07ebc..a5b23c5bc81e1ac6e9019318aadbe14bd20cbb7e 100644 --- a/internal/fsext/fileutil.go +++ b/internal/fsext/fileutil.go @@ -107,8 +107,9 @@ func SkipHidden(path string) bool { // FastGlobWalker provides gitignore-aware file walking with fastwalk type FastGlobWalker struct { - gitignore *ignore.GitIgnore - rootPath string + gitignore *ignore.GitIgnore + crushignore *ignore.GitIgnore + rootPath string } func NewFastGlobWalker(searchPath string) *FastGlobWalker { @@ -124,6 +125,14 @@ func NewFastGlobWalker(searchPath string) *FastGlobWalker { } } + // Load crushignore if it exists + crushignorePath := filepath.Join(searchPath, ".crushignore") + if _, err := os.Stat(crushignorePath); err == nil { + if ci, err := ignore.CompileIgnoreFile(crushignorePath); err == nil { + walker.crushignore = ci + } + } + return walker } @@ -132,13 +141,25 @@ func (w *FastGlobWalker) shouldSkip(path string) bool { return true } + relPath, err := filepath.Rel(w.rootPath, path) + if err != nil { + relPath = path + } + + // Check gitignore patterns if available if w.gitignore != nil { - relPath, err := filepath.Rel(w.rootPath, path) if err == nil && w.gitignore.MatchesPath(relPath) { return true } } + // Check crushignore patterns if available + if w.crushignore != nil { + if err == nil && w.crushignore.MatchesPath(relPath) { + return true + } + } + return false } diff --git a/internal/fsext/ignore_test.go b/internal/fsext/ignore_test.go new file mode 100644 index 0000000000000000000000000000000000000000..668e8383e5268684bda89cd699cb10428becd9a7 --- /dev/null +++ b/internal/fsext/ignore_test.go @@ -0,0 +1,44 @@ +package fsext + +import ( + "os" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestCrushIgnore(t *testing.T) { + // Create a temporary directory for testing + tempDir := t.TempDir() + + // Change to temp directory + oldWd, _ := os.Getwd() + err := os.Chdir(tempDir) + require.NoError(t, err) + defer os.Chdir(oldWd) + + // Create test files + require.NoError(t, os.WriteFile("test1.txt", []byte("test"), 0644)) + require.NoError(t, os.WriteFile("test2.log", []byte("test"), 0644)) + require.NoError(t, os.WriteFile("test3.tmp", []byte("test"), 0644)) + + // Create a .crushignore file that ignores .log files + require.NoError(t, os.WriteFile(".crushignore", []byte("*.log\n"), 0644)) + + // Test DirectoryLister + t.Run("DirectoryLister respects .crushignore", func(t *testing.T) { + dl := NewDirectoryLister(tempDir) + + // Test that .log files are ignored + require.True(t, dl.gitignore == nil, "gitignore should be nil") + require.NotNil(t, dl.crushignore, "crushignore should not be nil") + }) + + // Test FastGlobWalker + t.Run("FastGlobWalker respects .crushignore", func(t *testing.T) { + walker := NewFastGlobWalker(tempDir) + + require.True(t, walker.gitignore == nil, "gitignore should be nil") + require.NotNil(t, walker.crushignore, "crushignore should not be nil") + }) +} \ No newline at end of file diff --git a/internal/fsext/ls.go b/internal/fsext/ls.go index 2c08fd1c294cd35e8dfc436e8272004b68098b68..e800e921de74e41a9d46f4d1fafd6fc59bcf65a0 100644 --- a/internal/fsext/ls.go +++ b/internal/fsext/ls.go @@ -68,6 +68,7 @@ var CommonIgnorePatterns = []string{ type DirectoryLister struct { gitignore *ignore.GitIgnore + crushignore *ignore.GitIgnore commonIgnore *ignore.GitIgnore rootPath string } @@ -85,6 +86,14 @@ func NewDirectoryLister(rootPath string) *DirectoryLister { } } + // Load crushignore if it exists + crushignorePath := filepath.Join(rootPath, ".crushignore") + if _, err := os.Stat(crushignorePath); err == nil { + if ci, err := ignore.CompileIgnoreFile(crushignorePath); err == nil { + dl.crushignore = ci + } + } + // Create common ignore patterns dl.commonIgnore = ignore.CompileIgnoreLines(CommonIgnorePatterns...) @@ -107,6 +116,11 @@ func (dl *DirectoryLister) shouldIgnore(path string, ignorePatterns []string) bo return true } + // Check crushignore patterns if available + if dl.crushignore != nil && dl.crushignore.MatchesPath(relPath) { + return true + } + base := filepath.Base(path) for _, pattern := range ignorePatterns {