utils/env πΒΆ
This directory hosts the Python implementation behind make dotenv.
For the general rules that govern READMEs in code directories see documentation.md.
For the per-variable defaults that this code consumes see default.env.
Purpose π―ΒΆ
The package converts the committed default.env plus a small runtime context into the gitignored .env at the repo root.
Every module here belongs to one of four roles: parse, resolve, orchestrate, write.
Structure ποΈΒΆ
File |
Role |
|---|---|
|
Read default.env into |
|
Resolve host-context lookups (disk, RAM, hostname, GHA/Act flags, |
|
Thin orchestrator that defines |
|
Serialise an |
|
One module per dynamically-computed variable. See handlers README. |
The CLI entry point lives at main.py under cli/meta/env/.
Shell consumers source load.sh under scripts/meta/env/.
File Naming π·οΈΒΆ
Module names MUST stay lowercase snake_case.
Pure passthrough or simple parser/writer helpers MUST live directly under
utils/env/.Per-variable computation MUST live under
handlers/(see handlers README for the naming convention used there).Test files live in tests/unit/python/utils/env/ and mirror the module name with a
test_prefix.
Machine Facts vs Run Facts π§ΒΆ
The writer a handler picks decides how long a value lives. Both kinds are registered in default.env and both are visible to the lints; they differ only in whether the generated .env remembers what the environment said.
Writer |
Meaning |
On the next |
|---|---|---|
|
machine fact |
a non-empty value in the process env is adopted and written back |
|
run fact |
recomputed from |
setdefault is the operator-override contract: exporting a key changes it and the change persists. That persistence is why it MUST NOT carry a value an environment declares for a single run. Makefile exports BASH_ENV, so every make recipe sources .env β a value adopted once is re-exported into every later recipe and into every container that mounts the repo, and a per-run decision has silently become a property of the machine.
A key that some environment declares per run therefore MUST be written by a dedicated handler through eb.set. The exporting shell still wins for its own run, because load.sh preserves non-empty caller values when it sources .env; the file keeps the derived default. INFINITO_RUNNING_ON_GITHUB, INFINITO_CACHE_STACK and INFINITO_GHCR_MIRROR are written this way. Note the consequence: for those keys .env and the running shell can legitimately disagree, and .env is not the authority.
Import Rules πΒΆ
parser.py,runtime.py, andwriter.pyMUST NOT import frombuilder.pyorhandlers/.builder.pyMUST NOT import individual handler modules; it MUST go through theORDERED_HANDLERSlist exposed byhandlers/__init__.py.Handler modules MUST NOT import each other (see handlers README).