Search code examples
taskfile

Use environment variables in the "generates" section of a Taskfile


I have the following simple Taskfile.yml:

version: "3"
env:
  OUTPUT_FILENAME: output.txt

tasks:
  my_task:
    cmds:
      - rm -f $OUTPUT_FILENAME
      - cp input.txt $OUTPUT_FILENAME
      - echo "That was it" >> $OUTPUT_FILENAME
    sources:
      - input.txt
    generates:
      - output.txt
      # - $OUTPUT_FILENAME

This works as expected. However, if I swap the comments in the generates section of the task, then the task is always triggered even if the output is already generated and up-to-date.

How can I use the environment variable in the generates (and similarly in the sources ) section?


Solution

  • The problem you're having is because environment variables are only available inside shell environments (i.e. the commands in your task). If you want to use variables in other parts of your task, you need to use the templating engine:

    version: "3"
    
    env:
      OUTPUT_FILENAME: output.txt
    
    tasks:
      default:
        cmds:
          - rm -f $OUTPUT_FILENAME
          - cp input.txt $OUTPUT_FILENAME
          - echo "That was it" >> $OUTPUT_FILENAME
        sources:
          - input.txt
        generates:
          - "{{.OUTPUT_FILENAME}}" # <-- here we use templating syntax to output the variable
    

    Sidenote:

    The above solution works because all env variables are currently made available to the templating engine as well as vars. This behaviour has previously caused confusion and I'd like to see it removed in a future major version. If this were the case, you would need to set up your variables like so:

    version: "3"
    
    vars:
      OUTPUT_FILENAME: output.txt # <-- available to the templating engine
    env:
      OUTPUT_FILENAME: "{{.OUTPUT_FILENAME}}" # <-- available as an env var in your shell commands
    
    ...
    

    While this is more verbose, I think it is clearer what is going on, so this would be my preferred way of doing this today - regardless as to whether we make this change or not.