Skip to content

Proposal: Variable scope and inheritance #2035

@pd93

Description

@pd93

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:

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: variablesChanges related to variables.breaking changeChanges that are not backward compatible.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions