Variables in dotenv-filename
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...
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.
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)}}
Yes, please! It will solve my usecase, and it sounds .. sound.
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:
- call
dotenv-filenameat the global level of the justfile - pass
path/to/actionto 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}"
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!
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?
@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 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! 🙏
How about supporting a simpler scenario: ability to use the invocation_directory instead of working directory?
I'd love to do the following:
set dotenv-path := invocation_directory() + "/.env"
currently the workaround is to use an alias in my shell, eg:
alias j="just --dotenv-path $(pwd)/.env"