133 lines
4.2 KiB
Python
133 lines
4.2 KiB
Python
#!/usr/bin/env python
|
|
|
|
# Copyright 2021 The Brave Authors. All rights reserved.
|
|
# Use of this source code is governed by a BSD-style license that can be
|
|
# found in the LICENSE file.
|
|
|
|
"""XML processor"""
|
|
|
|
from pathlib import Path
|
|
import xml.etree.ElementTree as ET
|
|
|
|
import codecs
|
|
import argparse
|
|
import importlib.util
|
|
import os
|
|
import sys
|
|
|
|
sys.path.append(os.path.join(os.path.dirname(__file__),
|
|
os.pardir, os.pardir,
|
|
'build', 'android', 'gyp'))
|
|
from util import build_utils
|
|
from util import resource_utils
|
|
|
|
|
|
def _UnderJavaRes(source):
|
|
"""
|
|
Check from left whether java/res is part of input path, returns relative path to java/res.
|
|
Input path shall be absolute.
|
|
"""
|
|
source_path = Path(source)
|
|
source_path_parts = source_path.parts
|
|
for i in range(1, len(source_path_parts)):
|
|
if source_path_parts[i - 1] == 'java' and source_path_parts[i] == 'res':
|
|
parent_path = source_path.parents[len(source_path_parts) - i - 2]
|
|
try:
|
|
rel_path = str(source_path.relative_to(parent_path))
|
|
return rel_path
|
|
except ValueError as e:
|
|
print(e)
|
|
return None
|
|
|
|
|
|
def _AddBravePrefix(relpath):
|
|
dirname, filename = os.path.split(relpath)
|
|
return os.path.join(dirname, 'brave_' + filename)
|
|
|
|
|
|
def _ImportModuleByPath(module_path):
|
|
"""Imports a module by its source file."""
|
|
sys.path[0] = os.path.dirname(module_path)
|
|
|
|
module_name = os.path.splitext(os.path.basename(module_path))[0]
|
|
spec = importlib.util.spec_from_file_location(module_name, module_path)
|
|
module = importlib.util.module_from_spec(spec)
|
|
sys.modules[module_name] = module
|
|
spec.loader.exec_module(module)
|
|
|
|
return module
|
|
|
|
|
|
def _ProcessFile(output_filename, output):
|
|
if os.path.isfile(output_filename):
|
|
with codecs.open(output_filename, 'r', 'utf-8') as f:
|
|
if f.read() == output:
|
|
return
|
|
|
|
with open(output_filename, 'wb') as output_file:
|
|
output_file.write(output)
|
|
|
|
|
|
def _XMLTransform(source_pairs, outputs_zip):
|
|
"""
|
|
Apply module codes to input sources.
|
|
"""
|
|
with build_utils.TempDir() as temp_dir:
|
|
path_info = resource_utils.ResourceInfoFile()
|
|
for source, module in source_pairs:
|
|
with codecs.open(source, 'r', 'utf-8') as f:
|
|
xml_content = f.read()
|
|
loaded_module = _ImportModuleByPath(module)
|
|
|
|
if not xml_content or not loaded_module:
|
|
continue
|
|
|
|
root = ET.XML(xml_content)
|
|
result = loaded_module._ProcessXML(root)
|
|
output = ET.tostring(result, encoding='utf-8', xml_declaration=True)
|
|
|
|
# Parse output path
|
|
# For simplicity, we assume input path will always has java/res in it
|
|
if not (relpath := _UnderJavaRes(os.path.abspath(source))):
|
|
raise Exception('input file %s is not under java/res' % source)
|
|
|
|
# resource_overlay doesn't seem to work from android_generated_resources
|
|
relpath = _AddBravePrefix(relpath)
|
|
output_filename = os.path.join(temp_dir, relpath)
|
|
parent_dir = os.path.dirname(output_filename)
|
|
build_utils.MakeDirectory(parent_dir)
|
|
_ProcessFile(output_filename, output)
|
|
path_info.AddMapping(relpath, source)
|
|
|
|
path_info.Write(outputs_zip + '.info')
|
|
build_utils.ZipDir(outputs_zip, temp_dir)
|
|
|
|
|
|
def main(args):
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument('--xml-sources-path',
|
|
required=True,
|
|
help='Path to a list of input xml sources for this target.')
|
|
parser.add_argument('--module-sources-path',
|
|
required=True,
|
|
help='Path to a list of input python sources for this target. '
|
|
'Each python file shall have a function named _ProcessXML.')
|
|
parser.add_argument('--outputs-zip',
|
|
required=True,
|
|
help='Path to a list of expected outputs for this target.')
|
|
|
|
options = parser.parse_args(args)
|
|
|
|
with open(options.xml_sources_path) as f:
|
|
options.sources = f.read().splitlines()
|
|
with open(options.module_sources_path) as f:
|
|
options.modules = f.read().splitlines()
|
|
|
|
assert len(options.sources) == len(options.modules)
|
|
|
|
_XMLTransform(list(zip(options.sources, options.modules)), options.outputs_zip)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main(sys.argv[1:])
|