-
-
Notifications
You must be signed in to change notification settings - Fork 639
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
Any variables experiment #1415
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. |
Thanks for opening this issue! Some small comments:
|
Ok, that makes sense. I'll remove this section for now. We can revisit down the line if necessary. This reduces the amount of breaking changes.
I don't think I knew about Task in the days before There is always the option of not supporting maps initially. This would actually mean that we could release this without a major version bump as I don't think there would be any remaining backward-incompatible changes. |
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. |
Hi ! If you are interessed in, I can post a use case of it |
Thanks for the great work on Taskfile. I'm having issues suporting proposal 2 (not tested porposal 1 yet. Here's my Taskfile, containing one of the examples given… version: '3'
tasks:
foo:
desc: test
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
cmds:
- 'echo {{.FOO.a}}' When I attempt to call
Task version: v3.33.1 (h1:JJSRANHH7RQrr5Z2CTvSnTH7iWlfBlKV2W2O0JiZoLk=) And here's my TASK_X_ANY_VARIABLES=2
What am I doing wrong? |
Hi @toby-griffiths. Firstly, thanks for trying this out. Definitely looking for some feedback on these experiments. Secondly, apologies for any confusion. v3.33.1 does not contain support for the 2nd proposal and this change has not been included in any release yet. Unfortunately, we still haven't versioned our docs, so they are more up to date than Task itself (This is something we need to resolve). If you are using Go to install Task, then you can run
Just be aware that unreleased versions (particularly experiments) might be a bit buggy. Not a problem if you're just trying stuff out though. |
Ah, thanks @pd93 I'll try installing via go (I had used Homebrew). In case it's useful info, I've also just tried the following proposal 1 example… version: '3'
tasks:
foo:
vars:
ARRAY: [ 1, 2, 3 ]
cmds:
- 'echo {{range .ARRAY}}{{.}}{{end}}' … to receive the error…
So not sure if this is related or a separate issue? |
@toby-griffiths Your example works for me on v3.33.1.
The error you're getting is symptomatic of the experiment not being enabled, so I suspect that we're not reading your Are you by any chance using the |
@pd93 So I checked and it reported that the experiment was there an enabled, yet I got that error. I've since installed the Go version and it's working fine with both proposales. I also found that I wasn't using I'm using |
Ah, I just realised, this is probably related to #1463 which would explain why it's fixed when you tried
This shouldn't make a difference. They are equivalent.
Please let us know how you find them! |
Is it wanted behaviour, that nested keys in objects aren't templated? And how can I set a nested variable from the outside, e.g. via environment variables or some kind of flag? |
Hi @cwrau, could you please provide an example Taskfile with what you're seeing and what you expected to see. This will help me better understand what the problem you're having is.
This is outside of the scope of this experiment. Currently only string types are supported from environment variables. However, I'd be open to proposals on how this could work in a future improvement! |
vars:
image:
tag: '{{ .IMAGE_TAG | default "latest" }}' When used later, it just contains the string |
@cwrau @toby-griffiths If you have some time, please try out the changes #1526. They should address your comments/issues. If you have Go installed, you can try the version in the PR by running:
Also, if you have any other general feedback on the experiments, I'd be very keen to hear it. Particularly with regard to the two different proposals and how they handle map variables. Thanks |
Mh, doesn't appear to be working? version: '3'
vars:
cheese:
cake: chocolate
cheesecake: chocolate
tasks:
not-working:
cmd: echo {{ printf "%s" .cheese.cake }}
working:
cmd: echo {{ printf "%s" .cheesecake }} $ TASK_X_ANY_VARIABLES=1 task not-working
task: [not-working] echo %!s(*string=0xc00021ac40)
$ TASK_X_ANY_VARIABLES=1 task working
task: [working] echo chocolate
I'm definitely in favor of variant 1, it just seems more natural to define variables that way and dynamic variables are a special case, so prepending |
@cwrau Thanks for testing. I made a small mistake in my implementation. It worked when using a variable directly (e.g. Can you please try again with: |
That's now working, but the following isn't; version: '3'
vars:
cheese:
cake: chocolate
type: '{{ .cheese.cake }}'
cheesecake: chocolate
cheese_type: '{{ .cheesecake }}'
tasks:
not-working:
cmd: echo {{ printf "%s" .cheese.type }}
working:
cmd: echo {{ printf "%s" .cheese_type }} $ TASK_X_ANY_VARIABLES=1 task working
task: [working] echo chocolate
chocolate
$ TASK_X_ANY_VARIABLES=1 task not-working
task: [not-working] echo
|
@cwrau Thanks again. I've merged the changes in #1526 as I think the functionality added there is useful by itself. It's a bit more complicated to do what you've described in #1415 (comment), so I've opened #1544 to track this separately. Let's move any further discussion about this functionality to that issue. |
I think I found another bug?; version: '3'
vars:
tools:
controller-gen:
url: sigs.k8s.io/controller-tools/cmd/controller-gen
version: 0.14.0
tasks:
test:
vars:
tool: '{{ index .tools "controller-gen" }}'
type: '{{ typeOf (index .tools "controller-gen") }}'
cmds:
- echo "'{{ .type }}' should be map[string]interface {}"
- echo "'{{ typeOf .tool }}' should also be map[string]interface {}" $ TASK_X_ANY_VARIABLES=1 task test
task: [test] echo "'map[string]interface {}' should be map[string]interface {}"
'map[string]interface {}' should be map[string]interface {}
task: [test] echo "'string' should also be map[string]interface {}"
'string' should also be map[string]interface {} This prevents us from pulling in the tool and then using it, instead we need to |
@cwrau This is expected behaviour. The output type of a Go template will always be a Edit: I'm still not convinced by the |
to be more specific, I'm trying to accomplish the following; version: '3'
vars:
tools:
controller-gen:
url: sigs.k8s.io/controller-tools/cmd/controller-gen
version: 0.14.0
tasks:
test:
vars:
tool: '{{ index .tools "controller-gen" }}'
cmds:
- echo "'{{ .tool.url }}' should be 'sigs.k8s.io/controller-tools/cmd/controller-gen'" but this results in; $ task test
template: :1:3: executing "" at <index .tools "controller-gen">: error calling index: index of untyped nil Is there currently a way? |
@cwrau A couple of things here. Firstly, it looks like the error you got was because the experiment wasn't enabled. If I use
This error occurs because the field When you do: vars:
tool: '{{ .tools.controller_gen }}' This is not creating a variable of type With tasks:
test:
cmds:
- echo '{{ .tools.controller_gen.url }}' or redefine the bottom-level string values you want: tasks:
test:
vars:
url: '{{ .tools.controller_gen.url }}'
version: '{{ .tools.controller_gen.version }}'
cmds:
- echo "'{{ .url }}' should be 'sigs.k8s.io/controller-tools/cmd/controller-gen'"
- echo "'{{ .vesrion }}' should be '0.14.0'" However, with version: '3'
vars:
tools:
map:
controller-gen:
url: sigs.k8s.io/controller-tools/cmd/controller-gen
version: 0.14.0
tasks:
test:
vars:
tool:
ref: tools.controller-gen
cmds:
- echo "'{{ .tool.url }}' should be 'sigs.k8s.io/controller-tools/cmd/controller-gen'" Though, as I paste this example, I've realised that it's not currently working 😆 I will look into this. I imagine the syntax for passing by reference with proposal 1 could look something like this: version: '3'
vars:
tools:
controller-gen:
url: sigs.k8s.io/controller-tools/cmd/controller-gen
version: 0.14.0
tasks:
test:
vars:
tool: !tools.controller-gen
cmds:
- echo "'{{ .tool.url }}' should be 'sigs.k8s.io/controller-tools/cmd/controller-gen'" ... but this does not exist yet ... |
I guess you're right, sorry 😅
Ah, I see, I got a bit confused there
Ou, both examples look interesting, would be amazing to see them. But for now we'll just use a single, joined field for the full url, that's probably gonna work better with renovate anyways 😅 |
We have made the decision in #1547 to merge support for Any Variables in its current state, but without support for maps. Don't worry, map support is still coming! This functionality will now be tracked in #1585 instead. We have done this because we feel that it may still take some time to add support for maps. We still have many decisions to make regarding the syntax, and depending on these decisions, the required changes may be breaking (which will further delay the feature). Seeing as support for other variable types ( |
This experiment has been marked as a candidate! 🔥 This means that the implementation is nearing completion and we are entering a period for final comments and feedback! 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. |
This experiment has been released! 🚀 This means that it is no longer an experiment and is available in the latest major version of Task. Please see the experiment workflow documentation for more information on how we release experiments. |
Note
This experiment has been released and is now generally available since Task v3.37.0. This issue is kept for historical purposes only. For up-to-date information, you can read our blog post or check the variables documentation.
Context
This experiment attempts to solve the problems originally described by #140.
Currently, all Task variables are strings. You can define a variable as a YAML
string
,bool
,int
,float
ornull
value. However, when task interprets it, it will be decoded as a string regardless of the input type.For example, the following Taskfile will always output "foo" even when
BOOL
isfalse
because the variable is being interpreted as a string and anif
statement evaluates totrue
when the string is not empty:Lists are also interpreted as strings and this has led to some annoying workarounds in the codebase. For example, the
for
feature is great for running a task multiple times with different variables. However, if you want to loop over an arbitrary list of strings, you have to define the list as a delimiter separated string and then split it by specifying the delimiter in thefor
statement. For example:This could be simplified if we supported variables as lists:
Proposal
We propose to change the type of internal Task variables to
any
(otherwise known as an emptyinterface{}
in Go). This will allow users to define variables as any type they want, and Task will interpret them properly when used in tasks. The following types should be supported:string
bool
int
float
array
map
Adding support for these types is relatively simple by itself. However, there a few changes that will be needed to make the rest of Task's features work nicely with the new variable types:
for
should support iterating over arrays (and maybe maps?) feat: support looping over map variables #1436sh
needs to be removed and replaced with a new syntax for dynamically defined variables (see backwards compatibility)Backwards Compatibility
The current implementation of Task variables allows for dynamic variables to be specified by using the
sh
subkey. For example:Running
task foo
will output the following:Since we are adding support for map variables, this syntax will conflict and can no longer be supported. Instead, we should detect string variables that begin with a
$
and interpret them as a command to run. For example:If a user wants a string variable that starts with
$
, they can escape it with a backslash:\$
.Removing the
sh
subkey will break any Taskfiles that currently use it and it is possible that the new syntax will also break existing taskfiles that have variables that start with$
. For this reason, the functionality in this proposal will stay as an experiment until at least the next major version of Task.The text was updated successfully, but these errors were encountered: