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

Unable to override vars at task level #888

Closed
ssbarnea opened this issue Oct 9, 2022 · 6 comments
Closed

Unable to override vars at task level #888

ssbarnea opened this issue Oct 9, 2022 · 6 comments
Labels
area: variables Changes related to variables. type: question Further information is requested.

Comments

@ssbarnea
Copy link
Contributor

ssbarnea commented Oct 9, 2022

  • Task version: 3.16
  • Operating System: macos

Example Taskfile showing the issue

# this task will print apples instead of expected oranges
version: 3
vars:
  FOO: apples
tasks:
  subtask:
    cmds:
      - echo {{.FOO}}
  default:
    vars: # this vars do not override the global ones
      FOO: orages
    cmds:
      - task: subtask
        # vars: here would work as expected

Despite that the documentation suggests that there are 3 ways to override the vars, apparently none work for task leve, and we cannot even see one example of variable overriding inside the main test file from https://github.com/go-task/task/blob/master/testdata/vars/v3/Taskfile.yml -- all the vars are uniquely defined inside the file, which means that the overriding order is not tested by it.

We have at least these levels of vars:

  • global (defined in root)
  • task level (specific on a single tag)
  • command level (specific to a single command)
  • passed level, the level that applies when you call a task with arguments, probably should take precedence.

My expectation is that passed > command > task > global, but apparently I was not able to make the command level to work.

Temporary I could probably make use of YAML anchors in order to force taskfile to "inherit" the vars from the task level, still this should not be needed.

@pd93
Copy link
Member

pd93 commented Oct 10, 2022

@ssbarnea when you're calling the default task, the variable you set in default is not being sent into subtask. So when subtask is run it only has the global FOO available to it. If you want to override the global variable, you need to pass the variable into subtask when you call it. See the example below:

version: "3"

vars:
  FOO: global-foo

tasks:
  default:
    vars:
      FOO: default-foo
    cmds:
      - task: subtask
        vars:
          FOO: "{{.FOO}}"

  subtask:
    vars:
      FOO: '{{.FOO | default "subtask-foo"}}'
    cmds:
      - echo {{.FOO}}

In this example subtask will check if FOO is set (either globally, or via an argument) and if not, it will set a default value using the | default syntax. The default task is setting FOO and then sending it to subtask via vars.

@pd93 pd93 added type: question Further information is requested. state: awaiting response Waiting for issue author to respond. labels Oct 10, 2022
@prologic
Copy link

prologic commented Jan 3, 2023

I came here looking for an answer to a similar puzzle I have. I have this Taskfile.yml:

version: '3'

tasks:
  hello:
    desc: Print "Hello World!"
    cmds:
      - echo "Hello {{ .NAME }}!"
    vars:
      NAME: World

I expect to be able to override the variable NAMElike this:

$ task hello NAME=James
task: [hello] echo "Hello World!"
Hello World!

But sadly this does not seem to work 😢

@andreynering
Copy link
Member

Hi @prologic,

You have to use default as explained above by Pete. It makes variables overridable.

As the original question by @ssbarnea was also answered above, I'm closing this. If you happen to still have questions, let us know.

@prologic
Copy link

prologic commented Jan 5, 2023

@andreynering I think we're missing a subtle point here. It seems only possible to override variables declared globally and not at a task level. This is counter intuitive to me 😢 The following example Taskfile.yml works with the following usage(s):

version: '3'

vars:
  NAME: "World"

tasks:
  hello:
    desc: Print "Hello World!"
    cmds:
      - echo "Hello {{ .NAME }} !"
    vars:
      NAME: '{{ .NAME | default "World" }}'
$ task hello
task: [hello] echo "Hello World !"
Hello World !
$ task hello NAME=James
task: [hello] echo "Hello James !"
Hello James !

But the following does not:

version: '3'

tasks:
  hello:
    desc: Print "Hello World!"
    cmds:
      - echo "Hello {{ .NAME }} !"
    vars:
      NAME: 'World'

Yes you can do what has been suggested as (IMO) work-arounds here, but IMO the title of the issue still remains. It is not possible to override a task-level variable (only a global).

@andreynering andreynering added the area: variables Changes related to variables. label Jan 5, 2023
@andreynering
Copy link
Member

@prologic I understand what you mean, but changing that behavior now would cause side-effects and can be considered a breaking/backwards-incompatible change.

In another words, it was intentionally implemented this way so the task has the control of its variables, and there are Taskfiles out there depending on this behavior. Discussions for any changes in the would be for the (far in the future) next major release.

@prologic
Copy link

prologic commented Jan 5, 2023

Okay fair enough 👌 Can we please document this though in the Documentation section on Usage -> Variables? 🤔 I spent several hours on this myself trying to understand why this wasn't working for me (something I"m used to being able to do from make)

@pd93 pd93 removed the state: awaiting response Waiting for issue author to respond. label Jan 5, 2023
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. type: question Further information is requested.
Projects
None yet
Development

No branches or pull requests

4 participants