-
-
Notifications
You must be signed in to change notification settings - Fork 731
Description
One of the things I see a lot, is confusion about the differences between variables and environment variables. They essentially serve the same purpose (holding data), but they have a few differences:
- Both can be parsed into Task via the CLI as strings (though they have different syntaxes)
TASK_VAR=foo task ...
(environment variable)task ... VAR=foo
(variable)
- Both can be defined in the Taskfile (using different keywords) at a global or task level.
vars
can also be set when calling another task, butenv
cannot.
vars
can be of any type.env
only supports strings (though sort of works with other scalar values).vars
are output using templating syntax and anenv
is output using shell variable syntax.$FOO
(environment variable){{.FOO}}
(variable)
- They have slightly different inheritance/scoping rules.
- At this point, I'm not even sure what the differences are without investigating properly.
- Environment variables defined on the CLI/shell are available as variables, but ones defined using the
env
keyword are not.
I'm not convinced that any of these distinctions are necessary and I feel like they add an additional layer of confusion for both new users and people wanting to contribute to the project.
Therefore, I propose removing the env
key entirely. vars
would then inherit from the system environment and be overridable in Task. If a variable is not a string, it would be output using the stringer version of its value (%v
). All of the features below would then apply to vars
:
- Variables are only passed into Task via the shell environment (whether that be in an .rc file of a shell command).
- No more
task ... VAR=foo
syntax.
- No more
- Variables can be defined at a global or task level and passed when calling dependant tasks.
- Variables can be of any type, though they are still limited to strings when passed via the environment variables.
- Variables are output using templating syntax OR shell variable syntax depending on the user's needs.
- Variables have a consistent inheritance/scoping model as defined in Proposal: Variable scope and inheritance #2035.
Before:
version: '3'
env:
FOO: 'foo'
vars:
BAR: 'bar'
tasks:
default:
cmds:
- echo '$FOO'
- echo '{{.FOO}}'
- echo '$BAR'
- echo '{{.BAR}}'
foo
bar
After:
version: '3'
vars:
FOO: 'foo'
BAR: 'bar'
tasks:
default:
cmds:
- echo '$FOO'
- echo '{{.FOO}}'
- echo '$BAR'
- echo '{{.BAR}}'
foo
foo
bar
bar
One caveat to this proposal is that sometimes temporary variables are needed to perform operations and we don't always want to pollute the environment with these variables. To solve this, we can allow variables to be marked as internal, just like we would with tasks. This makes variables consistent with tasks and fulfills the same purpose that variables previously did.
Since most Task commands execute in a fairly specific context, this shouldn't be needed the majority of the time.
version: '3'
vars:
FOO: 'foo'
BAR:
value: 'bar'
internal: true
BAZ:
sh: 'echo "baz"'
internal: true
QUX:
ref: 'lower .BAZ'
internal: true
tasks:
default:
cmds:
- 'echo "foo: {{.FOO}}"'
- 'echo "bar: {{.BAR}}"'
- 'echo "baz: {{.BAZ}}"'
- 'echo "qux: {{.QUX}}"'
foo: foo
bar:
baz:
qux: