1# Copyright 2020 The Chromium Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5import argparse 6import errno 7import io 8import json 9import os 10import sys 11 12import grit.format.html_inline 13import grit.node.base 14import grit.util 15 16_CWD = os.getcwd() 17 18 19class PreprocessNode(grit.node.base.Node): 20 def __init__(self): 21 super(PreprocessNode, self).__init__() 22 23 def ProcessFile(self, filepath): 24 return grit.format.html_inline.InlineToString( 25 filepath, 26 self, 27 preprocess_only=True, 28 allow_external_script=False, 29 strip_whitespace=False, 30 rewrite_function=None, 31 filename_expansion_function=None) 32 33 def EvaluateCondition(self, expr): 34 return grit.node.base.Node.EvaluateExpression(expr, self.defines, 35 self.target_platform, {}) 36 37 def SetDefines(self, defines): 38 self.defines = defines 39 40 def SetTargetPlatform(self, target_platform): 41 self.target_platform = target_platform 42 43 @staticmethod 44 def Construct(defines, target_platform): 45 node = PreprocessNode() 46 node.SetDefines(defines) 47 node.SetTargetPlatform(target_platform or sys.platform) 48 return node 49 50 51def main(argv): 52 parser = argparse.ArgumentParser() 53 parser.add_argument('--in-folder', required=True) 54 parser.add_argument('--out-folder', required=True) 55 parser.add_argument('--out-manifest') 56 parser.add_argument('--in-files', required=True, nargs="*") 57 parser.add_argument('-D', '--defines', nargs="*", action='append') 58 parser.add_argument('-E', '--environment') 59 parser.add_argument('-t', '--target') 60 args = parser.parse_args(argv) 61 62 in_folder = os.path.normpath(os.path.join(_CWD, args.in_folder)) 63 out_folder = os.path.normpath(os.path.join(_CWD, args.out_folder)) 64 65 defines = {} 66 for define_arg in args.defines: 67 define, = define_arg 68 name, val = grit.util.ParseDefine(define) 69 defines[name] = val 70 71 node = PreprocessNode.Construct(defines, args.target) 72 73 for input_file in args.in_files: 74 output = node.ProcessFile(os.path.join(in_folder, input_file)) 75 76 out_path = os.path.join(out_folder, input_file) 77 out_dir = os.path.dirname(out_path) 78 assert out_dir.startswith(out_folder), \ 79 'Cannot preprocess files to locations not under %s.' % out_dir 80 try: 81 os.makedirs(out_dir) 82 except OSError as e: 83 # Ignore directory exists errors. This can happen if two build rules 84 # for overlapping directories hit the makedirs line at the same time. 85 if e.errno != errno.EEXIST: 86 raise 87 with io.open(out_path, mode='wb') as f: 88 f.write(output.encode('utf-8')) 89 90 if args.out_manifest: 91 manifest_data = {} 92 manifest_data['base_dir'] = '%s' % args.out_folder 93 manifest_data['files'] = args.in_files 94 manifest_file = open( 95 os.path.normpath(os.path.join(_CWD, args.out_manifest)), 'wb') 96 json.dump(manifest_data, manifest_file) 97 return 98 99 100if __name__ == '__main__': 101 main(sys.argv[1:]) 102