refactor: remove rootDir param, auto-detect .git as boundary

Walk up from task dir to find .git instead of threading rootDir through
Globs, checkers, and itemsFromFor. Gitignore rules are discarded if no
.git is found, matching ripgrep's require_git behavior. This keeps the
Globs signature clean and makes the future .taskignore integration
straightforward (loaded at setup like .taskrc, separate boundary).
This commit is contained in:
Valentin Maerten
2026-04-04 10:44:35 +02:00
parent 13ef1b2dda
commit 7cea8e3364
3 changed files with 28 additions and 34 deletions

View File

@@ -19,10 +19,7 @@ func initGitRepo(t *testing.T, dir string) {
func TestGlobsWithGitignore(t *testing.T) {
t.Parallel()
dir, err := os.MkdirTemp("", "task-gitignore-test-*")
require.NoError(t, err)
t.Cleanup(func() { os.RemoveAll(dir) })
dir := t.TempDir()
initGitRepo(t, dir)
require.NoError(t, os.WriteFile(filepath.Join(dir, "included.txt"), []byte("included"), 0o644))
@@ -70,10 +67,7 @@ func TestGlobsWithGitignore(t *testing.T) {
func TestGlobsWithGitignoreNested(t *testing.T) {
t.Parallel()
dir, err := os.MkdirTemp("", "task-gitignore-nested-*")
require.NoError(t, err)
t.Cleanup(func() { os.RemoveAll(dir) })
dir := t.TempDir()
initGitRepo(t, dir)
subDir := filepath.Join(dir, "sub")
@@ -82,9 +76,7 @@ func TestGlobsWithGitignoreNested(t *testing.T) {
require.NoError(t, os.WriteFile(filepath.Join(subDir, "keep.txt"), []byte("keep"), 0o644))
require.NoError(t, os.WriteFile(filepath.Join(subDir, "build.out"), []byte("build"), 0o644))
// Root .gitignore ignores *.log
require.NoError(t, os.WriteFile(filepath.Join(dir, ".gitignore"), []byte("*.log\n"), 0o644))
// Nested .gitignore ignores *.out
require.NoError(t, os.WriteFile(filepath.Join(subDir, ".gitignore"), []byte("*.out\n"), 0o644))
globs := []*ast.Glob{
@@ -102,7 +94,9 @@ func TestGlobsWithGitignoreNested(t *testing.T) {
func TestGlobsWithGitignoreNoRepo(t *testing.T) {
t.Parallel()
dir, err := os.MkdirTemp("", "task-gitignore-norepo-*")
// Cannot use t.TempDir() here because it creates a dir inside the
// go-task repo which has a .git parent, defeating the "no repo" test.
dir, err := os.MkdirTemp("", "task-gitignore-norepo-*") //nolint:usetesting
require.NoError(t, err)
t.Cleanup(func() { os.RemoveAll(dir) })

View File

@@ -156,7 +156,7 @@ func (t *Task) UnmarshalYAML(node *yaml.Node) error {
Internal bool
Method string
Prefix string
IgnoreError bool `yaml:"ignore_error"`
IgnoreError bool `yaml:"ignore_error"`
Gitignore *bool `yaml:"gitignore,omitempty"`
Run string
Platforms []*Platform

View File

@@ -20,16 +20,16 @@ var ErrIncludedTaskfilesCantHaveDotenvs = errors.New("task: Included Taskfiles c
// Taskfile is the abstract syntax tree for a Taskfile
type Taskfile struct {
Location string
Version *semver.Version
Output Output
Method string
Includes *Includes
Set []string
Shopt []string
Vars *Vars
Env *Vars
Tasks *Tasks
Location string
Version *semver.Version
Output Output
Method string
Includes *Includes
Set []string
Shopt []string
Vars *Vars
Env *Vars
Tasks *Tasks
Silent bool
Dotenv []string
Run string
@@ -77,18 +77,18 @@ func (tf *Taskfile) UnmarshalYAML(node *yaml.Node) error {
switch node.Kind {
case yaml.MappingNode:
var taskfile struct {
Version *semver.Version
Output Output
Method string
Includes *Includes
Set []string
Shopt []string
Vars *Vars
Env *Vars
Tasks *Tasks
Silent bool
Dotenv []string
Run string
Version *semver.Version
Output Output
Method string
Includes *Includes
Set []string
Shopt []string
Vars *Vars
Env *Vars
Tasks *Tasks
Silent bool
Dotenv []string
Run string
Interval time.Duration
Gitignore bool
}