task icon indicating copy to clipboard operation
task copied to clipboard

Explicit environment variable is not honoured when calling another task

Open chris-garrett opened this issue 4 years ago • 7 comments

  • Task version: 3.3.0
  • Operating System: Windows 10 (git bash)

Taskfile

version: '3'

vars:
  VAR_GLOBAL: IM_VAR_GLOBAL

env:
  ENV_GLOBAL: IM_ENV_GLOBAL

tasks:

  env_caller:
    cmds: 
      - { task: env_subtask, env: { ENV_CALLER_ARG: IM_ENV_CALLER_ARG }, vars: { VAR_CALLER_ARG: IM_VAR_CALLER_ARG }}
    env: { ENV_CALLER: IM_ENV_CALLER }
    vars: { VAR_CALLER: IM_VAR_CALLER }

  env_subtask:
    cmds:
      - echo ENV_GLOBAL=$ENV_GLOBAL
      - echo ENV_CALLER=$ENV_CALLER 
      - echo ENV_CALLER_ARG=$ENV_CALLER_ARG 
      - echo VAR_GLOBAL={{.VAR_GLOBAL}}
      - echo VAR_CALLER={{.VAR_CALLER}}
      - echo VAR_CALLER_ARG={{.VAR_CALLER_ARG}}

Output

$ ./task env_caller
ENV_GLOBAL=IM_ENV_GLOBAL
ENV_CALLER=
ENV_CALLER_ARG=
VAR_GLOBAL=IM_VAR_GLOBAL
VAR_CALLER=
VAR_CALLER_ARG=IM_VAR_CALLER_ARG

I expect that ENV_CALLER_ARG should be valid in env_subtask. Am I missing something?

chris-garrett avatar Oct 28 '21 18:10 chris-garrett

I hit a similar situation. Although I specify CC and CXX, it still uses the global environment variable.

# https://taskfile.dev
version: "3"

tasks:
  init_debug_mingw:
    env:
      CC: gcc
      CXX: g++
    cmds:
      - echo {{.CC}}

clang is printed instead of GCC

This is also related to #185

aminya avatar Nov 14 '21 09:11 aminya

There are couple of different issues here. @chris-garrett your env_caller env and vars values are only applicable for shell commands called within that command block. If you call another task with -task: env_subtask you can only pass vars to it. env block is ignored.

cmds:
- task:env_subtask
  vars: 
     VAR_CALLER_ARG: IM_VAR_CALLER_ARG

@aminya you're mixing up vars and env syntax. Both commands work here:

# https://taskfile.dev
version: "3"

tasks:
  one:
    vars:
      CC: gcc
    cmds:
      - echo {{.CC}}

  two:
    env:
      CC: gcc
    cmds:
      - echo $CC

kerma avatar Dec 04 '21 17:12 kerma

@kerma welcome to the collabs list!

There are couple of different issues here. @chris-garrett your env_caller env and vars values are only applicable for shell commands called within that command block. If you call another task with -task: env_subtask you can only pass vars to it. env block is ignored.

Can you explain why this is? Is this actually the behaviour that is desired?

Without this we are forced to convert ENVs to VARs and carry them around until you convert back to ENV when you need it. It's very clumsy on large projects.

chris-garrett avatar Dec 05 '21 20:12 chris-garrett

@chris-garrett I'm new to the project, so cannot tell the historical reasons, but atm it's how it's implemented.

There is another issue slightly related to this: #585.

To me it feels like task is missing a well documented context which is creating the confusion. To be honest I think it may be something I'd look into. Having a simple context and inheritance rules for dir, env and vars would probably make life easier for everyone. However it would be a major change and would need a new taskfile version.

kerma avatar Dec 06 '21 16:12 kerma

@kerma and @chris-garrett I "discovered" the same behaviour as well, and the behaviour is documented:

After much pain, testing and searching, I did finally realize that a shell command was being handled different than a task command from the task API reference:

env map[string]Variable A set of environment variables that will be made available to shell commands.

This was surprising since the schema suggests that it applies to all uses of env within the current task declaration. Whether this is intended, a bug or a feature request, I think there is a very strong case for it to work, and if not, then env should be removed from the target declaration and only be supported by individual cmd declarations.

I think making it work for both task invocation and shell invocation encourages reusability of tasks and 12 factor apps.

version: 3

tasks:
  start:
    vars:  # Passing in config by using vars is recommended
      NAME: '{{ .NAME | default "my-service" }}'
    env:
      PGDATABASE: '{{.NAME}}-db'
    cmds:
      - echo "Works here as promised: $PGDATABASE"
      - task: start-db # PGDATABASE is not passed in even though it is at the task level.
  start-db:
    cmds:
     - psql # Invoked by `start` or directly from command line with env configured (12 factor)

@andreynering I think this issue was opened before the labelling system was developed, can you consider applying the appropriate labels since I don't have permission?

dustinlharrison avatar Jul 19 '23 16:07 dustinlharrison