Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion taskrc/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ type Node struct {
func NewNode(
entrypoint string,
dir string,
possibleFileNames []string,
) (*Node, error) {
dir = fsext.DefaultDir(entrypoint, dir)
resolvedEntrypoint, err := fsext.SearchPath(dir, defaultTaskRCs)
resolvedEntrypoint, err := fsext.SearchPath(dir, possibleFileNames)
if err != nil {
return nil, err
}
Expand Down
40 changes: 33 additions & 7 deletions taskrc/taskrc.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,22 @@ import (
"os"
"path/filepath"
"slices"
"strings"

"github.com/go-task/task/v3/internal/fsext"
"github.com/go-task/task/v3/taskrc/ast"
)

var defaultTaskRCs = []string{
".taskrc.yml",
".taskrc.yaml",
}
var (
defaultXDGTaskRCs = []string{
"taskrc.yml",
"taskrc.yaml",
}
defaultTaskRCs = []string{
".taskrc.yml",
".taskrc.yaml",
}
)

// GetConfig loads and merges local and global Task configuration files
func GetConfig(dir string) (*ast.TaskRC, error) {
Expand All @@ -21,12 +28,31 @@ func GetConfig(dir string) (*ast.TaskRC, error) {

// Read the XDG config file
if xdgConfigHome := os.Getenv("XDG_CONFIG_HOME"); xdgConfigHome != "" {
xdgConfigNode, err := NewNode("", filepath.Join(xdgConfigHome, "task"))
xdgConfigNode, err := NewNode("", filepath.Join(xdgConfigHome, "task"), defaultXDGTaskRCs)
if err == nil && xdgConfigNode != nil {
config, err = reader.Read(xdgConfigNode)
xdgConfig, err := reader.Read(xdgConfigNode)
if err != nil {
return nil, err
}
config = xdgConfig
}
}

// If the current path does not contain $HOME
// If it does contain $HOME, then we will find this config later anyway
home, err := os.UserHomeDir()
if err == nil && !strings.Contains(home, dir) {
homeNode, err := NewNode("", home, defaultTaskRCs)
if err == nil && homeNode != nil {
homeConfig, err := reader.Read(homeNode)
if err != nil {
return nil, err
}
if config == nil {
config = homeConfig
} else {
config.Merge(homeConfig)
}
}
}

Expand All @@ -41,7 +67,7 @@ func GetConfig(dir string) (*ast.TaskRC, error) {

// Loop over the nodes, and merge them into the main config
for _, entrypoint := range entrypoints {
node, err := NewNode("", entrypoint)
node, err := NewNode("", entrypoint, defaultTaskRCs)
if err != nil {
return nil, err
}
Expand Down
4 changes: 2 additions & 2 deletions taskrc/taskrc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ func TestGetConfig_NoConfigFiles(t *testing.T) { //nolint:paralleltest // cannot
func TestGetConfig_OnlyXDG(t *testing.T) { //nolint:paralleltest // cannot run in parallel
xdgDir, _, localDir := setupDirs(t)

writeFile(t, xdgDir, ".taskrc.yml", xdgConfigYAML)
writeFile(t, xdgDir, "taskrc.yml", xdgConfigYAML)

cfg, err := GetConfig(localDir)
assert.NoError(t, err)
Expand Down Expand Up @@ -121,7 +121,7 @@ func TestGetConfig_All(t *testing.T) { //nolint:paralleltest // cannot run in pa
writeFile(t, homeDir, ".taskrc.yml", homeConfigYAML)

// Write XDG config
writeFile(t, xdgConfigDir, ".taskrc.yml", xdgConfigYAML)
writeFile(t, xdgConfigDir, "taskrc.yml", xdgConfigYAML)

cfg, err := GetConfig(localDir)
assert.NoError(t, err)
Expand Down
15 changes: 10 additions & 5 deletions website/src/docs/reference/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,24 +19,29 @@ files.

## File Precedence

Task's configuration files are named `.taskrc.yml` or `.taskrc.yaml`. Task will
automatically look for directories containing files with these names in the
following order with the highest priority first:
Task will automatically look for directories containing configuration files in
the following order with the highest priority first:

- Current directory (or the one specified by the `--taskfile`/`--entrypoint`
flags).
- Each directory walking up the file tree from the current directory (or the one
specified by the `--taskfile`/`--entrypoint` flags) until we reach the user's
home directory or the root directory of that drive.
- `$XDG_CONFIG_HOME/task`.
- The users `$HOME` directory.
- The `$XDG_CONFIG_HOME/task` directory.

Config files in the current directory, its parent folders or home directory
should be called `.taskrc.yml` or `.taskrc.yaml`. Config files in the
`$XDG_CONFIG_HOME/task` directory are named the same way, but should not contain
the `.` prefix.

All config files will be merged together into a unified config, starting with
the lowest priority file in `$XDG_CONFIG_HOME/task` with each subsequent file
overwriting the previous one if values are set.

For example, given the following files:

```yaml [$XDG_CONFIG_HOME/task/.taskrc.yml]
```yaml [$XDG_CONFIG_HOME/task/taskrc.yml]
# lowest priority global config
option_1: foo
option_2: foo
Expand Down
Loading