mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-06 02:54:26 +00:00
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 carries3f973eb137, which resolves the parent image for scripts/image/push.sh on its own, and05e4dbafcb, 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>
60 lines
1.9 KiB
Python
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:]))
|