Skip to content

Commit 5f1d46c

Browse files
authored
feat: can exclude task from being included (#1859)
1 parent 9727eef commit 5f1d46c

File tree

8 files changed

+121
-12
lines changed

8 files changed

+121
-12
lines changed

task_test.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1664,6 +1664,34 @@ func TestIncludesInterpolation(t *testing.T) { // nolint:paralleltest // cannot
16641664
}
16651665
}
16661666

1667+
func TestIncludesWithExclude(t *testing.T) {
1668+
var buff bytes.Buffer
1669+
e := task.Executor{
1670+
Dir: "testdata/includes_with_excludes",
1671+
Silent: true,
1672+
Stdout: &buff,
1673+
Stderr: &buff,
1674+
}
1675+
require.NoError(t, e.Setup())
1676+
1677+
err := e.Run(context.Background(), &ast.Call{Task: "included:bar"})
1678+
require.NoError(t, err)
1679+
assert.Equal(t, "bar\n", buff.String())
1680+
buff.Reset()
1681+
1682+
err = e.Run(context.Background(), &ast.Call{Task: "included:foo"})
1683+
require.Error(t, err)
1684+
buff.Reset()
1685+
1686+
err = e.Run(context.Background(), &ast.Call{Task: "bar"})
1687+
require.Error(t, err)
1688+
buff.Reset()
1689+
1690+
err = e.Run(context.Background(), &ast.Call{Task: "foo"})
1691+
require.NoError(t, err)
1692+
assert.Equal(t, "foo\n", buff.String())
1693+
}
1694+
16671695
func TestIncludedTaskfileVarMerging(t *testing.T) {
16681696
t.Parallel()
16691697

taskfile/ast/include.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"gopkg.in/yaml.v3"
55

66
"github.com/go-task/task/v3/errors"
7+
"github.com/go-task/task/v3/internal/deepcopy"
78
omap "github.com/go-task/task/v3/internal/omap"
89
)
910

@@ -15,6 +16,7 @@ type Include struct {
1516
Optional bool
1617
Internal bool
1718
Aliases []string
19+
Excludes []string
1820
AdvancedImport bool
1921
Vars *Vars
2022
Flatten bool
@@ -84,6 +86,7 @@ func (include *Include) UnmarshalYAML(node *yaml.Node) error {
8486
Internal bool
8587
Flatten bool
8688
Aliases []string
89+
Excludes []string
8790
Vars *Vars
8891
}
8992
if err := node.Decode(&includedTaskfile); err != nil {
@@ -94,6 +97,7 @@ func (include *Include) UnmarshalYAML(node *yaml.Node) error {
9497
include.Optional = includedTaskfile.Optional
9598
include.Internal = includedTaskfile.Internal
9699
include.Aliases = includedTaskfile.Aliases
100+
include.Excludes = includedTaskfile.Excludes
97101
include.AdvancedImport = true
98102
include.Vars = includedTaskfile.Vars
99103
include.Flatten = includedTaskfile.Flatten
@@ -115,6 +119,7 @@ func (include *Include) DeepCopy() *Include {
115119
Dir: include.Dir,
116120
Optional: include.Optional,
117121
Internal: include.Internal,
122+
Excludes: deepcopy.Slice(include.Excludes),
118123
AdvancedImport: include.AdvancedImport,
119124
Vars: include.Vars.DeepCopy(),
120125
Flatten: include.Flatten,

taskfile/ast/tasks.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,12 @@ func (t1 *Tasks) Merge(t2 Tasks, include *Include, includedTaskfileVars *Vars) e
5656
// taskfile are marked as internal
5757
task.Internal = task.Internal || (include != nil && include.Internal)
5858
taskName := name
59+
60+
// if the task is in the exclude list, don't add it to the merged taskfile and early return
61+
if slices.Contains(include.Excludes, name) {
62+
return nil
63+
}
64+
5965
if !include.Flatten {
6066
// Add namespaces to task dependencies
6167
for _, dep := range task.Deps {

taskfile/reader.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ func (r *Reader) include(node Node) error {
115115
Flatten: include.Flatten,
116116
Aliases: include.Aliases,
117117
AdvancedImport: include.AdvancedImport,
118+
Excludes: include.Excludes,
118119
Vars: include.Vars,
119120
}
120121
if err := cache.Err(); err != nil {
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
version: '3'
2+
3+
includes:
4+
included:
5+
taskfile: ./included/Taskfile.yml
6+
excludes:
7+
- foo
8+
included_flatten:
9+
taskfile: ./included/Taskfile.yml
10+
flatten: true
11+
excludes:
12+
- bar
13+
14+
tasks:
15+
default:
16+
cmds:
17+
- echo "called_dep" > called_dep.txt
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
version: '3'
2+
3+
tasks:
4+
foo: echo foo
5+
bar: echo bar

website/docs/usage.mdx

Lines changed: 52 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,8 @@ You can run `task foo` directly without the namespace.
393393
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 :
394394

395395
```text
396+
Greet
397+
Foo
396398
```
397399

398400
If multiple tasks have the same name, an error will be thrown:
@@ -409,14 +411,14 @@ If multiple tasks have the same name, an error will be thrown:
409411
version: '3'
410412
includes:
411413
lib:
412-
taskfile: ./Included.yml
413-
flatten: true
414-
415-
tasks:
416-
greet:
417-
cmds:
418-
- echo "Greet"
419-
- task: foo
414+
taskfile: ./Included.yml
415+
flatten: true
416+
417+
tasks:
418+
greet:
419+
cmds:
420+
- echo "Greet"
421+
- task: foo
420422
```
421423

422424

@@ -427,9 +429,9 @@ If multiple tasks have the same name, an error will be thrown:
427429
version: '3'
428430
429431
tasks:
430-
greet:
431-
cmds:
432-
- echo "Foo"
432+
greet:
433+
cmds:
434+
- echo "Foo"
433435
```
434436

435437

@@ -438,12 +440,50 @@ If multiple tasks have the same name, an error will be thrown:
438440
If you run `task -a` it will print:
439441
```text
440442
task: Found multiple tasks (greet) included by "lib"
441-
442443
```
443444

445+
If you the included Taskfile has a task with the same name as a task in the main Taskfile,
446+
you may want to exclude it from the flattened tasks.
447+
448+
You can do this by using the [`excludes` option](#exclude-tasks-from-being-included).
449+
450+
### Exclude tasks from being included
451+
452+
You can exclude tasks from being included by using the `excludes` option. This option takes the list of tasks to be excluded from this include.
453+
454+
<Tabs defaultValue="1"
455+
values={[
456+
{label: 'Taskfile.yml', value: '1'},
457+
{label: 'Included.yml', value: '2'}
458+
]}>
459+
460+
<TabItem value="1">
461+
```yaml
462+
version: '3'
463+
includes:
464+
included:
465+
taskfile: ./Included.yml
466+
excludes: [foo]
467+
```
468+
469+
470+
</TabItem>
471+
<TabItem value="2">
472+
473+
```yaml
474+
version: '3'
475+
476+
tasks:
477+
foo: echo "Foo"
478+
bar: echo "Bar"
479+
```
480+
444481

482+
</TabItem></Tabs>
445483

484+
`task included:foo` will throw an error because the `foo` task is excluded but `task included:bar` will work and display `Bar`.
446485

486+
It's compatible with the `flatten` option.
447487

448488
### Vars of included Taskfiles
449489

website/static/schema.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -653,6 +653,13 @@
653653
"type": "string"
654654
}
655655
},
656+
"excludes": {
657+
"description": "A list of tasks to be excluded from inclusion.",
658+
"type": "array",
659+
"items": {
660+
"type": "string"
661+
}
662+
},
656663
"vars": {
657664
"description": "A set of variables to apply to the included Taskfile.",
658665
"$ref": "#/definitions/vars"

0 commit comments

Comments
 (0)