nub/internal/tool/builtin/gitignore.go
Tom a97013d876 initial commit
- v 0.1.0 siehe CHANGELOG.md
2026-07-25 11:08:01 +02:00

53 lines
1.3 KiB
Go

package builtin
import (
"os"
"path/filepath"
"strings"
"github.com/bmatcuk/doublestar/v4"
)
// gitignore ist eine einfache, ausreichende Umsetzung: liest .gitignore im
// RepoRoot (keine verschachtelten .gitignore-Dateien, keine Negationen) und
// matcht Zeilen als doublestar-Patterns gegen den repo-relativen Pfad.
type gitignore struct {
patterns []string
}
func loadGitignore(repoRoot string) gitignore {
g := gitignore{patterns: []string{".git/**"}}
data, err := os.ReadFile(filepath.Join(repoRoot, ".gitignore"))
if err != nil {
return g
}
for _, line := range strings.Split(string(data), "\n") {
line = strings.TrimSpace(line)
if line == "" || strings.HasPrefix(line, "#") || strings.HasPrefix(line, "!") {
continue
}
line = strings.TrimPrefix(line, "/")
if strings.HasSuffix(line, "/") {
line += "**"
}
g.patterns = append(g.patterns, line, line+"/**")
}
return g
}
func (g gitignore) match(relPath string) bool {
relPath = filepath.ToSlash(relPath)
for _, p := range g.patterns {
if ok, _ := doublestar.Match(p, relPath); ok {
return true
}
// Auch gegen den Basename matchen, wie git es für unqualifizierte
// Patterns ohne "/" tut.
if !strings.Contains(p, "/") {
if ok, _ := doublestar.Match(p, filepath.Base(relPath)); ok {
return true
}
}
}
return false
}