1
0
mirror of https://github.com/go-task/task.git synced 2025-07-15 01:35:00 +02:00
This commit is contained in:
Andrey Nering
2024-05-08 21:32:16 -03:00
parent 7fa06eedf4
commit ee901fe568
12 changed files with 206 additions and 121 deletions

View File

@ -1,6 +1,6 @@
# Changelog # Changelog
## Unreleased ## v3.37.0 - 2024-05-08
- Released the - Released the
[Any Variables experiment](https://taskfile.dev/blog/any-variables), but [Any Variables experiment](https://taskfile.dev/blog/any-variables), but

2
package-lock.json generated
View File

@ -1,6 +1,6 @@
{ {
"name": "@go-task/cli", "name": "@go-task/cli",
"version": "3.36.0", "version": "3.37.0",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {

View File

@ -1,6 +1,6 @@
{ {
"name": "@go-task/cli", "name": "@go-task/cli",
"version": "3.36.0", "version": "3.37.0",
"description": "A task runner / simpler Make alternative written in Go", "description": "A task runner / simpler Make alternative written in Go",
"scripts": { "scripts": {
"postinstall": "go-npm install", "postinstall": "go-npm install",

View File

@ -5,6 +5,27 @@ sidebar_position: 14
# Changelog # Changelog
## v3.37.0 - 2024-05-08
- Released the
[Any Variables experiment](https://taskfile.dev/blog/any-variables), but
[_without support for maps_](https://github.com/go-task/task/issues/1415#issuecomment-2044756925)
(#1415, #1547 by @pd93).
- Refactored how Task reads, parses and merges Taskfiles using a DAG (#1563,
#1607 by @pd93).
- Fix a bug which stopped tasks from using `stdin` as input (#1593, #1623 by
@pd03).
- Fix error when a file or directory in the project contained a special char
like `&`, `(` or `)` (#1551, #1584 by @andreynering).
- Added alias `q` for template function `shellQuote` (#1601, #1603 by @vergenzt)
- Added support for `~` on ZSH completions (#1613 by @jwater7).
- Added the ability to pass variables by reference using Go template syntax when
the
[Map Variables experiment](https://taskfile.dev/experiments/map-variables/) is
enabled (#1612 by @pd93).
- Added support for environment variables in the templating engine in `includes`
(#1610 by @vmaerten).
## v3.36.0 - 2024-04-08 ## v3.36.0 - 2024-04-08
- Added support for - Added support for

View File

@ -5,6 +5,27 @@ sidebar_position: 14
# Changelog # Changelog
## v3.37.0 - 2024-05-08
- Released the
[Any Variables experiment](https://taskfile.dev/blog/any-variables), but
[_without support for maps_](https://github.com/go-task/task/issues/1415#issuecomment-2044756925)
(#1415, #1547 by @pd93).
- Refactored how Task reads, parses and merges Taskfiles using a DAG (#1563,
#1607 by @pd93).
- Fix a bug which stopped tasks from using `stdin` as input (#1593, #1623 by
@pd03).
- Fix error when a file or directory in the project contained a special char
like `&`, `(` or `)` (#1551, #1584 by @andreynering).
- Added alias `q` for template function `shellQuote` (#1601, #1603 by @vergenzt)
- Added support for `~` on ZSH completions (#1613 by @jwater7).
- Added the ability to pass variables by reference using Go template syntax when
the
[Map Variables experiment](https://taskfile.dev/experiments/map-variables/) is
enabled (#1612 by @pd93).
- Added support for environment variables in the templating engine in `includes`
(#1610 by @vmaerten).
## v3.36.0 - 2024-04-08 ## v3.36.0 - 2024-04-08
- Added support for - Added support for

View File

@ -45,5 +45,5 @@ if you want to adopt the new behavior, you can continue to use the `--force`
flag as you do now! flag as you do now!
{/* prettier-ignore-start */} {/* prettier-ignore-start */}
[enabling-experiments]: /experiments/#enabling-experiments [enabling-experiments]: ./experiments.mdx#enabling-experiments
{/* prettier-ignore-end */} {/* prettier-ignore-end */}

View File

@ -1,11 +1,11 @@
--- ---
slug: /experiments/any-variables/ slug: /experiments/map-variables/
--- ---
import Tabs from '@theme/Tabs'; import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem'; import TabItem from '@theme/TabItem';
# Any Variables (#1415) # Map Variables (#1585)
:::caution :::caution
@ -15,19 +15,9 @@ environment. They are intended for testing and feedback only.
::: :::
Currently, Task only supports string variables. This experiment allows you to Currently, Task supports all variable types except for maps. This experiment
specify and use the following variable types: adds two different proposals for map variables. Click on the tabs below to
switch between them.
- `string`
- `bool`
- `int`
- `float`
- `array`
- `map`
This allows you to have a lot more flexibility in how you use variables in
Task's templating engine. There are two active proposals for this experiment.
Click on the tabs below to switch between them.
<Tabs defaultValue="1" queryString="proposal" <Tabs defaultValue="1" queryString="proposal"
values={[ values={[
@ -48,13 +38,11 @@ This experiment proposal breaks the following functionality:
:::info :::info
To enable this experiment, set the environment variable: To enable this experiment, set the environment variable:
`TASK_X_ANY_VARIABLES=1`. Check out [our guide to enabling experiments `TASK_X_MAP_VARIABLES=1`. Check out [our guide to enabling experiments
][enabling-experiments] for more information. ][enabling-experiments] for more information.
::: :::
## Maps
This proposal removes support for the `sh` keyword in favour of a new syntax for This proposal removes support for the `sh` keyword in favour of a new syntax for
dynamically defined variables, This allows you to define a map directly as you dynamically defined variables, This allows you to define a map directly as you
would for any other type: would for any other type:
@ -111,19 +99,16 @@ will now need to escape the `$` with a backslash (`\`) to stop Task from
executing it as a command. executing it as a command.
</TabItem> </TabItem>
<TabItem value="2"> <TabItem value="2">
:::info :::info
To enable this experiment, set the environment variable: To enable this experiment, set the environment variable:
`TASK_X_ANY_VARIABLES=2`. Check out [our guide to enabling experiments `TASK_X_MAP_VARIABLES=2`. Check out [our guide to enabling experiments
][enabling-experiments] for more information. ][enabling-experiments] for more information.
::: :::
## Maps
This proposal maintains backwards-compatibility and the `sh` subkey and adds This proposal maintains backwards-compatibility and the `sh` subkey and adds
another new `map` subkey for defining map variables: another new `map` subkey for defining map variables:
@ -150,7 +135,13 @@ objects/arrays. This is similar to the `fromJSON` template function, but means
that you only have to parse the JSON/YAML once when you declare the variable, that you only have to parse the JSON/YAML once when you declare the variable,
instead of every time you want to access a value. instead of every time you want to access a value.
Before: <Tabs defaultValue="2"
values={[
{label: 'Before', value: '1'},
{label: 'After', value: '2'}
]}>
<TabItem value="1">
```yaml ```yaml
version: 3 version: 3
@ -164,7 +155,8 @@ tasks:
- 'echo {{(fromJSON .FOO).b}}' - 'echo {{(fromJSON .FOO).b}}'
``` ```
After: </TabItem>
<TabItem value="2">
```yaml ```yaml
version: 3 version: 3
@ -179,12 +171,26 @@ tasks:
- 'echo {{.FOO.b}}' - 'echo {{.FOO.b}}'
``` ```
</TabItem></Tabs>
## Variables by reference ## Variables by reference
Lastly, this proposal adds support for defining and passing variables by Lastly, this proposal adds support for defining and passing variables by
reference. This is really important now that variables can be types other than a reference. This is really important now that variables can be types other than a
string. Previously, to send a variable from one task to another, you would have string.
to use the templating system to pass it:
Previously, to send a variable from one task to another, you would have to use
the templating system. Unfortunately, the templater _always_ outputs a string
and operations on the passed variable may not have behaved as expected. With
this proposal, you can now pass variables by reference using the `ref` subkey:
<Tabs defaultValue="2"
values={[
{label: 'Before', value: '1'},
{label: 'After', value: '2'}
]}>
<TabItem value="1">
```yaml ```yaml
version: 3 version: 3
@ -202,10 +208,8 @@ tasks:
- 'echo {{index .FOO 0}}' # <-- FOO is a string so the task outputs '91' which is the ASCII code for '[' instead of the expected 'A' - 'echo {{index .FOO 0}}' # <-- FOO is a string so the task outputs '91' which is the ASCII code for '[' instead of the expected 'A'
``` ```
Unfortunately, this results in the value always being passed as a string as this </TabItem>
is the output type of the templater and operations on the passed variable may <TabItem value="2">
not behave as expected. With this proposal, you can now pass variables by
reference using the `ref` subkey:
```yaml ```yaml
version: 3 version: 3
@ -218,12 +222,14 @@ tasks:
- task: bar - task: bar
vars: vars:
FOO: FOO:
ref: FOO # <-- FOO gets passed by reference to bar and maintains its type ref: .FOO # <-- FOO gets passed by reference to bar and maintains its type
bar: bar:
cmds: cmds:
- 'echo {{index .FOO 0}}' # <-- FOO is still a map so the task outputs 'A' as expected - 'echo {{index .FOO 0}}' # <-- FOO is still a map so the task outputs 'A' as expected
``` ```
</TabItem></Tabs>
This means that the type of the variable is maintained when it is passed to This means that the type of the variable is maintained when it is passed to
another Task. This also works the same way when calling `deps` and when defining another Task. This also works the same way when calling `deps` and when defining
a variable and can be used in any combination: a variable and can be used in any combination:
@ -236,27 +242,54 @@ tasks:
vars: vars:
FOO: [A, B, C] # <-- FOO is defined as an array FOO: [A, B, C] # <-- FOO is defined as an array
BAR: BAR:
ref: FOO # <-- BAR is defined as a reference to FOO ref: .FOO # <-- BAR is defined as a reference to FOO
deps: deps:
- task: bar - task: bar
vars: vars:
BAR: BAR:
ref: BAR # <-- BAR gets passed by reference to bar and maintains its type ref: .BAR # <-- BAR gets passed by reference to bar and maintains its type
bar: bar:
cmds: cmds:
- 'echo {{index .BAR 0}}' # <-- BAR still refers to FOO so the task outputs 'A' - 'echo {{index .BAR 0}}' # <-- BAR still refers to FOO so the task outputs 'A'
``` ```
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`):
```yaml
version: 3
tasks:
foo:
vars:
FOO: [A, B, C] # <-- FOO is defined as an array
cmds:
- task: bar
vars:
FOO:
ref: index .FOO 0 # <-- The element at index 0 is passed by reference to bar
bar:
cmds:
- 'echo {{.MYVAR}}' # <-- FOO is just the letter 'A'
```
</TabItem></Tabs> </TabItem></Tabs>
--- ## Looping over maps
## Common to both proposals 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.
Both proposals add support for all other variable types by directly defining <Tabs defaultValue="1" queryString="proposal"
them in the Taskfile. For example: values={[
{label: 'Proposal 1', value: '1'},
{label: 'Proposal 2', value: '2'}
]}>
### Evaluating booleans <TabItem value="1">
```yaml ```yaml
version: 3 version: 3
@ -264,64 +297,15 @@ version: 3
tasks: tasks:
foo: foo:
vars: vars:
BOOL: false MAP: {a: 1, b: 2, c: 3}
cmds:
- '{{if .BOOL}}echo foo{{end}}'
```
### Arithmetic
```yaml
version: 3
tasks:
foo:
vars:
INT: 10
FLOAT: 3.14159
cmds:
- 'echo {{add .INT .FLOAT}}'
```
### Ranging
```yaml
version: 3
tasks:
foo:
vars:
ARRAY: [1, 2, 3]
cmds:
- 'echo {{range .ARRAY}}{{.}}{{end}}'
```
There are many more templating functions which can be used with the new types of
variables. For a full list, see the [slim-sprig][slim-sprig] documentation.
## Looping over variables
Previously, you would have to use a delimiter separated string to loop over an
arbitrary list of items in a variable and split them by using the `split` subkey
to specify the delimiter:
```yaml
version: 3
tasks:
foo:
vars:
LIST: 'foo,bar,baz'
cmds: cmds:
- for: - for:
var: LIST var: MAP
split: ',' cmd: 'echo "{{.KEY}}: {{.ITEM}}"'
cmd: echo {{.ITEM}}
``` ```
Both of these proposals add support for looping over "collection-type" variables </TabItem>
using the `for` keyword, so now you are able to loop over a map/array variable <TabItem value="2">
directly:
```yaml ```yaml
version: 3 version: 3
@ -329,18 +313,23 @@ version: 3
tasks: tasks:
foo: foo:
vars: vars:
LIST: [foo, bar, baz] map:
MAP: {a: 1, b: 2, c: 3}
cmds: cmds:
- for: - for:
var: LIST var: MAP
cmd: echo {{.ITEM}} cmd: 'echo "{{.KEY}}: {{.ITEM}}"'
``` ```
When looping over a map we also make an additional `{{.KEY}}` variable availabe :::note
that holds the string value of the map key. Remember that maps are unordered, so
Remember that maps are unordered, so
the order in which the items are looped over is random. the order in which the items are looped over is random.
:::
</TabItem></Tabs>
{/* prettier-ignore-start */} {/* prettier-ignore-start */}
[enabling-experiments]: /experiments/#enabling-experiments [enabling-experiments]: ./experiments.mdx#enabling-experiments
[slim-sprig]: https://go-task.github.io/slim-sprig/
{/* prettier-ignore-end */} {/* prettier-ignore-end */}

View File

@ -48,6 +48,20 @@ tasks:
and you run `task my-remote-namespace:hello`, it will print the text: "Hello and you run `task my-remote-namespace:hello`, it will print the text: "Hello
from the remote Taskfile!" to your console. from the remote Taskfile!" to your console.
The Taskfile location is processed by the templating system, so you can
reference environment variables in your URL if you need to add authentication.
For example:
```yaml
version: '3'
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`
## Security ## Security
Running commands from sources that you do not control is always a potential Running commands from sources that you do not control is always a potential
@ -99,6 +113,6 @@ the `--timeout` flag and specifying a duration. For example, `--timeout 5s` will
set the timeout to 5 seconds. set the timeout to 5 seconds.
{/* prettier-ignore-start */} {/* prettier-ignore-start */}
[enabling-experiments]: /experiments/#enabling-experiments [enabling-experiments]: ./experiments.mdx#enabling-experiments
[man-in-the-middle-attacks]: https://en.wikipedia.org/wiki/Man-in-the-middle_attack [man-in-the-middle-attacks]: https://en.wikipedia.org/wiki/Man-in-the-middle_attack
{/* prettier-ignore-end */} {/* prettier-ignore-end */}

View File

@ -38,5 +38,5 @@ information.
\{Short explanation of how users should migrate to the new behavior\} \{Short explanation of how users should migrate to the new behavior\}
{/* prettier-ignore-start */} {/* prettier-ignore-start */}
[enabling-experiments]: /experiments/#enabling-experiments [enabling-experiments]: ./experiments.mdx#enabling-experiments
{/* prettier-ignore-end */} {/* prettier-ignore-end */}

View File

@ -31,7 +31,7 @@ brew install go-task
### pkgx ### pkgx
If you're on macOS or Linux and have [pkgx](https://pkgx.sh/) installed, getting Task is as If you're on macOS or Linux and have [pkgx][pkgx] installed, getting Task is as
simple as running: simple as running:
```shell ```shell
@ -299,5 +299,5 @@ Invoke-Expression -Command path/to/task.ps1
[godownloader]: https://github.com/goreleaser/godownloader [godownloader]: https://github.com/goreleaser/godownloader
[choco]: https://chocolatey.org/ [choco]: https://chocolatey.org/
[scoop]: https://scoop.sh/ [scoop]: https://scoop.sh/
[tea]: https://tea.xyz/ [pkgx]: https://pkgx.sh/
{/* prettier-ignore-end */} {/* prettier-ignore-end */}

View File

@ -256,8 +256,8 @@ The variable priority order was also different:
4. `Taskvars.yml` variables 4. `Taskvars.yml` variables
{/* prettier-ignore-start */} {/* prettier-ignore-start */}
[deprecate-version-2-schema]: /deprecations/version-2-schema/ [deprecate-version-2-schema]: ./deprecations/version_2_schema.mdx
[output]: /usage#output-syntax [output]: ./usage.mdx#output-syntax
[ignore_errors]: /usage#ignore-errors [ignore_errors]: ./usage.mdx#ignore-errors
[includes]: /usage#including-other-taskfiles [includes]: ./usage.mdx#including-other-taskfiles
{/* prettier-ignore-end */} {/* prettier-ignore-end */}

View File

@ -121,13 +121,14 @@ tasks:
### Reading a Taskfile from stdin ### Reading a Taskfile from stdin
Taskfile also supports reading from stdin. This is useful if you are generating Taskfile also supports reading from stdin. This is useful if you are generating
Taskfiles dynamically and don't want write them to disk. This works just like Taskfiles dynamically and don't want write them to disk. To tell task to read
any other program that supports stdin. For example: from stdin, you must specify the `-t/--taskfile` flag with the special `-`
value. You may then pipe into Task as you would any other program:
```shell ```shell
task < <(cat ./Taskfile.yml) task -t - <(cat ./Taskfile.yml)
# OR # OR
cat ./Taskfile.yml | task cat ./Taskfile.yml | task -t -
``` ```
## Environment variables ## Environment variables
@ -947,8 +948,26 @@ tasks:
## Variables ## Variables
When doing interpolation of variables, Task will look for the below. They are Task allows you to set variables using the `vars` keyword. The following
listed below in order of importance (i.e. most important first): variable types are supported:
- `string`
- `bool`
- `int`
- `float`
- `array`
:::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:
:::
Variables can be set in many places in a Taskfile. When executing templates,
Task will look for variables in the order listed below (most important first):
- Variables declared in the task definition - Variables declared in the task definition
- Variables given while calling a task from another (See - Variables given while calling a task from another (See
@ -1093,8 +1112,8 @@ tasks:
### Looping over variables ### Looping over variables
To loop over the contents of a variable, you simply need to specify the variable To loop over the contents of a variable, you simply need to specify the variable
you want to loop over. By default, variables will be split on any whitespace you want to loop over. By default, string variables will be split on any
characters. whitespace characters.
```yaml ```yaml
version: '3' version: '3'
@ -1108,8 +1127,8 @@ tasks:
cmd: cat {{.ITEM}} cmd: cat {{.ITEM}}
``` ```
If you need to split on a different character, you can do this by specifying the If you need to split a string on a different character, you can do this by
`split` property: specifying the `split` property:
```yaml ```yaml
version: '3' version: '3'
@ -1123,6 +1142,26 @@ tasks:
cmd: cat {{.ITEM}} cmd: cat {{.ITEM}}
``` ```
You can also loop over arrays directly (and maps if you have the
[maps experiment](/experiments/map-variables) enabled):
```yaml
version: 3
tasks:
foo:
vars:
LIST: [foo, bar, baz]
cmds:
- for:
var: LIST
cmd: echo {{.ITEM}}
```
When looping over a map we also make an additional `{{.KEY}}` variable available
that holds the string value of the map key. Remember that maps are unordered, so
the order in which the items are looped over is random.
All of this also works with dynamic variables! All of this also works with dynamic variables!
```yaml ```yaml
@ -1956,4 +1995,5 @@ if called by another task, either directly or as a dependency.
{/* prettier-ignore-start */} {/* prettier-ignore-start */}
[gotemplate]: https://golang.org/pkg/text/template/ [gotemplate]: https://golang.org/pkg/text/template/
[map-variables]: ./experiments/map_variables.mdx
{/* prettier-ignore-end */} {/* prettier-ignore-end */}