From f27c417fc4eb39f993a0dcf950bce88e5ab0b0ef Mon Sep 17 00:00:00 2001 From: Matt Martz Date: Thu, 23 Apr 2020 10:36:14 -0500 Subject: [PATCH] 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 --- .../fragments/69104-galaxy-cli-templar.yml | 4 +++ lib/ansible/cli/galaxy.py | 26 ++++++++++--------- .../data/default/collection/galaxy.yml.j2 | 4 +-- test/units/cli/test_galaxy.py | 2 +- 4 files changed, 21 insertions(+), 15 deletions(-) create mode 100644 changelogs/fragments/69104-galaxy-cli-templar.yml diff --git a/changelogs/fragments/69104-galaxy-cli-templar.yml b/changelogs/fragments/69104-galaxy-cli-templar.yml new file mode 100644 index 00000000000..c3c05f67439 --- /dev/null +++ b/changelogs/fragments/69104-galaxy-cli-templar.yml @@ -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) diff --git a/lib/ansible/cli/galaxy.py b/lib/ansible/cli/galaxy.py index 58c911bd827..0aef3665f53 100644 --- a/lib/ansible/cli/galaxy.py +++ b/lib/ansible/cli/galaxy.py @@ -12,7 +12,6 @@ import textwrap import time import yaml -from jinja2 import BaseLoader, Environment, FileSystemLoader from yaml.error import YAMLError 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._text import to_bytes, to_native, to_text from ansible.module_utils import six +from ansible.parsing.dataloader import DataLoader from ansible.parsing.yaml.loader import AnsibleLoader from ansible.playbook.role.requirement import RoleRequirement +from ansible.template import Templar from ansible.utils.display import Display 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) - def to_yaml(v): - return yaml.safe_dump(v, default_flow_style=False).rstrip() + loader = DataLoader() + templar = Templar(loader, variables={'required_config': required_config, 'optional_config': optional_config}) + templar.environment.filters['comment_ify'] = comment_ify - env = Environment(loader=BaseLoader) - 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}) + meta_value = templar.template(meta_template) return meta_value @@ -790,6 +787,7 @@ class GalaxyCLI(CLI): documentation_url='http://docs.example.com', homepage_url='http://example.com', min_ansible_version=ansible_version[:3], # x.y + dependencies=[], )) obj_path = os.path.join(init_path, obj_name) @@ -839,7 +837,8 @@ class GalaxyCLI(CLI): to_native(obj_skeleton), galaxy_type) ) - template_env = Environment(loader=FileSystemLoader(obj_skeleton)) + loader = DataLoader() + templar = Templar(loader, variables=inject_data) # create role directory if not os.path.exists(b_obj_path): @@ -877,9 +876,12 @@ class GalaxyCLI(CLI): with open(b_dest_file, 'wb') as galaxy_obj: galaxy_obj.write(to_bytes(meta_value, errors='surrogate_or_strict')) 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) - 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: 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)) diff --git a/lib/ansible/galaxy/data/default/collection/galaxy.yml.j2 b/lib/ansible/galaxy/data/default/collection/galaxy.yml.j2 index a1c46391b3b..a95008fcdf8 100644 --- a/lib/ansible/galaxy/data/default/collection/galaxy.yml.j2 +++ b/lib/ansible/galaxy/data/default/collection/galaxy.yml.j2 @@ -1,11 +1,11 @@ ### REQUIRED {% for option in required_config %} {{ option.description | comment_ify }} -{{ {option.key: option.value} | to_yaml }} +{{ {option.key: option.value} | to_nice_yaml }} {% endfor %} ### OPTIONAL but strongly recommended {% for option in optional_config %} {{ option.description | comment_ify }} -{{ {option.key: option.value} | to_yaml }} +{{ {option.key: option.value} | to_nice_yaml }} {% endfor %} diff --git a/test/units/cli/test_galaxy.py b/test/units/cli/test_galaxy.py index 67d1c03f3c0..f8618466ec6 100644 --- a/test/units/cli/test_galaxy.py +++ b/test/units/cli/test_galaxy.py @@ -728,7 +728,7 @@ def test_collection_build(collection_artifact): elif file_entry['name'] == 'README.md': assert file_entry['ftype'] == 'file' assert file_entry['chksum_type'] == 'sha256' - assert file_entry['chksum_sha256'] == '45923ca2ece0e8ce31d29e5df9d8b649fe55e2f5b5b61c9724d7cc187bd6ad4a' + assert file_entry['chksum_sha256'] == '6d8b5f9b5d53d346a8cd7638a0ec26e75e8d9773d952162779a49d25da6ef4f5' else: assert file_entry['ftype'] == 'dir' assert file_entry['chksum_type'] is None