104 lines
2.8 KiB
Go
104 lines
2.8 KiB
Go
package config
|
|
|
|
import (
|
|
"bufio"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
)
|
|
|
|
// IgnorePatterns holds parsed .agentignore patterns.
|
|
type IgnorePatterns struct {
|
|
patterns []string
|
|
raw string // original file content for injection into system prompt
|
|
}
|
|
|
|
// LoadIgnoreFile reads and parses an .agentignore file from the given directory.
|
|
// Returns nil if no .agentignore file exists (not an error).
|
|
func LoadIgnoreFile(dir string) *IgnorePatterns {
|
|
path := filepath.Join(dir, ".agentignore")
|
|
f, err := os.Open(path)
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
defer f.Close()
|
|
|
|
var patterns []string
|
|
var rawLines []string
|
|
|
|
scanner := bufio.NewScanner(f)
|
|
for scanner.Scan() {
|
|
line := scanner.Text()
|
|
rawLines = append(rawLines, line)
|
|
|
|
trimmed := strings.TrimSpace(line)
|
|
// Skip empty lines and comments.
|
|
if trimmed == "" || strings.HasPrefix(trimmed, "#") {
|
|
continue
|
|
}
|
|
patterns = append(patterns, trimmed)
|
|
}
|
|
|
|
return &IgnorePatterns{
|
|
patterns: patterns,
|
|
raw: strings.Join(rawLines, "\n"),
|
|
}
|
|
}
|
|
|
|
// Match returns true if the given path should be ignored.
|
|
// Returns false if the receiver is nil.
|
|
func (ip *IgnorePatterns) Match(path string) bool {
|
|
if ip == nil || len(ip.patterns) == 0 {
|
|
return false
|
|
}
|
|
|
|
// Normalise the path separators and remove trailing slashes for comparison.
|
|
path = filepath.ToSlash(path)
|
|
cleanPath := strings.TrimSuffix(path, "/")
|
|
|
|
for _, pattern := range ip.patterns {
|
|
pat := strings.TrimSuffix(pattern, "/")
|
|
|
|
// Check each component of the path against the pattern.
|
|
// e.g. "node_modules" should match "node_modules", "node_modules/foo",
|
|
// and "src/node_modules/bar".
|
|
parts := strings.Split(cleanPath, "/")
|
|
for _, part := range parts {
|
|
if matched, _ := filepath.Match(pat, part); matched {
|
|
return true
|
|
}
|
|
}
|
|
|
|
// Also try matching the full path with the pattern (for glob patterns
|
|
// that include path separators like "build/output").
|
|
if matched, _ := filepath.Match(pat, cleanPath); matched {
|
|
return true
|
|
}
|
|
|
|
// Prefix match: path starts with the pattern directory.
|
|
if strings.HasPrefix(cleanPath, pat+"/") || cleanPath == pat {
|
|
return true
|
|
}
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
// Raw returns the raw file content for system prompt injection.
|
|
// Returns an empty string if the receiver is nil.
|
|
func (ip *IgnorePatterns) Raw() string {
|
|
if ip == nil {
|
|
return ""
|
|
}
|
|
return ip.raw
|
|
}
|
|
|
|
// Patterns returns the list of patterns.
|
|
// Returns nil if the receiver is nil.
|
|
func (ip *IgnorePatterns) Patterns() []string {
|
|
if ip == nil {
|
|
return nil
|
|
}
|
|
return ip.patterns
|
|
}
|