diff options
author | 2025-03-04 17:52:58 -0800 | |
---|---|---|
committer | 2025-03-04 17:52:58 -0800 | |
commit | e7fc6932ec9dbfc377a5baa47ebecf95cd57b1fc (patch) | |
tree | 3a767ebfc4ff652b21069727467589b976b255dd /scripts | |
parent | ac628ad7b51b7cf91d4c9257e30c3365cd5c4ac6 (diff) | |
parent | d183d9f24bf0e9b2b59330a6fa1346bbbef7b1ce (diff) |
Merge "Replace --revert-annotation with a flags config file" into main am: d183d9f24b
Original change: https://android-review.googlesource.com/c/platform/build/soong/+/3523090
Change-Id: I5cfd92e154ae2e604589b4a91388a7a535ad1f14
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
Diffstat (limited to 'scripts')
-rw-r--r-- | scripts/Android.bp | 10 | ||||
-rw-r--r-- | scripts/aconfig-to-metalava-flags.py | 103 | ||||
-rwxr-xr-x | scripts/keep-flagged-apis.sh | 37 |
3 files changed, 110 insertions, 40 deletions
diff --git a/scripts/Android.bp b/scripts/Android.bp index 94163a5c2..c0e13d52f 100644 --- a/scripts/Android.bp +++ b/scripts/Android.bp @@ -287,9 +287,13 @@ python_test_host { ], } -sh_binary_host { - name: "keep-flagged-apis", - src: "keep-flagged-apis.sh", +python_binary_host { + name: "aconfig-to-metalava-flags", + main: "aconfig-to-metalava-flags.py", + srcs: ["aconfig-to-metalava-flags.py"], + libs: [ + "libaconfig_python_proto", + ], } python_binary_host { diff --git a/scripts/aconfig-to-metalava-flags.py b/scripts/aconfig-to-metalava-flags.py new file mode 100644 index 000000000..efa85ecb3 --- /dev/null +++ b/scripts/aconfig-to-metalava-flags.py @@ -0,0 +1,103 @@ +#!/usr/bin/env python3 + +# Copyright (C) 2025 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. + +"""Converts a set of aconfig protobuf flags to a Metalava config file.""" + +# Formatted using `pyformat -i scripts/aconfig-to-metalava-flags.py` + +import argparse +import sys +import xml.etree.ElementTree as ET + +from protos import aconfig_pb2 + +_READ_ONLY = aconfig_pb2.flag_permission.READ_ONLY +_ENABLED = aconfig_pb2.flag_state.ENABLED +_DISABLED = aconfig_pb2.flag_state.DISABLED + +# The namespace of the Metalava config file. +CONFIG_NS = 'http://www.google.com/tools/metalava/config' + + +def config_name(tag: str): + """Create a QName in the config namespace. + + :param:tag the name of the entity in the config namespace. + """ + return f'{{{CONFIG_NS}}}{tag}' + + +def main(): + """Program entry point.""" + args_parser = argparse.ArgumentParser( + description='Generate Metalava flags config from aconfig protobuf', + ) + args_parser.add_argument( + 'input', + help='The path to the aconfig protobuf file', + ) + args = args_parser.parse_args(sys.argv[1:]) + + # Read the parsed_flags from the protobuf file. + with open(args.input, 'rb') as f: + parsed_flags = aconfig_pb2.parsed_flags.FromString(f.read()) + + # Create the structure of the XML config file. + config = ET.Element(config_name('config')) + api_flags = ET.SubElement(config, config_name('api-flags')) + # Create an <api-flag> element for each parsed_flag. + for flag in parsed_flags.parsed_flag: + if flag.permission == _READ_ONLY: + # Ignore any read only disabled flags as Metalava assumes that as the + # default when an <api-flags/> element is provided so this reduces the + # size of the file. + if flag.state == _DISABLED: + continue + mutability = 'immutable' + else: + mutability = 'mutable' + if flag.state == _ENABLED: + status = 'enabled' + else: + status = 'disabled' + attributes = { + 'package': flag.package, + 'name': flag.name, + 'mutability': mutability, + 'status': status, + } + # Convert the attribute names into qualified names in, what will become, the + # default namespace for the XML file. This is needed to ensure that the + # attribute will be written in the XML file without a prefix, e.g. + # `name="flag_name"`. Without it, a namespace prefix, e.g. `ns1`, will be + # synthesized for the attribute when writing the XML file, i.e. it + # will be written as `ns1:name="flag_name"`. Strictly speaking, that is + # unnecessary as the "Namespaces in XML 1.0 (Third Edition)" specification + # says that unprefixed attribute names have no namespace. + qualified_attributes = {config_name(k): v for (k, v) in attributes.items()} + ET.SubElement(api_flags, config_name('api-flag'), qualified_attributes) + + # Create a tree and add white space so it will pretty print when written out. + tree = ET.ElementTree(config) + ET.indent(tree) + + # Write the tree using the config namespace as the default. + tree.write(sys.stdout, encoding='unicode', default_namespace=CONFIG_NS) + sys.stdout.close() + + +if __name__ == '__main__': + main() diff --git a/scripts/keep-flagged-apis.sh b/scripts/keep-flagged-apis.sh deleted file mode 100755 index 48efb7a29..000000000 --- a/scripts/keep-flagged-apis.sh +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/bash -e -# -# Copyright 2023 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. - -# Convert a list of flags in the input file to a list of metalava options -# that will keep the APIs for those flags will hiding all other flagged -# APIs. - -FLAGS="$1" - -FLAGGED="android.annotation.FlaggedApi" - -# Convert the list of feature flags in the input file to Metalava options -# of the form `--revert-annotation !android.annotation.FlaggedApi("<flag>")` -# to prevent the annotated APIs from being hidden, i.e. include the annotated -# APIs in the SDK snapshots. -while read -r line; do - # Escape and quote the key for sed - escaped_line=$(echo "$line" | sed "s/'/\\\'/g; s/ /\\ /g") - - echo "--revert-annotation '!$FLAGGED(\"$escaped_line\")'" -done < "$FLAGS" - -# Revert all flagged APIs, unless listed above. -echo "--revert-annotation $FLAGGED" |