53 lines
1.3 KiB
Go
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
|
|
}
|