refactor: split manifest.py into domain-specific modules
Closes #157. Distributes the 1,026-line manifest.py across four focused modules: - _manifest_util.py: ManifestError + _as_json_object (shared base) - manifest_git.py: GitEntry, GitUser, git-gate config helpers - manifest_egress.py: EgressRoute, EgressConfig, PipelockRoutePolicy - manifest_agent.py: AgentProvider, Agent manifest.py is now the residual orchestration layer: Bottle, Manifest, and re-exports of all public names so existing callers are unaffected. All 867 unit tests pass.
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
"""Shared manifest primitives used by all manifest sub-modules."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import cast
|
||||
|
||||
|
||||
class ManifestError(Exception):
|
||||
"""A manifest file (or the manifest tree) is invalid."""
|
||||
|
||||
|
||||
def _as_json_object(value: object, label: str) -> dict[str, object]:
|
||||
"""Assert that `value` is a JSON object (str-keyed dict) and return
|
||||
a view typed as `dict[str, object]` so downstream `.get(...)` calls
|
||||
have a typed surface."""
|
||||
if not isinstance(value, dict):
|
||||
raise ManifestError(f"{label} must be a JSON object (was {type(value).__name__})")
|
||||
items = cast(dict[object, object], value)
|
||||
out: dict[str, object] = {}
|
||||
for k, v in items.items():
|
||||
if not isinstance(k, str):
|
||||
raise ManifestError(f"{label} keys must be strings (found {type(k).__name__})")
|
||||
out[k] = v
|
||||
return out
|
||||
Reference in New Issue
Block a user