diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a4d3c20..06c9e79 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -34,6 +34,16 @@ repos: types: [python] pass_filenames: false + # Jinja2 template validation + - repo: local + hooks: + - id: jinja2-check + name: jinja2 template syntax + entry: uv run python -c "import sys; from jinja2 import Template; [Template(open(f).read()) for f in sys.argv[1:]]" + language: system + files: ^dropkit/templates/.*\.yaml$ + types: [file] + # Shell script linting - repo: https://github.com/koalaman/shellcheck-precommit rev: v0.10.0 diff --git a/dropkit/templates/default-cloud-init.yaml b/dropkit/templates/default-cloud-init.yaml index 07a7e23..ccc2e06 100644 --- a/dropkit/templates/default-cloud-init.yaml +++ b/dropkit/templates/default-cloud-init.yaml @@ -1,5 +1,5 @@ #cloud-config -# Warning: This whole file will be evaluated by Jinja. Escape any special literals (`{{`, `{%`, `{#`). +# Warning: This whole file will be evaluated by Jinja. Escape any special literals # Update and upgrade system packages package_update: true diff --git a/tests/test_cloudinit.py b/tests/test_cloudinit.py new file mode 100644 index 0000000..a51c020 --- /dev/null +++ b/tests/test_cloudinit.py @@ -0,0 +1,53 @@ +"""Tests for cloud-init template parsing and rendering.""" + +from jinja2 import Template, TemplateSyntaxError + +from dropkit.config import Config + + +def _load_default_template() -> str: + """Load the default cloud-init template content.""" + path = Config.get_default_template_path() + return path.read_text() + + +def test_default_template_parses(): + """Verify the default template is valid Jinja2 syntax.""" + content = _load_default_template() + try: + Template(content) + except TemplateSyntaxError as exc: + raise AssertionError(f"Template has Jinja2 syntax error: {exc}") from exc + + +def test_default_template_renders(): + """Verify the template renders with sample variables.""" + content = _load_default_template() + template = Template(content) + rendered = template.render( + username="testuser", + full_name="Test User", + email="test@example.com", + ssh_keys=["ssh-ed25519 AAAAC3... test@host"], + tailscale_enabled=True, + ) + assert "testuser" in rendered + assert "ssh-ed25519 AAAAC3... test@host" in rendered + assert "git config --global user.name 'Test User'" in rendered + assert "git config --global user.email 'test@example.com'" in rendered + assert "tailscale" in rendered + + +def test_default_template_renders_without_tailscale(): + """Verify the Tailscale section is absent when disabled.""" + content = _load_default_template() + template = Template(content) + rendered = template.render( + username="testuser", + full_name="Test User", + email="test@example.com", + ssh_keys=["ssh-ed25519 AAAAC3... test@host"], + tailscale_enabled=False, + ) + assert "testuser" in rendered + assert "tailscale.com/install.sh" not in rendered