_mako_renderer.py
Go to the documentation of this file.
1 #!/usr/bin/env python3
2 # Copyright 2015 gRPC authors.
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
7 #
8 # http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15 """Simple Mako renderer.
16 
17 Just a wrapper around the mako rendering library.
18 """
19 
20 import getopt
21 import glob
22 import importlib.util
23 import os
24 import pickle
25 import shutil
26 import sys
27 from typing import List
28 
29 from mako import exceptions
30 from mako.lookup import TemplateLookup
31 from mako.runtime import Context
32 from mako.template import Template
33 import yaml
34 
35 PROJECT_ROOT = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..",
36  "..")
37 # TODO(lidiz) find a better way for plugins to reference each other
38 sys.path.append(os.path.join(PROJECT_ROOT, 'tools', 'buildgen', 'plugins'))
39 
40 
41 def out(msg: str) -> None:
42  print(msg, file=sys.stderr)
43 
44 
45 def showhelp() -> None:
46  out('mako-renderer.py [-o out] [-m cache] [-P preprocessed_input] [-d dict] [-d dict...]'
47  ' [-t template] [-w preprocessed_output]')
48 
49 
50 def render_template(template: Template, context: Context) -> None:
51  """Render the mako template with given context.
52 
53  Prints an error template to indicate where and what in the template caused
54  the render failure.
55  """
56  try:
57  template.render_context(context)
58  except:
59  out(exceptions.text_error_template().render())
60  raise
61 
62 
63 def main(argv: List[str]) -> None:
64  got_input = False
65  module_directory = None
66  preprocessed_output = None
67  dictionary = {}
68  json_dict = {}
69  got_output = False
70  output_name = None
71  got_preprocessed_input = False
72  output_merged = None
73 
74  try:
75  opts, args = getopt.getopt(argv, 'hM:m:o:t:P:')
76  except getopt.GetoptError:
77  out('Unknown option')
78  showhelp()
79  sys.exit(2)
80 
81  for opt, arg in opts:
82  if opt == '-h':
83  out('Displaying showhelp')
84  showhelp()
85  sys.exit()
86  elif opt == '-o':
87  if got_output:
88  out('Got more than one output')
89  showhelp()
90  sys.exit(3)
91  got_output = True
92  output_name = arg
93  elif opt == '-m':
94  if module_directory is not None:
95  out('Got more than one cache directory')
96  showhelp()
97  sys.exit(4)
98  module_directory = arg
99  elif opt == '-M':
100  if output_merged is not None:
101  out('Got more than one output merged path')
102  showhelp()
103  sys.exit(5)
104  output_merged = arg
105  elif opt == '-P':
106  assert not got_preprocessed_input
107  assert json_dict == {}
108  with open(arg, 'rb') as dict_file:
109  dictionary = pickle.load(dict_file)
110  got_preprocessed_input = True
111 
112  cleared_dir = False
113  for arg in args:
114  got_input = True
115  with open(arg) as f:
116  srcs = list(yaml.load_all(f.read(), Loader=yaml.FullLoader))
117  for src in srcs:
118  if isinstance(src, str):
119  assert len(srcs) == 1
120  template = Template(src,
121  filename=arg,
122  module_directory=module_directory,
123  lookup=TemplateLookup(directories=['.']))
124  with open(output_name, 'w') as output_file:
125  render_template(template, Context(output_file,
126  **dictionary))
127  else:
128  # we have optional control data: this template represents
129  # a directory
130  if not cleared_dir:
131  if not os.path.exists(output_name):
132  pass
133  elif os.path.isfile(output_name):
134  os.unlink(output_name)
135  else:
136  shutil.rmtree(output_name, ignore_errors=True)
137  cleared_dir = True
138  items = []
139  if 'foreach' in src:
140  for el in dictionary[src['foreach']]:
141  if 'cond' in src:
142  args = dict(dictionary)
143  args['selected'] = el
144  if not eval(src['cond'], {}, args):
145  continue
146  items.append(el)
147  assert items
148  else:
149  items = [None]
150  for item in items:
151  args = dict(dictionary)
152  args['selected'] = item
153  item_output_name = os.path.join(
154  output_name,
155  Template(src['output_name']).render(**args))
156  if not os.path.exists(os.path.dirname(item_output_name)):
157  os.makedirs(os.path.dirname(item_output_name))
158  template = Template(
159  src['template'],
160  filename=arg,
161  module_directory=module_directory,
162  lookup=TemplateLookup(directories=['.']))
163  with open(item_output_name, 'w') as output_file:
164  render_template(template, Context(output_file, **args))
165 
166  if not got_input and not preprocessed_output:
167  out('Got nothing to do')
168  showhelp()
169 
170 
171 if __name__ == '__main__':
172  main(sys.argv[1:])
_mako_renderer.main
None main(List[str] argv)
Definition: _mako_renderer.py:63
_mako_renderer.out
None out(str msg)
Definition: _mako_renderer.py:41
render
Definition: render.py:1
main
Definition: main.py:1
_mako_renderer.showhelp
None showhelp()
Definition: _mako_renderer.py:45
_mako_renderer.render_template
None render_template(Template template, Context context)
Definition: _mako_renderer.py:50
open
#define open
Definition: test-fs.c:46
len
int len
Definition: abseil-cpp/absl/base/internal/low_level_alloc_test.cc:46


grpc
Author(s):
autogenerated on Fri May 16 2025 02:57:38