mirror of
https://github.com/d9pouces/id_configurator.git
synced 2026-11-09 01:47:21 +01:00
6e086b0964
Signed-off-by: d9pouces <github@19pouces.net>
67 lines
2.2 KiB
Python
67 lines
2.2 KiB
Python
"""Utilities for the Docker integration tests under tests/."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
import pathlib
|
|
from typing import Annotated
|
|
|
|
import jinja2
|
|
import typer
|
|
|
|
app = typer.Typer(help="Utilities for the tests/ Docker integration tests")
|
|
|
|
TESTS_DIR = pathlib.Path(__file__).resolve().parent.parent / "tests"
|
|
|
|
|
|
def _env(name: str) -> str:
|
|
"""Jinja2 filter: `'NAME' | env` -> the environment variable NAME."""
|
|
return os.environ[name]
|
|
|
|
|
|
def _file(relative: str) -> str:
|
|
"""Jinja2 filter: `'relative/path' | file` -> content of tests/relative/path."""
|
|
path = (TESTS_DIR / relative).resolve()
|
|
if path != TESTS_DIR and TESTS_DIR not in path.parents:
|
|
raise ValueError(f"refusing to read a file outside of {TESTS_DIR}: {relative}")
|
|
return path.read_text(encoding="utf-8")
|
|
|
|
|
|
def render_template(text: str) -> str:
|
|
"""Render a tests/configs/*.yaml.j2 fixture as a Jinja2 template.
|
|
|
|
Custom filters: `| env` reads an environment variable, `| file` reads a
|
|
file relative to tests/. Combine with Jinja2's built-in `indent` filter
|
|
to fit multi-line content (e.g. a PEM certificate) into a YAML
|
|
block-literal field, e.g.:
|
|
|
|
content: |
|
|
{{ 'certs/test-ca.crt.pem' | file | indent(6, first=true) }}
|
|
"""
|
|
# Autoescaping is for HTML output; these templates render YAML, so escaping
|
|
# would corrupt them (e.g. turning "&" into "&" inside a PEM/URL).
|
|
environment = jinja2.Environment(undefined=jinja2.StrictUndefined) # nosec B701
|
|
environment.filters["env"] = _env
|
|
environment.filters["file"] = _file
|
|
return environment.from_string(text).render()
|
|
|
|
|
|
@app.command(
|
|
name="render-config",
|
|
help="Render a tests/configs/*.yaml.j2 fixture into a ready-to-use configuration.",
|
|
)
|
|
def render_config(
|
|
template: Annotated[pathlib.Path, typer.Argument(exists=True, dir_okay=False)],
|
|
output: pathlib.Path,
|
|
) -> None:
|
|
"""Renders `template` as a Jinja2 template (see `render_template`) and
|
|
writes the result to `output`, creating its parent directories as
|
|
needed."""
|
|
content = render_template(template.read_text(encoding="utf-8"))
|
|
output.parent.mkdir(parents=True, exist_ok=True)
|
|
output.write_text(content, encoding="utf-8")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
app()
|