Add feature to dynamically set environment variables in `envs.ENV.env-vars`
Discussed in https://github.com/pypa/hatch/discussions/1554
Originally posted by ketozhang June 6, 2024 Is there any way to dynamically set environment variables?
In my use case, I want to set a secret variable dynamically using a command that takes in another env var for the secret key/name.
[tool.hatch.envs.default.env-vars]
SECRET_KEY="some-key-name"
SECRET="$(get-secret $SECRET_KEY)" # get-secret is a placeholder command
The only way I can think of is to set it in scripts.
[tool.hatch.envs.default.scripts]
test="SECRET=$(get-secret $SECRET_KEY) printenv"
...which does not scale, unless you can use secret="export SECRET=..." then test=["secret", "printenv"], but I don't think hatch preserves export.
Out of curiosity, does that workaround I mentioned in that discussion work for you (temporarily)?
Yes it does–thank you!
Just to note for other readers until a better solution is put in place, you can currently do this by creating an Environment Collector plugin which can arbitrarily edit the env vars of all environments.
based on @johnpyp's suggestion I created a plugin to automatically collect variables from a .envfile and set it to all hatch environments:
from pathlib import Path
import re
from hatch.env.collectors.plugin.interface import EnvironmentCollectorInterface
class EnvVarSetter(EnvironmentCollectorInterface):
def finalize_environments(self, config):
env_file = Path(".env")
if not env_file.exists():
return config
# collect new env vars in .env
new_vars = dict()
pattern = re.compile(r"""^([^\s=]+)=(?:[\s"']*)(.+?)(?:[\s"']*)$""")
with env_file.open(encoding="utf-8") as infile:
for line in infile:
match = pattern.match(line)
if match is not None:
new_vars[match.group(1)] = match.group(2)
# add new env vars
for env_name, env_entry in config.items():
if not env_name.startswith("hatch"):
if "env-vars" not in env_entry:
env_entry["env-vars"] = new_vars
else:
env_entry["env-vars"].update(new_vars)
return config
and then simply add this to your pyproject.toml:
[tool.hatch.env.collectors.custom]
path = "path/to/envvarsetter.py"
I guess the plugin can be easily modified to set other variables