This commit is contained in:
Valentin Maerten
2026-04-04 10:29:45 +02:00
parent 714ffdb1b5
commit 78e057e9cb
11 changed files with 38 additions and 43 deletions

View File

@@ -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
}

View File

@@ -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)
}

View File

@@ -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

View File

@@ -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:

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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

View File

@@ -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
}

View File

@@ -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
}