Coverage for src/rhiza_hooks/_config_schema.py: 100%
12 statements
« prev ^ index » next coverage.py v7.14.1, created at 2026-07-30 04:36 +0000
« prev ^ index » next coverage.py v7.14.1, created at 2026-07-30 04:36 +0000
1#!/usr/bin/env python3
2"""Canonical schema for ``.rhiza/template.yml`` — keys, aliases, normalization.
4This is the single source of truth for the shape of a rhiza template config. It
5owns the canonical key sets (:data:`REQUIRED_KEYS`, :data:`OPTIONAL_KEYS`,
6:data:`VALID_KEYS`), the :data:`KEY_ALIASES` map from accepted alias spellings to
7their canonical names, and :func:`normalize_config`, which rewrites a raw mapping
8so every alias becomes its canonical key.
10Both the config validator (:mod:`rhiza_hooks.check_rhiza_config`) and the
11template-bundles reader (:mod:`rhiza_hooks._bundles_config`) import from here so
12the alias handling never drifts between them. The module is a leaf: it imports
13nothing from the rest of :mod:`rhiza_hooks`.
14"""
16from __future__ import annotations
18from typing import Any
20REQUIRED_KEYS = {"template-repository", "template-branch"}
21OPTIONAL_KEYS = {"include", "exclude", "templates"}
22VALID_KEYS = REQUIRED_KEYS | OPTIONAL_KEYS
23# Alternative (alias) key names mapped to their canonical spellings.
24KEY_ALIASES = {
25 "repository": "template-repository",
26 "ref": "template-branch",
27 "profiles": "templates",
28}
31def normalize_config(config: dict[str, Any]) -> dict[str, Any]:
32 """Normalize configuration by replacing aliases with canonical keys.
34 Args:
35 config: Raw configuration dictionary
37 Returns:
38 Normalized configuration with aliases replaced
39 """
40 normalized: dict[str, Any] = {}
41 for key, value in config.items():
42 # Replace alias with canonical name if it exists
43 canonical_key = KEY_ALIASES.get(key, key)
44 normalized[canonical_key] = value
45 return normalized