--- 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. :::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: ```yaml version: 3 tasks: foo: vars: CALCULATED_VAR: sh: 'echo hello' cmds: - 'echo {{.CALCULATED_VAR}}' ``` ```yaml version: 3 tasks: foo: vars: CALCULATED_VAR: '$echo hello' # <-- Prefix dynamic variable with a `$` cmds: - 'echo {{.CALCULATED_VAR}}' ``` ### References ```yaml version: 3 tasks: foo: vars: VAR: 42 VAR_REF: ref: '.FOO' cmds: - 'echo {{.VAR_REF}}' ``` ```yaml version: 3 tasks: foo: vars: VAR: 42 VAR_REF: '#.FOO' # <-- Prefix reference with a `#` cmds: - 'echo {{.VAR_REF}}' ``` 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. :::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}}' ``` ## 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. ```yaml version: 3 tasks: foo: vars: MAP: {a: 1, b: 2, c: 3} cmds: - for: var: MAP cmd: 'echo "{{.KEY}}: {{.ITEM}}"' ``` ```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. ::: {/* prettier-ignore-start */} [enabling-experiments]: ./experiments.mdx#enabling-experiments {/* prettier-ignore-end */}