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

Improve how we handle ENV priority (OS vs. .env files vs. Taskfile ENVs). Have a setting or this? #693

Open
ghostsquad opened this issue Mar 24, 2022 · 12 comments
Labels
area: env Changes related to environment variables. type: breaking change Changes that are not backward compatible. type: proposal A ticket that proposes a new feat/enhancement.

Comments

@ghostsquad
Copy link
Contributor

ghostsquad commented Mar 24, 2022

I find it very difficult to use task, as I cannot override environment variables if they are declared in the user's shell beforehand. Here's an example:

version: "3"

tasks:
  ham:
    env:
      HAM: "ham"
    cmds:
      - echo "$HAM"
at 17:31:04 ❯ t ham
task: [ham] echo "$HAM"
ham
at 17:31:06 ❯ HAM=BONE t ham
task: [ham] echo "$HAM"
BONE

I know this has been posted before, even probably by me. The use of VAR is not really a good workaround because specifically the commands I'm running are expecting an environment variable, not a command line parameter.

I understand this is a backwards incompatible change, so if there was a top-level set of "feature flags" that I could enable/disable to control behavior, that would be useful.

@andreynering andreynering added v4 area: env Changes related to environment variables. type: proposal A ticket that proposes a new feat/enhancement. labels Mar 24, 2022
@andreynering andreynering changed the title Unable to override env variables such as AWS_PROFILE Improve how we handle ENV priority (OS vs. .env files vs. Taskfile ENVs). Have a setting or this? Mar 24, 2022
@andreynering
Copy link
Member

Hi @ghostsquad,

I feel your frustration and I'm open to discuss changes to how we do this. Probably the ideal scenario would be to have some kind of setting, for which we would flip the default value only on v4, for backwards compatibility as you mentioned.

We currently have multiple levels of ENVs:

  • OS environment
  • .env files
  • Taskfile global ENVs
  • Task specific ENVs

So we need to think in a way that make it easy for the users to understand how it works, and if we have a setting, what that would change exactly.

Currently, we follow the priority as the list above. That's kinda a convention between different tools out there. For example: .env libs usually don't override existing ENVs from the OS, and Task follows that.

On the other hand, if we inverted the priority list above, it'd make it more consistent with how variable work currently, where something like FOO: '{{.FOO | default "bar"}}' is required if the user want the variable to be overridable.

I'm more than open for opinion so we can make a plan. 🙂

@andreynering
Copy link
Member

As a workaround, while we don't improve it, you need to call commands like this currently:

env FOO=bar echo $FOO

Basically making it part the command itself.

@ghostsquad
Copy link
Contributor Author

As a workaround, while we don't improve it, you need to call commands like this currently:

env FOO=bar echo $FOO

Basically making it part the command itself.

This is very redundant, and I prefer not to do this. Especially when there are many ENV vars, and when ENV vars need to be passed from task to task.


Regarding order of priority, least specific to most specific, similar to Make. In this way, Task specific ENVs take highest priority.

@tylermmorton
Copy link
Contributor

Sometimes I think of tasks as functions, and it does seem to make more programatic sense to have the order of priority be least specific to most specific. Like the scoping of vars as if you were writing some javascript

var msg = "global"

function scope() {
  var msg = "scoped"	
  console.log(msg) // "scoped"
}

scope()
console.log(msg) // "global"

@aminya
Copy link
Contributor

aminya commented Jul 21, 2022

I expect the task env to override the shell environment variables. The current behaviour is confusing.

@ghostsquad
Copy link
Contributor Author

I expect the task env to override the shell environment variables. The current behaviour is confusing.

I agree. If you need access to the shell environment, there's always the function from slim sprig {{ env }}.

@pd93 pd93 added type: breaking change Changes that are not backward compatible. and removed v4 labels Oct 15, 2022
@kirinnee
Copy link

kirinnee commented Mar 11, 2023

I believe there are use-case for both, perhaps a suggest:

  • have a default priority
  • allow overriding the priority list per task, and globally
version: v4
priority:
 - os
 - taskfile
 - .env
env:
  HELLO: "good morning"
task:
  run:
     priority:
      - taskfile
      - os
      - .env
     cmd: 
      -  echo: "$HELLO"
   start:
      cmd:
      - echo: "$HELLO"

running:

export HELLO="good afternoon"
task run # -> prints "good morning"
task start # -> prints "good afternoon"

@Antonboom

This comment was marked as spam.

@ghostsquad
Copy link
Contributor Author

Make I think does this correctly. Each variable defines it's own behavior.

# https://www.gnu.org/software/make/manual/html_node/Immediate-Assignment.html
FOO = bar

# https://www.gnu.org/software/make/manual/html_node/Conditional-Assignment.html
FOO ?= bar

# https://www.gnu.org/software/make/manual/html_node/Simple-Assignment.html
FOO := bar

# https://www.gnu.org/software/make/manual/html_node/Recursive-Assignment.html
foo = $(bar)
bar = $(ugh)
ugh = Huh?

In this case, each variable itself is in control of this decision.

The next problem is that Task is becoming exceedingly verbose as compared to Make. In some ways, this is fine (this is similar to Golang), but in other ways, it also creates a ton of boilerplate. The ideal is a balance between explicit, easy to read, and cryptically sparse.

@benc-uk
Copy link
Contributor

benc-uk commented Jun 4, 2023

I expect the task env to override the shell environment variables. The current behaviour is confusing.

Funny, as of 3.2 I'm seeing the opposite, envs and vars set in the taskfiles are always taking priority and this is exactly the behaviour I want to get away from. I'd expect the taskfiles to define some defaults which users can then override with OS level env vars or .env files.

I can't imagine any situation where user can't redefine and set variables when running a task. My team have evaluated task on a project and we're going back to Makefiles due to this inflexibility with being able to have overridable defaults

@andreynering
Copy link
Member

Hey @benc-uk, have you tried the default template function? That's how we usually suggest to handle it considering how Task work today.

tasks:
  echo:
    vars:
      MESSAGE: '{{.MESSAGE | default "my default message"}}'
    cmds:
      - echo "{{.MESSAGE}}"

@benc-uk
Copy link
Contributor

benc-uk commented Jun 4, 2023

Cool that helps, it's a little verbose but works for now

Hopefully v4 brings some changes in this area

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: env Changes related to environment variables. type: breaking change Changes that are not backward compatible. type: proposal A ticket that proposes a new feat/enhancement.
Projects
None yet
Development

No branches or pull requests

8 participants