mirror of
https://github.com/trailofbits/dropkit
synced 2026-06-21 14:11:54 +00:00
Add Jinja2 template validation test and pre-commit hook (#45)
* Remove escaped chars in comments * Add Jinja2 template validation test and pre-commit hook Catch template syntax errors early with a unit test that parses and renders the default cloud-init template, and a pre-commit hook that validates all templates in dropkit/templates/ on change. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
committed by
GitHub
parent
fde89df590
commit
0efeea52bb
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user