Use Templar for galaxy skeletons (#69106)

* Use Templar for galaxy skeletons. Fixes #69104

* Update checksum, our templar doesn't remove trailing newline, jinja2 seems to remove it
This commit is contained in:
Matt Martz 2020-04-23 10:36:14 -05:00 committed by GitHub
parent 85bb804cda
commit f27c417fc4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 21 additions and 15 deletions

View file

@ -0,0 +1,4 @@
bugfixes:
- ansible-galaxy - Utilize ``Templar`` for templating skeleton files, so that
they have access to Ansible filters/tests/lookups
(https://github.com/ansible/ansible/issues/69104)

View file

@ -12,7 +12,6 @@ import textwrap
import time import time
import yaml import yaml
from jinja2 import BaseLoader, Environment, FileSystemLoader
from yaml.error import YAMLError from yaml.error import YAMLError
import ansible.constants as C import ansible.constants as C
@ -40,8 +39,10 @@ from ansible.module_utils.ansible_release import __version__ as ansible_version
from ansible.module_utils.common.collections import is_iterable from ansible.module_utils.common.collections import is_iterable
from ansible.module_utils._text import to_bytes, to_native, to_text from ansible.module_utils._text import to_bytes, to_native, to_text
from ansible.module_utils import six from ansible.module_utils import six
from ansible.parsing.dataloader import DataLoader
from ansible.parsing.yaml.loader import AnsibleLoader from ansible.parsing.yaml.loader import AnsibleLoader
from ansible.playbook.role.requirement import RoleRequirement from ansible.playbook.role.requirement import RoleRequirement
from ansible.template import Templar
from ansible.utils.display import Display from ansible.utils.display import Display
from ansible.utils.plugin_docs import get_versioned_doclink from ansible.utils.plugin_docs import get_versioned_doclink
@ -667,15 +668,11 @@ class GalaxyCLI(CLI):
return textwrap.fill(v, width=117, initial_indent="# ", subsequent_indent="# ", break_on_hyphens=False) return textwrap.fill(v, width=117, initial_indent="# ", subsequent_indent="# ", break_on_hyphens=False)
def to_yaml(v): loader = DataLoader()
return yaml.safe_dump(v, default_flow_style=False).rstrip() templar = Templar(loader, variables={'required_config': required_config, 'optional_config': optional_config})
templar.environment.filters['comment_ify'] = comment_ify
env = Environment(loader=BaseLoader) meta_value = templar.template(meta_template)
env.filters['comment_ify'] = comment_ify
env.filters['to_yaml'] = to_yaml
template = env.from_string(meta_template)
meta_value = template.render({'required_config': required_config, 'optional_config': optional_config})
return meta_value return meta_value
@ -790,6 +787,7 @@ class GalaxyCLI(CLI):
documentation_url='http://docs.example.com', documentation_url='http://docs.example.com',
homepage_url='http://example.com', homepage_url='http://example.com',
min_ansible_version=ansible_version[:3], # x.y min_ansible_version=ansible_version[:3], # x.y
dependencies=[],
)) ))
obj_path = os.path.join(init_path, obj_name) obj_path = os.path.join(init_path, obj_name)
@ -839,7 +837,8 @@ class GalaxyCLI(CLI):
to_native(obj_skeleton), galaxy_type) to_native(obj_skeleton), galaxy_type)
) )
template_env = Environment(loader=FileSystemLoader(obj_skeleton)) loader = DataLoader()
templar = Templar(loader, variables=inject_data)
# create role directory # create role directory
if not os.path.exists(b_obj_path): if not os.path.exists(b_obj_path):
@ -877,9 +876,12 @@ class GalaxyCLI(CLI):
with open(b_dest_file, 'wb') as galaxy_obj: with open(b_dest_file, 'wb') as galaxy_obj:
galaxy_obj.write(to_bytes(meta_value, errors='surrogate_or_strict')) galaxy_obj.write(to_bytes(meta_value, errors='surrogate_or_strict'))
elif ext == ".j2" and not in_templates_dir: elif ext == ".j2" and not in_templates_dir:
src_template = os.path.join(rel_root, f) src_template = os.path.join(root, f)
dest_file = os.path.join(obj_path, rel_root, filename) dest_file = os.path.join(obj_path, rel_root, filename)
template_env.get_template(src_template).stream(inject_data).dump(dest_file, encoding='utf-8') template_data = to_text(loader._get_file_contents(src_template)[0], errors='surrogate_or_strict')
b_rendered = to_bytes(templar.template(template_data), errors='surrogate_or_strict')
with open(dest_file, 'wb') as df:
df.write(b_rendered)
else: else:
f_rel_path = os.path.relpath(os.path.join(root, f), obj_skeleton) f_rel_path = os.path.relpath(os.path.join(root, f), obj_skeleton)
shutil.copyfile(os.path.join(root, f), os.path.join(obj_path, f_rel_path)) shutil.copyfile(os.path.join(root, f), os.path.join(obj_path, f_rel_path))

View file

@ -1,11 +1,11 @@
### REQUIRED ### REQUIRED
{% for option in required_config %} {% for option in required_config %}
{{ option.description | comment_ify }} {{ option.description | comment_ify }}
{{ {option.key: option.value} | to_yaml }} {{ {option.key: option.value} | to_nice_yaml }}
{% endfor %} {% endfor %}
### OPTIONAL but strongly recommended ### OPTIONAL but strongly recommended
{% for option in optional_config %} {% for option in optional_config %}
{{ option.description | comment_ify }} {{ option.description | comment_ify }}
{{ {option.key: option.value} | to_yaml }} {{ {option.key: option.value} | to_nice_yaml }}
{% endfor %} {% endfor %}

View file

@ -728,7 +728,7 @@ def test_collection_build(collection_artifact):
elif file_entry['name'] == 'README.md': elif file_entry['name'] == 'README.md':
assert file_entry['ftype'] == 'file' assert file_entry['ftype'] == 'file'
assert file_entry['chksum_type'] == 'sha256' assert file_entry['chksum_type'] == 'sha256'
assert file_entry['chksum_sha256'] == '45923ca2ece0e8ce31d29e5df9d8b649fe55e2f5b5b61c9724d7cc187bd6ad4a' assert file_entry['chksum_sha256'] == '6d8b5f9b5d53d346a8cd7638a0ec26e75e8d9773d952162779a49d25da6ef4f5'
else: else:
assert file_entry['ftype'] == 'dir' assert file_entry['ftype'] == 'dir'
assert file_entry['chksum_type'] is None assert file_entry['chksum_type'] is None