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