Add support for including files using the default template processor
The syntax is '{% include "file" %}' where file is either an absolute path or a path relative to the current template file's directory. Variables in the included file will be replaced as for the main template. But the included file can't include files itself.
This commit is contained in:
parent
48d77c9f21
commit
9bcf070dfe
3 changed files with 97 additions and 3 deletions
|
@ -88,6 +88,36 @@ Included section for distro = {LOCAL_DISTRO} ({LOCAL_DISTRO} again)
|
|||
end of template
|
||||
'''
|
||||
|
||||
INCLUDE_BASIC = 'basic\n'
|
||||
INCLUDE_VARIABLES = f'''\
|
||||
included <{{{{ yadm.class }}}}> file
|
||||
|
||||
empty line above
|
||||
'''
|
||||
INCLUDE_NESTED = 'no newline at the end'
|
||||
|
||||
TEMPLATE_INCLUDE = '''\
|
||||
The first line
|
||||
{% include empty %}
|
||||
An empty file removes the line above
|
||||
{%include basic%}
|
||||
{% include "./variables.{{ yadm.os }}" %}
|
||||
{% include dir/nested %}
|
||||
Include basic again:
|
||||
{% include basic %}
|
||||
'''
|
||||
EXPECTED_INCLUDE = f'''\
|
||||
The first line
|
||||
An empty file removes the line above
|
||||
basic
|
||||
included <{LOCAL_CLASS}> file
|
||||
|
||||
empty line above
|
||||
no newline at the end
|
||||
Include basic again:
|
||||
basic
|
||||
'''
|
||||
|
||||
|
||||
def test_template_default(runner, yadm, tmpdir):
|
||||
"""Test template_default"""
|
||||
|
@ -132,3 +162,37 @@ def test_source(runner, yadm, tmpdir):
|
|||
assert run.err == ''
|
||||
assert output_file.read().strip() == str(input_file)
|
||||
assert os.stat(output_file).st_mode == os.stat(input_file).st_mode
|
||||
|
||||
|
||||
def test_include(runner, yadm, tmpdir):
|
||||
"""Test include"""
|
||||
|
||||
empty_file = tmpdir.join('empty')
|
||||
empty_file.write('', ensure=True)
|
||||
|
||||
basic_file = tmpdir.join('basic')
|
||||
basic_file.write(INCLUDE_BASIC)
|
||||
|
||||
variables_file = tmpdir.join(f'variables.{LOCAL_SYSTEM}')
|
||||
variables_file.write(INCLUDE_VARIABLES)
|
||||
|
||||
nested_file = tmpdir.join('dir').join('nested')
|
||||
nested_file.write(INCLUDE_NESTED, ensure=True)
|
||||
|
||||
input_file = tmpdir.join('input')
|
||||
input_file.write(TEMPLATE_INCLUDE)
|
||||
input_file.chmod(FILE_MODE)
|
||||
output_file = tmpdir.join('output')
|
||||
|
||||
script = f"""
|
||||
YADM_TEST=1 source {yadm}
|
||||
set_awk
|
||||
local_class="{LOCAL_CLASS}"
|
||||
local_system="{LOCAL_SYSTEM}"
|
||||
template_default "{input_file}" "{output_file}"
|
||||
"""
|
||||
run = runner(command=['bash'], inp=script)
|
||||
assert run.success
|
||||
assert run.err == ''
|
||||
assert output_file.read() == EXPECTED_INCLUDE
|
||||
assert os.stat(output_file).st_mode == os.stat(input_file).st_mode
|
||||
|
|
28
yadm
28
yadm
|
@ -357,8 +357,13 @@ BEGIN {
|
|||
els = "^{%" blank "*else" blank "*%}$"
|
||||
end = "^{%" blank "*endif" blank "*%}$"
|
||||
skp = "^{%" blank "*(if|else|endif)"
|
||||
inc_start = "^{%" blank "*include" blank "+\"?"
|
||||
inc_end = "\"?" blank "*%}$"
|
||||
inc = inc_start ".+" inc_end
|
||||
prt = 1
|
||||
err = 0
|
||||
}
|
||||
END { exit err }
|
||||
{ replace_vars() } # variable replacements
|
||||
$0 ~ vld, $0 ~ end {
|
||||
if ($0 ~ vld || $0 ~ end) prt=1;
|
||||
|
@ -370,7 +375,25 @@ $0 ~ vld, $0 ~ end {
|
|||
if ($0 ~ els || $0 ~ end) prt=1;
|
||||
if ($0 ~ skp) next;
|
||||
}
|
||||
{ if (prt) print }
|
||||
{ if (!prt) next }
|
||||
$0 ~ inc {
|
||||
file = $0
|
||||
sub(inc_start, "", file)
|
||||
sub(inc_end, "", file)
|
||||
sub(/^[^\/].*$/, source_dir "/&", file)
|
||||
|
||||
while ((res = getline <file) > 0) {
|
||||
replace_vars()
|
||||
print
|
||||
}
|
||||
if (res < 0) {
|
||||
printf "%s:%d: error: could not read '%s'\n", FILENAME, NR, file | "cat 1>&2"
|
||||
err = 1
|
||||
}
|
||||
close(file)
|
||||
next
|
||||
}
|
||||
{ print }
|
||||
function replace_vars() {
|
||||
for (label in c) {
|
||||
gsub(("{{" blank "*yadm\\." label blank "*}}"), c[label])
|
||||
|
@ -396,8 +419,9 @@ EOF
|
|||
-v user="$local_user" \
|
||||
-v distro="$local_distro" \
|
||||
-v source="$input" \
|
||||
-v source_dir="$(dirname "$input")" \
|
||||
"$awk_pgm" \
|
||||
"$input" > "$temp_file"
|
||||
"$input" > "$temp_file" || rm -f "$temp_file"
|
||||
|
||||
if [ -f "$temp_file" ] ; then
|
||||
copy_perms "$input" "$temp_file"
|
||||
|
|
8
yadm.1
8
yadm.1
|
@ -708,6 +708,7 @@ with the following content
|
|||
config={{yadm.class}}-{{yadm.os}}
|
||||
{% else %}
|
||||
config=dev-whatever
|
||||
{% include "whatever.extra" %}
|
||||
{% endif %}
|
||||
|
||||
would output a file named
|
||||
|
@ -716,9 +717,12 @@ with the following content if the user is "harvey":
|
|||
|
||||
config=work-Linux
|
||||
|
||||
and the following otherwise:
|
||||
and the following otherwise (if
|
||||
.I whatever.extra
|
||||
contains admin=false):
|
||||
|
||||
config=dev-whatever
|
||||
admin=false
|
||||
|
||||
An equivalent Jinja template named
|
||||
.I whatever##template.j2
|
||||
|
@ -728,6 +732,7 @@ would look like:
|
|||
config={{YADM_CLASS}}-{{YADM_OS}}
|
||||
{% else -%}
|
||||
config=dev-whatever
|
||||
{% include 'whatever.extra' %}
|
||||
{% endif -%}
|
||||
|
||||
An equivalent ESH templated named
|
||||
|
@ -738,6 +743,7 @@ would look like:
|
|||
config=<%= $YADM_CLASS %>-<%= $YADM_OS %>
|
||||
<% else -%>
|
||||
config=dev-whatever
|
||||
<%+ whatever.extra %>
|
||||
<% fi -%>
|
||||
|
||||
.SH ENCRYPTION
|
||||
|
|
Loading…
Reference in a new issue