Story 2011116: recursively find jinja2 vars from templates

Don't only try to find undeclared variables from the current template
but also recursively find undeclared variables from included and
imported jinja2 templates.
Otherwise included/imported templates with variables can not be used.

Change-Id: Iebdce1accf74f27901d80a41c85624ba819bf2a8
This commit is contained in:
Thomas Bechtold 2024-05-06 12:14:02 +02:00
parent 770a4bbb4a
commit c5fce78f71
4 changed files with 40 additions and 2 deletions

View File

@ -294,10 +294,25 @@ class J2Template(J2BaseYamlObject):
self._template_text = template_text
self._template = self._jinja2_env.from_string(template_text)
def _params_from_referenced_templates(self, template_text):
"""
Find recursively undeclared jinja2 variables from any
(nested) included template(s)
"""
required_params = set()
ast = self._jinja2_env.parse(template_text)
for rt in jinja2.meta.find_referenced_templates(ast):
# recursive call to find params also from nested includes
template_text = Path(self._find_file(rt, 0)).read_text()
required_params.update(
self._params_from_referenced_templates(template_text)
)
required_params.update(jinja2.meta.find_undeclared_variables(ast))
return required_params
@cached_property
def required_params(self):
ast = self._jinja2_env.parse(self._template_text)
return jinja2.meta.find_undeclared_variables(ast)
return self._params_from_referenced_templates(self._template_text)
def _render(self, params):
return self._render_template(

View File

@ -0,0 +1,2 @@
{# make sure the variable "globalvar1" is available in a nested include #}
{{ globalvar1 }}

View File

@ -0,0 +1,18 @@
- defaults:
name: global
globalvar1: "global-var-1"
globalvar2: "global-var-2"
- project:
name: "test-project"
var1: !j2: |
{% include 'jinja-include03.yaml.inc' %}
jobs:
- "job-{globalvar1}"
- job-template:
name: "job-{globalvar1}"
description: |
{var1}
{globalvar1}
{globalvar2}

View File

@ -0,0 +1,3 @@
{%- import 'jinja-include03.j2.inc' as common with context -%}
{# make sure the variable "globalvar1" is available in a nested include #}
{{ globalvar1 }}