mirror of
https://github.com/go-task/task.git
synced 2025-08-08 22:36:57 +02:00
v3.43.0
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# Changelog
|
||||
|
||||
## Unreleased
|
||||
## v3.43.0 - 2025-04-21
|
||||
|
||||
- Significant improvements were made to the watcher. We migrated from
|
||||
[watcher](https://github.com/radovskyb/watcher) to
|
||||
|
@@ -1 +1 @@
|
||||
3.42.1
|
||||
3.43.0
|
||||
|
2
package-lock.json
generated
2
package-lock.json
generated
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@go-task/cli",
|
||||
"version": "3.42.1",
|
||||
"version": "3.43.0",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@go-task/cli",
|
||||
"version": "3.42.1",
|
||||
"version": "3.43.0",
|
||||
"description": "A task runner / simpler Make alternative written in Go",
|
||||
"scripts": {
|
||||
"postinstall": "go-npm install",
|
||||
|
@@ -5,6 +5,77 @@ sidebar_position: 14
|
||||
|
||||
# Changelog
|
||||
|
||||
## v3.43.0 - 2025-04-21
|
||||
|
||||
- Significant improvements were made to the watcher. We migrated from
|
||||
[watcher](https://github.com/radovskyb/watcher) to
|
||||
[fsnotify](https://github.com/fsnotify/fsnotify). The former library used
|
||||
polling, which means Task had a high CPU usage when watching too many files.
|
||||
`fsnotify` uses proper the APIs from each operating system to watch files,
|
||||
which means a much better performance. The default interval changed from 5
|
||||
seconds to 100 milliseconds, because now it configures the wait time for
|
||||
duplicated events, instead of the polling time (#2048 by @andreynering, #1508,
|
||||
#985, #1179).
|
||||
- The [Map Variables experiment](https://github.com/go-task/task/issues/1585)
|
||||
was made generally available so you can now
|
||||
[define map variables in your Taskfiles!](https://taskfile.dev/usage/#variables)
|
||||
(#1585, #1547, #2081 by @pd93).
|
||||
- Wildcards can now
|
||||
[match multiple tasks](https://taskfile.dev/usage/#wildcard-arguments) (#2072,
|
||||
#2121 by @pd93).
|
||||
- Added the ability to
|
||||
[loop over the files specified by the `generates` keyword](https://taskfile.dev/usage/#looping-over-your-tasks-sources-or-generated-files).
|
||||
This works the same way as looping over sources (#2151 by @sedyh).
|
||||
- Added the ability to resolve variables when defining an include variable
|
||||
(#2108, #2113 by @pd93).
|
||||
- A few changes have been made to the
|
||||
[Remote Taskfiles experiment](https://github.com/go-task/task/issues/1317)
|
||||
(#1402, #2176 by @pd93):
|
||||
- Cached files are now prioritized over remote ones.
|
||||
- Added an `--expiry` flag which sets the TTL for a remote file cache. By
|
||||
default the value will be 0 (caching disabled). If Task is running in
|
||||
offline mode or fails to make a connection, it will fallback on the cache.
|
||||
- `.taskrc` files can now be used from subdirectories and will be searched for
|
||||
recursively up the file tree in the same way that Taskfiles are (#2159, #2166
|
||||
by @pd93).
|
||||
- The default taskfile (output when using the `--init` flag) is now an embedded
|
||||
file in the binary instead of being stored in the code (#2112 by @pd93).
|
||||
- Improved the way we report the Task version when using the `--version` flag or
|
||||
`{{.TASK_VERSION}}` variable. This should now be more consistent and easier
|
||||
for package maintainers to use (#2131 by @pd93).
|
||||
- Fixed a bug where globstar (`**`) matching in `sources` only resolved the
|
||||
first result (#2073, #2075 by @pd93).
|
||||
- Fixed a bug where sorting tasks by "none" would use the default sorting
|
||||
instead of leaving tasks in the order they were defined (#2124, #2125 by
|
||||
@trulede).
|
||||
- Fixed Fish completion on newer Fish versions (#2130 by @atusy).
|
||||
- Fixed a bug where undefined/null variables resolved to an empty string instead
|
||||
of `nil` (#1911, #2144 by @pd93).
|
||||
- The `USER_WORKING_DIR` special now will now properly account for the `--dir`
|
||||
(`-d`) flag, if given (#2102, #2103 by @jaynis, #2186 by @andreynering).
|
||||
- Fix Fish completions when `--global` (`-g`) is given (#2134 by @atusy).
|
||||
- Fixed variables not available when using `defer:` (#1909, #2173 by @vmaerten).
|
||||
|
||||
#### Package API
|
||||
|
||||
- The [`Executor`](https://pkg.go.dev/github.com/go-task/task/v3#Executor) now
|
||||
uses the functional options pattern (#2085, #2147, #2148 by @pd93).
|
||||
- The functional options for the
|
||||
[`taskfile.Reader`](https://pkg.go.dev/github.com/go-task/task/v3/taskfile#Reader)
|
||||
and
|
||||
[`taskfile.Snippet`](https://pkg.go.dev/github.com/go-task/task/v3/taskfile#Snippet)
|
||||
types no longer have the `Reader`/`Snippet` respective prefixes (#2148 by
|
||||
@pd93).
|
||||
- [`taskfile.Reader`](https://pkg.go.dev/github.com/go-task/task/v3/taskfile#Reader)
|
||||
no longer accepts a
|
||||
[`taskfile.Node`](https://pkg.go.dev/github.com/go-task/task/v3/taskfile#Node).
|
||||
Instead nodes are passed directly into the
|
||||
[`Reader.Read`](https://pkg.go.dev/github.com/go-task/task/v3/taskfile#Reader.Read)
|
||||
method (#2169 by @pd93).
|
||||
- [`Reader.Read`](https://pkg.go.dev/github.com/go-task/task/v3/taskfile#Reader.Read)
|
||||
also now accepts a [`context.Context`](https://pkg.go.dev/context#Context)
|
||||
(#2176 by @pd93).
|
||||
|
||||
## v3.42.1 - 2025-03-10
|
||||
|
||||
- Fixed a bug where some special variables caused a type error when used global
|
||||
|
@@ -5,6 +5,77 @@ sidebar_position: 14
|
||||
|
||||
# Changelog
|
||||
|
||||
## v3.43.0 - 2025-04-21
|
||||
|
||||
- Significant improvements were made to the watcher. We migrated from
|
||||
[watcher](https://github.com/radovskyb/watcher) to
|
||||
[fsnotify](https://github.com/fsnotify/fsnotify). The former library used
|
||||
polling, which means Task had a high CPU usage when watching too many files.
|
||||
`fsnotify` uses proper the APIs from each operating system to watch files,
|
||||
which means a much better performance. The default interval changed from 5
|
||||
seconds to 100 milliseconds, because now it configures the wait time for
|
||||
duplicated events, instead of the polling time (#2048 by @andreynering, #1508,
|
||||
#985, #1179).
|
||||
- The [Map Variables experiment](https://github.com/go-task/task/issues/1585)
|
||||
was made generally available so you can now
|
||||
[define map variables in your Taskfiles!](https://taskfile.dev/usage/#variables)
|
||||
(#1585, #1547, #2081 by @pd93).
|
||||
- Wildcards can now
|
||||
[match multiple tasks](https://taskfile.dev/usage/#wildcard-arguments) (#2072,
|
||||
#2121 by @pd93).
|
||||
- Added the ability to
|
||||
[loop over the files specified by the `generates` keyword](https://taskfile.dev/usage/#looping-over-your-tasks-sources-or-generated-files).
|
||||
This works the same way as looping over sources (#2151 by @sedyh).
|
||||
- Added the ability to resolve variables when defining an include variable
|
||||
(#2108, #2113 by @pd93).
|
||||
- A few changes have been made to the
|
||||
[Remote Taskfiles experiment](https://github.com/go-task/task/issues/1317)
|
||||
(#1402, #2176 by @pd93):
|
||||
- Cached files are now prioritized over remote ones.
|
||||
- Added an `--expiry` flag which sets the TTL for a remote file cache. By
|
||||
default the value will be 0 (caching disabled). If Task is running in
|
||||
offline mode or fails to make a connection, it will fallback on the cache.
|
||||
- `.taskrc` files can now be used from subdirectories and will be searched for
|
||||
recursively up the file tree in the same way that Taskfiles are (#2159, #2166
|
||||
by @pd93).
|
||||
- The default taskfile (output when using the `--init` flag) is now an embedded
|
||||
file in the binary instead of being stored in the code (#2112 by @pd93).
|
||||
- Improved the way we report the Task version when using the `--version` flag or
|
||||
`{{.TASK_VERSION}}` variable. This should now be more consistent and easier
|
||||
for package maintainers to use (#2131 by @pd93).
|
||||
- Fixed a bug where globstar (`**`) matching in `sources` only resolved the
|
||||
first result (#2073, #2075 by @pd93).
|
||||
- Fixed a bug where sorting tasks by "none" would use the default sorting
|
||||
instead of leaving tasks in the order they were defined (#2124, #2125 by
|
||||
@trulede).
|
||||
- Fixed Fish completion on newer Fish versions (#2130 by @atusy).
|
||||
- Fixed a bug where undefined/null variables resolved to an empty string instead
|
||||
of `nil` (#1911, #2144 by @pd93).
|
||||
- The `USER_WORKING_DIR` special now will now properly account for the `--dir`
|
||||
(`-d`) flag, if given (#2102, #2103 by @jaynis, #2186 by @andreynering).
|
||||
- Fix Fish completions when `--global` (`-g`) is given (#2134 by @atusy).
|
||||
- Fixed variables not available when using `defer:` (#1909, #2173 by @vmaerten).
|
||||
|
||||
#### Package API
|
||||
|
||||
- The [`Executor`](https://pkg.go.dev/github.com/go-task/task/v3#Executor) now
|
||||
uses the functional options pattern (#2085, #2147, #2148 by @pd93).
|
||||
- The functional options for the
|
||||
[`taskfile.Reader`](https://pkg.go.dev/github.com/go-task/task/v3/taskfile#Reader)
|
||||
and
|
||||
[`taskfile.Snippet`](https://pkg.go.dev/github.com/go-task/task/v3/taskfile#Snippet)
|
||||
types no longer have the `Reader`/`Snippet` respective prefixes (#2148 by
|
||||
@pd93).
|
||||
- [`taskfile.Reader`](https://pkg.go.dev/github.com/go-task/task/v3/taskfile#Reader)
|
||||
no longer accepts a
|
||||
[`taskfile.Node`](https://pkg.go.dev/github.com/go-task/task/v3/taskfile#Node).
|
||||
Instead nodes are passed directly into the
|
||||
[`Reader.Read`](https://pkg.go.dev/github.com/go-task/task/v3/taskfile#Reader.Read)
|
||||
method (#2169 by @pd93).
|
||||
- [`Reader.Read`](https://pkg.go.dev/github.com/go-task/task/v3/taskfile#Reader.Read)
|
||||
also now accepts a [`context.Context`](https://pkg.go.dev/context#Context)
|
||||
(#2176 by @pd93).
|
||||
|
||||
## v3.42.1 - 2025-03-10
|
||||
|
||||
- Fixed a bug where some special variables caused a type error when used global
|
||||
|
@@ -1,245 +0,0 @@
|
||||
---
|
||||
slug: /experiments/map-variables/
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# Map Variables (#1585)
|
||||
|
||||
:::caution
|
||||
|
||||
All experimental features are subject to breaking changes and/or removal _at any
|
||||
time_. We strongly recommend that you do not use these features in a production
|
||||
environment. They are intended for testing and feedback only.
|
||||
|
||||
:::
|
||||
|
||||
Currently, Task supports all variable types except for maps. This experiment
|
||||
adds two different proposals for map variables. Click on the tabs below to
|
||||
switch between them.
|
||||
|
||||
<Tabs defaultValue="1" queryString="proposal"
|
||||
values={[
|
||||
{label: 'Proposal 1', value: '1'},
|
||||
{label: 'Proposal 2', value: '2'}
|
||||
]}>
|
||||
|
||||
<TabItem value="1">
|
||||
|
||||
:::warning
|
||||
|
||||
This experiment proposal breaks the following functionality:
|
||||
|
||||
- Dynamically defined variables (using the `sh` keyword)
|
||||
|
||||
:::
|
||||
|
||||
:::info
|
||||
|
||||
To enable this experiment, set the environment variable:
|
||||
`TASK_X_MAP_VARIABLES=1`. Check out [our guide to enabling experiments
|
||||
][enabling-experiments] for more information.
|
||||
|
||||
:::
|
||||
|
||||
This proposal removes support for the `sh` and `ref` keywords in favour of a new
|
||||
syntax for dynamically defined variables and references. This allows you to
|
||||
define a map directly as you would for any other type:
|
||||
|
||||
```yaml
|
||||
version: 3
|
||||
|
||||
tasks:
|
||||
foo:
|
||||
vars:
|
||||
FOO: {a: 1, b: 2, c: 3} # <-- Directly defined map on the `FOO` key
|
||||
cmds:
|
||||
- 'echo {{.FOO.a}}'
|
||||
```
|
||||
|
||||
## Migration
|
||||
|
||||
Taskfiles with dynamically defined variables via the `sh` subkey or references
|
||||
defined with `ref` will no longer work with this experiment enabled. In order to
|
||||
keep using these features, you will need to migrate your Taskfile to use the new
|
||||
syntax.
|
||||
|
||||
### Dynamic Variables
|
||||
|
||||
Previously, you had to define dynamic variables using the `sh` subkey. With this
|
||||
experiment enabled, you will need to remove the `sh` subkey and define your
|
||||
command as a string that begins with a `$`. This will instruct Task to interpret
|
||||
the string as a command instead of a literal value and the variable will be
|
||||
populated with the output of the command. For example:
|
||||
|
||||
<Tabs defaultValue="2"
|
||||
values={[
|
||||
{label: 'Before', value: '1'},
|
||||
{label: 'After', value: '2'}
|
||||
]}>
|
||||
|
||||
<TabItem value="1">
|
||||
|
||||
```yaml
|
||||
version: 3
|
||||
|
||||
tasks:
|
||||
foo:
|
||||
vars:
|
||||
CALCULATED_VAR:
|
||||
sh: 'echo hello'
|
||||
cmds:
|
||||
- 'echo {{.CALCULATED_VAR}}'
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="2">
|
||||
|
||||
```yaml
|
||||
version: 3
|
||||
|
||||
tasks:
|
||||
foo:
|
||||
vars:
|
||||
CALCULATED_VAR: '$echo hello' # <-- Prefix dynamic variable with a `$`
|
||||
cmds:
|
||||
- 'echo {{.CALCULATED_VAR}}'
|
||||
```
|
||||
|
||||
</TabItem></Tabs>
|
||||
|
||||
### References
|
||||
|
||||
<Tabs defaultValue="2"
|
||||
values={[
|
||||
{label: 'Before', value: '1'},
|
||||
{label: 'After', value: '2'}
|
||||
]}>
|
||||
|
||||
<TabItem value="1">
|
||||
|
||||
```yaml
|
||||
version: 3
|
||||
|
||||
tasks:
|
||||
foo:
|
||||
vars:
|
||||
VAR: 42
|
||||
VAR_REF:
|
||||
ref: '.FOO'
|
||||
cmds:
|
||||
- 'echo {{.VAR_REF}}'
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="2">
|
||||
|
||||
```yaml
|
||||
version: 3
|
||||
|
||||
tasks:
|
||||
foo:
|
||||
vars:
|
||||
VAR: 42
|
||||
VAR_REF: '#.FOO' # <-- Prefix reference with a `#`
|
||||
cmds:
|
||||
- 'echo {{.VAR_REF}}'
|
||||
```
|
||||
|
||||
</TabItem></Tabs>
|
||||
|
||||
If your current Taskfile contains a string variable that begins with a `$` or a
|
||||
`#`, you will now need to escape it with a backslash (`\`) to stop Task from
|
||||
interpreting it as a command or reference.
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="2">
|
||||
|
||||
:::info
|
||||
|
||||
To enable this experiment, set the environment variable:
|
||||
`TASK_X_MAP_VARIABLES=2`. Check out [our guide to enabling experiments
|
||||
][enabling-experiments] for more information.
|
||||
|
||||
:::
|
||||
|
||||
This proposal maintains backwards-compatibility and the `sh` subkey and adds
|
||||
another new `map` subkey for defining map variables:
|
||||
|
||||
```yaml
|
||||
version: 3
|
||||
|
||||
tasks:
|
||||
foo:
|
||||
vars:
|
||||
FOO:
|
||||
map: {a: 1, b: 2, c: 3} # <-- Defined using the `map' subkey instead of directly on 'FOO'
|
||||
BAR: true # <-- Other types of variables are still defined directly on the key
|
||||
BAZ:
|
||||
sh: 'echo Hello Task' # <-- The `sh` subkey is still supported
|
||||
QUX:
|
||||
ref: '.BAZ' # <-- The `ref` subkey is still supported
|
||||
cmds:
|
||||
- 'echo {{.FOO.a}}'
|
||||
```
|
||||
|
||||
</TabItem></Tabs>
|
||||
|
||||
## Looping over maps
|
||||
|
||||
This experiment also adds support for looping over maps using the `for` keyword,
|
||||
just like arrays. In addition to the `{{.ITEM}}` variable being populated when
|
||||
looping over a map, we also make an additional `{{.KEY}}` variable available
|
||||
that holds the string value of the map key.
|
||||
|
||||
<Tabs defaultValue="1" queryString="proposal"
|
||||
values={[
|
||||
{label: 'Proposal 1', value: '1'},
|
||||
{label: 'Proposal 2', value: '2'}
|
||||
]}>
|
||||
|
||||
<TabItem value="1">
|
||||
|
||||
```yaml
|
||||
version: 3
|
||||
|
||||
tasks:
|
||||
foo:
|
||||
vars:
|
||||
MAP: {a: 1, b: 2, c: 3}
|
||||
cmds:
|
||||
- for:
|
||||
var: MAP
|
||||
cmd: 'echo "{{.KEY}}: {{.ITEM}}"'
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="2">
|
||||
|
||||
```yaml
|
||||
version: 3
|
||||
|
||||
tasks:
|
||||
foo:
|
||||
vars:
|
||||
map:
|
||||
MAP: {a: 1, b: 2, c: 3}
|
||||
cmds:
|
||||
- for:
|
||||
var: MAP
|
||||
cmd: 'echo "{{.KEY}}: {{.ITEM}}"'
|
||||
```
|
||||
|
||||
:::note
|
||||
|
||||
Remember that maps are unordered, so
|
||||
the order in which the items are looped over is random.
|
||||
|
||||
:::
|
||||
|
||||
</TabItem></Tabs>
|
||||
|
||||
{/* prettier-ignore-start */}
|
||||
[enabling-experiments]: ./experiments.mdx#enabling-experiments
|
||||
{/* prettier-ignore-end */}
|
@@ -2,6 +2,9 @@
|
||||
slug: /experiments/remote-taskfiles/
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# Remote Taskfiles (#1317)
|
||||
|
||||
:::caution
|
||||
@@ -20,33 +23,151 @@ To enable this experiment, set the environment variable:
|
||||
|
||||
:::
|
||||
|
||||
This experiment allows you to specify a remote Taskfile URL when including a
|
||||
Taskfile. For example:
|
||||
:::danger
|
||||
Never run remote Taskfiles from sources that you do not trust.
|
||||
:::
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
This experiment allows you to use Taskfiles which are stored in remote
|
||||
locations. This applies to both the root Taskfile (aka. Entrypoint) and also
|
||||
when including Taskfiles.
|
||||
|
||||
includes:
|
||||
my-remote-namespace: https://raw.githubusercontent.com/my-org/my-repo/main/Taskfile.yml
|
||||
```
|
||||
Task uses "nodes" to reference remote Taskfiles. There are a few different types
|
||||
of node which you can use:
|
||||
|
||||
This works exactly the same way that including a local file does. Any tasks in
|
||||
the remote Taskfile will be available to run from your main Taskfile via the
|
||||
namespace `my-remote-namespace`. For example, if the remote file contains the
|
||||
following:
|
||||
<Tabs groupId="method" queryString>
|
||||
<TabItem value="http" label="HTTP/HTTPS">
|
||||
|
||||
`https://raw.githubusercontent.com/go-task/task/main/website/static/Taskfile.yml`
|
||||
|
||||
This is the most basic type of remote node and works by downloading the file
|
||||
from the specified URL. The file must be a valid Taskfile and can be of any
|
||||
name. If a file is not found at the specified URL, Task will append each of the
|
||||
[supported file names][supported-file-names] in turn until it finds a valid
|
||||
file. If it still does not find a valid Taskfile, an error is returned.
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="git-http" label="Git over HTTP">
|
||||
|
||||
`https://github.com/go-task/task.git//website/static/Taskfile.yml?ref=main`
|
||||
|
||||
This type of node works by downloading the file from a Git repository over
|
||||
HTTP/HTTPS. The first part of the URL is the base URL of the Git repository.
|
||||
This is the same URL that you would use to clone the repo over HTTP.
|
||||
|
||||
- You can optionally add the path to the Taskfile in the repository by appending
|
||||
`//<path>` to the URL.
|
||||
- You can also optionally specify a branch or tag to use by appending
|
||||
`?ref=<ref>` to the end of the URL. If you omit a reference, the default branch
|
||||
will be used.
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="git-ssh" label="Git over SSH">
|
||||
|
||||
`git@github.com/go-task/task.git//website/static/Taskfile.yml?ref=main`
|
||||
|
||||
This type of node works by downloading the file from a Git repository over SSH.
|
||||
The first part of the URL is the user and base URL of the Git repository. This
|
||||
is the same URL that you would use to clone the repo over SSH.
|
||||
|
||||
To use Git over SSH, you need to make sure that your SSH agent has your private
|
||||
SSH keys added so that they can be used during authentication.
|
||||
|
||||
- You can optionally add the path to the Taskfile in the repository by appending
|
||||
`//<path>` to the URL.
|
||||
- You can also optionally specify a branch or tag to use by appending
|
||||
`?ref=<ref>` to the end of the URL. If you omit a reference, the default branch
|
||||
will be used.
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Task has an [example remote Taskfile][example-remote-taskfile] in our repository
|
||||
that you can use for testing and that we will use throughout this document:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
hello:
|
||||
silent: true
|
||||
default:
|
||||
cmds:
|
||||
- echo "Hello from the remote Taskfile!"
|
||||
- task: hello
|
||||
|
||||
hello:
|
||||
cmds:
|
||||
- echo "Hello Task!"
|
||||
```
|
||||
|
||||
and you run `task my-remote-namespace:hello`, it will print the text: "Hello
|
||||
from the remote Taskfile!" to your console.
|
||||
## Specifying a remote entrypoint
|
||||
|
||||
By default, Task will look for one of the [supported file
|
||||
names][supported-file-names] on your local filesystem. If you want to use a
|
||||
remote file instead, you can pass its URI into the `--taskfile`/`-t` flag just
|
||||
like you would to specify a different local file. For example:
|
||||
|
||||
<Tabs groupId="method" queryString>
|
||||
<TabItem value="http" label="HTTP/HTTPS">
|
||||
```shell
|
||||
$ task --taskfile https://raw.githubusercontent.com/go-task/task/main/website/static/Taskfile.yml
|
||||
task: [hello] echo "Hello Task!"
|
||||
Hello Task!
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="git-http" label="Git over HTTP">
|
||||
```shell
|
||||
$ task --taskfile https://github.com/go-task/task.git//website/static/Taskfile.yml?ref=main
|
||||
task: [hello] echo "Hello Task!"
|
||||
Hello Task!
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="git-ssh" label="Git over SSH">
|
||||
```shell
|
||||
$ task --taskfile git@github.com/go-task/task.git//website/static/Taskfile.yml?ref=main
|
||||
task: [hello] echo "Hello Task!"
|
||||
Hello Task!
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Including remote Taskfiles
|
||||
|
||||
Including a remote file works exactly the same way that including a local file
|
||||
does. You just need to replace the local path with a remote URI. Any tasks in
|
||||
the remote Taskfile will be available to run from your main Taskfile.
|
||||
|
||||
<Tabs groupId="method" queryString>
|
||||
<TabItem value="http" label="HTTP/HTTPS">
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
includes:
|
||||
my-remote-namespace: https://raw.githubusercontent.com/go-task/task/main/website/static/Taskfile.yml
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="git-http" label="Git over HTTP">
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
includes:
|
||||
my-remote-namespace: https://github.com/go-task/task.git//website/static/Taskfile.yml?ref=main
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="git-ssh" label="Git over SSH">
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
includes:
|
||||
my-remote-namespace: git@github.com/go-task/task.git//website/static/Taskfile.yml?ref=main
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
```shell
|
||||
$ task my-remote-namespace:hello
|
||||
task: [hello] echo "Hello Task!"
|
||||
Hello Task!
|
||||
```
|
||||
|
||||
### Authenticating using environment variables
|
||||
|
||||
The Taskfile location is processed by the templating system, so you can
|
||||
reference environment variables in your URL if you need to add authentication.
|
||||
@@ -59,19 +180,6 @@ includes:
|
||||
my-remote-namespace: https://{{.TOKEN}}@raw.githubusercontent.com/my-org/my-repo/main/Taskfile.yml
|
||||
```
|
||||
|
||||
`TOKEN=my-token task my-remote-namespace:hello` will be resolved by Task to
|
||||
`https://my-token@raw.githubusercontent.com/my-org/my-repo/main/Taskfile.yml`
|
||||
|
||||
## Git nodes
|
||||
|
||||
You can also include a Taskfile from a Git node. We currently support ssh-style and http / https addresses like `git@example.com/foo/bar.git//Taskfiles.yml?ref=v1` and `https://example.com/foo/bar.git//Taskfiles.yml?ref=v1`.
|
||||
|
||||
You need to follow this pattern : `<baseUrl>.git//<path>?ref=<ref>`.
|
||||
The `ref` parameter, optional, can be a branch name or a tag, if not provided it'll pick up the default branch.
|
||||
The `path` is the path to the Taskfile in the repository.
|
||||
|
||||
If you want to use the SSH protocol, you need to make sure that your ssh-agent has your private ssh keys added so that they can be used during authentication.
|
||||
|
||||
## Security
|
||||
|
||||
Running commands from sources that you do not control is always a potential
|
||||
@@ -104,20 +212,26 @@ flag. Before enabling this flag, you should:
|
||||
Task currently supports both `http` and `https` URLs. However, the `http`
|
||||
requests will not execute by default unless you run the task with the
|
||||
`--insecure` flag. This is to protect you from accidentally running a remote
|
||||
Taskfile that is via an unencrypted connection. Sources that are not protected
|
||||
by TLS are vulnerable to [man-in-the-middle attacks][man-in-the-middle-attacks]
|
||||
and should be avoided unless you know what you are doing.
|
||||
Taskfile that is downloaded via an unencrypted connection. Sources that are not
|
||||
protected by TLS are vulnerable to [man-in-the-middle
|
||||
attacks][man-in-the-middle-attacks] and should be avoided unless you know what
|
||||
you are doing.
|
||||
|
||||
## Caching & Running Offline
|
||||
|
||||
Whenever you run a remote Taskfile, the latest copy will be downloaded from the
|
||||
internet and cached locally. If for whatever reason, you lose access to the
|
||||
internet, you will still be able to run your tasks by specifying the `--offline`
|
||||
flag. This will tell Task to use the latest cached version of the file instead
|
||||
of trying to download it. You are able to use the `--download` flag to update
|
||||
the cached version of the remote files without running any tasks. You are able
|
||||
to use the `--clear-cache` flag to clear all cached version of the remote files
|
||||
without running any tasks.
|
||||
internet and cached locally. This cached file will be used for all future
|
||||
invocations of the Taskfile until the cache expires. Once it expires, Task will
|
||||
download the latest copy of the file and update the cache. By default, the cache
|
||||
is set to expire immediately. This means that Task will always fetch the latest
|
||||
version. However, the cache expiry duration can be modified by setting the
|
||||
`--expiry` flag.
|
||||
|
||||
If for any reason you lose access to the internet or you are running Task in
|
||||
offline mode (via the `--offline` flag or `TASK_OFFLINE` environment variable),
|
||||
Task will run the any available cached files _even if they are expired_. This
|
||||
means that you should never be stuck without the ability to run your tasks as
|
||||
long as you have downloaded a remote Taskfile at least once.
|
||||
|
||||
By default, Task will timeout requests to download remote files after 10 seconds
|
||||
and look for a cached copy instead. This timeout can be configured by setting
|
||||
@@ -129,7 +243,14 @@ By default, the cache is stored in the Task temp directory, represented by the
|
||||
override the location of the cache by setting the `TASK_REMOTE_DIR` environment
|
||||
variable. This way, you can share the cache between different projects.
|
||||
|
||||
You can force Task to ignore the cache and download the latest version
|
||||
by using the `--download` flag.
|
||||
|
||||
You can use the `--clear-cache` flag to clear all cached remote files.
|
||||
|
||||
{/* prettier-ignore-start */}
|
||||
[enabling-experiments]: ./experiments.mdx#enabling-experiments
|
||||
[man-in-the-middle-attacks]: https://en.wikipedia.org/wiki/Man-in-the-middle_attack
|
||||
[supported-file-names]: https://taskfile.dev/usage/#supported-file-names
|
||||
[example-remote-taskfile]: https://raw.githubusercontent.com/go-task/task/main/website/static/Taskfile.yml
|
||||
{/* prettier-ignore-end */}
|
||||
|
@@ -62,8 +62,8 @@ the commands.
|
||||
|
||||
## Calling a task
|
||||
|
||||
To call the task, you simply invoke `task` followed by the name of the task you
|
||||
want to run. In this case, the name of the task is `default`, so you should run:
|
||||
To call the task, invoke `task` followed by the name of the task you want to
|
||||
run. In this case, the name of the task is `default`, so you should run:
|
||||
|
||||
```shell
|
||||
task default
|
||||
|
@@ -181,6 +181,11 @@ to install a specific version:
|
||||
sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d v3.36.0
|
||||
```
|
||||
|
||||
Parameters are order specific, to set both installation directory and version:
|
||||
```shell
|
||||
sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b ~/.local/bin v3.42.1
|
||||
```
|
||||
|
||||
### GitHub Actions
|
||||
|
||||
If you want to install Task in GitHub Actions you can try using
|
||||
|
@@ -24,7 +24,7 @@ If `--` is given, all remaining arguments will be assigned to a special
|
||||
| ----- | --------------------------- | -------- | -------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `-c` | `--color` | `bool` | `true` | Colored output. Enabled by default. Set flag to `false` or use `NO_COLOR=1` to disable. |
|
||||
| `-C` | `--concurrency` | `int` | `0` | Limit number tasks to run concurrently. Zero means unlimited. |
|
||||
| `-d` | `--dir` | `string` | Working directory | Sets directory of execution. |
|
||||
| `-d` | `--dir` | `string` | Working directory | Sets the directory in which Task will execute and look for a Taskfile. |
|
||||
| `-n` | `--dry` | `bool` | `false` | Compiles and prints tasks in the order that they would be run, without executing them. |
|
||||
| `-x` | `--exit-code` | `bool` | `false` | Pass-through the exit code of the task command. |
|
||||
| `-f` | `--force` | `bool` | `false` | Forces execution even when the task is up-to-date. |
|
||||
|
@@ -23,7 +23,145 @@ changelog entry for breaking changes to the package API.
|
||||
Task is primarily a CLI tool that is agnostic of any programming language.
|
||||
However, it is written in Go and therefore can also be used as a Go package too.
|
||||
This can be useful if you are already using Go in your project and you need to
|
||||
extend Task's functionality in some way.
|
||||
extend Task's functionality in some way. In this document, we describe the
|
||||
public API surface of Task and how to use it. This may also be useful if you
|
||||
want to contribute to Task or understand how it works in more detail.
|
||||
|
||||
The full generated documentation for the package API is available on
|
||||
[pkg.go.dev](https://pkg.go.dev/github.com/go-task/task/v3).
|
||||
## Key packages
|
||||
|
||||
The following packages make up the most important parts of Task's package API.
|
||||
Below we have listed what they are for and some of the key types available:
|
||||
|
||||
### [`github.com/go-task/task/v3`]
|
||||
|
||||
The core task package provides most of the main functionality for Task including
|
||||
fetching and executing tasks from a Taskfile. At this time, the vast majority of
|
||||
the this package's functionality is exposed via the [`task.Executor`] which
|
||||
allows the user to fetch and execute tasks from a Taskfile.
|
||||
|
||||
:::note
|
||||
This is the package which is most likely to be the subject of breaking changes
|
||||
as we refine the API.
|
||||
:::
|
||||
|
||||
### [`github.com/go-task/task/v3/taskfile`]
|
||||
|
||||
The `taskfile` package provides utilities for _reading_ Taskfiles from various
|
||||
sources. These sources can be local files, remote files, or even in-memory
|
||||
strings (via stdin).
|
||||
|
||||
- [`taskfile.Node`] - A reference to the location of a Taskfile. A `Node` is an
|
||||
interface that has several implementations:
|
||||
- [`taskfile.FileNode`] - Local files
|
||||
- [`taskfile.HTTPNode`] - Remote files via HTTP/HTTPS
|
||||
- [`taskfile.GitNode`] - Remote files via Git
|
||||
- [`taskfile.StdinNode`] - In-memory strings (via stdin)
|
||||
- [`taskfile.Reader`] - Accepts a `Node` and reads the Taskfile from it.
|
||||
- [`taskfile.Snippet`] - Mostly used for rendering Taskfile errors. A snippet
|
||||
stores a small part of a taskfile around a given line number and column. The
|
||||
output can be syntax highlighted for CLIs and include line/column indicators.
|
||||
|
||||
### [`github.com/go-task/task/v3/taskfile/ast`]
|
||||
|
||||
AST stands for ["Abstract Syntax Tree"][ast]. An AST allows us to easily
|
||||
represent the Taskfile syntax in Go. This package provides a way to parse
|
||||
Taskfile YAML into an AST and store them in memory.
|
||||
|
||||
- [`ast.TaskfileGraph`] - Represents a set of Taskfiles and their dependencies
|
||||
between one another.
|
||||
- [`ast.Taskfile`] - Represents a single Taskfile or a set of merged Taskfiles.
|
||||
The `Taskfile` type contains all of the subtypes for the Taskfile syntax, such
|
||||
as `tasks`, `includes`, `vars`, etc. These are not listed here for brevity.
|
||||
|
||||
### [`github.com/go-task/task/v3/errors`]
|
||||
|
||||
Contains all of the error types used in Task. All of these types implement the
|
||||
[`errors.TaskError`] interface which wraps Go's standard [`error`] interface.
|
||||
This allows you to call the `Code` method on the error to obtain the unique exit
|
||||
code for any error.
|
||||
|
||||
## Reading Taskfiles
|
||||
|
||||
Start by importing the `github.com/go-task/task/v3/taskfile` package. This
|
||||
provides all of the functions you need to read a Taskfile into memory:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/go-task/task/v3/taskfile"
|
||||
)
|
||||
```
|
||||
|
||||
Reading Taskfiles is done by using a [`taskfile.Reader`] and an implementation
|
||||
of [`taskfile.Node`]. In this example we will read a local file by using the
|
||||
[`taskfile.FileNode`] type. You can create this by calling the
|
||||
[`taskfile.NewFileNode`] function:
|
||||
|
||||
```go
|
||||
node := taskfile.NewFileNode("Taskfile.yml", "./path/to/dir")
|
||||
```
|
||||
|
||||
and then create a your reader by calling the [`taskfile.NewReader`] function and
|
||||
passing any functional options you want to use. For example, you could pass a
|
||||
debug function to the reader which will be called with debug messages:
|
||||
|
||||
```go
|
||||
reader := taskfile.NewReader(
|
||||
taskfile.WithDebugFunc(func(s string) {
|
||||
slog.Debug(s)
|
||||
}),
|
||||
)
|
||||
```
|
||||
|
||||
Now that everything is set up, you can read the Taskfile (and any included
|
||||
Taskfiles) by calling the `Read` method on the reader and pass the `Node` as an
|
||||
argument:
|
||||
|
||||
```go
|
||||
ctx := context.Background()
|
||||
tfg, err := reader.Read(ctx, node)
|
||||
// handle error
|
||||
```
|
||||
|
||||
This returns an instance of [`ast.TaskfileGraph`] which is a "Directed Acyclic
|
||||
Graph" (DAG) of all the parsed Taskfiles. We use this graph to store and resolve
|
||||
the `includes` directives in Taskfiles. However most of the time, you will want
|
||||
a merged Taskfile. To do this, simply call the `Merge` method on the Taskfile
|
||||
graph:
|
||||
|
||||
```go
|
||||
tf, err := tfg.Merge()
|
||||
// handle error
|
||||
```
|
||||
|
||||
This compiles the DAG into a single [`ast.Taskfile`] containing all the
|
||||
namespaces and tasks from all the Taskfiles we read.
|
||||
|
||||
:::note
|
||||
We plan to remove AST merging in the future as it is unnecessarily complex and
|
||||
causes lots of issues with scoping.
|
||||
:::
|
||||
|
||||
{/* prettier-ignore-start */}
|
||||
[`github.com/go-task/task/v3`]: https://pkg.go.dev/github.com/go-task/task/v3
|
||||
[`github.com/go-task/task/v3/taskfile`]: https://pkg.go.dev/github.com/go-task/task/v3/taskfile
|
||||
[`github.com/go-task/task/v3/taskfile/ast`]: https://pkg.go.dev/github.com/go-task/task/v3/taskfile/ast
|
||||
[`github.com/go-task/task/v3/errors`]: https://pkg.go.dev/github.com/go-task/task/v3/errors
|
||||
|
||||
[`ast.TaskfileGraph`]: https://pkg.go.dev/github.com/go-task/task/v3/taskfile/ast#TaskfileGraph
|
||||
[`ast.Taskfile`]: https://pkg.go.dev/github.com/go-task/task/v3/taskfile/ast#Taskfile
|
||||
[`taskfile.Node`]: https://pkg.go.dev/github.com/go-task/task/v3/taskfile#Node
|
||||
[`taskfile.FileNode`]: https://pkg.go.dev/github.com/go-task/task/v3/taskfile#FileNode
|
||||
[`taskfile.HTTPNode`]: https://pkg.go.dev/github.com/go-task/task/v3/taskfile#HTTPNode
|
||||
[`taskfile.GitNode`]: https://pkg.go.dev/github.com/go-task/task/v3/taskfile#GitNode
|
||||
[`taskfile.StdinNode`]: https://pkg.go.dev/github.com/go-task/task/v3/taskfile#StdinNode
|
||||
[`taskfile.NewFileNode`]: https://pkg.go.dev/github.com/go-task/task/v3/taskfile#NewFileNode
|
||||
[`taskfile.Reader`]: https://pkg.go.dev/github.com/go-task/task/v3/taskfile#Reader
|
||||
[`taskfile.NewReader`]: https://pkg.go.dev/github.com/go-task/task/v3/taskfile#NewReader
|
||||
[`taskfile.Snippet`]: https://pkg.go.dev/github.com/go-task/task/v3/taskfile#Snippet
|
||||
[`task.Executor`]: https://pkg.go.dev/github.com/go-task/task/v3#Executor
|
||||
[`task.Formatter`]: https://pkg.go.dev/github.com/go-task/task/v3#Formatter
|
||||
[`errors.TaskError`]: https://pkg.go.dev/github.com/go-task/task/v3/errors#TaskError
|
||||
[`error`]: https://pkg.go.dev/builtin#error
|
||||
|
||||
[ast]: https://en.wikipedia.org/wiki/Abstract_syntax_tree
|
||||
{/* prettier-ignore-end */}
|
||||
|
@@ -196,9 +196,12 @@ If defined as a string this is a shell command, otherwise it is a map defining a
|
||||
The `for` parameter can be defined as a string, a list of strings or a map. If
|
||||
it is defined as a string, you can give it any of the following values:
|
||||
|
||||
- `source` - Will run the command for each source file defined on the task.
|
||||
- `sources` - Will run the command for each source file defined on the task.
|
||||
(Glob patterns will be resolved, so `*.go` will run for every Go file that
|
||||
matches).
|
||||
- `generates` - Will run the command for each file defined in the task's generates
|
||||
list. (Glob patterns will be resolved, so `*.txt` will run for every text file
|
||||
that matches).
|
||||
|
||||
If it is defined as a list of strings, the command will be run for each value.
|
||||
|
||||
|
@@ -115,7 +115,7 @@ special variable will be overridden.
|
||||
| `TASKFILE` | The absolute path of the included Taskfile. |
|
||||
| `TASKFILE_DIR` | The absolute path of the included Taskfile directory. |
|
||||
| `TASK_DIR` | The absolute path of the directory where the task is executed. |
|
||||
| `USER_WORKING_DIR` | The absolute path of the directory `task` was called from. |
|
||||
| `USER_WORKING_DIR` | The absolute path of the directory `task` was called from, or the value of `--dir` (`-d`) if given. |
|
||||
| `CHECKSUM` | The checksum of the files listed in `sources`. Only available within the `status` prop and if method is set to `checksum`. |
|
||||
| `TIMESTAMP` | The date object of the greatest timestamp of the files listed in `sources`. Only available within the `status` prop and if method is set to `timestamp`. |
|
||||
| `TASK_VERSION` | The current version of task. |
|
||||
|
@@ -61,6 +61,12 @@ In this example, we can run `cd <service>` and `task up` and as long as the
|
||||
`<service>` directory contains a `docker-compose.yml`, the Docker composition
|
||||
will be brought up.
|
||||
|
||||
:::info
|
||||
|
||||
`.USER_WORKING_DIR` will contain the value of the `--dir` (`-d`) flag, if given.
|
||||
|
||||
:::
|
||||
|
||||
### Running a global Taskfile
|
||||
|
||||
If you call Task with the `--global` (alias `-g`) flag, it will look for your
|
||||
@@ -309,45 +315,38 @@ You can flatten the included Taskfile tasks into the main Taskfile by using the
|
||||
It means that the included Taskfile tasks will be available without the namespace.
|
||||
|
||||
|
||||
<Tabs defaultValue="1"
|
||||
values={[
|
||||
{label: 'Taskfile.yml', value: '1'},
|
||||
{label: 'Included.yml', value: '2'}
|
||||
]}>
|
||||
<Tabs defaultValue="1">
|
||||
<TabItem value="1" label="Taskfile.yml">
|
||||
|
||||
<TabItem value="1">
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
includes:
|
||||
lib:
|
||||
taskfile: ./Included.yml
|
||||
flatten: true
|
||||
|
||||
includes:
|
||||
lib:
|
||||
taskfile: ./Included.yml
|
||||
flatten: true
|
||||
tasks:
|
||||
greet:
|
||||
cmds:
|
||||
- echo "Greet"
|
||||
- task: foo
|
||||
```
|
||||
|
||||
tasks:
|
||||
greet:
|
||||
cmds:
|
||||
- echo "Greet"
|
||||
- task: foo
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="2" label="Included.yml">
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="2">
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
foo:
|
||||
cmds:
|
||||
- echo "Foo"
|
||||
```
|
||||
|
||||
|
||||
</TabItem></Tabs>
|
||||
tasks:
|
||||
foo:
|
||||
cmds:
|
||||
- echo "Foo"
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
If you run `task -a` it will print :
|
||||
|
||||
@@ -368,43 +367,37 @@ Foo
|
||||
|
||||
If multiple tasks have the same name, an error will be thrown:
|
||||
|
||||
<Tabs defaultValue="1"
|
||||
values={[
|
||||
{label: 'Taskfile.yml', value: '1'},
|
||||
{label: 'Included.yml', value: '2'}
|
||||
]}>
|
||||
<Tabs defaultValue="1">
|
||||
<TabItem value="1" label="Taskfile.yml">
|
||||
|
||||
<TabItem value="1">
|
||||
```yaml
|
||||
version: '3'
|
||||
includes:
|
||||
lib:
|
||||
taskfile: ./Included.yml
|
||||
flatten: true
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
includes:
|
||||
lib:
|
||||
taskfile: ./Included.yml
|
||||
flatten: true
|
||||
tasks:
|
||||
greet:
|
||||
cmds:
|
||||
- echo "Greet"
|
||||
- task: foo
|
||||
```
|
||||
|
||||
tasks:
|
||||
greet:
|
||||
cmds:
|
||||
- echo "Greet"
|
||||
- task: foo
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="2" label="Included.yml">
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="2">
|
||||
tasks:
|
||||
greet:
|
||||
cmds:
|
||||
- echo "Foo"
|
||||
```
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
greet:
|
||||
cmds:
|
||||
- echo "Foo"
|
||||
```
|
||||
|
||||
|
||||
</TabItem></Tabs>
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
If you run `task -a` it will print:
|
||||
```text
|
||||
@@ -420,35 +413,29 @@ You can do this by using the [`excludes` option](#exclude-tasks-from-being-inclu
|
||||
|
||||
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'}
|
||||
]}>
|
||||
<Tabs defaultValue="1">
|
||||
<TabItem value="1" label="Taskfile.yml">
|
||||
|
||||
<TabItem value="1">
|
||||
```yaml
|
||||
version: '3'
|
||||
includes:
|
||||
included:
|
||||
taskfile: ./Included.yml
|
||||
excludes: [foo]
|
||||
```
|
||||
```yaml
|
||||
version: '3'
|
||||
includes:
|
||||
included:
|
||||
taskfile: ./Included.yml
|
||||
excludes: [foo]
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="2" label="Included.yml">
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="2">
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
tasks:
|
||||
foo: echo "Foo"
|
||||
bar: echo "Bar"
|
||||
```
|
||||
|
||||
tasks:
|
||||
foo: echo "Foo"
|
||||
bar: echo "Bar"
|
||||
```
|
||||
|
||||
|
||||
</TabItem></Tabs>
|
||||
</TabItem></Tabs>
|
||||
|
||||
`task included:foo` will throw an error because the `foo` task is excluded but `task included:bar` will work and display `Bar`.
|
||||
|
||||
@@ -1113,53 +1100,38 @@ variable types are supported:
|
||||
- `int`
|
||||
- `float`
|
||||
- `array`
|
||||
- `map`
|
||||
|
||||
:::note
|
||||
|
||||
Maps are not supported by default, but there is an
|
||||
[experiment][map-variables] that can be enabled to add support. If
|
||||
you're interested in this functionality, we would appreciate your feedback.
|
||||
:pray:
|
||||
|
||||
In the meantime, it is technically possible to define a map using a `ref` resolver and a templating function. For example:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
task-with-map:
|
||||
vars:
|
||||
FOO:
|
||||
ref: dict "a" "1" "b" "2" "c" "3"
|
||||
cmds:
|
||||
- echo {{.FOO}}
|
||||
```
|
||||
|
||||
```txt
|
||||
map[a:1 b:2 c:3]
|
||||
```
|
||||
|
||||
OR by using the same technique with JSON:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
task-with-map:
|
||||
vars:
|
||||
JSON: '{"a": 1, "b": 2, "c": 3}'
|
||||
FOO:
|
||||
ref: "fromJson .JSON"
|
||||
cmds:
|
||||
- echo {{.FOO}}
|
||||
```
|
||||
|
||||
```txt
|
||||
map[a:1 b:2 c:3]
|
||||
```
|
||||
Defining a map requires that you use a special `map` subkey (see example below).
|
||||
|
||||
:::
|
||||
|
||||
```yaml
|
||||
version: 3
|
||||
|
||||
tasks:
|
||||
foo:
|
||||
vars:
|
||||
STRING: 'Hello, World!'
|
||||
BOOL: true
|
||||
INT: 42
|
||||
FLOAT: 3.14
|
||||
ARRAY: [1, 2, 3]
|
||||
MAP:
|
||||
map: {A: 1, B: 2, C: 3}
|
||||
cmds:
|
||||
- 'echo {{.STRING}}' # Hello, World!
|
||||
- 'echo {{.BOOL}}' # true
|
||||
- 'echo {{.INT}}' # 42
|
||||
- 'echo {{.FLOAT}}' # 3.14
|
||||
- 'echo {{.ARRAY}}' # [1 2 3]
|
||||
- 'echo {{.ARRAY.0}}' # 1
|
||||
- 'echo {{.MAP}}' # map[A:1 B:2 C:3]
|
||||
- 'echo {{.MAP.A}}' # 1
|
||||
```
|
||||
|
||||
Variables can be set in many places in a Taskfile. When executing
|
||||
[templates][templating-reference], Task will look for variables in the order
|
||||
listed below (most important first):
|
||||
@@ -1270,13 +1242,8 @@ a value from one task to another. However, the templating engine is only able to
|
||||
output strings. If you want to pass something other than a string to another
|
||||
task then you will need to use a reference (`ref`) instead.
|
||||
|
||||
<Tabs defaultValue="2"
|
||||
values={[
|
||||
{ label: 'Templating Engine', value: '1' },
|
||||
{ label: 'Reference', value: '2' }
|
||||
]}>
|
||||
|
||||
<TabItem value="1">
|
||||
<Tabs defaultValue="2">
|
||||
<TabItem value="1" label="Templating Engine">
|
||||
|
||||
```yaml
|
||||
version: 3
|
||||
@@ -1295,7 +1262,7 @@ tasks:
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="2">
|
||||
<TabItem value="2" label="Reference">
|
||||
|
||||
```yaml
|
||||
version: 3
|
||||
@@ -1314,7 +1281,8 @@ tasks:
|
||||
- 'echo {{index .FOO 0}}' # <-- FOO is still a map so the task outputs 'A' as expected
|
||||
```
|
||||
|
||||
</TabItem></Tabs>
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
This also works the same way when calling `deps` and when defining
|
||||
a variable and can be used in any combination:
|
||||
@@ -1339,8 +1307,8 @@ tasks:
|
||||
```
|
||||
|
||||
All references use the same templating syntax as regular templates, so in
|
||||
addition to simply calling `.FOO`, you can also pass subkeys (`.FOO.BAR`) or
|
||||
indexes (`index .FOO 0`) and use functions (`len .FOO`) as described in the
|
||||
addition to calling `.FOO`, you can also pass subkeys (`.FOO.BAR`) or indexes
|
||||
(`index .FOO 0`) and use functions (`len .FOO`) as described in the
|
||||
[templating-reference][templating-reference]:
|
||||
|
||||
```yaml
|
||||
@@ -1360,6 +1328,29 @@ tasks:
|
||||
- 'echo {{.FOO}}' # <-- FOO is just the letter 'A'
|
||||
```
|
||||
|
||||
### Parsing JSON/YAML into map variables
|
||||
|
||||
If you have a raw JSON or YAML string that you want to process in Task, you can
|
||||
use a combination of the `ref` keyword and the `fromJson` or `fromYaml`
|
||||
templating functions to parse the string into a map variable. For example:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
task-with-map:
|
||||
vars:
|
||||
JSON: '{"a": 1, "b": 2, "c": 3}'
|
||||
FOO:
|
||||
ref: "fromJson .JSON"
|
||||
cmds:
|
||||
- echo {{.FOO}}
|
||||
```
|
||||
|
||||
```txt
|
||||
map[a:1 b:2 c:3]
|
||||
```
|
||||
|
||||
## Looping over values
|
||||
|
||||
Task allows you to loop over certain values and execute a command for each.
|
||||
@@ -1433,9 +1424,13 @@ tasks:
|
||||
cmd: echo "{{.ITEM.OS}}/{{.ITEM.ARCH}}"
|
||||
```
|
||||
|
||||
### Looping over your task's sources
|
||||
### Looping over your task's sources or generated files
|
||||
|
||||
You are also able to loop over the sources of your task:
|
||||
You are also able to loop over the sources of your task or the files it
|
||||
generates:
|
||||
|
||||
<Tabs defaultValue="1" groupId="sources-generates">
|
||||
<TabItem value="1" label="Sources">
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
@@ -1450,14 +1445,37 @@ tasks:
|
||||
cmd: cat {{ .ITEM }}
|
||||
```
|
||||
|
||||
This will also work if you use globbing syntax in your sources. For example, if
|
||||
you specify a source for `*.txt`, the loop will iterate over all files that
|
||||
match that glob.
|
||||
</TabItem>
|
||||
<TabItem value="2" label="Generates">
|
||||
|
||||
Source paths will always be returned as paths relative to the task directory. If
|
||||
you need to convert this to an absolute path, you can use the built-in
|
||||
`joinPath` function. There are some [special variables](/reference/templating/#special-variables)
|
||||
that you may find useful for this.
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
default:
|
||||
generates:
|
||||
- foo.txt
|
||||
- bar.txt
|
||||
cmds:
|
||||
- for: generates
|
||||
cmd: cat {{ .ITEM }}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
This will also work if you use globbing syntax in `sources` or `generates`. For
|
||||
example, if you specify a source for `*.txt`, the loop will iterate over all
|
||||
files that match that glob.
|
||||
|
||||
Paths will always be returned as paths relative to the task directory. If you
|
||||
need to convert this to an absolute path, you can use the built-in `joinPath`
|
||||
function. There are some [special
|
||||
variables](/reference/templating/#special-variables) that you may find useful
|
||||
for this.
|
||||
|
||||
<Tabs defaultValue="1" groupId="sources-generates">
|
||||
<TabItem value="1" label="Sources">
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
@@ -1475,11 +1493,33 @@ tasks:
|
||||
cmd: cat {{joinPath .MY_DIR .ITEM}}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="2" label="Generates">
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
default:
|
||||
vars:
|
||||
MY_DIR: /path/to/dir
|
||||
dir: '{{.MY_DIR}}'
|
||||
generates:
|
||||
- foo.txt
|
||||
- bar.txt
|
||||
cmds:
|
||||
- for: generates
|
||||
cmd: cat {{joinPath .MY_DIR .ITEM}}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
### Looping over variables
|
||||
|
||||
To loop over the contents of a variable, you simply need to specify the variable
|
||||
you want to loop over. By default, string variables will be split on any
|
||||
whitespace characters.
|
||||
To loop over the contents of a variable, use the `var` key followed by the name
|
||||
of the variable you want to loop over. By default, string variables will be
|
||||
split on any whitespace characters.
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
@@ -1508,7 +1548,7 @@ tasks:
|
||||
cmd: cat {{.ITEM}}
|
||||
```
|
||||
|
||||
You can also loop over arrays directly and maps:
|
||||
You can also loop over arrays and maps directly:
|
||||
|
||||
```yaml
|
||||
version: 3
|
||||
@@ -1674,36 +1714,45 @@ clear what they contain:
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
echo-*:
|
||||
start:*:*:
|
||||
vars:
|
||||
TEXT: '{{index .MATCH 0}}'
|
||||
SERVICE: "{{index .MATCH 0}}"
|
||||
REPLICAS: "{{index .MATCH 1}}"
|
||||
cmds:
|
||||
- echo {{.TEXT}}
|
||||
- echo "Starting {{.SERVICE}} with {{.REPLICAS}} replicas"
|
||||
|
||||
run-*-*:
|
||||
start:*:
|
||||
vars:
|
||||
ARG_1: '{{index .MATCH 0}}'
|
||||
ARG_2: '{{index .MATCH 1}}'
|
||||
SERVICE: "{{index .MATCH 0}}"
|
||||
cmds:
|
||||
- echo {{.ARG_1}} {{.ARG_2}}
|
||||
- echo "Starting {{.SERVICE}}"
|
||||
```
|
||||
|
||||
This call matches the `start:*` task and the string "foo" is captured by the
|
||||
wildcard and stored in the `.MATCH` variable. We then index the `.MATCH` array
|
||||
and store the result in the `.SERVICE` variable which is then echoed out in the
|
||||
cmds:
|
||||
|
||||
```shell
|
||||
# This call matches the "echo-*" task and the string "hello" is captured by the
|
||||
# wildcard and stored in the .MATCH variable. We then index the .MATCH array and
|
||||
# store the result in the .TEXT variable which is then echoed out in the cmds.
|
||||
$ task echo-hello
|
||||
hello
|
||||
# You can use whitespace in your arguments as long as you quote the task name
|
||||
$ task "echo-hello world"
|
||||
hello world
|
||||
# And you can pass multiple arguments
|
||||
$ task run-foo-bar
|
||||
foo bar
|
||||
$ task start:foo
|
||||
Starting foo
|
||||
```
|
||||
|
||||
If multiple matching tasks are found, an error occurs. If you are using included
|
||||
Taskfiles, tasks in parent files will be considered first.
|
||||
You can use whitespace in your arguments as long as you quote the task name:
|
||||
|
||||
```shell
|
||||
$ task "start:foo bar"
|
||||
Starting foo bar
|
||||
```
|
||||
|
||||
If multiple matching tasks are found, the first one listed in the Taskfile will
|
||||
be used. If you are using included Taskfiles, tasks in parent files will be
|
||||
considered first.
|
||||
|
||||
```shell
|
||||
$ task start:foo:3
|
||||
Starting foo with 3 replicas
|
||||
```
|
||||
|
||||
## Doing task cleanup with `defer`
|
||||
|
||||
@@ -2285,9 +2334,11 @@ With the flags `--watch` or `-w` task will watch for file changes and run the
|
||||
task again. This requires the `sources` attribute to be given, so task knows
|
||||
which files to watch.
|
||||
|
||||
The default watch interval is 5 seconds, but it's possible to change it by
|
||||
either setting `interval: '500ms'` in the root of the Taskfile or by passing it
|
||||
as an argument like `--interval=500ms`.
|
||||
The default watch interval is 100 milliseconds, but it's possible to change it
|
||||
by either setting `interval: '500ms'` in the root of the Taskfile or by passing
|
||||
it as an argument like `--interval=500ms`.
|
||||
This interval is the time Task will wait for duplicated events. It will only run
|
||||
the task again once, even if multiple changes happen within the interval.
|
||||
|
||||
Also, it's possible to set `watch: true` in a given task and it'll automatically
|
||||
run in watch mode:
|
||||
@@ -2317,6 +2368,5 @@ if called by another task, either directly or as a dependency.
|
||||
|
||||
{/* prettier-ignore-start */}
|
||||
[gotemplate]: https://golang.org/pkg/text/template/
|
||||
[map-variables]: ./experiments/map_variables.mdx
|
||||
[templating-reference]: ./reference/templating.mdx
|
||||
{/* prettier-ignore-end */}
|
||||
|
Reference in New Issue
Block a user