From dc864a07cff6fda7ac5a7b7333c6dc993e91c83b Mon Sep 17 00:00:00 2001 From: Owen W. Taylor Date: Mar 16 2018 21:29:00 +0000 Subject: Use a Jinja2 template to format the output Instead of depending on modulemd functionality, format the output using a Jinja2 template. While this is somewhat more cumbersome, it allows for ordering and indenting the output as we want, and will allow comments to be added in the future. See: https://pagure.io/modularity/fedmod/issue/8 --- diff --git a/src/MANIFEST.in b/src/MANIFEST.in index b52089f..c4bf916 100644 --- a/src/MANIFEST.in +++ b/src/MANIFEST.in @@ -3,3 +3,4 @@ include README.md include LICENSE include modtools recursive-include modularity * +include _fedmod/templates/*.j2 diff --git a/src/_fedmod/module_generator.py b/src/_fedmod/module_generator.py index ee03dcc..ec54758 100644 --- a/src/_fedmod/module_generator.py +++ b/src/_fedmod/module_generator.py @@ -1,5 +1,8 @@ +import jinja2 import sys import modulemd +import pkg_resources +import yaml import logging from . import _depchase, _repodata @@ -18,12 +21,21 @@ def _categorise_deps(all_rpm_deps, *, allow_bootstrap=False): remaining_rpm_deps.add(pkgname) return module_deps, remaining_rpm_deps +def sortitems_filter(items): + return sorted(items, key=lambda item: item[0]) + +def key_filter(obj): + return yaml.dump({obj: 'x'}, default_flow_style=False).strip()[:-3] +def value_filter(obj): + return yaml.dump({'x': obj}, default_flow_style=False).strip()[3:] + class ModuleGenerator(object): def __init__(self, pkgs): self.pkgs = pkgs self.core_srpm = None self.mmd = modulemd.ModuleMetadata() + self.template = 'module.yaml.j2' self._pool = _depchase.make_pool("x86_64") def _calculate_dependencies(self, build_deps_iterations): @@ -74,11 +86,19 @@ class ModuleGenerator(object): Function writes modulemd to either stdout or the given filename :return: """ + + env = jinja2.Environment(loader=jinja2.PackageLoader('_fedmod', 'templates'), + autoescape=False) + env.filters['sortitems'] = sortitems_filter + env.filters['key'] = key_filter + env.filters['value'] = value_filter + template = env.get_template('module.yaml.j2') + if output_fname is not None: - self.mmd.dump(output_fname) + template.stream(mmd=self.mmd).dump(output_fname) print('Generated modulemd file: %r' % output_fname) else: - print(self.mmd.dumps()) + print(template.render(mmd=self.mmd)) return True def _update_module_md(self): diff --git a/src/_fedmod/templates/module.yaml.j2 b/src/_fedmod/templates/module.yaml.j2 new file mode 100644 index 0000000..f2ccfd7 --- /dev/null +++ b/src/_fedmod/templates/module.yaml.j2 @@ -0,0 +1,48 @@ +document: modulemd +version: 1 +data: + summary: {{ mmd.summary|value }} + description:> + {{ mmd.description|indent(8) }} + license: + module: + - MIT + {%- if mmd.profiles %} + profiles: + {%- for name, profile in mmd.profiles.items() %} + {{ name|key }}: + rpms: + {%- for name in profile.rpms %} + - {{ name|value }} + {%- endfor %} + {%- endfor %} + {%- endif %} + api: + rpms: + {%- for name in mmd.api.rpms %} + - {{ name|value }} + {%- endfor %} + {%- if mmd.buildrequires or mmd.requires %} + dependencies: + {%- if mmd.buildrequires %} + buildrequires: + {%- for module, stream in mmd.buildrequires.items()|sortitems %} + {{ module|key }}: {{ stream|value }} + {%- endfor %} + {%- endif %} + {%- if mmd.requires %} + requires: + {%- for module, stream in mmd.requires.items()|sortitems %} + {{ module|key }}: {{ stream|value }} + {%- endfor %} + {%- endif %} + {%- endif %} + components: + rpms: + {%- for name, rpm in mmd.components.rpms.items()|sortitems %} + {{ name|key }}: + {%- if rpm.buildorder %} + buildorder: {{ rpm.buildorder|value }} + {%- endif %} + rationale: {{ rpm.rationale|value }} + {%- endfor -%} diff --git a/src/setup.py b/src/setup.py index dc22804..1cff183 100644 --- a/src/setup.py +++ b/src/setup.py @@ -26,6 +26,7 @@ setup( install_requires=[ 'modulemd', 'click', + 'jinja2', 'requests', 'requests-toolbelt', 'lxml', @@ -33,4 +34,5 @@ setup( 'PyYAML', ], packages=find_packages(), + include_package_data=True, )