Files
computer-playbook/cli/meta/env/__main__.py
kevinveenbirkenbachandClaude Opus 5.5 1079f48feb fix(env): derive the image and container names from the distro under test
A compose deploy job labelled centos or arch built its stack image from
pkgmgr-debian and ran it as infinito_nexus_debian (#794). distros.sh
exports INFINITO_DISTRO per iteration and sources load.sh again, but the
loader returned early because INFINITO_ENV_LOADED and the .env mtime were
unchanged. A full reload would not have helped either: the debian values
were already exported, so the restore step kept them as caller intent.

load.sh now records the distro it loaded for. Another INFINITO_DISTRO
defeats the early return and drops INFINITO_CONTAINER,
INFINITO_PARENT_IMAGE and INFINITO_IMAGE, the three keys the env handlers
derive from the distro. When the requested distro also differs from the
one .env was generated for, the loader sources a set that
`python -m cli.meta.env --output` generates for it in a private temp
directory and leaves .env untouched, so a local multi-distro run does not
switch the checkout's distro. A caller value set for the loaded distro
still wins.

Verified: tests/unit/python/scripts/meta/env/test_load.py and the new
distros.sh case pass. Against main's loader both fail with the symptom of
the issue: INFINITO_DISTRO=centos next to infinito_nexus_debian and
pkgmgr-debian:stable, and distros.sh handing debian, arch and centos the
same debian parent. shellcheck is clean.

Consequence: CI jobs labelled arch, ubuntu, fedora or centos now build
and deploy that distro, so a failure that shows up there was masked
before.

feature/store-i18n carries 3f973eb137, which resolves the parent image
for scripts/image/push.sh on its own, and 05e4dbafcb, which inserts the
INFINITO_INSTANCE slot check into the block this commit restructures. The
merge keeps the slot check ahead of the distro check.

Closes #794

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-13 21:30:48 +02:00

60 lines
1.9 KiB
Python

"""CLI entry: `python -m cli.meta.env` (also `make dotenv`)."""
from __future__ import annotations
import argparse
import os
import sys
from pathlib import Path
from utils.env.builder import build_env
from utils.env.parser import parse_static_env_with_comments
from utils.env.writer import write_dotenv
from . import PROJECT_ROOT as REPO_ROOT
HOST_OWNED_KEY = "INFINITO_DOTENV_HOST_OWNED" # nocheck: dotenv-host-owned-marker Reason: set only by compose.yml inside the runner container; not a configuration key, a .env entry could freeze the host .env
def main(argv: list[str] | None = None) -> int:
"""Generate the env set from default.env and the runtime context.
Args:
argv: command-line arguments; ``--output PATH`` writes the set to PATH
instead of the repository's ``.env``, which then stays untouched.
Returns:
0 on success, 2 when default.env is missing.
"""
parser = argparse.ArgumentParser(prog="python -m cli.meta.env")
parser.add_argument("--output", type=Path)
args = parser.parse_args([] if argv is None else argv)
static_path = REPO_ROOT / "default.env"
out_path = args.output or REPO_ROOT / ".env"
out_name = args.output or ".env"
if not static_path.is_file():
print(f"ERROR: missing {static_path}", file=sys.stderr)
return 2
if (
args.output is None
and out_path.is_file()
and os.environ.get(HOST_OWNED_KEY) == "true"
):
print(
f"Kept {out_name}: the host checkout owns it ({HOST_OWNED_KEY})",
file=sys.stderr,
)
return 0
static, static_comments = parse_static_env_with_comments(static_path)
eb = build_env(static, repo_root=REPO_ROOT, comments=static_comments)
write_dotenv(eb, out_path)
print(f"Wrote {out_name} ({len(eb.values)} variables)", file=sys.stderr)
return 0
if __name__ == "__main__":
sys.exit(main(sys.argv[1:]))