Files
computer-playbook/tests/utils/bare_bootstrap_probe.py
T
kevinveenbirkenbachandClaude Opus 5 79ba511bb7 fix(env): keep the .env generator stdlib-only
The env generator runs on the bare bootstrap python, before any
dependency is installed. utils/distros.py reached PyYAML through
utils.cache.yaml, so `python -m cli.meta.env` died with
ModuleNotFoundError on every dev-runtime image that ships python3
without PyYAML.

utils/yaml_bootstrap.load_block reads the block-YAML subset the SPOT
files use with stdlib only. It raises BootstrapYamlError on anything it
cannot parse identically to yaml.safe_load, so meta/distros.yml fails
loud instead of drifting.

The per-line regex lint meant to guard this is gone: one hop of
indirection defeated it and it stayed green while the invariant was
broken. It is replaced by a test that runs the real generator with
every non-stdlib import blocked.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-28 19:47:01 +02:00

42 lines
1.1 KiB
Python

"""Run the .env generator with every non-stdlib, non-repo import blocked.
Executed as a subprocess, never imported. Argv is ``<repo-root> <out-path>``.
A blocked import propagates so the traceback names the offending chain.
"""
from __future__ import annotations
import sys
from pathlib import Path
REPO = Path(sys.argv[1]).resolve()
OUT = Path(sys.argv[2])
sys.path.insert(0, str(REPO))
REPO_TOP = frozenset(
{"cli", "utils", "plugins", "filter_plugins", "lookup_plugins", "module_utils"}
)
STDLIB = frozenset(sys.stdlib_module_names)
class Blocker:
def find_spec(self, fullname, path=None, target=None):
top = fullname.split(".")[0]
if top in STDLIB or top in REPO_TOP:
return
raise ModuleNotFoundError(f"No module named {fullname!r}", name=fullname)
sys.meta_path.insert(0, Blocker())
from cli.meta.env.__main__ import ( # noqa: E402
build_env,
parse_static_env_with_comments,
write_dotenv,
)
static, comments = parse_static_env_with_comments(REPO / "default.env")
eb = build_env(static, repo_root=REPO, comments=comments)
write_dotenv(eb, OUT)
print(len(eb.values))