feat: support .crushignore as well as .gitignore

Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>
This commit is contained in:
Carlos Alexandro Becker
2025-07-31 16:06:53 -03:00
committed by Kujtim Hoxha
parent 2c82ed2812
commit 5a6329cc34
3 changed files with 82 additions and 3 deletions

View File

@@ -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
}

View File

@@ -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")
})
}

View File

@@ -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 {