task
task copied to clipboard
Explicit vars?
Firstly — another thanks for this library! It's much more accessible than make, and others are starting to use it at my company.
Something that can be confusing for users is understanding what variables need to be supplied for a task, without reading the whole task. As a result, I have a convention of listing them explicitly for each task or file, like:
switch-env:
vars:
project: "{{.project}}"
cluser: "{{.cluster}}"
This works well at the task level, but not the file level. So one question and one feature question:
- It doesn't seem to work at the file level; i.e. this will pass an empty string for
{{project}}when another taskfile sets the var. Removing this definition allows it work. Could I ask why that is?
vars:
project: "{{.project}}"
- Is there more general demand for explicitly listing variables by task & file? I would be interested in a
strictsetting that warned if variables were used implicitly, since it makes them difficult to track.
Thanks again
I get away with:
build:
vars:
IMAGE_NAME: >-
{{.IMAGE_NAME | default nil)}}
IMAGE_TAG: >-
{{.IMAGE_TAG | default nil}}
preconditions:
- sh: "[ {{.IMAGE_NAME}} ]"
msg: "IMAGE_NAME not set"
edit: its early
edit2: I totally lied about fail apparently. It will be evaluated before being passed to default in templates.
having {{.VAR}} at the file level will use the current value of .VAR in the context - null.
Your subsequent task declarations will inherit that. default and fail are slim-sprig functions to handle a null.
So, after looking at it again, you don't have short-circuit evaluations in templates - fail has to be a part of a block.
You could use:
{{.VAR | default nil}}
and later
preconditions:
- sh: "[ {{.IMAGE_NAME}} ]"
msg: "reason"
There's also probably a template that you could define that gets more into a feature suggestion:
{{define "required"}}
{{with (index . 0)}}
{{.}}
{{else}}
{{(fail (index . 1))}}
{{end}}
{{end}}
{{template "required" (list .VAR "VAR is required")}}
edit: we can use precondition...
Thanks @d3dc . That's indeed the sort of feature that I would make this more concise.
Hi @max-sixty ,
I think that having a task attribute to validate that given vars are required probably makes sense 👍.
I think this would be very handy. Being able to essentially have args for a task feels like a common need, and having optional (with or without defaults) and mandatory ones makes sense. What's the latest on that? What's the format you're proposing @andreynering?
In my experience, it can be quite dangerous to rely on something being available in the environment.
Let's imagine this command:
rm -rf {{.PROJECT_ROOT}}/opt
You can probably guess what happens if PROJECT_ROOT isn't set anywhere.
In such a case, it'd be cool to have a strict mode which ensures that variables are actually set somewhere. I remember this from Jinja which has this: https://jinja2docs.readthedocs.io/en/stable/api.html#jinja2.StrictUndefined
UPDATE Shells have it too with set -u or set -o nounset: https://manpages.org/set
related to https://github.com/go-task/task/issues/1063
Also from this below suggestion, I didn't find where we could define templates from Taskfile:
There's also probably a template that you could define that gets more into a feature suggestion:
{{define "required"}} {{with (index . 0)}} {{.}} {{else}} {{(fail (index . 1))}} {{end}} {{end}}{{template "required" (list .VAR "VAR is required")}}
Closing as duplicate of #1203 and #1204.