Skip to content
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

Proposal: Variable scope and inheritance #2035

Open
pd93 opened this issue Feb 3, 2025 · 3 comments
Open

Proposal: Variable scope and inheritance #2035

pd93 opened this issue Feb 3, 2025 · 3 comments
Labels
area: variables Changes related to variables. breaking change Changes that are not backward compatible.

Comments

@pd93
Copy link
Member

pd93 commented Feb 3, 2025

Variable/environment variable precedence is an area that has caused a lot of confusion. The ENV_PRECEDENCE experiment has mitigated some of this, but does not solve all of the issues.

One of the main causes of our problems is the merging that is done when parsing Taskfiles. In this process, we lose all information about the priority of variables and where they were set. This leads to a situation where variables are not scoped correctly and leak from a child Taskfile into a parent.

We also have small differences between how variables and environment variables inherit values. This proposal is intended to be paired with #2036 which merges the two types of variable together. The rest of this issue will assume that there is only one type of variable in Task.

I propose that variables should be set with the following precedence, starting with the lowest priority and finishing with the highest. Each item in the list inherits from the previous items and overrides any existing variables.

  1. Environment Scope
    1. Set in the host shell
    2. Set in the command line when calling task
  2. Entrypoint Scope
    1. Global dotenv files in the entrypoint Taskfile
    2. Global vars in the entrypoint Taskfile
  3. Include Scope(s) (in the order in which they are included)
    1. Variables specified in the include statement
    2. Global dotenv files in each included taskfile (not currently supported)
    3. Global vars in each included taskfile
  4. Task Scope
    1. Variables passed into a task via another task
    2. Task-level dotenv files
    3. Task-level vars

Note the term "scope". Scopes are used to sandbox variables so that they don't leak into other tasks. Variables in a higher priority scope cannot be accessed from a scope of lower priority or a sibling scope. For example, a variable set in one task, cannot be accessed in another task because that would be a sibling scope. Likewise, it cannot be accessed in a parent Taskfile since this is a lower priority scope.

This kind of precedence and scoping can be achieved by utilizing the new Taskfile DAG and removing merging entirely. This allows us to traverse the graph when searching for a Task and resolve variables as we go. This also has the distinct advantage that we only need to resolve variables that are relevant to the task(s) being called, rather than resolving all variables in all Taskfiles.

Related issues:

@pd93 pd93 added area: variables Changes related to variables. breaking change Changes that are not backward compatible. labels Feb 3, 2025
@trulede
Copy link

trulede commented Feb 4, 2025

How is that different to the existing? Aside from the implied combination of the last two items (in the list below).

Variables can be set in many places in a Taskfile. When executing templates, Task will look for variables in the order listed below (most important first):

  • Variables declared in the task definition
  • Variables given while calling a task from another (See Calling another task above)
  • Variables of the included Taskfile (when the task is included)
  • Variables of the inclusion of the Taskfile (when the task is included)
  • Global variables (those declared in the vars: option in the Taskfile)
  • Environment variables

@pd93
Copy link
Member Author

pd93 commented Feb 4, 2025

The main point of this proposal and #2036 is to unify, simplify and iron out any unexpected behavior with variables and environment variables. If we assume that #2036 is accepted, then we need to decide how unified variables will behave as environment variables do not always behave the same way as the current variables.

You are right that the existing variables largely follow the inheritance model described here. However, they are not scoped at all and the piece of work to enable this is significant (stopping the merging of Taskfiles). This proposal tracks that work.

@vmaerten
Copy link
Member

vmaerten commented Feb 8, 2025

I think this is a good proposal and the right way to go. Scoping variables has been missing, and its absence often leads to confusion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: variables Changes related to variables. breaking change Changes that are not backward compatible.
Projects
None yet
Development

No branches or pull requests

3 participants