ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
verify_locked_environment.py
Go to the documentation of this file.
1#!/usr/bin/env python3
2# SPDX-License-Identifier: MIT
3# Copyright (c) 2026 Brighton Sikarskie
4"""Verify that a managed virtual environment exactly matches a uv export."""
5
6from __future__ import annotations
7
8import importlib.metadata
9import platform
10import re
11import sys
12import tempfile
13from pathlib import Path
14
15PIN_RE = re.compile(
16 r"^([A-Za-z0-9][A-Za-z0-9_.-]*)==([0-9][A-Za-z0-9.!+_-]*)"
17 r"(?: ; (.+?))? \\?$"
18)
19IGNORED_BOOTSTRAP_PACKAGES = {"pip", "setuptools", "wheel"}
20MIN_LOCKED_PACKAGES = 10
21REQUIREMENTS_ARG_COUNT = 2
22HASH_RE = re.compile(r"^--hash=sha256:([0-9a-f]{64})(?: \\)?$")
23
24
25def canonical_name(name: str) -> str:
26 """Apply Python distribution-name canonicalization."""
27 return re.sub(r"[-_.]+", "-", name).lower()
28
29
30def marker_applies(marker: str | None) -> bool:
31 """Evaluate the small exact marker vocabulary emitted by the locked groups."""
32 if marker is None:
33 return True
34 values = {
35 "implementation_name": sys.implementation.name,
36 "platform_python_implementation": platform.python_implementation(),
37 "sys_platform": sys.platform,
38 }
39 clauses = marker.split(" and ")
40 for clause in clauses:
41 match = re.fullmatch(
42 r"(implementation_name|platform_python_implementation|sys_platform) "
43 r"(==|!=) '([^']+)'",
44 clause,
45 )
46 if match is None:
47 message = f"unsupported environment marker in lock export: {marker!r}"
48 raise ValueError(message)
49 variable, operator, expected = match.groups()
50 equal = values[variable] == expected
51 if (operator == "==" and not equal) or (operator == "!=" and equal):
52 return False
53 return True
54
55
56def expected_packages(lock_path: Path) -> dict[str, str]:
57 """Parse exact records and require authenticated hashes for every one."""
58 expected: dict[str, str] = {}
59 seen: set[str] = set()
60 current: tuple[str, str, bool, set[str]] | None = None
61
62 def finish_record() -> None:
63 nonlocal current
64 if current is None:
65 return
66 name, version, applies, hashes = current
67 if not hashes:
68 message = f"locked requirement has no SHA-256 hashes: {name}"
69 raise ValueError(message)
70 if applies:
71 expected[name] = version
72 current = None
73
74 for line_number, line in enumerate(lock_path.read_text(encoding="utf-8").splitlines(), start=1):
75 stripped = line.strip()
76 if not stripped or stripped.startswith("#"):
77 continue
78 pin = PIN_RE.fullmatch(stripped)
79 if pin is not None:
80 finish_record()
81 raw_name, version, marker = pin.groups()
82 name = canonical_name(raw_name)
83 if name in seen:
84 message = f"duplicate locked requirement: {name}"
85 raise ValueError(message)
86 seen.add(name)
87 current = (name, version, marker_applies(marker), set())
88 continue
89 digest = HASH_RE.fullmatch(stripped)
90 if digest is not None:
91 if current is None:
92 message = f"stray hash on line {line_number}"
93 raise ValueError(message)
94 if digest.group(1) in current[3]:
95 message = f"duplicate hash on line {line_number}"
96 raise ValueError(message)
97 current[3].add(digest.group(1))
98 continue
99 message = f"malformed locked requirement on line {line_number}: {stripped!r}"
100 raise ValueError(message)
101 finish_record()
102 if len(expected) < MIN_LOCKED_PACKAGES:
103 message = f"locked environment export contains only {len(expected)} packages"
104 raise ValueError(message)
105 return expected
106
107
108def installed_packages() -> dict[str, str]:
109 """Read installed distributions, excluding venv bootstrap tools."""
110 return {
111 canonical_name(distribution.metadata["Name"]): distribution.version
112 for distribution in importlib.metadata.distributions()
113 if canonical_name(distribution.metadata["Name"]) not in IGNORED_BOOTSTRAP_PACKAGES
114 }
115
116
117def findings(expected: dict[str, str], installed: dict[str, str]) -> list[str]:
118 """Return missing, extra, and wrong-version findings in stable order."""
119 problems: list[str] = []
120 for name in sorted(expected.keys() | installed.keys()):
121 wanted = expected.get(name)
122 actual = installed.get(name)
123 if wanted != actual:
124 problems.append(
125 f"{name}: expected {wanted or 'absent'}, installed {actual or 'absent'}"
126 )
127 return problems
128
129
130def selftest() -> int:
131 """Prove parsing, hash enforcement, and exact comparison both ways."""
132 expected = {"alpha": "1.0", "bravo": "2.0"}
133 if findings(expected, dict(expected)):
134 print("selftest: an exact environment failed", file=sys.stderr)
135 return 1
136 cases = (
137 {"alpha": "1.0"},
138 {"alpha": "1.0", "bravo": "2.0", "extra": "3.0"},
139 {"alpha": "9.0", "bravo": "2.0"},
140 )
141 if any(not findings(expected, case) for case in cases):
142 print("selftest: missing, extra, or wrong version passed", file=sys.stderr)
143 return 1
144 records = [
145 f"package-{index}==1.{index} \\" + f"\n --hash=sha256:{index:064x}"
146 for index in range(MIN_LOCKED_PACKAGES)
147 ]
148 valid = "\n".join(records)
149 fixtures = {
150 "valid": (valid, True),
151 "undersized": (records[0], False),
152 "malformed": (f"{valid}\nnot an exact pin", False),
153 "duplicate-record": (f"{valid}\n{records[0]}", False),
154 "hashless": ("\n".join([*records, "extra==1.0 \\"]), False),
155 "stray-hash": (
156 f"--hash=sha256:{'f' * 64}\n{valid}",
157 False,
158 ),
159 "invalid-hash": (
160 valid.replace("0" * 64, "not-a-digest", 1),
161 False,
162 ),
163 "unknown-marker": (
164 f"{valid}\noptional==1.0 ; os_name ~= 'posix' \\" + f"\n --hash=sha256:{'e' * 64}",
165 False,
166 ),
167 }
168 if not marker_applies("sys_platform != 'definitely-not-this-platform'"):
169 print("selftest: true environment marker evaluated false", file=sys.stderr)
170 return 1
171 if marker_applies(f"sys_platform == '{sys.platform}-other'"):
172 print("selftest: false environment marker evaluated true", file=sys.stderr)
173 return 1
174 with tempfile.TemporaryDirectory() as raw:
175 path = Path(raw) / "requirements.lock"
176 for label, (content, should_pass) in fixtures.items():
177 path.write_text(f"{content}\n", encoding="utf-8")
178 try:
179 parsed = expected_packages(path)
180 except ValueError:
181 passed = False
182 else:
183 passed = len(parsed) == MIN_LOCKED_PACKAGES
184 if passed != should_pass:
185 print(f"selftest: parser fixture {label} judged {passed}", file=sys.stderr)
186 return 1
187 print("verify_locked_environment.py --selftest: PASS")
188 return 0
189
190
191def main() -> int:
192 """Verify the running interpreter against the provided export."""
193 if sys.argv[1:] == ["--selftest"]:
194 return selftest()
195 if len(sys.argv) != REQUIREMENTS_ARG_COUNT:
196 print(f"usage: {Path(sys.argv[0]).name} REQUIREMENTS_LOCK", file=sys.stderr)
197 return 2
198 try:
199 problems = findings(expected_packages(Path(sys.argv[1])), installed_packages())
200 except (OSError, TypeError, ValueError) as error:
201 print(f"verify_locked_environment.py: FATAL: {error}", file=sys.stderr)
202 return 2
203 if problems:
204 print("\n".join(problems), file=sys.stderr)
205 return 1
206 print("managed environment exactly matches the uv lock export")
207 return 0
208
209
210if __name__ == "__main__":
211 raise SystemExit(main())
void main(void)
The application entry point Reset_Handler hands control to.
Definition main.c:298