OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # | 2 # |
3 # Copyright 2014 The Chromium Authors. All rights reserved. | 3 # Copyright 2014 The Chromium Authors. All rights reserved. |
4 # Use of this source code is governed by a BSD-style license that can be | 4 # Use of this source code is governed by a BSD-style license that can be |
5 # found in the LICENSE file. | 5 # found in the LICENSE file. |
6 | 6 |
7 """Renders one or more template files using the Jinja template engine.""" | 7 """Renders one or more template files using the Jinja template engine.""" |
8 | 8 |
9 import codecs | 9 import codecs |
10 import optparse | 10 import optparse |
11 import os | 11 import os |
12 import sys | 12 import sys |
13 | 13 |
14 from util import build_utils | 14 from util import build_utils |
15 | 15 |
16 # Import jinja2 from third_party/jinja2 | 16 # Import jinja2 from third_party/jinja2 |
17 sys.path.append(os.path.join(os.path.dirname(__file__), '../../../third_party')) | 17 sys.path.append(os.path.join(os.path.dirname(__file__), '../../../third_party')) |
18 import jinja2 # pylint: disable=F0401 | 18 import jinja2 # pylint: disable=F0401 |
19 | 19 |
20 | 20 |
21 def ProcessFile(input_filename, output_filename, variables): | 21 class RecordingFileSystemLoader(jinja2.FileSystemLoader): |
22 with codecs.open(input_filename, 'r', 'utf-8') as input_file: | 22 '''A FileSystemLoader that stores a list of loaded templates.''' |
23 input_ = input_file.read() | 23 def __init__(self, searchpath): |
24 env = jinja2.Environment(undefined=jinja2.StrictUndefined) | 24 jinja2.FileSystemLoader.__init__(self, searchpath) |
25 template = env.from_string(input_) | 25 self.loaded_templates = set() |
26 template.filename = os.path.abspath(input_filename) | 26 |
| 27 def get_source(self, environment, template): |
| 28 contents, filename, uptodate = jinja2.FileSystemLoader.get_source( |
| 29 self, environment, template) |
| 30 self.loaded_templates.add(os.path.relpath(filename)) |
| 31 return contents, filename, uptodate |
| 32 |
| 33 def get_loaded_templates(self): |
| 34 return list(self.loaded_templates) |
| 35 |
| 36 |
| 37 def ProcessFile(env, input_filename, output_filename, variables): |
| 38 input_rel_path = os.path.relpath(input_filename, build_utils.CHROMIUM_SRC) |
| 39 template = env.get_template(input_rel_path) |
27 output = template.render(variables) | 40 output = template.render(variables) |
28 with codecs.open(output_filename, 'w', 'utf-8') as output_file: | 41 with codecs.open(output_filename, 'w', 'utf-8') as output_file: |
29 output_file.write(output) | 42 output_file.write(output) |
30 | 43 |
31 | 44 |
32 def ProcessFiles(input_filenames, inputs_base_dir, outputs_zip, variables): | 45 def ProcessFiles(env, input_filenames, inputs_base_dir, outputs_zip, variables): |
33 with build_utils.TempDir() as temp_dir: | 46 with build_utils.TempDir() as temp_dir: |
34 for input_filename in input_filenames: | 47 for input_filename in input_filenames: |
35 relpath = os.path.relpath(os.path.abspath(input_filename), | 48 relpath = os.path.relpath(os.path.abspath(input_filename), |
36 os.path.abspath(inputs_base_dir)) | 49 os.path.abspath(inputs_base_dir)) |
37 if relpath.startswith(os.pardir): | 50 if relpath.startswith(os.pardir): |
38 raise Exception('input file %s is not contained in inputs base dir %s' | 51 raise Exception('input file %s is not contained in inputs base dir %s' |
39 % input_filename, inputs_base_dir) | 52 % input_filename, inputs_base_dir) |
40 | 53 |
41 output_filename = os.path.join(temp_dir, relpath) | 54 output_filename = os.path.join(temp_dir, relpath) |
42 parent_dir = os.path.dirname(output_filename) | 55 parent_dir = os.path.dirname(output_filename) |
43 build_utils.MakeDirectory(parent_dir) | 56 build_utils.MakeDirectory(parent_dir) |
44 ProcessFile(input_filename, output_filename, variables) | 57 ProcessFile(env, input_filename, output_filename, variables) |
45 | 58 |
46 build_utils.ZipDir(outputs_zip, temp_dir) | 59 build_utils.ZipDir(outputs_zip, temp_dir) |
47 | 60 |
48 | 61 |
49 def main(): | 62 def main(): |
50 parser = optparse.OptionParser() | 63 parser = optparse.OptionParser() |
51 build_utils.AddDepfileOption(parser) | 64 build_utils.AddDepfileOption(parser) |
52 parser.add_option('--inputs', help='The template files to process.') | 65 parser.add_option('--inputs', help='The template files to process.') |
53 parser.add_option('--output', help='The output file to generate. Valid ' | 66 parser.add_option('--output', help='The output file to generate. Valid ' |
54 'only if there is a single input.') | 67 'only if there is a single input.') |
(...skipping 20 matching lines...) Expand all Loading... |
75 if args: | 88 if args: |
76 parser.error('No positional arguments should be given.') | 89 parser.error('No positional arguments should be given.') |
77 | 90 |
78 variables = {} | 91 variables = {} |
79 for v in build_utils.ParseGypList(options.variables): | 92 for v in build_utils.ParseGypList(options.variables): |
80 if '=' not in v: | 93 if '=' not in v: |
81 parser.error('--variables argument must contain "=": ' + v) | 94 parser.error('--variables argument must contain "=": ' + v) |
82 name, _, value = v.partition('=') | 95 name, _, value = v.partition('=') |
83 variables[name] = value | 96 variables[name] = value |
84 | 97 |
| 98 loader = RecordingFileSystemLoader(build_utils.CHROMIUM_SRC) |
| 99 env = jinja2.Environment(loader=loader, undefined=jinja2.StrictUndefined, |
| 100 line_comment_prefix='##') |
85 if options.output: | 101 if options.output: |
86 ProcessFile(inputs[0], options.output, variables) | 102 ProcessFile(env, inputs[0], options.output, variables) |
87 else: | 103 else: |
88 ProcessFiles(inputs, options.inputs_base_dir, options.outputs_zip, | 104 ProcessFiles(env, inputs, options.inputs_base_dir, options.outputs_zip, |
89 variables) | 105 variables) |
90 | 106 |
91 if options.depfile: | 107 if options.depfile: |
92 deps = inputs + build_utils.GetPythonDependencies() | 108 deps = loader.get_loaded_templates() + build_utils.GetPythonDependencies() |
93 build_utils.WriteDepfile(options.depfile, deps) | 109 build_utils.WriteDepfile(options.depfile, deps) |
94 | 110 |
95 | 111 |
96 if __name__ == '__main__': | 112 if __name__ == '__main__': |
97 main() | 113 main() |
OLD | NEW |