From f2dc0c7e2d9703a8bcb80d721cd1b6434c995aa9 Mon Sep 17 00:00:00 2001 From: Valentin Maerten Date: Sun, 30 Jun 2024 23:25:40 +0200 Subject: [PATCH 1/8] feat: add flatten task --- taskfile/ast/include.go | 4 + taskfile/ast/taskfile.go | 4 +- taskfile/ast/tasks.go | 75 +++++++++++-------- taskfile/reader.go | 1 + testdata/includes_flatten/.gitignore | 1 + testdata/includes_flatten/Taskfile.yml | 14 ++++ .../includes_flatten/included/Taskfile.yml | 9 +++ .../includes_flatten/module1/Taskfile.yml | 10 +++ website/static/schema.json | 4 + 9 files changed, 87 insertions(+), 35 deletions(-) create mode 100644 testdata/includes_flatten/.gitignore create mode 100644 testdata/includes_flatten/Taskfile.yml create mode 100644 testdata/includes_flatten/included/Taskfile.yml create mode 100644 testdata/includes_flatten/module1/Taskfile.yml diff --git a/taskfile/ast/include.go b/taskfile/ast/include.go index defe7c44a6..659070de4a 100644 --- a/taskfile/ast/include.go +++ b/taskfile/ast/include.go @@ -17,6 +17,7 @@ type Include struct { Aliases []string AdvancedImport bool Vars *Vars + Flatten bool } // Includes represents information about included tasksfiles @@ -81,6 +82,7 @@ func (include *Include) UnmarshalYAML(node *yaml.Node) error { Dir string Optional bool Internal bool + Flatten bool Aliases []string Vars *Vars } @@ -94,6 +96,7 @@ func (include *Include) UnmarshalYAML(node *yaml.Node) error { include.Aliases = includedTaskfile.Aliases include.AdvancedImport = true include.Vars = includedTaskfile.Vars + include.Flatten = includedTaskfile.Flatten return nil } @@ -114,5 +117,6 @@ func (include *Include) DeepCopy() *Include { Internal: include.Internal, AdvancedImport: include.AdvancedImport, Vars: include.Vars.DeepCopy(), + Flatten: include.Flatten, } } diff --git a/taskfile/ast/taskfile.go b/taskfile/ast/taskfile.go index 42a8486ab5..f01c1279ab 100644 --- a/taskfile/ast/taskfile.go +++ b/taskfile/ast/taskfile.go @@ -55,8 +55,8 @@ func (t1 *Taskfile) Merge(t2 *Taskfile, include *Include) error { } t1.Vars.Merge(t2.Vars, include) t1.Env.Merge(t2.Env, include) - t1.Tasks.Merge(t2.Tasks, include, t1.Vars) - return nil + err := t1.Tasks.Merge(t2.Tasks, include, t1.Vars) + return err } func (tf *Taskfile) UnmarshalYAML(node *yaml.Node) error { diff --git a/taskfile/ast/tasks.go b/taskfile/ast/tasks.go index b4c3951a63..c0ff988fb6 100644 --- a/taskfile/ast/tasks.go +++ b/taskfile/ast/tasks.go @@ -46,8 +46,8 @@ func (t *Tasks) FindMatchingTasks(call *Call) []*MatchingTask { return matchingTasks } -func (t1 *Tasks) Merge(t2 Tasks, include *Include, includedTaskfileVars *Vars) { - _ = t2.Range(func(name string, v *Task) error { +func (t1 *Tasks) Merge(t2 Tasks, include *Include, includedTaskfileVars *Vars) error { + err := t2.Range(func(name string, v *Task) error { // We do a deep copy of the task struct here to ensure that no data can // be changed elsewhere once the taskfile is merged. task := v.DeepCopy() @@ -55,50 +55,58 @@ func (t1 *Tasks) Merge(t2 Tasks, include *Include, includedTaskfileVars *Vars) { // Set the task to internal if EITHER the included task or the included // taskfile are marked as internal task.Internal = task.Internal || (include != nil && include.Internal) + taskName := name + if !include.Flatten { + // Add namespaces to task dependencies + for _, dep := range task.Deps { + if dep != nil && dep.Task != "" { + dep.Task = taskNameWithNamespace(dep.Task, include.Namespace) + } + } - // Add namespaces to task dependencies - for _, dep := range task.Deps { - if dep != nil && dep.Task != "" { - dep.Task = taskNameWithNamespace(dep.Task, include.Namespace) + // Add namespaces to task commands + for _, cmd := range task.Cmds { + if cmd != nil && cmd.Task != "" { + cmd.Task = taskNameWithNamespace(cmd.Task, include.Namespace) + } } - } - // Add namespaces to task commands - for _, cmd := range task.Cmds { - if cmd != nil && cmd.Task != "" { - cmd.Task = taskNameWithNamespace(cmd.Task, include.Namespace) + // Add namespaces to task aliases + for i, alias := range task.Aliases { + task.Aliases[i] = taskNameWithNamespace(alias, include.Namespace) } - } - // Add namespaces to task aliases - for i, alias := range task.Aliases { - task.Aliases[i] = taskNameWithNamespace(alias, include.Namespace) - } + // Add namespace aliases + if include != nil { + for _, namespaceAlias := range include.Aliases { + task.Aliases = append(task.Aliases, taskNameWithNamespace(task.Task, namespaceAlias)) + for _, alias := range v.Aliases { + task.Aliases = append(task.Aliases, taskNameWithNamespace(alias, namespaceAlias)) + } + } + } - // Add namespace aliases - if include != nil { - for _, namespaceAlias := range include.Aliases { - task.Aliases = append(task.Aliases, taskNameWithNamespace(task.Task, namespaceAlias)) - for _, alias := range v.Aliases { - task.Aliases = append(task.Aliases, taskNameWithNamespace(alias, namespaceAlias)) + if include.AdvancedImport { + task.Dir = filepathext.SmartJoin(include.Dir, task.Dir) + if task.IncludeVars == nil { + task.IncludeVars = &Vars{} } + task.IncludeVars.Merge(include.Vars, nil) + task.IncludedTaskfileVars = includedTaskfileVars.DeepCopy() } + taskName = taskNameWithNamespace(name, include.Namespace) + task.Namespace = include.Namespace + task.Task = taskName } - if include.AdvancedImport { - task.Dir = filepathext.SmartJoin(include.Dir, task.Dir) - if task.IncludeVars == nil { - task.IncludeVars = &Vars{} + if t1.Get(taskName) != nil { + return &errors.TaskNameConflictError{ + Call: "", + TaskNames: []string{taskName}, } - task.IncludeVars.Merge(include.Vars, nil) - task.IncludedTaskfileVars = includedTaskfileVars.DeepCopy() } - // Add the task to the merged taskfile - taskNameWithNamespace := taskNameWithNamespace(name, include.Namespace) - task.Namespace = include.Namespace - task.Task = taskNameWithNamespace - t1.Set(taskNameWithNamespace, task) + t1.Set(taskName, task) return nil }) @@ -113,6 +121,7 @@ func (t1 *Tasks) Merge(t2 Tasks, include *Include, includedTaskfileVars *Vars) { t1.Get(defaultTaskName).Aliases = append(t1.Get(defaultTaskName).Aliases, include.Namespace) t1.Get(defaultTaskName).Aliases = append(t1.Get(defaultTaskName).Aliases, include.Aliases...) } + return err } func (t *Tasks) UnmarshalYAML(node *yaml.Node) error { diff --git a/taskfile/reader.go b/taskfile/reader.go index 7899ee0907..32783dea66 100644 --- a/taskfile/reader.go +++ b/taskfile/reader.go @@ -109,6 +109,7 @@ func (r *Reader) include(node Node) error { Dir: templater.Replace(include.Dir, cache), Optional: include.Optional, Internal: include.Internal, + Flatten: include.Flatten, Aliases: include.Aliases, AdvancedImport: include.AdvancedImport, Vars: include.Vars, diff --git a/testdata/includes_flatten/.gitignore b/testdata/includes_flatten/.gitignore new file mode 100644 index 0000000000..2211df63dd --- /dev/null +++ b/testdata/includes_flatten/.gitignore @@ -0,0 +1 @@ +*.txt diff --git a/testdata/includes_flatten/Taskfile.yml b/testdata/includes_flatten/Taskfile.yml new file mode 100644 index 0000000000..fa382230a8 --- /dev/null +++ b/testdata/includes_flatten/Taskfile.yml @@ -0,0 +1,14 @@ +version: '3' + +includes: + included: + taskfile: ./included + flatten: true + included_module1: + taskfile: ./module1 + +tasks: + default: + cmds: + - echo root_directory > root_directory.txt + diff --git a/testdata/includes_flatten/included/Taskfile.yml b/testdata/includes_flatten/included/Taskfile.yml new file mode 100644 index 0000000000..963cba6f53 --- /dev/null +++ b/testdata/includes_flatten/included/Taskfile.yml @@ -0,0 +1,9 @@ +version: '3' + +tasks: + truc: + cmds: + - echo included_directory > included_directory.txt + gen: + cmds: + - echo included_directory > included_directory.txt diff --git a/testdata/includes_flatten/module1/Taskfile.yml b/testdata/includes_flatten/module1/Taskfile.yml new file mode 100644 index 0000000000..fdb06ab1cd --- /dev/null +++ b/testdata/includes_flatten/module1/Taskfile.yml @@ -0,0 +1,10 @@ +version: '3' + +tasks: + lol: + cmds: + - echo included_directory_without_dir > included_directory_without_dir.txt + gen: + cmds: + - echo included_directory_without_dir > included_directory_without_dir.txt + diff --git a/website/static/schema.json b/website/static/schema.json index 899adff564..317213b42d 100644 --- a/website/static/schema.json +++ b/website/static/schema.json @@ -610,6 +610,10 @@ "description": "If `true`, no errors will be thrown if the specified file does not exist.", "type": "boolean" }, + "flatten": { + "description": "If `true`, the tasks from the included Taskfile will be available in the including Taskfile without a namespace. If a task with the same name already exists in the including Taskfile, an error will be thrown.", + "type": "boolean" + }, "internal": { "description": "Stops any task in the included Taskfile from being callable on the command line. These commands will also be omitted from the output when used with `--list`.", "type": "boolean" From 19673ae44b4370bdff5c48f95ebee6639ca6ff2e Mon Sep 17 00:00:00 2001 From: Valentin Maerten Date: Mon, 1 Jul 2024 13:27:46 +0200 Subject: [PATCH 2/8] add docs --- .editorconfig | 2 +- errors/errors_task.go | 13 +++ taskfile/ast/tasks.go | 6 +- testdata/includes_flatten/Taskfile.yml | 1 + website/docs/reference/schema.mdx | 5 +- website/docs/usage.mdx | 112 +++++++++++++++++++++++++ 6 files changed, 133 insertions(+), 6 deletions(-) diff --git a/.editorconfig b/.editorconfig index d37c349a76..034e5486c6 100644 --- a/.editorconfig +++ b/.editorconfig @@ -8,6 +8,6 @@ charset = utf-8 trim_trailing_whitespace = true indent_style = tab -[*.{md,yml,yaml,json,toml,htm,html,js,css,svg,sh,bash,fish}] +[*.{mdx,yml,yaml,json,toml,htm,html,js,css,svg,sh,bash,fish}] indent_style = space indent_size = 2 diff --git a/errors/errors_task.go b/errors/errors_task.go index bcbf1bb36a..1214a5a9bc 100644 --- a/errors/errors_task.go +++ b/errors/errors_task.go @@ -80,6 +80,19 @@ func (err *TaskNameConflictError) Code() int { return CodeTaskNameConflict } +type TaskNameFlattenConflictError struct { + TaskName string + Include string +} + +func (err *TaskNameFlattenConflictError) Error() string { + return fmt.Sprintf(`task: Found multiple tasks (%s) included by "%s""`, err.TaskName, err.Include) +} + +func (err *TaskNameFlattenConflictError) Code() int { + return CodeTaskNameConflict +} + // TaskCalledTooManyTimesError is returned when the maximum task call limit is // exceeded. This is to prevent infinite loops and cyclic dependencies. type TaskCalledTooManyTimesError struct { diff --git a/taskfile/ast/tasks.go b/taskfile/ast/tasks.go index c0ff988fb6..52828d1824 100644 --- a/taskfile/ast/tasks.go +++ b/taskfile/ast/tasks.go @@ -100,9 +100,9 @@ func (t1 *Tasks) Merge(t2 Tasks, include *Include, includedTaskfileVars *Vars) e } if t1.Get(taskName) != nil { - return &errors.TaskNameConflictError{ - Call: "", - TaskNames: []string{taskName}, + return &errors.TaskNameFlattenConflictError{ + TaskName: taskName, + Include: include.Namespace, } } // Add the task to the merged taskfile diff --git a/testdata/includes_flatten/Taskfile.yml b/testdata/includes_flatten/Taskfile.yml index fa382230a8..f801e1cc5e 100644 --- a/testdata/includes_flatten/Taskfile.yml +++ b/testdata/includes_flatten/Taskfile.yml @@ -6,6 +6,7 @@ includes: flatten: true included_module1: taskfile: ./module1 + flatten: true tasks: default: diff --git a/website/docs/reference/schema.mdx b/website/docs/reference/schema.mdx index a7f861d639..a67743cc47 100644 --- a/website/docs/reference/schema.mdx +++ b/website/docs/reference/schema.mdx @@ -8,7 +8,7 @@ toc_max_heading_level: 5 # Schema Reference | Attribute | Type | Default | Description | -| ---------- | ---------------------------------- | ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +|------------|------------------------------------|---------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | `version` | `string` | | Version of the Taskfile. The current version is `3`. | | `output` | `string` | `interleaved` | Output mode. Available options: `interleaved`, `group` and `prefixed`. | | `method` | `string` | `checksum` | Default method in this Taskfile. Can be overridden in a task by task basis. Available options: `checksum`, `timestamp` and `none`. | @@ -26,10 +26,11 @@ toc_max_heading_level: 5 ## Include | Attribute | Type | Default | Description | -| ---------- | --------------------- | ----------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +|------------|-----------------------|-------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | `taskfile` | `string` | | The path for the Taskfile or directory to be included. If a directory, Task will look for files named `Taskfile.yml` or `Taskfile.yaml` inside that directory. If a relative path, resolved relative to the directory containing the including Taskfile. | | `dir` | `string` | The parent Taskfile directory | The working directory of the included tasks when run. | | `optional` | `bool` | `false` | If `true`, no errors will be thrown if the specified file does not exist. | +| `flatten` | `bool` | `false` | If `true`, the tasks from the included Taskfile will be available in the including Taskfile without a namespace. If a task with the same name already exists in the including Taskfile, an error will be thrown. | | `internal` | `bool` | `false` | Stops any task in the included Taskfile from being callable on the command line. These commands will also be omitted from the output when used with `--list`. | | `aliases` | `[]string` | | Alternative names for the namespace of the included Taskfile. | | `vars` | `map[string]Variable` | | A set of variables to apply to the included Taskfile. | diff --git a/website/docs/usage.mdx b/website/docs/usage.mdx index c0d6b3e7e5..aa582de4de 100644 --- a/website/docs/usage.mdx +++ b/website/docs/usage.mdx @@ -334,6 +334,118 @@ includes: internal: true ``` +### Flatten includes + +You can flatten the included Taskfile tasks into the main Taskfile by using the `flatten` option. +It means that the included Taskfile tasks will be available without the namespace. + + + + + + + ```yaml + version: '3' + + includes: + lib: + taskfile: ./Included.yml + flatten: true + + tasks: + greet: + cmds: + - echo "Greet" + - task: foo + ``` + + + + + + ```yaml + version: '3' + + tasks: + foo: + cmds: + - echo "Foo" + ``` + + + + + +If you run `task -a` it will print : + +```sh +task: Available tasks for this project: +* greet: +* foo +``` + +You can run `task foo` directly without the namespace. + +You can also reference the task in other tasks without the namespace. So if you run `task greet` it will run `greet` and `foo` tasks and the output will be : + +```text +``` + +If multiple tasks have the same name, an error will be thrown: + + + + + + ```yaml + version: '3' + + includes: + lib: + taskfile: ./Included.yml + flatten: true + + tasks: + greet: + cmds: + - echo "Greet" + - task: foo + ``` + + + + + + ```yaml + version: '3' + + tasks: + greet: + cmds: + - echo "Foo" + ``` + + + + +If you run `task -a` it will print: +```text +task: Found multiple tasks (greet) included by "lib" + +``` + + + + + ### Vars of included Taskfiles You can also specify variables when including a Taskfile. This may be useful for From 08e41bfb4ce8b4c97a09558935229b1d8dddd3ee Mon Sep 17 00:00:00 2001 From: Valentin Maerten Date: Mon, 1 Jul 2024 13:55:15 +0200 Subject: [PATCH 3/8] add tests --- task_test.go | 38 +++++++++++++++++++ .../includes_flatten/Taskfile.multiple.yml | 12 ++++++ testdata/includes_flatten/Taskfile.yml | 3 -- .../includes_flatten/included/Taskfile.yml | 16 ++++++-- .../includes_flatten/module1/Taskfile.yml | 10 ----- testdata/includes_flatten/nested/Taskfile.yml | 6 +++ website/docs/usage.mdx | 9 ++--- 7 files changed, 72 insertions(+), 22 deletions(-) create mode 100644 testdata/includes_flatten/Taskfile.multiple.yml delete mode 100644 testdata/includes_flatten/module1/Taskfile.yml create mode 100644 testdata/includes_flatten/nested/Taskfile.yml diff --git a/task_test.go b/task_test.go index 0dd489caaf..41d0f7fae2 100644 --- a/task_test.go +++ b/task_test.go @@ -1216,6 +1216,44 @@ func TestIncludesInternal(t *testing.T) { } } +func TestIncludesFlatten(t *testing.T) { + const dir = "testdata/includes_flatten" + tests := []struct { + name string + taskfile string + task string + expectedErr bool + expectedOutput string + }{ + {"included flatten", "Taskfile.yml", "gen", false, "gen from included\n"}, + {"included flatten with deps", "Taskfile.yml", "with_deps", false, "gen from included\nwith_deps from included\n"}, + {"included flatten nested", "Taskfile.yml", "from_nested", false, "from nested\n"}, + {"included flatten multiple same task", "Taskfile.multiple.yml", "gen", true, "task: Found multiple tasks (gen) included by \"included\"\""}, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + var buff bytes.Buffer + e := task.Executor{ + Dir: dir, + Entrypoint: dir + "/" + test.taskfile, + Stdout: &buff, + Stderr: &buff, + Silent: true, + } + err := e.Setup() + if test.expectedErr { + require.Error(t, err) + assert.Equal(t, test.expectedOutput, err.Error()) + } else { + require.NoError(t, err) + _ = e.Run(context.Background(), &ast.Call{Task: test.task}) + assert.Equal(t, test.expectedOutput, buff.String()) + } + }) + } +} + func TestIncludesInterpolation(t *testing.T) { const dir = "testdata/includes_interpolation" tests := []struct { diff --git a/testdata/includes_flatten/Taskfile.multiple.yml b/testdata/includes_flatten/Taskfile.multiple.yml new file mode 100644 index 0000000000..87909649a6 --- /dev/null +++ b/testdata/includes_flatten/Taskfile.multiple.yml @@ -0,0 +1,12 @@ +version: '3' + +includes: + included: + taskfile: ./included + flatten: true + +tasks: + gen: + cmds: + - echo "gen multiple" + diff --git a/testdata/includes_flatten/Taskfile.yml b/testdata/includes_flatten/Taskfile.yml index f801e1cc5e..b2bcb48e46 100644 --- a/testdata/includes_flatten/Taskfile.yml +++ b/testdata/includes_flatten/Taskfile.yml @@ -4,9 +4,6 @@ includes: included: taskfile: ./included flatten: true - included_module1: - taskfile: ./module1 - flatten: true tasks: default: diff --git a/testdata/includes_flatten/included/Taskfile.yml b/testdata/includes_flatten/included/Taskfile.yml index 963cba6f53..2de3af6bc5 100644 --- a/testdata/includes_flatten/included/Taskfile.yml +++ b/testdata/includes_flatten/included/Taskfile.yml @@ -1,9 +1,17 @@ version: '3' +includes: + nested: + taskfile: ../nested + flatten: true + tasks: - truc: - cmds: - - echo included_directory > included_directory.txt gen: cmds: - - echo included_directory > included_directory.txt + - echo "gen from included" + + with_deps: + deps: + - gen + cmds: + - echo "with_deps from included" diff --git a/testdata/includes_flatten/module1/Taskfile.yml b/testdata/includes_flatten/module1/Taskfile.yml deleted file mode 100644 index fdb06ab1cd..0000000000 --- a/testdata/includes_flatten/module1/Taskfile.yml +++ /dev/null @@ -1,10 +0,0 @@ -version: '3' - -tasks: - lol: - cmds: - - echo included_directory_without_dir > included_directory_without_dir.txt - gen: - cmds: - - echo included_directory_without_dir > included_directory_without_dir.txt - diff --git a/testdata/includes_flatten/nested/Taskfile.yml b/testdata/includes_flatten/nested/Taskfile.yml new file mode 100644 index 0000000000..4bf281a6a6 --- /dev/null +++ b/testdata/includes_flatten/nested/Taskfile.yml @@ -0,0 +1,6 @@ +version: '3' + +tasks: + from_nested: + cmds: + - echo "from nested" diff --git a/website/docs/usage.mdx b/website/docs/usage.mdx index aa582de4de..7b6246273d 100644 --- a/website/docs/usage.mdx +++ b/website/docs/usage.mdx @@ -405,11 +405,10 @@ If multiple tasks have the same name, an error will be thrown: - ```yaml - version: '3' - - includes: - lib: + ```yaml + version: '3' + includes: + lib: taskfile: ./Included.yml flatten: true From 1becd9b82f212aeb004af2d595cc072835fc5348 Mon Sep 17 00:00:00 2001 From: Valentin Maerten Date: Mon, 1 Jul 2024 16:32:16 -0400 Subject: [PATCH 4/8] Update taskfile/ast/taskfile.go fix return --- taskfile/ast/taskfile.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/taskfile/ast/taskfile.go b/taskfile/ast/taskfile.go index f01c1279ab..9e0c0b7924 100644 --- a/taskfile/ast/taskfile.go +++ b/taskfile/ast/taskfile.go @@ -55,8 +55,7 @@ func (t1 *Taskfile) Merge(t2 *Taskfile, include *Include) error { } t1.Vars.Merge(t2.Vars, include) t1.Env.Merge(t2.Env, include) - err := t1.Tasks.Merge(t2.Tasks, include, t1.Vars) - return err + return t1.Tasks.Merge(t2.Tasks, include, t1.Vars) } func (tf *Taskfile) UnmarshalYAML(node *yaml.Node) error { From d7f9bf2c80918387e4f5b3b0a49c60b8cfd52ac0 Mon Sep 17 00:00:00 2001 From: Valentin Maerten Date: Mon, 1 Jul 2024 22:42:23 +0200 Subject: [PATCH 5/8] add md in editorconfig --- .editorconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.editorconfig b/.editorconfig index 034e5486c6..8bb6a753e9 100644 --- a/.editorconfig +++ b/.editorconfig @@ -8,6 +8,6 @@ charset = utf-8 trim_trailing_whitespace = true indent_style = tab -[*.{mdx,yml,yaml,json,toml,htm,html,js,css,svg,sh,bash,fish}] +[*.{md,mdx,yml,yaml,json,toml,htm,html,js,css,svg,sh,bash,fish}] indent_style = space indent_size = 2 From 77e71e21f0a01f34f190540c0513c847fc6d76d5 Mon Sep 17 00:00:00 2001 From: Valentin Maerten Date: Mon, 1 Jul 2024 23:25:13 +0200 Subject: [PATCH 6/8] lint test --- task_test.go | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/task_test.go b/task_test.go index 41d0f7fae2..321d9770cf 100644 --- a/task_test.go +++ b/task_test.go @@ -1225,10 +1225,10 @@ func TestIncludesFlatten(t *testing.T) { expectedErr bool expectedOutput string }{ - {"included flatten", "Taskfile.yml", "gen", false, "gen from included\n"}, - {"included flatten with deps", "Taskfile.yml", "with_deps", false, "gen from included\nwith_deps from included\n"}, - {"included flatten nested", "Taskfile.yml", "from_nested", false, "from nested\n"}, - {"included flatten multiple same task", "Taskfile.multiple.yml", "gen", true, "task: Found multiple tasks (gen) included by \"included\"\""}, + {name: "included flatten", taskfile: "Taskfile.yml", task: "gen", expectedOutput: "gen from included\n"}, + {name: "included flatten with deps", taskfile: "Taskfile.yml", task: "with_deps", expectedOutput: "gen from included\nwith_deps from included\n"}, + {name: "included flatten nested", taskfile: "Taskfile.yml", task: "from_nested", expectedOutput: "from nested\n"}, + {name: "included flatten multiple same task", taskfile: "Taskfile.multiple.yml", task: "gen", expectedErr: true, expectedOutput: "task: Found multiple tasks (gen) included by \"included\"\""}, } for _, test := range tests { @@ -1243,8 +1243,7 @@ func TestIncludesFlatten(t *testing.T) { } err := e.Setup() if test.expectedErr { - require.Error(t, err) - assert.Equal(t, test.expectedOutput, err.Error()) + assert.EqualError(t, err, test.expectedOutput) } else { require.NoError(t, err) _ = e.Run(context.Background(), &ast.Call{Task: test.task}) From 23542f18bdf6b65e0838b9b37fdd38f8a1e5e463 Mon Sep 17 00:00:00 2001 From: Valentin Maerten Date: Fri, 5 Jul 2024 15:05:54 +0200 Subject: [PATCH 7/8] fix: include dir --- taskfile/ast/tasks.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/taskfile/ast/tasks.go b/taskfile/ast/tasks.go index 52828d1824..73a532a08c 100644 --- a/taskfile/ast/tasks.go +++ b/taskfile/ast/tasks.go @@ -2,6 +2,7 @@ package ast import ( "fmt" + "path" "strings" "gopkg.in/yaml.v3" @@ -51,7 +52,6 @@ func (t1 *Tasks) Merge(t2 Tasks, include *Include, includedTaskfileVars *Vars) e // We do a deep copy of the task struct here to ensure that no data can // be changed elsewhere once the taskfile is merged. task := v.DeepCopy() - // Set the task to internal if EITHER the included task or the included // taskfile are marked as internal task.Internal = task.Internal || (include != nil && include.Internal) @@ -97,6 +97,8 @@ func (t1 *Tasks) Merge(t2 Tasks, include *Include, includedTaskfileVars *Vars) e taskName = taskNameWithNamespace(name, include.Namespace) task.Namespace = include.Namespace task.Task = taskName + } else { + task.Dir = path.Join(include.Dir, task.Dir) } if t1.Get(taskName) != nil { From 71094a8a457aded91ef136ce445df0515de982f3 Mon Sep 17 00:00:00 2001 From: Valentin Maerten Date: Fri, 5 Jul 2024 15:40:36 +0200 Subject: [PATCH 8/8] fix: include dir --- taskfile/ast/tasks.go | 20 +++++++++---------- testdata/includes_flatten/Taskfile.yml | 1 + .../includes_flatten/included/Taskfile.yml | 6 ++++++ 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/taskfile/ast/tasks.go b/taskfile/ast/tasks.go index 73a532a08c..1e67bd8d6a 100644 --- a/taskfile/ast/tasks.go +++ b/taskfile/ast/tasks.go @@ -2,7 +2,6 @@ package ast import ( "fmt" - "path" "strings" "gopkg.in/yaml.v3" @@ -86,19 +85,18 @@ func (t1 *Tasks) Merge(t2 Tasks, include *Include, includedTaskfileVars *Vars) e } } - if include.AdvancedImport { - task.Dir = filepathext.SmartJoin(include.Dir, task.Dir) - if task.IncludeVars == nil { - task.IncludeVars = &Vars{} - } - task.IncludeVars.Merge(include.Vars, nil) - task.IncludedTaskfileVars = includedTaskfileVars.DeepCopy() - } taskName = taskNameWithNamespace(name, include.Namespace) task.Namespace = include.Namespace task.Task = taskName - } else { - task.Dir = path.Join(include.Dir, task.Dir) + } + + if include.AdvancedImport { + task.Dir = filepathext.SmartJoin(include.Dir, task.Dir) + if task.IncludeVars == nil { + task.IncludeVars = &Vars{} + } + task.IncludeVars.Merge(include.Vars, nil) + task.IncludedTaskfileVars = includedTaskfileVars.DeepCopy() } if t1.Get(taskName) != nil { diff --git a/testdata/includes_flatten/Taskfile.yml b/testdata/includes_flatten/Taskfile.yml index b2bcb48e46..1ed6cd9ccb 100644 --- a/testdata/includes_flatten/Taskfile.yml +++ b/testdata/includes_flatten/Taskfile.yml @@ -3,6 +3,7 @@ version: '3' includes: included: taskfile: ./included + dir: ./included flatten: true tasks: diff --git a/testdata/includes_flatten/included/Taskfile.yml b/testdata/includes_flatten/included/Taskfile.yml index 2de3af6bc5..c7af41dca1 100644 --- a/testdata/includes_flatten/included/Taskfile.yml +++ b/testdata/includes_flatten/included/Taskfile.yml @@ -15,3 +15,9 @@ tasks: - gen cmds: - echo "with_deps from included" + + + pwd: + desc: Print working directory + cmds: + - pwd