Coverage for src/rhiza_hooks/_bundles_config.py: 100%
21 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"""Read the project's ``.rhiza/template.yml`` configuration.
4Helpers for extracting the bits of the rhiza config that the
5``check-template-bundles`` hook needs: the raw mapping and the declared set of
6template names. Returning ``None`` signals "absent or unusable", which callers
7treat as "skip validation".
8"""
10from __future__ import annotations
12from pathlib import Path
13from typing import Any
15from rhiza_hooks._config_schema import normalize_config
16from rhiza_hooks._yaml import YamlFailure, load_yaml_mapping
19def _get_config_data(config_path: Path) -> dict[str, Any] | None:
20 """Get the configuration from .rhiza/template.yml.
22 Aliases (``repository``/``ref``/``profiles``) are normalized to their
23 canonical keys so downstream reads of ``template-repository`` /
24 ``template-branch`` / ``templates`` work for both alias and canonical forms.
26 Args:
27 config_path: Path to .rhiza/template.yml
29 Returns:
30 Configuration dictionary, or None if file not found or invalid
31 """
32 result = load_yaml_mapping(config_path)
33 if isinstance(result, YamlFailure):
34 return None
35 return normalize_config(result)
38def _get_templates_from_config(config_path: Path) -> set[str] | None:
39 """Get the list of templates from .rhiza/template.yml.
41 Args:
42 config_path: Path to .rhiza/template.yml
44 Returns:
45 Set of template names, or None if templates field doesn't exist or file not found
46 """
47 config = _get_config_data(config_path)
48 if config is None:
49 return None
51 templates = config.get("templates")
52 if templates is None:
53 return None
55 if not isinstance(templates, list):
56 return None
58 template_names: set[str] = {str(t) for t in templates}
59 return template_names