Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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:]]"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
entry: uv run python -c "import sys; from jinja2 import Template; [Template(open(f).read()) for f in sys.argv[1:]]"
entry: uv run --with jinja2 python -c "import sys; from jinja2 import Template; [Template(open(f).read()) for f in sys.argv[1:]]"

Maybe that's more resilient?

language: system
files: ^dropkit/templates/.*\.yaml$
types: [file]

# Shell script linting
- repo: https://github.com/koalaman/shellcheck-precommit
rev: v0.10.0
Expand Down
2 changes: 1 addition & 1 deletion dropkit/templates/default-cloud-init.yaml
Original file line number Diff line number Diff line change
@@ -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
Expand Down
53 changes: 53 additions & 0 deletions tests/test_cloudinit.py
Original file line number Diff line number Diff line change
@@ -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