casey / just

🤖 Just a command runner
https://just.systems
Creative Commons Zero v1.0 Universal
20.05k stars 448 forks source link

Variables in dotenv-filename #1724

Open amarao opened 10 months ago

amarao commented 10 months ago

Scenario: I have justfile which wants to use a specific env file. This name is also been used few times in the recipes, so I want to put it into variable.

Unfortunately, currently it's impossible to use variable names in dotenv-filename directive.

I understand that this creates some kind of circular dependency, but having ability to use variable in both dotenv-filename and in other places made is really natural. May be, it's possible to forbid redefinition of variables used to load dotenv-filename?

Alternatively, dotenv-filename can be processed at a specific moment, may be with a different directive compare to set. Or it can be a command for recipe to move it to runtime...

casey commented 10 months ago

Variables can depend on dotenv variables, regardless of whether they're redefined, since they can use env variables, so I don't think this is possible in general. I'll leave it open though, in case anyone has any clever ideas.

laniakea64 commented 10 months ago

One possible line of thinking, what about approaching this the other way around: Would having the ability to obtain a setting's value work for this case? so you could define the name once in the dotenv-filename setting, then retrieve this name from the setting value in other uses. For example, if a function for this were added, then you would be able to do something like -

set dotenv-filename := 'mydotenv'

foo:
  cat {{quote(get_setting('dotenv-filename'))}}

# or put it in a variable
f := get_setting('dotenv-filename')

foo2:
  cat {{quote(f)}}
amarao commented 7 months ago

Yes, please! It will solve my usecase, and it sounds .. sound.

maurelian commented 6 months ago

This would also be very helpful to us. I particularly like the get_setting approach suggested above.

To clarify our use case, we use just in a repo which records past and future on-chain governance actions to be taken on the Optimism rollup network. These actions need to be signed by multisig participants, and we use just to define the commands the signers need to run.

In the root of the repo we have a couple justfiles, and in subdirs we have a structure like:

/path/to/action/
├── README.md   # describes the action
├── .env        # contains action specific variables that all signers need (ie. multisig contract nonce)
└── input.json  # defines the transactions to sign

The just recipe needs to be able to find both the .env file and the input.json file, but there isn't a straightforward way AFAICT to pass in path/to/action and use that to both:

  1. call dotenv-filename at the global level of the justfile
  2. pass path/to/action to the just recipe itself.

Aside from get_setting another nice syntax would be to ability to set dotenv-filename within a recipe:

foo dirpath: 
    dotenv-filename(join(dirpath,".env")
    input_path=join(dirpath,"input.json")
    echo "now we are going to sign the tx in ${input_path}"
casey commented 4 months ago

Great thought, @laniakea64!

I think this should be pretty simple. I'd just make it setting(name). In particular, name can be a keyword token. If anyone wants to take a crack at this, feel free!

jneuendorf-i4h commented 1 month ago

I also want to use set dotenv-filename dynamically. However, I want to pick from different env files (containing different passwords for example).

I don't see a reason why

set doting-filename := "$ENV_FILE"

should not work or be counterintuitive. In this case, strings need to be parsed, but the grammar doesn't change.

The slightly more convenient case

set doting-filename := env('ENV_FILE', '.env')

would require a grammar extensions for setting to sth. like this:

setting       : ...
              | 'dotenv-filename' ':=' value

The invocation would could look like this: ENV_FILE='.env.prod' just a/b


@casey Is there a good reason to limit settings to strings?

laniakea64 commented 1 month ago

@jneuendorf-i4h If you're setting it via environment variable, can you use shell-expanded string?

set dotenv-filename := x'${ENV_FILE:-.env}'
jneuendorf-i4h commented 1 month ago

@jneuendorf-i4h If you're setting it via environment variable, can you use shell-expanded string?

set dotenv-filename := x'${ENV_FILE:-.env}'

Thanks a lot, your suggestion works! 🙏