Skip to content

Global variables with the same name in multiple Taskfile.yml files break scoping #2680

@sbowman

Description

@sbowman

Description

I don't think this is intentional, but if you have a Taskfile.yml that includes another Taskfile.yml, and both files share a global variable, the included Taskfile.yml's variable will overwrite the one in the root file.

For example, if I have a Taskfile.yml in the root of my project:

version: '3'

vars:
  TARGETS: sample
  DIST_DIR: './dist'

includes:
  sample: ./sample/Taskfile.yml

tasks:
  build:
    desc: Build everything!
    cmds:
      - for: { var: TARGETS }
        task: build-target
        vars:
          TARGET: '{{.ITEM}}'

  build-target:
    cmds:
      - echo "Root is {{.DIST_DIR}}"
      - task: '{{.TARGET}}:build'

And a subdirectory, sample, with a Taskfile.yml that looks like this:

version: '3'

vars:
  DIST_DIR: './another_dir'

tasks:
  build:
    desc: Build the sample
    cmds:
      - echo 'Building to {{.DIST_DIR}}'
      - echo 'Should have been ./dist'

When I run task build at the root of the project, the build outputs:

Root is ./another_dir
...
Building to ./another_dir

Side note: it doesn't matter in the root Taskfile.yml what order "vars" or "includes" appears in; the included file's global variable will always overwrite the variable in the parent.

Is this intentional? What's the logic behind having a child Taskfile.yml like sample/Taskfile.yml overwrite the variable in the root Taskfile.yml?

I would have expected the reverse to be true. Why is an included file overwriting the variables at the root? And what happens when you have multiple included files with the same values? This means I not only have to be very careful in my child build files, but if I create shared libraries of tasks, such as for creating docker images, those task libraries could override the variables in the Taskfile that called them?

I can override what's in the child by passing in "vars" when I call the child task:

  build-target:
    cmds:
      - echo "Root is {{.DIST_DIR}}"
      - task: '{{.TARGET}}:build'
        vars:
          DIST_DIR: 'this value will overwrite what's defined in the sample/Taskfile.yml'

But it still overwrites the DIST_DIR defined in the root Taskfile.yml.

Version

3.48.0

Operating system

macOS

Experiments Enabled

No response

Example Taskfile

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions