From ecedbf67ac8c00a10cb71f3976ca8ae4c4061590 Mon Sep 17 00:00:00 2001 From: Alexander Block Date: Fri, 1 Mar 2024 16:23:28 +0100 Subject: [PATCH 1/2] fix: Also take local vars into account when using render or get_var --- python_src/go_jinja2/ext/kluctl_ext.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/python_src/go_jinja2/ext/kluctl_ext.py b/python_src/go_jinja2/ext/kluctl_ext.py index ccf0816..310fc2b 100644 --- a/python_src/go_jinja2/ext/kluctl_ext.py +++ b/python_src/go_jinja2/ext/kluctl_ext.py @@ -42,7 +42,7 @@ def from_yaml(s): @jinja2.pass_context def render(ctx, string): t = ctx.environment.from_string(string) - return t.render(ctx.parent) + return t.render(ctx.get_all()) def sha256(s, digest_len=None): @@ -63,7 +63,7 @@ def slugify(s, allow_unicode=False): def load_template(ctx, path, **kwargs): ctx.environment.print_debug("load_template(%s)" % path) t = ctx.environment.get_template(path.replace(os.path.sep, '/'), parent=ctx.name) - vars = merge_dict(ctx.parent, kwargs) + vars = merge_dict(ctx.get_all(), kwargs) return t.render(vars) @@ -75,8 +75,10 @@ class VarNotFoundException(Exception): def get_var(ctx, path, default=None): if not isinstance(path, list): path = [path] + + all_vars = ctx.get_all() for p in path: - r = get_dict_value(ctx.parent, p, VarNotFoundException()) + r = get_dict_value(all_vars, p, VarNotFoundException()) if isinstance(r, VarNotFoundException): continue return r From 3c2dea47dc40be414ae15b58b804e5d55fe73dd7 Mon Sep 17 00:00:00 2001 From: Alexander Block Date: Fri, 1 Mar 2024 16:23:39 +0100 Subject: [PATCH 2/2] tests: Add tests for get_var and render --- jinja2_ext_test.go | 48 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/jinja2_ext_test.go b/jinja2_ext_test.go index 3c1891f..9d76ae1 100644 --- a/jinja2_ext_test.go +++ b/jinja2_ext_test.go @@ -43,3 +43,51 @@ func TestSha256PrefixLength(t *testing.T) { assert.NoError(t, err) assert.Equal(t, "9f86d0", s) } + +func TestGetVarAndRender(t *testing.T) { + j2 := newJinja2(t, WithGlobals(map[string]any{ + "g1": "v1", + "g2": "v2", + "g3": map[string]any{ + "nested": "v3", + }, + "list": []map[string]any{ + {"x": "i1"}, + {"x": "i2"}, + }, + })) + + type testCase struct { + tmpl string + result string + } + + tests := []testCase{ + {tmpl: "{{ get_var('missing') }}", result: "None"}, + {tmpl: "{{ get_var('missing', 'default') }}", result: "default"}, + {tmpl: "{{ get_var(['missing']) }}", result: "None"}, + {tmpl: "{{ get_var(['missing'], 'default') }}", result: "default"}, + {tmpl: "{{ get_var(['missing1', 'missing2'], 'default') }}", result: "default"}, + {tmpl: "{{ get_var(['g1', 'missing']) }}", result: "v1"}, + {tmpl: "{{ get_var(['missing', 'g1']) }}", result: "v1"}, + {tmpl: "{{ get_var(['g1', 'g2']) }}", result: "v1"}, + {tmpl: "{{ get_var(['g2', 'g1']) }}", result: "v2"}, + {tmpl: "{{ get_var('list') }}", result: `[{'x': 'i1'}, {'x': 'i2'}]`}, + {tmpl: "{{ get_var('list[0].x') }}", result: "i1"}, + {tmpl: "{% set loc = 'l1' %}{{ get_var('loc') }}", result: "l1"}, + // TODO test for this when https://github.com/pallets/jinja/issues/1478 gets fixed + // {tmpl: "{% for e in list %}{{ get_var('e.x') }}{% endfor %}", result: ""}, + {tmpl: "{% set loc = 'l1' %}{{ '{{ loc }}' | render }}", result: "l1"}, + // TODO test for this when https://github.com/pallets/jinja/issues/1478 gets fixed + // {tmpl: "{% for e in list %}{{ '{{ e }}' | render }}{% endfor %}", result: ""}, + } + + for i, tc := range tests { + tc := tc + t.Run(fmt.Sprintf("%d", i), func(t *testing.T) { + s, err := j2.RenderString(tc.tmpl) + assert.NoError(t, err) + assert.Equal(t, tc.result, s) + }) + } +}