mirror of
https://github.com/klzgrad/naiveproxy.git
synced 2024-11-24 06:16:30 +03:00
154 lines
5.0 KiB
Python
154 lines
5.0 KiB
Python
# Copyright 2020 The Chromium Authors
|
|
# Use of this source code is governed by a BSD-style license that can be
|
|
# found in the LICENSE file.
|
|
|
|
import argparse
|
|
import errno
|
|
import io
|
|
import json
|
|
import os
|
|
import sys
|
|
|
|
# For Node, EvaluateExpression
|
|
import grit.node.base
|
|
# For CheckConditionalElements
|
|
import grit.format.html_inline
|
|
|
|
_CWD = os.getcwd()
|
|
|
|
|
|
class PreprocessIfExprNode(grit.node.base.Node):
|
|
def __init__(self):
|
|
super().__init__()
|
|
|
|
def PreprocessIfExpr(self, content, removal_comments_extension):
|
|
return grit.format.html_inline.CheckConditionalElements(
|
|
self, content, removal_comments_extension)
|
|
|
|
def EvaluateCondition(self, expr):
|
|
return grit.node.base.Node.EvaluateExpression(expr, self.defines,
|
|
self.target_platform, {})
|
|
|
|
def SetDefines(self, defines):
|
|
self.defines = defines
|
|
|
|
def SetTargetPlatform(self, target_platform):
|
|
self.target_platform = target_platform
|
|
|
|
@staticmethod
|
|
def Construct(defines, target_platform):
|
|
node = PreprocessIfExprNode()
|
|
node.SetDefines(defines)
|
|
node.SetTargetPlatform(target_platform or sys.platform)
|
|
return node
|
|
|
|
|
|
def ParseDefinesArg(definesArg):
|
|
defines = {}
|
|
for define in definesArg:
|
|
parts = [part.strip() for part in define.split('=', 1)]
|
|
name = parts[0]
|
|
val = True if len(parts) == 1 else parts[1]
|
|
if (val == "1" or val == "true"):
|
|
val = True
|
|
elif (val == "0" or val == "false"):
|
|
val = False
|
|
defines[name] = val
|
|
return defines
|
|
|
|
|
|
def ExtensionForComments(input_file):
|
|
"""Get the file extension that determines the comment style.
|
|
|
|
Returns the file extension that determines the format of the
|
|
'grit-removed-lines' comments. '.ts' or '.js' will produce '/*...*/'-style
|
|
comments, '.html; will produce '<!-- -->'-style comments.
|
|
"""
|
|
split = os.path.splitext(input_file)
|
|
extension = split[1]
|
|
# .html.ts and .html.js files should still use HTML comments.
|
|
if os.path.splitext(split[0])[1] == '.html':
|
|
extension = '.html'
|
|
return extension
|
|
|
|
|
|
def main(argv):
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument('--in-folder', required=True)
|
|
parser.add_argument('--out-folder', required=True)
|
|
parser.add_argument('--out-manifest')
|
|
parser.add_argument('--in-files', required=True, nargs="*")
|
|
parser.add_argument('-D', '--defines', action='append')
|
|
parser.add_argument('-E', '--environment')
|
|
parser.add_argument('-t', '--target')
|
|
parser.add_argument('--enable_removal_comments', action='store_true')
|
|
args = parser.parse_args(argv)
|
|
|
|
in_folder = os.path.normpath(os.path.join(_CWD, args.in_folder))
|
|
out_folder = os.path.normpath(os.path.join(_CWD, args.out_folder))
|
|
|
|
defines = ParseDefinesArg(args.defines)
|
|
|
|
node = PreprocessIfExprNode.Construct(defines, args.target)
|
|
|
|
for input_file in args.in_files:
|
|
in_path = os.path.join(in_folder, input_file)
|
|
content = ""
|
|
with open(in_path, encoding='utf-8') as f:
|
|
content = f.read()
|
|
|
|
removal_comments_extension = None # None means no removal comments
|
|
if args.enable_removal_comments:
|
|
removal_comments_extension = ExtensionForComments(input_file)
|
|
|
|
try:
|
|
preprocessed = node.PreprocessIfExpr(content, removal_comments_extension)
|
|
except:
|
|
raise Exception('Error processing %s' % in_path)
|
|
out_path = os.path.join(out_folder, input_file)
|
|
out_dir = os.path.dirname(out_path)
|
|
assert out_dir.startswith(out_folder), \
|
|
'Cannot preprocess files to locations not under %s.' % out_dir
|
|
try:
|
|
os.makedirs(out_dir)
|
|
except OSError as e:
|
|
# Ignore directory exists errors. This can happen if two build rules
|
|
# for overlapping directories hit the makedirs line at the same time.
|
|
if e.errno != errno.EEXIST:
|
|
raise
|
|
|
|
# Delete the target file before witing it, as it may be hardlinked to other
|
|
# files, which can break the build. This is the case in particular if the
|
|
# file was "copied" to different locations with GN (as GN's copy is actually
|
|
# a hard link under the hood). See https://crbug.com/1332497
|
|
if os.path.exists(out_path):
|
|
os.remove(out_path)
|
|
|
|
# Detect and delete any stale TypeScript files present in the output folder,
|
|
# corresponding to input .js files, since they can get picked up by
|
|
# subsequent ts_library() invocations and cause transient build failures.
|
|
# This can happen when a file is migrated from JS to TS and a bot is
|
|
# switched from building a later CL to building an earlier CL.
|
|
[pathname, extension] = os.path.splitext(out_path)
|
|
if extension == '.js':
|
|
to_check = pathname + '.ts'
|
|
if os.path.exists(to_check):
|
|
os.remove(to_check)
|
|
|
|
with open(out_path, mode='wb') as f:
|
|
f.write(preprocessed.encode('utf-8'))
|
|
|
|
if args.out_manifest:
|
|
manifest_data = {}
|
|
manifest_data['base_dir'] = '%s' % args.out_folder
|
|
manifest_data['files'] = args.in_files
|
|
manifest_file = open(
|
|
os.path.normpath(os.path.join(_CWD, args.out_manifest)), 'w',
|
|
encoding='utf-8', newline='\n')
|
|
json.dump(manifest_data, manifest_file)
|
|
return
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main(sys.argv[1:])
|