diff options
Diffstat (limited to 'scripts')
| -rw-r--r-- | scripts/Android.bp | 60 | ||||
| -rw-r--r-- | scripts/OWNERS | 1 | ||||
| -rwxr-xr-x | scripts/build-mainline-modules.sh | 25 | ||||
| -rwxr-xr-x | scripts/construct_context.py | 90 | ||||
| -rwxr-xr-x | scripts/construct_context_test.py | 81 | ||||
| -rw-r--r-- | scripts/gen-kotlin-build-file.py | 94 | ||||
| -rwxr-xr-x | scripts/gen-kotlin-build-file.sh | 73 | ||||
| -rwxr-xr-x | scripts/lint-project-xml.py | 151 | ||||
| -rw-r--r-- | scripts/ninja_rsp.py | 83 | ||||
| -rw-r--r-- | scripts/rustfmt.toml | 5 | ||||
| -rwxr-xr-x | scripts/transitive-deps.sh | 4 |
11 files changed, 589 insertions, 78 deletions
diff --git a/scripts/Android.bp b/scripts/Android.bp index e848b5019..7782c6862 100644 --- a/scripts/Android.bp +++ b/scripts/Android.bp @@ -106,7 +106,7 @@ python_binary_host { py3: { enabled: false, }, - } + }, } python_binary_host { @@ -148,3 +148,61 @@ python_test_host { ], test_suites: ["general-tests"], } + +python_binary_host { + name: "construct_context", + main: "construct_context.py", + srcs: [ + "construct_context.py", + ], + version: { + py2: { + enabled: true, + }, + py3: { + enabled: false, + }, + }, + libs: [ + "manifest_utils", + ], +} + +python_test_host { + name: "construct_context_test", + main: "construct_context_test.py", + srcs: [ + "construct_context_test.py", + "construct_context.py", + ], + version: { + py2: { + enabled: true, + }, + py3: { + enabled: false, + }, + }, + libs: [ + "manifest_utils", + ], + test_suites: ["general-tests"], +} + +python_binary_host { + name: "lint-project-xml", + main: "lint-project-xml.py", + srcs: [ + "lint-project-xml.py", + "ninja_rsp.py", + ], +} + +python_binary_host { + name: "gen-kotlin-build-file.py", + main: "gen-kotlin-build-file.py", + srcs: [ + "gen-kotlin-build-file.py", + "ninja_rsp.py", + ], +} diff --git a/scripts/OWNERS b/scripts/OWNERS index dd0966fa5..8c644247e 100644 --- a/scripts/OWNERS +++ b/scripts/OWNERS @@ -1,3 +1,4 @@ per-file system-clang-format,system-clang-format-2 = enh@google.com,smoreland@google.com per-file build-mainline-modules.sh = ngeoffray@google.com,paulduffin@google.com,mast@google.com per-file build-aml-prebuilts.sh = ngeoffray@google.com,paulduffin@google.com,mast@google.com +per-file construct_context.py = ngeoffray@google.com,calin@google.com,mathieuc@google.com,skvadrik@google.com diff --git a/scripts/build-mainline-modules.sh b/scripts/build-mainline-modules.sh index df763c822..c7baca70d 100755 --- a/scripts/build-mainline-modules.sh +++ b/scripts/build-mainline-modules.sh @@ -21,6 +21,16 @@ MODULES_SDK_AND_EXPORTS=( conscrypt-module-host-exports runtime-module-sdk runtime-module-host-exports + i18n-module-test-exports + i18n-module-sdk + platform-mainline-sdk +) + +# List of libraries installed on the platform that are needed for ART chroot +# testing. +PLATFORM_LIBRARIES=( + liblog + libartpalette-system ) # We want to create apex modules for all supported architectures. @@ -41,13 +51,21 @@ echo_and_run() { "$@" } +lib_dir() { + case $1 in + (aosp_arm|aosp_x86) echo "lib";; + (aosp_arm64|aosp_x86_64) echo "lib64";; + esac +} + OUT_DIR=$(source build/envsetup.sh > /dev/null; TARGET_PRODUCT= get_build_var OUT_DIR) DIST_DIR=$(source build/envsetup.sh > /dev/null; TARGET_PRODUCT= get_build_var DIST_DIR) for product in "${PRODUCTS[@]}"; do echo_and_run build/soong/soong_ui.bash --make-mode $@ \ TARGET_PRODUCT=${product} \ - ${MAINLINE_MODULES[@]} + ${MAINLINE_MODULES[@]} \ + ${PLATFORM_LIBRARIES[@]} PRODUCT_OUT=$(source build/envsetup.sh > /dev/null; TARGET_PRODUCT=${product} get_build_var PRODUCT_OUT) TARGET_ARCH=$(source build/envsetup.sh > /dev/null; TARGET_PRODUCT=${product} get_build_var TARGET_ARCH) @@ -56,9 +74,12 @@ for product in "${PRODUCTS[@]}"; do for module in "${MAINLINE_MODULES[@]}"; do echo_and_run cp ${PWD}/${PRODUCT_OUT}/system/apex/${module}.apex ${DIST_DIR}/${TARGET_ARCH}/ done + for library in "${PLATFORM_LIBRARIES[@]}"; do + libdir=$(lib_dir $product) + echo_and_run cp ${PWD}/${PRODUCT_OUT}/system/${libdir}/${library}.so ${DIST_DIR}/${TARGET_ARCH}/ + done done - # Create multi-archs SDKs in a different out directory. The multi-arch script # uses Soong in --skip-make mode which cannot use the same directory as normal # mode with make. diff --git a/scripts/construct_context.py b/scripts/construct_context.py new file mode 100755 index 000000000..8717fe305 --- /dev/null +++ b/scripts/construct_context.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# +# Copyright (C) 2020 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +"""A tool for constructing class loader context.""" + +from __future__ import print_function + +import argparse +import sys + +from manifest import compare_version_gt + + +def parse_args(args): + """Parse commandline arguments.""" + parser = argparse.ArgumentParser() + parser.add_argument('--target-sdk-version', default='', dest='sdk', + help='specify target SDK version (as it appears in the manifest)') + parser.add_argument('--host-classpath-for-sdk', dest='host_classpaths', + action='append', nargs=2, metavar=('sdk','classpath'), + help='specify classpath on host for a given SDK version or "any" version') + parser.add_argument('--target-classpath-for-sdk', dest='target_classpaths', + action='append', nargs=2, metavar=('sdk','classpath'), + help='specify classpath on target for a given SDK version or "any" version') + return parser.parse_args(args) + +# The hidl.manager shared library has a dependency on hidl.base. We manually +# add that information to the class loader context if we see those libraries. +HIDL_MANAGER = 'android.hidl.manager-V1.0-java' +HIDL_BASE = 'android.hidl.base-V1.0-java' + +# Special keyword that means that the classpath should be added to class loader +# context regardless of the target SDK version. +any_sdk = 'any' + +# We assume that the order of classpath arguments passed to this script is +# correct (matches the order computed by package manager). It is possible to +# sort them here, but Soong needs to use deterministic order anyway, so it can +# as well use the correct order. +def construct_context(versioned_classpaths, target_sdk): + context = [] + for [sdk, classpath] in versioned_classpaths: + if sdk == any_sdk or compare_version_gt(sdk, target_sdk): + for jar in classpath.split(':'): + pcl = 'PCL[%s]' % jar + if HIDL_MANAGER in jar: + pcl += '{PCL[%s]}' % jar.replace(HIDL_MANAGER, HIDL_BASE, 1) + context.append(pcl) + return context + +def construct_contexts(args): + host_context = construct_context(args.host_classpaths, args.sdk) + target_context = construct_context(args.target_classpaths, args.sdk) + context_sep = '#' + return ('class_loader_context_arg=--class-loader-context=PCL[]{%s} ; ' % context_sep.join(host_context) + + 'stored_class_loader_context_arg=--stored-class-loader-context=PCL[]{%s}' % context_sep.join(target_context)) + +def main(): + """Program entry point.""" + try: + args = parse_args(sys.argv[1:]) + if not args.sdk: + raise SystemExit('target sdk version is not set') + if not args.host_classpaths: + raise SystemExit('host classpath is not set') + if not args.target_classpaths: + raise SystemExit('target classpath is not set') + + print(construct_contexts(args)) + + # pylint: disable=broad-except + except Exception as err: + print('error: ' + str(err), file=sys.stderr) + sys.exit(-1) + +if __name__ == '__main__': + main() diff --git a/scripts/construct_context_test.py b/scripts/construct_context_test.py new file mode 100755 index 000000000..0b0b0a315 --- /dev/null +++ b/scripts/construct_context_test.py @@ -0,0 +1,81 @@ +#!/usr/bin/env python +# +# Copyright (C) 2020 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +"""Unit tests for construct_context.py.""" + +import sys +import unittest + +import construct_context as cc + +sys.dont_write_bytecode = True + +def construct_contexts(arglist): + args = cc.parse_args(arglist) + return cc.construct_contexts(args) + +classpaths = [ + '--host-classpath-for-sdk', '28', 'out/zdir/z.jar', + '--target-classpath-for-sdk', '28', '/system/z.jar', + '--host-classpath-for-sdk', '29', 'out/xdir/x.jar:out/ydir/y.jar', + '--target-classpath-for-sdk', '29', '/system/x.jar:/product/y.jar', + '--host-classpath-for-sdk', 'any', 'out/adir/a.jar:out/android.hidl.manager-V1.0-java.jar:out/bdir/b.jar', + '--target-classpath-for-sdk', 'any', '/system/a.jar:/system/android.hidl.manager-V1.0-java.jar:/product/b.jar', +] + +class ConstructContextTest(unittest.TestCase): + def test_construct_context_28(self): + args = ['--target-sdk-version', '28'] + classpaths + result = construct_contexts(args) + expect = ('class_loader_context_arg=--class-loader-context=PCL[]{PCL[out/xdir/x.jar]' + '#PCL[out/ydir/y.jar]' + '#PCL[out/adir/a.jar]' + '#PCL[out/android.hidl.manager-V1.0-java.jar]{PCL[out/android.hidl.base-V1.0-java.jar]}' + '#PCL[out/bdir/b.jar]}' + ' ; ' + 'stored_class_loader_context_arg=--stored-class-loader-context=PCL[]{PCL[/system/x.jar]' + '#PCL[/product/y.jar]' + '#PCL[/system/a.jar]' + '#PCL[/system/android.hidl.manager-V1.0-java.jar]{PCL[/system/android.hidl.base-V1.0-java.jar]}' + '#PCL[/product/b.jar]}') + self.assertEqual(result, expect) + + def test_construct_context_29(self): + args = ['--target-sdk-version', '29'] + classpaths + result = construct_contexts(args) + expect = ('class_loader_context_arg=--class-loader-context=PCL[]{PCL[out/adir/a.jar]' + '#PCL[out/android.hidl.manager-V1.0-java.jar]{PCL[out/android.hidl.base-V1.0-java.jar]}' + '#PCL[out/bdir/b.jar]}' + ' ; ' + 'stored_class_loader_context_arg=--stored-class-loader-context=PCL[]{PCL[/system/a.jar]' + '#PCL[/system/android.hidl.manager-V1.0-java.jar]{PCL[/system/android.hidl.base-V1.0-java.jar]}' + '#PCL[/product/b.jar]}') + self.assertEqual(result, expect) + + def test_construct_context_S(self): + args = ['--target-sdk-version', 'S'] + classpaths + result = construct_contexts(args) + expect = ('class_loader_context_arg=--class-loader-context=PCL[]{PCL[out/adir/a.jar]' + '#PCL[out/android.hidl.manager-V1.0-java.jar]{PCL[out/android.hidl.base-V1.0-java.jar]}' + '#PCL[out/bdir/b.jar]}' + ' ; ' + 'stored_class_loader_context_arg=--stored-class-loader-context=PCL[]{PCL[/system/a.jar]' + '#PCL[/system/android.hidl.manager-V1.0-java.jar]{PCL[/system/android.hidl.base-V1.0-java.jar]}' + '#PCL[/product/b.jar]}') + self.assertEqual(result, expect) + +if __name__ == '__main__': + unittest.main(verbosity=2) diff --git a/scripts/gen-kotlin-build-file.py b/scripts/gen-kotlin-build-file.py new file mode 100644 index 000000000..83b4cd8a3 --- /dev/null +++ b/scripts/gen-kotlin-build-file.py @@ -0,0 +1,94 @@ +#!/usr/bin/env python3 +# +# Copyright 2018 Google Inc. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generates kotlinc module xml file to drive kotlinc + +import argparse +import os + +from ninja_rsp import NinjaRspFileReader + +def parse_args(): + """Parse commandline arguments.""" + + def convert_arg_line_to_args(arg_line): + for arg in arg_line.split(): + if arg.startswith('#'): + return + if not arg.strip(): + continue + yield arg + + parser = argparse.ArgumentParser(fromfile_prefix_chars='@') + parser.convert_arg_line_to_args = convert_arg_line_to_args + parser.add_argument('--out', dest='out', + help='file to which the module.xml contents will be written.') + parser.add_argument('--classpath', dest='classpath', action='append', default=[], + help='classpath to pass to kotlinc.') + parser.add_argument('--name', dest='name', + help='name of the module.') + parser.add_argument('--out_dir', dest='out_dir', + help='directory to which kotlinc will write output files.') + parser.add_argument('--srcs', dest='srcs', action='append', default=[], + help='file containing whitespace separated list of source files.') + parser.add_argument('--common_srcs', dest='common_srcs', action='append', default=[], + help='file containing whitespace separated list of common multiplatform source files.') + + return parser.parse_args() + +def main(): + """Program entry point.""" + args = parse_args() + + if not args.out: + raise RuntimeError('--out argument is required') + + if not args.name: + raise RuntimeError('--name argument is required') + + with open(args.out, 'w') as f: + # Print preamble + f.write('<modules>\n') + f.write(' <module name="%s" type="java-production" outputDir="%s">\n' % (args.name, args.out_dir or '')) + + # Print classpath entries + for c in args.classpath: + for entry in c.split(':'): + path = os.path.abspath(entry) + f.write(' <classpath path="%s"/>\n' % path) + + # For each rsp file, print source entries + for rsp_file in args.srcs: + for src in NinjaRspFileReader(rsp_file): + path = os.path.abspath(src) + if src.endswith('.java'): + f.write(' <javaSourceRoots path="%s"/>\n' % path) + elif src.endswith('.kt'): + f.write(' <sources path="%s"/>\n' % path) + else: + raise RuntimeError('unknown source file type %s' % file) + + for rsp_file in args.common_srcs: + for src in NinjaRspFileReader(rsp_file): + path = os.path.abspath(src) + f.write(' <sources path="%s"/>\n' % path) + f.write(' <commonSources path="%s"/>\n' % path) + + f.write(' </module>\n') + f.write('</modules>\n') + +if __name__ == '__main__': + main() diff --git a/scripts/gen-kotlin-build-file.sh b/scripts/gen-kotlin-build-file.sh deleted file mode 100755 index 177ca1b04..000000000 --- a/scripts/gen-kotlin-build-file.sh +++ /dev/null @@ -1,73 +0,0 @@ -#!/bin/bash -e - -# Copyright 2018 Google Inc. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Generates kotlinc module xml file to standard output based on rsp files - -if [[ -z "$1" ]]; then - echo "usage: $0 <classpath> <name> <outDir> <rspFiles>..." >&2 - exit 1 -fi - -# Classpath variable has a tendency to be prefixed by "-classpath", remove it. -if [[ $1 == "-classpath" ]]; then - shift -fi; - -classpath=$1 -name=$2 -out_dir=$3 -shift 3 - -# Path in the build file may be relative to the build file, we need to make them -# absolute -prefix="$(pwd)" - -get_abs_path () { - local file="$1" - if [[ "${file:0:1}" == '/' ]] ; then - echo "${file}" - else - echo "${prefix}/${file}" - fi -} - -# Print preamble -echo "<modules><module name=\"${name}\" type=\"java-production\" outputDir=\"${out_dir}\">" - -# Print classpath entries -for file in $(echo "$classpath" | tr ":" "\n"); do - path="$(get_abs_path "$file")" - echo " <classpath path=\"${path}\"/>" -done - -# For each rsp file, print source entries -while (( "$#" )); do - for file in $(cat "$1"); do - path="$(get_abs_path "$file")" - if [[ $file == *.java ]]; then - echo " <javaSourceRoots path=\"${path}\"/>" - elif [[ $file == *.kt ]]; then - echo " <sources path=\"${path}\"/>" - else - echo "Unknown source file type ${file}" - exit 1 - fi - done - - shift -done - -echo "</module></modules>" diff --git a/scripts/lint-project-xml.py b/scripts/lint-project-xml.py new file mode 100755 index 000000000..f1ef85dcc --- /dev/null +++ b/scripts/lint-project-xml.py @@ -0,0 +1,151 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2018 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +"""This file generates project.xml and lint.xml files used to drive the Android Lint CLI tool.""" + +import argparse + +from ninja_rsp import NinjaRspFileReader + + +def check_action(check_type): + """ + Returns an action that appends a tuple of check_type and the argument to the dest. + """ + class CheckAction(argparse.Action): + def __init__(self, option_strings, dest, nargs=None, **kwargs): + if nargs is not None: + raise ValueError("nargs must be None, was %s" % nargs) + super(CheckAction, self).__init__(option_strings, dest, **kwargs) + def __call__(self, parser, namespace, values, option_string=None): + checks = getattr(namespace, self.dest, []) + checks.append((check_type, values)) + setattr(namespace, self.dest, checks) + return CheckAction + + +def parse_args(): + """Parse commandline arguments.""" + + def convert_arg_line_to_args(arg_line): + for arg in arg_line.split(): + if arg.startswith('#'): + return + if not arg.strip(): + continue + yield arg + + parser = argparse.ArgumentParser(fromfile_prefix_chars='@') + parser.convert_arg_line_to_args = convert_arg_line_to_args + parser.add_argument('--project_out', dest='project_out', + help='file to which the project.xml contents will be written.') + parser.add_argument('--config_out', dest='config_out', + help='file to which the lint.xml contents will be written.') + parser.add_argument('--name', dest='name', + help='name of the module.') + parser.add_argument('--srcs', dest='srcs', action='append', default=[], + help='file containing whitespace separated list of source files.') + parser.add_argument('--generated_srcs', dest='generated_srcs', action='append', default=[], + help='file containing whitespace separated list of generated source files.') + parser.add_argument('--resources', dest='resources', action='append', default=[], + help='file containing whitespace separated list of resource files.') + parser.add_argument('--classes', dest='classes', action='append', default=[], + help='file containing the module\'s classes.') + parser.add_argument('--classpath', dest='classpath', action='append', default=[], + help='file containing classes from dependencies.') + parser.add_argument('--extra_checks_jar', dest='extra_checks_jars', action='append', default=[], + help='file containing extra lint checks.') + parser.add_argument('--manifest', dest='manifest', + help='file containing the module\'s manifest.') + parser.add_argument('--merged_manifest', dest='merged_manifest', + help='file containing merged manifest for the module and its dependencies.') + parser.add_argument('--library', dest='library', action='store_true', + help='mark the module as a library.') + parser.add_argument('--test', dest='test', action='store_true', + help='mark the module as a test.') + parser.add_argument('--cache_dir', dest='cache_dir', + help='directory to use for cached file.') + parser.add_argument('--root_dir', dest='root_dir', + help='directory to use for root dir.') + group = parser.add_argument_group('check arguments', 'later arguments override earlier ones.') + group.add_argument('--fatal_check', dest='checks', action=check_action('fatal'), default=[], + help='treat a lint issue as a fatal error.') + group.add_argument('--error_check', dest='checks', action=check_action('error'), default=[], + help='treat a lint issue as an error.') + group.add_argument('--warning_check', dest='checks', action=check_action('warning'), default=[], + help='treat a lint issue as a warning.') + group.add_argument('--disable_check', dest='checks', action=check_action('ignore'), default=[], + help='disable a lint issue.') + return parser.parse_args() + + +def write_project_xml(f, args): + test_attr = "test='true' " if args.test else "" + + f.write("<?xml version='1.0' encoding='utf-8'?>\n") + f.write("<project>\n") + if args.root_dir: + f.write(" <root dir='%s' />\n" % args.root_dir) + f.write(" <module name='%s' android='true' %sdesugar='full' >\n" % (args.name, "library='true' " if args.library else "")) + if args.manifest: + f.write(" <manifest file='%s' %s/>\n" % (args.manifest, test_attr)) + if args.merged_manifest: + f.write(" <merged-manifest file='%s' %s/>\n" % (args.merged_manifest, test_attr)) + for src_file in args.srcs: + for src in NinjaRspFileReader(src_file): + f.write(" <src file='%s' %s/>\n" % (src, test_attr)) + for src_file in args.generated_srcs: + for src in NinjaRspFileReader(src_file): + f.write(" <src file='%s' generated='true' %s/>\n" % (src, test_attr)) + for res_file in args.resources: + for res in NinjaRspFileReader(res_file): + f.write(" <resource file='%s' %s/>\n" % (res, test_attr)) + for classes in args.classes: + f.write(" <classes jar='%s' />\n" % classes) + for classpath in args.classpath: + f.write(" <classpath jar='%s' />\n" % classpath) + for extra in args.extra_checks_jars: + f.write(" <lint-checks jar='%s' />\n" % extra) + f.write(" </module>\n") + if args.cache_dir: + f.write(" <cache dir='%s'/>\n" % args.cache_dir) + f.write("</project>\n") + + +def write_config_xml(f, args): + f.write("<?xml version='1.0' encoding='utf-8'?>\n") + f.write("<lint>\n") + for check in args.checks: + f.write(" <issue id='%s' severity='%s' />\n" % (check[1], check[0])) + f.write("</lint>\n") + + +def main(): + """Program entry point.""" + args = parse_args() + + if args.project_out: + with open(args.project_out, 'w') as f: + write_project_xml(f, args) + + if args.config_out: + with open(args.config_out, 'w') as f: + write_config_xml(f, args) + + +if __name__ == '__main__': + main() diff --git a/scripts/ninja_rsp.py b/scripts/ninja_rsp.py new file mode 100644 index 000000000..004ce4733 --- /dev/null +++ b/scripts/ninja_rsp.py @@ -0,0 +1,83 @@ +# Copyright (C) 2020 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +"""This file reads entries from a Ninja rsp file.""" + +class NinjaRspFileReader: + """ + Reads entries from a Ninja rsp file. Ninja escapes any entries in the file that contain a + non-standard character by surrounding the whole entry with single quotes, and then replacing + any single quotes in the entry with the escape sequence '\''. + """ + + def __init__(self, filename): + self.f = open(filename, 'r') + self.r = self.character_reader(self.f) + + def __iter__(self): + return self + + def character_reader(self, f): + """Turns a file into a generator that returns one character at a time.""" + while True: + c = f.read(1) + if c: + yield c + else: + return + + def __next__(self): + entry = self.read_entry() + if entry: + return entry + else: + raise StopIteration + + def read_entry(self): + c = next(self.r, "") + if not c: + return "" + elif c == "'": + return self.read_quoted_entry() + else: + entry = c + for c in self.r: + if c == " " or c == "\n": + break + entry += c + return entry + + def read_quoted_entry(self): + entry = "" + for c in self.r: + if c == "'": + # Either the end of the quoted entry, or the beginning of an escape sequence, read the next + # character to find out. + c = next(self.r) + if not c or c == " " or c == "\n": + # End of the item + return entry + elif c == "\\": + # Escape sequence, expect a ' + c = next(self.r) + if c != "'": + # Malformed escape sequence + raise "malformed escape sequence %s'\\%s" % (entry, c) + entry += "'" + else: + raise "malformed escape sequence %s'%s" % (entry, c) + else: + entry += c + raise "unterminated quoted entry %s" % entry diff --git a/scripts/rustfmt.toml b/scripts/rustfmt.toml new file mode 100644 index 000000000..617d42585 --- /dev/null +++ b/scripts/rustfmt.toml @@ -0,0 +1,5 @@ +# Android Format Style + +edition = "2018" +use_small_heuristics = "Max" +newline_style = "Unix" diff --git a/scripts/transitive-deps.sh b/scripts/transitive-deps.sh index c6f8b76e4..ba36ba4bf 100755 --- a/scripts/transitive-deps.sh +++ b/scripts/transitive-deps.sh @@ -56,7 +56,7 @@ Output Options: temporary / intermediate files. -sep=<delim> Use 'delim' as output field separator between notice checksum and notice filename in notice output. - e.g. sep='\t' + e.g. sep='\\t' (Default space) -csv Shorthand for -sep=',' -directories=<f> Output directory names of dependencies to 'f'. @@ -280,7 +280,7 @@ while [ $# -gt 0 ]; do notices=) notices_out=$(expr "${flag}" : '^.*=\(.*\)$');; *) - die "Unknown flag ${1}";; + die "${usage}\n\nUnknown flag ${1}";; esac ;; *) |