xref: /aosp_15_r20/external/google-cloud-java/owl-bot-postprocessor/synthtool/sources/templates.py (revision 55e87721aa1bc457b326496a7ca40f3ea1a63287)
1# Copyright 2018 Google LLC
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#     https://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15from typing import Union, List
16from pathlib import Path
17
18import jinja2
19import re
20
21from synthtool import log
22from synthtool import tmp
23
24
25PathOrStr = Union[str, Path]
26
27
28def _make_env(location):
29    env = jinja2.Environment(
30        loader=jinja2.FileSystemLoader(str(location)),
31        autoescape=False,
32        keep_trailing_newline=True,
33    )
34    env.filters["release_quality_badge"] = release_quality_badge
35    env.filters["language_pretty"] = language_pretty
36    env.filters["slugify"] = slugify
37    env.filters["syntax_highlighter"] = syntax_highlighter
38    return env
39
40
41def _render_to_path(env, template_name, dest, params):
42    template = env.get_template(template_name)
43
44    output = template.stream(**params)
45
46    if template_name.endswith(".j2"):
47        template_name = template.name[:-3]
48
49    dest = dest / template_name
50    dest.parent.mkdir(parents=True, exist_ok=True)
51
52    with dest.open("w") as fh:
53        output.dump(fh)
54
55    # Copy file mode over
56    source_path = Path(template.filename)
57    mode = source_path.stat().st_mode
58    dest.chmod(mode)
59
60    return dest
61
62
63class Templates:
64    def __init__(self, location: PathOrStr) -> None:
65        self.env = _make_env(location)
66        self.source_path = Path(location)
67        self.dir = tmp.tmpdir()
68
69    def render(self, template_name: str, subdir: PathOrStr = ".", **kwargs) -> Path:
70        return _render_to_path(self.env, template_name, self.dir / subdir, kwargs)
71
72
73class TemplateGroup:
74    def __init__(self, location: PathOrStr, excludes: List[str] = []) -> None:
75        self.env = _make_env(location)
76        self.dir = tmp.tmpdir()
77        self.excludes = excludes
78
79    def render(self, subdir: PathOrStr = ".", **kwargs) -> Path:
80        for template_name in self.env.list_templates():
81            if template_name not in self.excludes:
82                print(template_name)
83                _render_to_path(self.env, template_name, self.dir / subdir, kwargs)
84            else:
85                print(f"Skipping: {template_name}")
86
87        return self.dir
88
89
90def release_quality_badge(input: str) -> str:
91    """Generates a markdown badge for displaying a "Release Quality'."""
92    if not input:
93        log.error("ensure you pass a string 'quality' to release_quality_badge")
94        return ""
95
96    release_quality = input.upper()
97    badge = ""
98
99    if release_quality == "GA":
100        badge = "general%20availability%20%28GA%29-brightgreen"
101    elif release_quality == "STABLE":
102        badge = "stable-brightgreen"
103    elif release_quality == "PREVIEW":
104        badge = "preview-yellow"
105    elif release_quality == "BETA":
106        badge = "beta-yellow"
107    elif release_quality == "ALPHA":
108        badge = "alpha-orange"
109    elif release_quality == "EAP":
110        badge = "EAP-yellow"
111    elif release_quality == "DEPRECATED":
112        badge = "deprecated-red"
113    else:
114        log.error(
115            "Expected 'release_quality' to be one of: (ga, stable, preview, beta, alpha, eap, deprecated)"
116        )
117        return ""
118    return f"[![release level](https://img.shields.io/badge/release%20level-{badge}.svg?style=flat)](https://cloud.google.com/terms/launch-stages)"
119
120
121def language_pretty(input: str) -> str:
122    """.repo-metadata.json language field to pretty language."""
123    if input == "nodejs":
124        return "Node.js"
125    return input
126
127
128def slugify(input: str) -> str:
129    """Converts Foo Bar into foo-bar, for use wih anchor links."""
130    input = re.sub(r"([() ]+)", "-", input.lower())
131    return re.sub(r"-$", "", input)
132
133
134def syntax_highlighter(input: str) -> str:
135    """.repo-metadata.json language field to syntax highlighter name."""
136    if input == "nodejs":
137        return "javascript"
138    return input
139