File: resolver.py

package info (click to toggle)
python-changelogd 0.1.9-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 448 kB
  • sloc: python: 1,921; makefile: 21
file content (83 lines) | stat: -rw-r--r-- 2,851 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
import os
import sys
import typing
from pathlib import Path

import jinja2

from .config import Config


class Resolver:
    """Class responsible for resolving templates"""

    def __init__(self, config: Config):
        self._config: Config = config
        self._templates_dir: Path = config.path / "templates"

    def full_resolve(self, releases: typing.List[typing.Dict]) -> str:
        env = jinja2.Environment(
            loader=jinja2.FileSystemLoader(self._templates_dir.as_posix()),
        )

        templates = self._get_template_file_names(
            self._templates_dir, ("entry", "main", "release"), env
        )

        message_types = self._config.get_value("message_types", [])
        resolved_releases = [
            self._resolve_release(message_types, release, templates)
            for release in releases
        ]

        template = templates["main"]
        return template.render(**self._config.get_context(), releases=resolved_releases)

    def _resolve_release(
        self,
        message_types: typing.List[typing.Dict],
        release: typing.Dict,
        templates: typing.Dict[str, jinja2.Template],
    ) -> str:
        groups = {}
        for group_name, group in release.pop("entries", {}).items():
            groups[group_name] = [
                self._resolve_entry(entry, templates["entry"]) for entry in group
            ]

            release["entry_groups"] = []
            for message_type in message_types:
                name = message_type.get("name")

                if name in groups or message_type.get("include_empty"):
                    release["entry_groups"].append(
                        {**message_type, "entries": groups.get(name, [])}
                    )

        template = templates["release"]
        return template.render(**self._config.get_context(), **release)

    def _get_template_file_names(
        self,
        templates_dir: Path,
        templates: typing.Tuple[str, ...],
        env: jinja2.Environment,
    ) -> typing.Dict[str, jinja2.Template]:
        template_files = os.listdir(templates_dir.as_posix())
        try:
            return {
                entry: env.get_template(
                    next(
                        (item for item in template_files if item.startswith(entry)),
                        entry,
                    )
                )
                for entry in templates
            }
        except jinja2.exceptions.TemplateSyntaxError as exc:
            sys.exit(f"Syntax error in template '{exc.filename}':\n\t{exc.message}")
        except jinja2.exceptions.TemplateNotFound as exc:
            sys.exit(f"Template file for '{exc.name}' not found.")

    def _resolve_entry(self, entry: typing.Dict, template: jinja2.Template) -> str:
        return template.render(**self._config.get_context(), **entry)