mirror of
https://github.com/go-task/task.git
synced 2025-06-23 00:38:19 +02:00
feat: make map variables experiment (prop 2) generally available (#2081)
* feat: make map variables experiment (prop 2) generally available * docs: remove map variables experiment page and update usage to include map variable info
This commit is contained in:
@ -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 */}
|
@ -1113,53 +1113,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):
|
||||
@ -1360,6 +1345,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.
|
||||
@ -1508,7 +1516,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
|
||||
@ -2319,6 +2327,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