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
strict
setting 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.