Files
devx/src/devx/tools/check_jinja_expr.py
T
emilandDevin <158243242+devin-ai-integration[bot]@users.noreply.github.com> 8f1232a7d7 refactor: extract wait_for_checks, consolidate ansible_checks, deprecate ci/discover_runners
Phase 1a-c of REFACTORING-PLAN.md:

- Extract devx.ci.wait_for_checks module (replaces inline polling in
  grm ci.yml) with 100% test coverage (26 tests)
- Consolidate 5 Ansible check tools into composable
  devx.tools.ansible_checks/ subpackage with shared utilities
  (AnsibleFileFinder, AnsibleYAMLParser, ViolationReporter); old
  modules remain as thin backward-compat wrappers
- Merge ci/discover_runners into molecule/discover_runners (canonical
  implementation with improved error logging); ci/discover_runners
  becomes a deprecated wrapper re-exporting from molecule

All 2393 existing tests pass; new modules at 100% coverage.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-08-12 19:25:15 +02:00

66 lines
2.1 KiB
Python

"""Validate Jinja2 expressions in Ansible files by rendering them.
Thin wrapper around :mod:`devx.tools.ansible_checks.jinja_expr` for
backward compatibility. The check logic lives in the subpackage; this
module preserves the CLI entry point and re-exports the internal
helpers so existing tests and imports continue to work.
Usage::
python -m devx.tools.check_jinja_expr
python -m devx.tools.check_jinja_expr --path ansible/playbooks/deploy-observability.yml
Exit code 0 if all renderable expressions pass, 1 if any fail.
"""
from __future__ import annotations
import sys
from pathlib import Path
import click
from devx.tools.ansible_checks.jinja_expr import (
EXPR_PATTERN, # noqa: F401 — re-exported for backward compat
MOCK_CONTEXT, # noqa: F401
_check_file, # noqa: F401
_default_ansible_dirs, # noqa: F401
_extract_expressions, # noqa: F401
_find_yaml_files, # noqa: F401
_render_expression, # noqa: F401
check_jinja_expr, # noqa: F401
)
@click.command()
@click.option(
"--path",
type=click.Path(exists=True, path_type=Path),
help="Check a specific file or directory (default: ansible/playbooks + ansible/roles).",
)
@click.option(
"--ansible-dir",
"ansible_dirs",
type=click.Path(exists=True, path_type=Path),
multiple=True,
default=None,
help="Override the default ansible directories (can be repeated). Defaults to ansible/playbooks and ansible/roles.",
)
def main(path: Path | None, ansible_dirs: tuple[Path, ...]) -> None:
"""Validate Jinja2 expressions in Ansible files."""
dirs = list(ansible_dirs) if ansible_dirs else _default_ansible_dirs()
all_violations = check_jinja_expr(path) if path else check_jinja_expr(None, dirs)
if all_violations:
click.echo("[check-jinja-expr] FAIL: invalid Jinja expressions found:")
for v in all_violations:
click.echo(f" - {v}")
click.echo("\nFix: test expressions with `ansible localhost -m debug -a 'msg={{ <expr> }}'`")
sys.exit(1)
else:
click.echo("[check-jinja-expr] OK: all Jinja expressions render correctly.")
if __name__ == "__main__": # pragma: no cover
main()