diff --git a/internal/ignore/rules.go b/internal/ignore/rules.go index 9bd25b6c..f24fb69d 100644 --- a/internal/ignore/rules.go +++ b/internal/ignore/rules.go @@ -94,6 +94,7 @@ func (r *Rules) AddDefaults() { r.parseRule("**/.agentuity-*") r.parseRule("**/biome.json") r.parseRule("**/.DS_Store") + r.parseRule("!setup.sh") // Explicitly don't ignore setup.sh } // Add a rule to the ignore set. @@ -152,6 +153,7 @@ func (r *Rules) Ignore(path string, fi os.FileInfo) bool { } var fullWildcard bool + var matched bool for n, p := range r.patterns { if p.match == nil { @@ -172,19 +174,19 @@ func (r *Rules) Ignore(path string, fi os.FileInfo) bool { if p.negate { // if full wildcard, we inverse the negation to only match files that match the following rules if fullWildcard { - if p.mustDir && fi.IsDir() { + if p.mustDir && fi != nil && fi.IsDir() { return false } if p.match(path, fi) { return false } } else { - // otherwise, we only match files that don't match the rule - if p.mustDir && !fi.IsDir() { - return true + // For negation rules, if the path matches the pattern, it should NOT be ignored + if p.mustDir && fi != nil && !fi.IsDir() { + continue } - if !p.match(path, fi) { - return true + if p.match(path, fi) { + return false } } continue @@ -192,14 +194,19 @@ func (r *Rules) Ignore(path string, fi os.FileInfo) bool { // If the rule is looking for directories, and this is not a directory, // skip it. - if p.mustDir && !fi.IsDir() { + if p.mustDir && fi != nil && !fi.IsDir() { continue } if p.match(path, fi) { - return true + matched = true + // Don't return immediately - keep checking for negation rules } } - return fullWildcard + + if fullWildcard { + return true + } + return matched } // parseRule parses a rule string and creates a pattern, which is then stored in the Rules object. diff --git a/internal/ignore/rules_test.go b/internal/ignore/rules_test.go index e0595d12..2c4f4345 100644 --- a/internal/ignore/rules_test.go +++ b/internal/ignore/rules_test.go @@ -36,12 +36,14 @@ func TestRules(t *testing.T) { assert.True(t, rules.Ignore("/Users/foobar/example/.foo.swp", nil)) assert.True(t, rules.Ignore("/Users/foobar/example/src/__test__/test_bar.py", nil)) assert.True(t, rules.Ignore("/Users/foobar/example/.agentuity-12345", nil)) + assert.False(t, rules.Ignore("/Users/foobar/setup.sh", nil)) } func TestNegateRules(t *testing.T) { rules := Empty() rules.AddDefaults() - rules.Add("!**/foo.py") + rules.Add("**/*.py") // First ignore all Python files + rules.Add("!**/foo.py") // Then negate foo.py specifically assert.False(t, rules.Ignore("/Users/foobar/example/src/foo.py", nil)) assert.False(t, rules.Ignore("foo.py", nil)) assert.True(t, rules.Ignore("bar.py", nil))