Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: exclude task from being included #1859

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
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
28 changes: 28 additions & 0 deletions task_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1305,6 +1305,34 @@ func TestIncludesInterpolation(t *testing.T) {
}
}

func TestIncludesWithExclude(t *testing.T) {
var buff bytes.Buffer
e := task.Executor{
Dir: "testdata/includes_with_excludes",
Silent: true,
Stdout: &buff,
Stderr: &buff,
}
require.NoError(t, e.Setup())

err := e.Run(context.Background(), &ast.Call{Task: "included:bar"})
require.NoError(t, err)
assert.Equal(t, "bar\n", buff.String())
buff.Reset()

err = e.Run(context.Background(), &ast.Call{Task: "included:foo"})
require.Error(t, err)
buff.Reset()

err = e.Run(context.Background(), &ast.Call{Task: "bar"})
require.Error(t, err)
buff.Reset()

err = e.Run(context.Background(), &ast.Call{Task: "foo"})
require.NoError(t, err)
assert.Equal(t, "foo\n", buff.String())
}

func TestIncludedTaskfileVarMerging(t *testing.T) {
const dir = "testdata/included_taskfile_var_merging"
tests := []struct {
Expand Down
5 changes: 5 additions & 0 deletions taskfile/ast/include.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"gopkg.in/yaml.v3"

"github.com/go-task/task/v3/errors"
"github.com/go-task/task/v3/internal/deepcopy"
omap "github.com/go-task/task/v3/internal/omap"
)

Expand All @@ -15,6 +16,7 @@ type Include struct {
Optional bool
Internal bool
Aliases []string
Excludes []string
AdvancedImport bool
Vars *Vars
Flatten bool
Expand Down Expand Up @@ -84,6 +86,7 @@ func (include *Include) UnmarshalYAML(node *yaml.Node) error {
Internal bool
Flatten bool
Aliases []string
Excludes []string
Vars *Vars
}
if err := node.Decode(&includedTaskfile); err != nil {
Expand All @@ -94,6 +97,7 @@ func (include *Include) UnmarshalYAML(node *yaml.Node) error {
include.Optional = includedTaskfile.Optional
include.Internal = includedTaskfile.Internal
include.Aliases = includedTaskfile.Aliases
include.Excludes = includedTaskfile.Excludes
include.AdvancedImport = true
include.Vars = includedTaskfile.Vars
include.Flatten = includedTaskfile.Flatten
Expand All @@ -115,6 +119,7 @@ func (include *Include) DeepCopy() *Include {
Dir: include.Dir,
Optional: include.Optional,
Internal: include.Internal,
Excludes: deepcopy.Slice(include.Excludes),
AdvancedImport: include.AdvancedImport,
Vars: include.Vars.DeepCopy(),
Flatten: include.Flatten,
Expand Down
6 changes: 6 additions & 0 deletions taskfile/ast/tasks.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@ func (t1 *Tasks) Merge(t2 Tasks, include *Include, includedTaskfileVars *Vars) e
// taskfile are marked as internal
task.Internal = task.Internal || (include != nil && include.Internal)
taskName := name

// if the task is in the exclude list, don't add it to the merged taskfile and early return
if slices.Contains(include.Excludes, name) {
return nil
}

if !include.Flatten {
// Add namespaces to task dependencies
for _, dep := range task.Deps {
Expand Down
1 change: 1 addition & 0 deletions taskfile/reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ func (r *Reader) include(node Node) error {
Flatten: include.Flatten,
Aliases: include.Aliases,
AdvancedImport: include.AdvancedImport,
Excludes: include.Excludes,
Vars: include.Vars,
}
if err := cache.Err(); err != nil {
Expand Down
17 changes: 17 additions & 0 deletions testdata/includes_with_excludes/Taskfile.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
version: '3'

includes:
included:
taskfile: ./included/Taskfile.yml
excludes:
- foo
included_flatten:
taskfile: ./included/Taskfile.yml
flatten: true
excludes:
- bar

tasks:
default:
cmds:
- echo "called_dep" > called_dep.txt
5 changes: 5 additions & 0 deletions testdata/includes_with_excludes/included/Taskfile.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
version: '3'

tasks:
foo: echo foo
bar: echo bar
64 changes: 52 additions & 12 deletions website/docs/usage.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,8 @@ 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
Greet
Foo
```

If multiple tasks have the same name, an error will be thrown:
Expand All @@ -409,14 +411,14 @@ If multiple tasks have the same name, an error will be thrown:
version: '3'
includes:
lib:
taskfile: ./Included.yml
flatten: true

tasks:
greet:
cmds:
- echo "Greet"
- task: foo
taskfile: ./Included.yml
flatten: true

tasks:
greet:
cmds:
- echo "Greet"
- task: foo
```


Expand All @@ -427,9 +429,9 @@ If multiple tasks have the same name, an error will be thrown:
version: '3'

tasks:
greet:
cmds:
- echo "Foo"
greet:
cmds:
- echo "Foo"
```


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

```

If you the included Taskfile has a task with the same name as a task in the main Taskfile,
you may want to exclude it from the flattened tasks.

You can do this by using the [`excludes` option](#exclude-tasks-from-being-included).

### Exclude tasks from being included

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.

<Tabs defaultValue="1"
values={[
{label: 'Taskfile.yml', value: '1'},
{label: 'Included.yml', value: '2'}
]}>

<TabItem value="1">
```yaml
version: '3'
includes:
included:
taskfile: ./Included.yml
excludes: [foo]
```


</TabItem>
<TabItem value="2">

```yaml
version: '3'

tasks:
foo: echo "Foo"
bar: echo "Bar"
```


</TabItem></Tabs>

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

It's compatible with the `flatten` option.

### Vars of included Taskfiles

Expand Down
7 changes: 7 additions & 0 deletions website/static/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -634,6 +634,13 @@
"type": "string"
}
},
"excludes": {
"description": "A list of tasks to be excluded from inclusion.",
"type": "array",
"items": {
"type": "string"
}
},
"vars": {
"description": "A set of variables to apply to the included Taskfile.",
"$ref": "#/definitions/vars"
Expand Down
Loading