Merge pull request #10889 from brave/android_res_xml_parser
[Android] XML pre-processor
This commit is contained in:
@@ -899,3 +899,7 @@ brave_java_resources = [
|
||||
"java/res/xml/unstoppable_domains_preferences.xml",
|
||||
"java/res/xml/use_custom_tabs_brave_preference.xml",
|
||||
]
|
||||
|
||||
# XML preprocessing
|
||||
brave_java_preprocess_xml_sources = []
|
||||
brave_java_preprocess_module_sources = []
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
# 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.
|
||||
|
||||
import("//build/config/android/rules.gni")
|
||||
import("//build/config/python.gni")
|
||||
|
||||
template("brave_xml_preprocessor") {
|
||||
forward_variables_from(invoker, [ "testonly" ])
|
||||
|
||||
_preprocess_target_name = "${target_name}__preprocess"
|
||||
|
||||
_xml_sources_path = "${target_gen_dir}/${target_name}.xml.sources"
|
||||
_module_sources_path = "${target_gen_dir}/${target_name}.py.sources"
|
||||
_xml_output_zip = "${target_out_dir}/${target_name}.resources.zip"
|
||||
|
||||
action_with_pydeps(_preprocess_target_name) {
|
||||
script = "//brave/android/xml_processor.py"
|
||||
|
||||
# Input files
|
||||
sources = invoker.sources
|
||||
modules = invoker.modules
|
||||
inputs = modules # so gn will rebuild upon changes
|
||||
|
||||
outputs = [ _xml_output_zip ]
|
||||
|
||||
# Rebase path
|
||||
_rebased_xml_source_files = rebase_path(sources, root_build_dir)
|
||||
_rebased_module_source_files = rebase_path(modules, root_build_dir)
|
||||
|
||||
# Write sources to file
|
||||
write_file(_xml_sources_path, _rebased_xml_source_files)
|
||||
write_file(_module_sources_path, _rebased_module_source_files)
|
||||
|
||||
# Rebase file paths for python
|
||||
_rebased_xml_sources_path = rebase_path(_xml_sources_path, root_build_dir)
|
||||
_rebased_module_sources_path =
|
||||
rebase_path(_module_sources_path, root_build_dir)
|
||||
|
||||
args = [
|
||||
"--outputs-zip",
|
||||
rebase_path(_xml_output_zip, root_build_dir),
|
||||
"--xml-sources-path=${_rebased_xml_sources_path}",
|
||||
"--module-sources-path=${_rebased_module_sources_path}",
|
||||
]
|
||||
}
|
||||
|
||||
android_generated_resources(target_name) {
|
||||
forward_variables_from(invoker,
|
||||
TESTONLY_AND_VISIBILITY + [
|
||||
"deps",
|
||||
"resource_overlay",
|
||||
])
|
||||
generating_target = ":$_preprocess_target_name"
|
||||
generated_resources_zip = _xml_output_zip
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
#!/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:])
|
||||
@@ -0,0 +1,31 @@
|
||||
# Generated by running:
|
||||
# build/print_python_deps.py --root brave/android --output brave/android/xml_processor.pydeps brave/android/xml_processor.py
|
||||
../../build/android/gyp/util/__init__.py
|
||||
../../build/android/gyp/util/build_utils.py
|
||||
../../build/android/gyp/util/resource_utils.py
|
||||
../../build/gn_helpers.py
|
||||
../../third_party/jinja2/__init__.py
|
||||
../../third_party/jinja2/_compat.py
|
||||
../../third_party/jinja2/_identifier.py
|
||||
../../third_party/jinja2/asyncfilters.py
|
||||
../../third_party/jinja2/asyncsupport.py
|
||||
../../third_party/jinja2/bccache.py
|
||||
../../third_party/jinja2/compiler.py
|
||||
../../third_party/jinja2/defaults.py
|
||||
../../third_party/jinja2/environment.py
|
||||
../../third_party/jinja2/exceptions.py
|
||||
../../third_party/jinja2/filters.py
|
||||
../../third_party/jinja2/idtracking.py
|
||||
../../third_party/jinja2/lexer.py
|
||||
../../third_party/jinja2/loaders.py
|
||||
../../third_party/jinja2/nodes.py
|
||||
../../third_party/jinja2/optimizer.py
|
||||
../../third_party/jinja2/parser.py
|
||||
../../third_party/jinja2/runtime.py
|
||||
../../third_party/jinja2/tests.py
|
||||
../../third_party/jinja2/utils.py
|
||||
../../third_party/jinja2/visitor.py
|
||||
../../third_party/markupsafe/__init__.py
|
||||
../../third_party/markupsafe/_compat.py
|
||||
../../third_party/markupsafe/_native.py
|
||||
xml_processor.py
|
||||
@@ -1,3 +1,4 @@
|
||||
import("//brave/android/brave_xml_preprocessor.gni")
|
||||
import("//brave/build/config.gni")
|
||||
import("//build/config/android/rules.gni")
|
||||
import("//tools/grit/grit_rule.gni")
|
||||
@@ -168,6 +169,11 @@ java_strings_grd("android_brave_strings_grd") {
|
||||
]
|
||||
}
|
||||
|
||||
brave_xml_preprocessor("brave_java_xml_preprocess_resources") {
|
||||
sources = brave_java_preprocess_xml_sources
|
||||
modules = brave_java_preprocess_module_sources
|
||||
}
|
||||
|
||||
generate_jni("jni_headers") {
|
||||
sources = [
|
||||
"//brave/android/java/org/chromium/chrome/browser/BraveFeatureList.java",
|
||||
|
||||
@@ -39,8 +39,10 @@ brave_chrome_java_srcjar_deps = [
|
||||
"//brave/browser/android/preferences:java_pref_names_srcjar",
|
||||
]
|
||||
|
||||
brave_chrome_app_java_resources_deps =
|
||||
[ "//brave/build/android:android_brave_strings_grd" ]
|
||||
brave_chrome_app_java_resources_deps = [
|
||||
"//brave/build/android:android_brave_strings_grd",
|
||||
"//brave/build/android:brave_java_xml_preprocess_resources",
|
||||
]
|
||||
|
||||
brave_resources_exclusion_exceptions =
|
||||
[ "*com_google_android_material*design_bottom_*" ]
|
||||
|
||||
Reference in New Issue
Block a user