From 78e057e9cb61713c602adb420096e54ef6268c92 Mon Sep 17 00:00:00 2001 From: Valentin Maerten Date: Sat, 4 Apr 2026 10:29:45 +0200 Subject: [PATCH] wip --- internal/fingerprint/gitignore.go | 20 ++++++++++++++------ internal/fingerprint/gitignore_test.go | 8 ++++---- internal/fingerprint/glob.go | 4 ++-- internal/fingerprint/sources.go | 6 +++--- internal/fingerprint/sources_checksum.go | 6 ++---- internal/fingerprint/sources_timestamp.go | 10 ++++------ internal/fingerprint/task.go | 9 +-------- status.go | 2 +- task.go | 1 - variables.go | 13 ++++++------- watch.go | 2 +- 11 files changed, 38 insertions(+), 43 deletions(-) diff --git a/internal/fingerprint/gitignore.go b/internal/fingerprint/gitignore.go index 43b40671..62287f0d 100644 --- a/internal/fingerprint/gitignore.go +++ b/internal/fingerprint/gitignore.go @@ -14,13 +14,16 @@ type gitignoreRule struct { matcher *ignore.GitIgnore } -// loadGitignoreRules reads .gitignore files walking up from dir to rootDir. -func loadGitignoreRules(rootDir, dir string) []gitignoreRule { - rootDir, _ = filepath.Abs(rootDir) +// loadGitignoreRules walks up from dir collecting .gitignore files. +// Stops at the first .git (file or directory) found. +// Returns nil if no .git is found (not in a git repo). +func loadGitignoreRules(dir string) []gitignoreRule { dir, _ = filepath.Abs(dir) var rules []gitignoreRule + foundGit := false current := dir + for { lines := readGitignoreLines(filepath.Join(current, ".gitignore")) if len(lines) > 0 { @@ -29,7 +32,8 @@ func loadGitignoreRules(rootDir, dir string) []gitignoreRule { matcher: ignore.CompileIgnoreLines(lines...), }) } - if current == rootDir { + if _, err := os.Stat(filepath.Join(current, ".git")); err == nil { + foundGit = true break } parent := filepath.Dir(current) @@ -39,6 +43,10 @@ func loadGitignoreRules(rootDir, dir string) []gitignoreRule { current = parent } + if !foundGit { + return nil + } + return rules } @@ -61,8 +69,8 @@ func readGitignoreLines(path string) []string { } // filterGitignored removes entries from the file map that match gitignore rules. -func filterGitignored(files map[string]bool, rootDir, dir string) map[string]bool { - rules := loadGitignoreRules(rootDir, dir) +func filterGitignored(files map[string]bool, dir string) map[string]bool { + rules := loadGitignoreRules(dir) if len(rules) == 0 { return files } diff --git a/internal/fingerprint/gitignore_test.go b/internal/fingerprint/gitignore_test.go index 2a09fdb6..1c5118f8 100644 --- a/internal/fingerprint/gitignore_test.go +++ b/internal/fingerprint/gitignore_test.go @@ -34,10 +34,10 @@ func TestGlobsWithGitignore(t *testing.T) { {Glob: "./*"}, } - filesWithout, err := Globs(dir, globs, false, dir) + filesWithout, err := Globs(dir, globs, false) require.NoError(t, err) - filesWith, err := Globs(dir, globs, true, dir) + filesWith, err := Globs(dir, globs, true) require.NoError(t, err) hasLog := false @@ -91,7 +91,7 @@ func TestGlobsWithGitignoreNested(t *testing.T) { {Glob: "./*"}, } - files, err := Globs(subDir, globs, true, dir) + files, err := Globs(subDir, globs, true) require.NoError(t, err) for _, f := range files { @@ -112,7 +112,7 @@ func TestGlobsWithGitignoreNoRepo(t *testing.T) { {Glob: "./*"}, } - files, err := Globs(dir, globs, true, dir) + files, err := Globs(dir, globs, true) require.NoError(t, err) assert.Len(t, files, 1) } diff --git a/internal/fingerprint/glob.go b/internal/fingerprint/glob.go index f19da358..c87c9ec3 100644 --- a/internal/fingerprint/glob.go +++ b/internal/fingerprint/glob.go @@ -10,7 +10,7 @@ import ( "github.com/go-task/task/v3/taskfile/ast" ) -func Globs(dir string, globs []*ast.Glob, gitignore bool, rootDir string) ([]string, error) { +func Globs(dir string, globs []*ast.Glob, gitignore bool) ([]string, error) { resultMap := make(map[string]bool) for _, g := range globs { matches, err := glob(dir, g.Glob) @@ -23,7 +23,7 @@ func Globs(dir string, globs []*ast.Glob, gitignore bool, rootDir string) ([]str } if gitignore { - resultMap = filterGitignored(resultMap, rootDir, dir) + resultMap = filterGitignored(resultMap, dir) } return collectKeys(resultMap), nil diff --git a/internal/fingerprint/sources.go b/internal/fingerprint/sources.go index 54303a46..34d3a04b 100644 --- a/internal/fingerprint/sources.go +++ b/internal/fingerprint/sources.go @@ -2,12 +2,12 @@ package fingerprint import "fmt" -func NewSourcesChecker(method, tempDir string, dry bool, rootDir string) (SourcesCheckable, error) { +func NewSourcesChecker(method, tempDir string, dry bool) (SourcesCheckable, error) { switch method { case "timestamp": - return NewTimestampChecker(tempDir, dry, rootDir), nil + return NewTimestampChecker(tempDir, dry), nil case "checksum": - return NewChecksumChecker(tempDir, dry, rootDir), nil + return NewChecksumChecker(tempDir, dry), nil case "none": return NoneChecker{}, nil default: diff --git a/internal/fingerprint/sources_checksum.go b/internal/fingerprint/sources_checksum.go index 94a97a6d..ef9e7387 100644 --- a/internal/fingerprint/sources_checksum.go +++ b/internal/fingerprint/sources_checksum.go @@ -19,14 +19,12 @@ import ( type ChecksumChecker struct { tempDir string dry bool - rootDir string } -func NewChecksumChecker(tempDir string, dry bool, rootDir string) *ChecksumChecker { +func NewChecksumChecker(tempDir string, dry bool) *ChecksumChecker { return &ChecksumChecker{ tempDir: tempDir, dry: dry, - rootDir: rootDir, } } @@ -91,7 +89,7 @@ func (*ChecksumChecker) Kind() string { } func (c *ChecksumChecker) checksum(t *ast.Task) (string, error) { - sources, err := Globs(t.Dir, t.Sources, t.IsGitignore(), c.rootDir) + sources, err := Globs(t.Dir, t.Sources, t.IsGitignore()) if err != nil { return "", err } diff --git a/internal/fingerprint/sources_timestamp.go b/internal/fingerprint/sources_timestamp.go index 003e0a26..5d482851 100644 --- a/internal/fingerprint/sources_timestamp.go +++ b/internal/fingerprint/sources_timestamp.go @@ -13,14 +13,12 @@ import ( type TimestampChecker struct { tempDir string dry bool - rootDir string } -func NewTimestampChecker(tempDir string, dry bool, rootDir string) *TimestampChecker { +func NewTimestampChecker(tempDir string, dry bool) *TimestampChecker { return &TimestampChecker{ tempDir: tempDir, dry: dry, - rootDir: rootDir, } } @@ -30,7 +28,7 @@ func (checker *TimestampChecker) IsUpToDate(t *ast.Task) (bool, error) { return false, nil } - sources, err := Globs(t.Dir, t.Sources, t.IsGitignore(), checker.rootDir) + sources, err := Globs(t.Dir, t.Sources, t.IsGitignore()) if err != nil { return false, nil } @@ -56,7 +54,7 @@ func (checker *TimestampChecker) IsUpToDate(t *ast.Task) (bool, error) { } } - generates, err := Globs(t.Dir, t.Generates, t.IsGitignore(), checker.rootDir) + generates, err := Globs(t.Dir, t.Generates, t.IsGitignore()) if err != nil { return false, nil } @@ -114,7 +112,7 @@ func (checker *TimestampChecker) Kind() string { // Value implements the Checker Interface func (checker *TimestampChecker) Value(t *ast.Task) (any, error) { - sources, err := Globs(t.Dir, t.Sources, t.IsGitignore(), checker.rootDir) + sources, err := Globs(t.Dir, t.Sources, t.IsGitignore()) if err != nil { return time.Now(), err } diff --git a/internal/fingerprint/task.go b/internal/fingerprint/task.go index ca8e18b9..2b48e114 100644 --- a/internal/fingerprint/task.go +++ b/internal/fingerprint/task.go @@ -13,7 +13,6 @@ type ( method string dry bool tempDir string - rootDir string logger *logger.Logger statusChecker StatusCheckable sourcesChecker SourcesCheckable @@ -38,12 +37,6 @@ func WithTempDir(tempDir string) CheckerOption { } } -func WithRootDir(rootDir string) CheckerOption { - return func(config *CheckerConfig) { - config.rootDir = rootDir - } -} - func WithLogger(logger *logger.Logger) CheckerOption { return func(config *CheckerConfig) { config.logger = logger @@ -93,7 +86,7 @@ func IsTaskUpToDate( // If no sources checker was given, set up the default one if config.sourcesChecker == nil { - config.sourcesChecker, err = NewSourcesChecker(config.method, config.tempDir, config.dry, config.rootDir) + config.sourcesChecker, err = NewSourcesChecker(config.method, config.tempDir, config.dry) if err != nil { return false, err } diff --git a/status.go b/status.go index 8680d527..ae40f5ba 100644 --- a/status.go +++ b/status.go @@ -46,7 +46,7 @@ func (e *Executor) statusOnError(t *ast.Task) error { if method == "" { method = e.Taskfile.Method } - checker, err := fingerprint.NewSourcesChecker(method, e.TempDir.Fingerprint, e.Dry, e.Dir) + checker, err := fingerprint.NewSourcesChecker(method, e.TempDir.Fingerprint, e.Dry) if err != nil { return err } diff --git a/task.go b/task.go index fa2842e4..54cda927 100644 --- a/task.go +++ b/task.go @@ -231,7 +231,6 @@ func (e *Executor) RunTask(ctx context.Context, call *Call) error { fingerprint.WithTempDir(e.TempDir.Fingerprint), fingerprint.WithDry(e.Dry), fingerprint.WithLogger(e.Logger), - fingerprint.WithRootDir(e.Dir), ) if err != nil { return err diff --git a/variables.go b/variables.go index 7f4054bf..18d716a5 100644 --- a/variables.go +++ b/variables.go @@ -203,9 +203,9 @@ func (e *Executor) compiledTask(call *Call, evaluateShVars bool) (*ast.Task, err var checker fingerprint.SourcesCheckable if origTask.Method == "timestamp" { - checker = fingerprint.NewTimestampChecker(e.TempDir.Fingerprint, e.Dry, e.Dir) + checker = fingerprint.NewTimestampChecker(e.TempDir.Fingerprint, e.Dry) } else { - checker = fingerprint.NewChecksumChecker(e.TempDir.Fingerprint, e.Dry, e.Dir) + checker = fingerprint.NewChecksumChecker(e.TempDir.Fingerprint, e.Dry) } value, err := checker.Value(&new) @@ -226,7 +226,7 @@ func (e *Executor) compiledTask(call *Call, evaluateShVars bool) (*ast.Task, err continue } if cmd.For != nil { - list, keys, err := itemsFromFor(cmd.For, new.Dir, new.Sources, new.Generates, gitignore, e.Dir, vars, origTask.Location, cache) + list, keys, err := itemsFromFor(cmd.For, new.Dir, new.Sources, new.Generates, gitignore, vars, origTask.Location, cache) if err != nil { return nil, err } @@ -275,7 +275,7 @@ func (e *Executor) compiledTask(call *Call, evaluateShVars bool) (*ast.Task, err continue } if dep.For != nil { - list, keys, err := itemsFromFor(dep.For, new.Dir, new.Sources, new.Generates, gitignore, e.Dir, vars, origTask.Location, cache) + list, keys, err := itemsFromFor(dep.For, new.Dir, new.Sources, new.Generates, gitignore, vars, origTask.Location, cache) if err != nil { return nil, err } @@ -347,7 +347,6 @@ func itemsFromFor( sources []*ast.Glob, generates []*ast.Glob, gitignore bool, - rootDir string, vars *ast.Vars, location *ast.Location, cache *templater.Cache, @@ -370,7 +369,7 @@ func itemsFromFor( } // Get the list from the task sources if f.From == "sources" { - glist, err := fingerprint.Globs(dir, sources, gitignore, rootDir) + glist, err := fingerprint.Globs(dir, sources, gitignore) if err != nil { return nil, nil, err } @@ -384,7 +383,7 @@ func itemsFromFor( } // Get the list from the task generates if f.From == "generates" { - glist, err := fingerprint.Globs(dir, generates, gitignore, rootDir) + glist, err := fingerprint.Globs(dir, generates, gitignore) if err != nil { return nil, nil, err } diff --git a/watch.go b/watch.go index a246ae55..349dd57a 100644 --- a/watch.go +++ b/watch.go @@ -205,7 +205,7 @@ func (e *Executor) collectSources(calls []*Call) ([]string, error) { var sources []string err := e.traverse(calls, func(task *ast.Task) error { - files, err := fingerprint.Globs(task.Dir, task.Sources, task.IsGitignore(), e.Dir) + files, err := fingerprint.Globs(task.Dir, task.Sources, task.IsGitignore()) if err != nil { return err }