-
-
Notifications
You must be signed in to change notification settings - Fork 631
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
Map variables experiment #1585
Comments
This issue has been marked as an experiment proposal! 🧪 It will now enter a period of consultation during which we encourage the community to provide feedback on the proposed design. Please see the experiment workflow documentation for more information on how we release experiments. |
Is there a way to do templating in map variables? version: 3
tasks:
foo:
vars:
PREFIX: prefix_
MAP:
map:
a: '{{.PREFIX}}1'
b: '{{.PREFIX}}2'
c: '{{.PREFIX}}3'
cmds:
- echo {{index .MAP "a"}} This will print |
@simonrouse9461 See #1526 and #1544. Your example works in the latest release. Also worth noting that |
@pd93 Thanks! Upgrading to the latest release solved the problem. |
Suggestion: version: 3
tasks:
foo:
requires:
vars: [VAR_NAME]
vars:
VAR_MAP:
map:
FOO: [1, 2, 3]
BAR: [4, 5, 6]
cmds:
- task: bar
vars:
VAR:
ref: index .VAR_MAP .VAR_NAME
bar:
cmds:
- echo {{index .VAR 0}} Then,
This will make things more flexible and programmable. |
@simonrouse9461 I was initially going to reply saying that this is quite difficult as the |
This experiment has been marked as a draft! ✨ This means that an initial implementation has been added to the latest release of Task! You can find information about this experiment and how to enable it in our experiments documentation. Please see the experiment workflow documentation for more information on how we release experiments. |
Suggestion: Like proposal 1 but use YAML custom tags in order to define version: 3
tasks:
foo:
vars:
FOO: {a: 1, b: 2, c: 3} # <-- Directly defined map on the `FOO` key
BAR: !sh 'echo Hello Task' # <-- Use a custom tag for a sh
BAZ: !ref '.BAR' # <-- Use a custom tag for a ref
MAP_WITH_TAGS: {a: 1, b: !ref '.BAR', c: !sh 'echo 2'} # <-- Use sh or ref in defined map
cmds:
- 'echo {{.FOO.a}}' As an alternative to maintain backwards-compatibility also use YAML custom tags to define data types like version: 3
tasks:
foo:
vars:
FOO: !map {a: 1, b: 2, c: 3} # <-- Use a custom tag for map data type
BAR: !sh 'echo Hello Task' # <-- Use a custom tag for a sh
BAZ: !ref '.BAR' # <-- Use a custom tag for a ref
cmds:
- 'echo {{.FOO.a}}' See also:
For example Symfony YAML uses custom tags to add native PHP types like |
@steffans, @simonrouse9461, I took a look at this today. It's an interesting proposal. It definitely has some clear advantages over the other 2 proposals. However after some (very limited) research, I can see some drawbacks too:
|
I've been taking a poke at this very briefly but it made me wonder if there would be interest in something that would support using the output of a For instance: ---
version: 3
tasks:
foo:
vars:
BAZ:
sh: 'echo "{a: 1, b: 2, c: 3}"'
FOO:
map: '{{.BAZ}}'
cmds:
- 'echo {{.FOO.a}}' Or, a more streamlined: ---
version: 3
tasks:
foo:
vars:
FOO:
map:
sh: 'echo "{a: 1, b: 2, c: 3}"'
cmds:
- 'echo {{.FOO.a}}' |
I have another suggestion: version: 3
vars:
PACKAGE_VERSION_TAG: 'v{{sh "pwsh -C"}}(gc ./package.json | ConvertFrom-Json -AsHashtable).version{{end}}'
tasks:
git:tag:package-version:
desc: 'Create a git tag based on the version defined in package.json. The version value is prepended with "v"'
cmd: git tag '{{.PACKAGE_VERSION_TAG}}' Advantages:
Adressing @JonZeolla's post: also post-processing of the shell output seems quite simple using the pipe syntax.: tasks:
foo:
vars:
FOO: '{{sh | fromJson}}echo "{a: 1, b: 2, c: 3}"{{end}}'
cmds:
- 'echo {{.FOO.a}}' @pd93 Is there a chance to have a Proposal 3 for this? |
@JonZeolla What you propose in your comment is actually already possible today by using version: 3
tasks:
foo:
vars:
FOO: '{"a": 1, "b": 2, "c": 3}'
BAR:
ref: 'fromJson .FOO'
cmds:
- 'echo {{.BAR.a}}' I don't think we need a new keyword to deal with this. @quirin-buechner-mdctec the same thing applies to your comment but it is worth noting that it is impossible to output anything other than a string from a template. If your var contains Most of the time, users will want to define maps statically, not dynamically. As such, any new proposal for defining maps would need to allow a user to define a static map object in YAML or its not worth having IMO. Converting strings to a map dynamically is already possible as shown above. |
Warning
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.
Context
This experiment attempts to solve the problems originally described by #140. It is a follow-up to the "Any Variables" experiment (#1415) which was merged without support for maps.
Currently, all variable types are allowed except for maps. This is because there is some debate around the syntax that should be used to define them. The proposals for these syntaxes are described below.
Proposal 1
Warning
This experiment proposal breaks the following functionality:
sh
keyword)Note
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
keyword in favour of a new syntax fordynamically defined variables, This allows you to define a map directly as you
would for any other type:
Migration
Taskfiles with dynamically defined variables via the
sh
subkey will no longerwork with this experiment enabled. In order to keep using dynamically defined
variables, you will need to migrate your Taskfile to use the new syntax.
Previously, you might have defined a dynamic variable like this:
With this experiment enabled, you will need to remove the
sh
subkey and defineyour command as a string that begins with a
$
. This will instruct Task tointerpret the string as a command instead of a literal value and the variable
will be populated with the output of the command. For example:
If your current Taskfile contains a string variable that begins with a
$
, youwill now need to escape the
$
with a backslash (\
) to stop Task fromexecuting it as a command.
Proposal 2
Note
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 newmap
subkey for defining map variables:Parsing JSON and YAML
In addition to the new
map
keyword, this proposal also adds support for thejson
andyaml
keywords for parsing JSON and YAML strings into real objects/arrays. This is similar to thefromJSON
template function, but means 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.
Before:
After:
Variables by reference
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 string.
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:Before:
After:
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 a variable and can be used in any combination:All references use the same templating syntax as regular templates, so in
addition to simply calling
.FOO
, you can also pass subkeys (.FOO.BAR
) orindexes (
index .FOO 0
) and use functions (len .FOO
):Looping over maps (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.Proposal 1
Proposal 2
Note
Remember that maps are unordered, so the order in which the items are looped over is random.
The text was updated successfully, but these errors were encountered: