From 39462cbfde27f7d2905fe1de4c35b8c150b8e841 Mon Sep 17 00:00:00 2001 From: Pete Davison Date: Wed, 20 Aug 2025 12:13:26 +0100 Subject: [PATCH] feat: change XDG taskrc naming (#2391) --- taskrc/node.go | 3 ++- taskrc/taskrc.go | 40 +++++++++++++++++++++++----- taskrc/taskrc_test.go | 4 +-- website/src/docs/reference/config.md | 15 +++++++---- 4 files changed, 47 insertions(+), 15 deletions(-) diff --git a/taskrc/node.go b/taskrc/node.go index fa0dfe4f..29781ad9 100644 --- a/taskrc/node.go +++ b/taskrc/node.go @@ -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 } diff --git a/taskrc/taskrc.go b/taskrc/taskrc.go index ae9d7f65..db81b1bc 100644 --- a/taskrc/taskrc.go +++ b/taskrc/taskrc.go @@ -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) { @@ -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) + } } } @@ -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 } diff --git a/taskrc/taskrc_test.go b/taskrc/taskrc_test.go index 84261012..1db8221a 100644 --- a/taskrc/taskrc_test.go +++ b/taskrc/taskrc_test.go @@ -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) @@ -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) diff --git a/website/src/docs/reference/config.md b/website/src/docs/reference/config.md index ddba3b4c..0895db89 100644 --- a/website/src/docs/reference/config.md +++ b/website/src/docs/reference/config.md @@ -19,16 +19,21 @@ 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 @@ -36,7 +41,7 @@ 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