on main help sign in
feat: support .crushignore as well as .gitignore

Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>

commit5a6329cc343a16df1b0441fc6d1932b6aed68edd authorCarlos Alexandro Becker <caarlos0@users.noreply.github.com> dateThu 31 Jul 2025, 16:06 (1 year ago) parent2c82ed2
3 files changed+82−3
internal/fsext/fileutil.go+24−3 internal/fsext/ignore_test.go+44 internal/fsext/ls.go+14
internal/fsext/fileutil.go+24−3
@@ -107,8 +107,9 @@ func SkipHidden(path string) bool {
107107
108108// FastGlobWalker provides gitignore-aware file walking with fastwalk
109109type FastGlobWalker struct {
110− gitignore *ignore.GitIgnore
111− rootPath string
110+ gitignore *ignore.GitIgnore
111+ crushignore *ignore.GitIgnore
112+ rootPath string
112113}
113114
114115func NewFastGlobWalker(searchPath string) *FastGlobWalker {
@@ -124,6 +125,14 @@ func NewFastGlobWalker(searchPath string) *FastGlobWalker {
124125 }
125126 }
126127
128+ // Load crushignore if it exists
129+ crushignorePath := filepath.Join(searchPath, ".crushignore")
130+ if _, err := os.Stat(crushignorePath); err == nil {
131+ if ci, err := ignore.CompileIgnoreFile(crushignorePath); err == nil {
132+ walker.crushignore = ci
133+ }
134+ }
135+
127136 return walker
128137}
129138
@@ -132,13 +141,25 @@ func (w *FastGlobWalker) shouldSkip(path string) bool {
132141 return true
133142 }
134143
144+ relPath, err := filepath.Rel(w.rootPath, path)
145+ if err != nil {
146+ relPath = path
147+ }
148+
149+ // Check gitignore patterns if available
135150 if w.gitignore != nil {
136− relPath, err := filepath.Rel(w.rootPath, path)
137151 if err == nil && w.gitignore.MatchesPath(relPath) {
138152 return true
139153 }
140154 }
141155
156+ // Check crushignore patterns if available
157+ if w.crushignore != nil {
158+ if err == nil && w.crushignore.MatchesPath(relPath) {
159+ return true
160+ }
161+ }
162+
142163 return false
143164}
144165
internal/fsext/ignore_test.gonew file+44
@@ -0,0 +1,44 @@
1+package fsext
2+
3+import (
4+ "os"
5+ "testing"
6+
7+ "github.com/stretchr/testify/require"
8+)
9+
10+func TestCrushIgnore(t *testing.T) {
11+ // Create a temporary directory for testing
12+ tempDir := t.TempDir()
13+
14+ // Change to temp directory
15+ oldWd, _ := os.Getwd()
16+ err := os.Chdir(tempDir)
17+ require.NoError(t, err)
18+ defer os.Chdir(oldWd)
19+
20+ // Create test files
21+ require.NoError(t, os.WriteFile("test1.txt", []byte("test"), 0644))
22+ require.NoError(t, os.WriteFile("test2.log", []byte("test"), 0644))
23+ require.NoError(t, os.WriteFile("test3.tmp", []byte("test"), 0644))
24+
25+ // Create a .crushignore file that ignores .log files
26+ require.NoError(t, os.WriteFile(".crushignore", []byte("*.log\n"), 0644))
27+
28+ // Test DirectoryLister
29+ t.Run("DirectoryLister respects .crushignore", func(t *testing.T) {
30+ dl := NewDirectoryLister(tempDir)
31+
32+ // Test that .log files are ignored
33+ require.True(t, dl.gitignore == nil, "gitignore should be nil")
34+ require.NotNil(t, dl.crushignore, "crushignore should not be nil")
35+ })
36+
37+ // Test FastGlobWalker
38+ t.Run("FastGlobWalker respects .crushignore", func(t *testing.T) {
39+ walker := NewFastGlobWalker(tempDir)
40+
41+ require.True(t, walker.gitignore == nil, "gitignore should be nil")
42+ require.NotNil(t, walker.crushignore, "crushignore should not be nil")
43+ })
44+}
internal/fsext/ls.go+14
@@ -68,6 +68,7 @@ var CommonIgnorePatterns = []string{
6868
6969type DirectoryLister struct {
7070 gitignore *ignore.GitIgnore
71+ crushignore *ignore.GitIgnore
7172 commonIgnore *ignore.GitIgnore
7273 rootPath string
7374}
@@ -85,6 +86,14 @@ func NewDirectoryLister(rootPath string) *DirectoryLister {
8586 }
8687 }
8788
89+ // Load crushignore if it exists
90+ crushignorePath := filepath.Join(rootPath, ".crushignore")
91+ if _, err := os.Stat(crushignorePath); err == nil {
92+ if ci, err := ignore.CompileIgnoreFile(crushignorePath); err == nil {
93+ dl.crushignore = ci
94+ }
95+ }
96+
8897 // Create common ignore patterns
8998 dl.commonIgnore = ignore.CompileIgnoreLines(CommonIgnorePatterns...)
9099
@@ -107,6 +116,11 @@ func (dl *DirectoryLister) shouldIgnore(path string, ignorePatterns []string) bo
107116 return true
108117 }
109118
119+ // Check crushignore patterns if available
120+ if dl.crushignore != nil && dl.crushignore.MatchesPath(relPath) {
121+ return true
122+ }
123+
110124 base := filepath.Base(path)
111125
112126 for _, pattern := range ignorePatterns {