xref: /aosp_15_r20/tools/metalava/scripts/gather-android-metalava-artifacts.py (revision 115816f9299ab6ddd6b9673b81f34e707f6bacab)
1*115816f9SAndroid Build Coastguard Worker#!/usr/bin/env -S python3 -u
2*115816f9SAndroid Build Coastguard Worker#  Copyright (C) 2024 The Android Open Source Project
3*115816f9SAndroid Build Coastguard Worker#
4*115816f9SAndroid Build Coastguard Worker#  Licensed under the Apache License, Version 2.0 (the "License");
5*115816f9SAndroid Build Coastguard Worker#  you may not use this file except in compliance with the License.
6*115816f9SAndroid Build Coastguard Worker#  You may obtain a copy of the License at
7*115816f9SAndroid Build Coastguard Worker#
8*115816f9SAndroid Build Coastguard Worker#       http://www.apache.org/licenses/LICENSE-2.0
9*115816f9SAndroid Build Coastguard Worker#
10*115816f9SAndroid Build Coastguard Worker#  Unless required by applicable law or agreed to in writing, software
11*115816f9SAndroid Build Coastguard Worker#  distributed under the License is distributed on an "AS IS" BASIS,
12*115816f9SAndroid Build Coastguard Worker#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*115816f9SAndroid Build Coastguard Worker#  See the License for the specific language governing permissions and
14*115816f9SAndroid Build Coastguard Worker#  limitations under the License.
15*115816f9SAndroid Build Coastguard Worker
16*115816f9SAndroid Build Coastguard Workerimport argparse
17*115816f9SAndroid Build Coastguard Workerimport os
18*115816f9SAndroid Build Coastguard Workerfrom pathlib import Path
19*115816f9SAndroid Build Coastguard Workerimport shutil
20*115816f9SAndroid Build Coastguard Workerimport subprocess
21*115816f9SAndroid Build Coastguard Workerimport sys
22*115816f9SAndroid Build Coastguard Worker
23*115816f9SAndroid Build Coastguard Worker# Formatted using: pyformat -s 4 --force_quote_type double -i scripts/gather-android-metalava-artifacts.py
24*115816f9SAndroid Build Coastguard Worker
25*115816f9SAndroid Build Coastguard Worker
26*115816f9SAndroid Build Coastguard Workerdef parse_command_line_args(args):
27*115816f9SAndroid Build Coastguard Worker    """Define the command line options and the parse the command line arguments with them.
28*115816f9SAndroid Build Coastguard Worker
29*115816f9SAndroid Build Coastguard Worker    :param args: the command line arguments :return: Return the result of
30*115816f9SAndroid Build Coastguard Worker    parsing the command line arguments.
31*115816f9SAndroid Build Coastguard Worker    """
32*115816f9SAndroid Build Coastguard Worker    args_parser = argparse.ArgumentParser(
33*115816f9SAndroid Build Coastguard Worker        description=(
34*115816f9SAndroid Build Coastguard Worker            "Gather Android artifacts created by Metalava. This will build and"
35*115816f9SAndroid Build Coastguard Worker            " then copy a set of targets to the output directory. If no custom"
36*115816f9SAndroid Build Coastguard Worker            " targets are provided then a set of default ones will be provided"
37*115816f9SAndroid Build Coastguard Worker            " that covers stub generation, signature to JDiff conversion and"
38*115816f9SAndroid Build Coastguard Worker            " api-versions.xml file generation. The intent is that this would"
39*115816f9SAndroid Build Coastguard Worker            " be run this before and after making the change to build and copy"
40*115816f9SAndroid Build Coastguard Worker            " the artifacts into two separate directories that can then be"
41*115816f9SAndroid Build Coastguard Worker            " compared to see what, if any, changes have happened. This does"
42*115816f9SAndroid Build Coastguard Worker            " not check signature file generation as that can be easily checked"
43*115816f9SAndroid Build Coastguard Worker            " by running `m checkapi`."
44*115816f9SAndroid Build Coastguard Worker        ),
45*115816f9SAndroid Build Coastguard Worker    )
46*115816f9SAndroid Build Coastguard Worker    args_parser.add_argument(
47*115816f9SAndroid Build Coastguard Worker        "directory",
48*115816f9SAndroid Build Coastguard Worker        help="Output directory into which artifacts will be copied.",
49*115816f9SAndroid Build Coastguard Worker    )
50*115816f9SAndroid Build Coastguard Worker    args_parser.add_argument(
51*115816f9SAndroid Build Coastguard Worker        "--stub-src-jar",
52*115816f9SAndroid Build Coastguard Worker        action="append",
53*115816f9SAndroid Build Coastguard Worker        help="Additional stub jar to gather",
54*115816f9SAndroid Build Coastguard Worker    )
55*115816f9SAndroid Build Coastguard Worker
56*115816f9SAndroid Build Coastguard Worker    return args_parser.parse_args(args)
57*115816f9SAndroid Build Coastguard Worker
58*115816f9SAndroid Build Coastguard Worker
59*115816f9SAndroid Build Coastguard Workerdef default_stub_files():
60*115816f9SAndroid Build Coastguard Worker    """:return: A representative sample list of stub source jars generated by the Android build using Metalava"""
61*115816f9SAndroid Build Coastguard Worker    return [
62*115816f9SAndroid Build Coastguard Worker        f"out/target/common/docs/{x}-stubs.srcjar"
63*115816f9SAndroid Build Coastguard Worker        for x in [
64*115816f9SAndroid Build Coastguard Worker            "api-stubs-docs-non-updatable",
65*115816f9SAndroid Build Coastguard Worker            "system-api-stubs-docs-non-updatable",
66*115816f9SAndroid Build Coastguard Worker            "test-api-stubs-docs-non-updatable",
67*115816f9SAndroid Build Coastguard Worker            "module-lib-api-stubs-docs-non-updatable",
68*115816f9SAndroid Build Coastguard Worker        ]
69*115816f9SAndroid Build Coastguard Worker    ]
70*115816f9SAndroid Build Coastguard Worker
71*115816f9SAndroid Build Coastguard Worker
72*115816f9SAndroid Build Coastguard Workerdef default_doc_stub_files():
73*115816f9SAndroid Build Coastguard Worker    """:return: A representative sample list of doc stub source jars generated by the Android build using Metalava"""
74*115816f9SAndroid Build Coastguard Worker    return [
75*115816f9SAndroid Build Coastguard Worker        "out/target/common/docs/framework-doc-stubs-stubs.srcjar",
76*115816f9SAndroid Build Coastguard Worker        "out/target/common/docs/framework-doc-system-stubs-stubs.srcjar",
77*115816f9SAndroid Build Coastguard Worker    ]
78*115816f9SAndroid Build Coastguard Worker
79*115816f9SAndroid Build Coastguard Worker
80*115816f9SAndroid Build Coastguard Workerdef default_api_version_files():
81*115816f9SAndroid Build Coastguard Worker    """:return: A representative sample list of `api-versions.xml` files generated by the Android build using
82*115816f9SAndroid Build Coastguard Worker
83*115816f9SAndroid Build Coastguard Worker    Metalava.
84*115816f9SAndroid Build Coastguard Worker    """
85*115816f9SAndroid Build Coastguard Worker    return [
86*115816f9SAndroid Build Coastguard Worker        "out/soong/lint/api_versions_public.xml",
87*115816f9SAndroid Build Coastguard Worker        "out/soong/lint/api_versions_system.xml",
88*115816f9SAndroid Build Coastguard Worker        "out/soong/lint/api_versions_module_lib.xml",
89*115816f9SAndroid Build Coastguard Worker        "out/soong/lint/api_versions_system_server.xml",
90*115816f9SAndroid Build Coastguard Worker        "out/target/common/obj/PACKAGING/api_versions_module_lib_complete_generated-api-versions.xml",
91*115816f9SAndroid Build Coastguard Worker        "out/target/common/obj/PACKAGING/api_versions_system_server_complete_generated-api-versions.xml",
92*115816f9SAndroid Build Coastguard Worker    ]
93*115816f9SAndroid Build Coastguard Worker
94*115816f9SAndroid Build Coastguard Worker
95*115816f9SAndroid Build Coastguard Workerdef default_jdiff_files():
96*115816f9SAndroid Build Coastguard Worker    """:return: A representative sample list of JDiff files created by the Android build using Metalava."""
97*115816f9SAndroid Build Coastguard Worker    return [
98*115816f9SAndroid Build Coastguard Worker        # JDiff files generated from jar files.
99*115816f9SAndroid Build Coastguard Worker        "out/target/common/obj/api.xml",
100*115816f9SAndroid Build Coastguard Worker        "out/target/common/obj/system-api.xml",
101*115816f9SAndroid Build Coastguard Worker        "out/target/common/obj/module-lib-api.xml",
102*115816f9SAndroid Build Coastguard Worker        "out/target/common/obj/system-server-api.xml",
103*115816f9SAndroid Build Coastguard Worker        "out/target/common/obj/test-api.xml",
104*115816f9SAndroid Build Coastguard Worker        # JDiff files generated from txt files.
105*115816f9SAndroid Build Coastguard Worker        "out/soong/.intermediates/packages/services/Car/car-lib/android.car-test-stubs-jdiff/gen/car-test-api.xml",
106*115816f9SAndroid Build Coastguard Worker        "out/soong/.intermediates/packages/services/Car/car-lib/android.car-stubs-jdiff/gen/car-api.xml",
107*115816f9SAndroid Build Coastguard Worker        "out/soong/.intermediates/packages/services/Car/car-lib/android.car-system-stubs-jdiff/gen/car-system-api.xml",
108*115816f9SAndroid Build Coastguard Worker        ""# JDiff files generated from txt files and then compressed using gzip..
109*115816f9SAndroid Build Coastguard Worker        "out/soong/.intermediates/cts/tests/signature/api/cts-android-test-base-current-api-gz/gen/android-test-base-current.api.gz",
110*115816f9SAndroid Build Coastguard Worker        "out/soong/.intermediates/cts/tests/signature/api/cts-android-test-mock-current-api-gz/gen/android-test-mock-current.api.gz",
111*115816f9SAndroid Build Coastguard Worker        "out/soong/.intermediates/cts/tests/signature/api/cts-android-test-runner-current-api-gz/gen/android-test-runner-current.api.gz",
112*115816f9SAndroid Build Coastguard Worker        "out/soong/.intermediates/cts/tests/signature/api/cts-apache-http-legacy-current-api-gz/gen/apache-http-legacy-current.api.gz",
113*115816f9SAndroid Build Coastguard Worker        "out/soong/.intermediates/cts/tests/signature/api/cts-car-system-current-api-gz/gen/car-system-current.api.gz",
114*115816f9SAndroid Build Coastguard Worker        "out/soong/.intermediates/cts/tests/signature/api/cts-current-api-gz/android_common/gen/current.api.gz",
115*115816f9SAndroid Build Coastguard Worker        "out/soong/.intermediates/cts/tests/signature/api/cts-system-current-api-gz/android_common/gen/system-current.api.gz",
116*115816f9SAndroid Build Coastguard Worker        "out/soong/.intermediates/cts/tests/signature/api/cts-system-removed-api-gz/android_common/gen/system-removed.api.gz",
117*115816f9SAndroid Build Coastguard Worker
118*115816f9SAndroid Build Coastguard Worker    ]
119*115816f9SAndroid Build Coastguard Worker
120*115816f9SAndroid Build Coastguard Worker
121*115816f9SAndroid Build Coastguard Workerdef default_dex_writer_files():
122*115816f9SAndroid Build Coastguard Worker    """:return: A representative sample list of dex writer related files created by the Android build using Metalava."""
123*115816f9SAndroid Build Coastguard Worker    return [
124*115816f9SAndroid Build Coastguard Worker        # This is not actually a dex writer file but it contains information derived from lots of dex writer files so
125*115816f9SAndroid Build Coastguard Worker        # any differences in the dex writer files will affect this file.
126*115816f9SAndroid Build Coastguard Worker        "out/soong/hiddenapi/hiddenapi-flags.csv",
127*115816f9SAndroid Build Coastguard Worker    ]
128*115816f9SAndroid Build Coastguard Worker
129*115816f9SAndroid Build Coastguard Worker
130*115816f9SAndroid Build Coastguard Workerdef default_custom_files(top):
131*115816f9SAndroid Build Coastguard Worker    """Returns a representative sample list of custom files created by the Android build using a custom tool based, at
132*115816f9SAndroid Build Coastguard Worker
133*115816f9SAndroid Build Coastguard Worker    least in part, on Metalava.
134*115816f9SAndroid Build Coastguard Worker    :return: A list of custom files.
135*115816f9SAndroid Build Coastguard Worker    """
136*115816f9SAndroid Build Coastguard Worker    product_out = Path(os.environ.get("ANDROID_PRODUCT_OUT")).relative_to(top)
137*115816f9SAndroid Build Coastguard Worker    return [
138*115816f9SAndroid Build Coastguard Worker        f"{product_out}/obj/ETC/flag-api-mapping-{surface}_intermediates/flag-api-mapping-{surface}"
139*115816f9SAndroid Build Coastguard Worker        for surface in [
140*115816f9SAndroid Build Coastguard Worker            "PublicApi",
141*115816f9SAndroid Build Coastguard Worker            "SystemApi",
142*115816f9SAndroid Build Coastguard Worker            "ModuleLibApi",
143*115816f9SAndroid Build Coastguard Worker            "SystemServerApi",
144*115816f9SAndroid Build Coastguard Worker        ]
145*115816f9SAndroid Build Coastguard Worker    ]
146*115816f9SAndroid Build Coastguard Worker
147*115816f9SAndroid Build Coastguard Worker
148*115816f9SAndroid Build Coastguard Workerdef construct_target_list(args, top):
149*115816f9SAndroid Build Coastguard Worker    """Generate a list of targets from the supplied arguments
150*115816f9SAndroid Build Coastguard Worker
151*115816f9SAndroid Build Coastguard Worker    :param args: the command line arguments.
152*115816f9SAndroid Build Coastguard Worker    :return: a non-empty list of targets to build.
153*115816f9SAndroid Build Coastguard Worker    """
154*115816f9SAndroid Build Coastguard Worker    targets = []
155*115816f9SAndroid Build Coastguard Worker    # If any custom options have been provided then build them.
156*115816f9SAndroid Build Coastguard Worker    if args.stub_src_jar:
157*115816f9SAndroid Build Coastguard Worker        targets += args.stub_src_jar
158*115816f9SAndroid Build Coastguard Worker    # If no custom targets have been provided then use the default targets.
159*115816f9SAndroid Build Coastguard Worker    if not targets:
160*115816f9SAndroid Build Coastguard Worker        targets += default_stub_files()
161*115816f9SAndroid Build Coastguard Worker        targets += default_doc_stub_files()
162*115816f9SAndroid Build Coastguard Worker        targets += default_jdiff_files()
163*115816f9SAndroid Build Coastguard Worker        targets += default_api_version_files()
164*115816f9SAndroid Build Coastguard Worker        targets += default_dex_writer_files()
165*115816f9SAndroid Build Coastguard Worker        targets += default_custom_files(top)
166*115816f9SAndroid Build Coastguard Worker    return targets
167*115816f9SAndroid Build Coastguard Worker
168*115816f9SAndroid Build Coastguard Worker
169*115816f9SAndroid Build Coastguard Workerdef main(args):
170*115816f9SAndroid Build Coastguard Worker    top = os.environ.get("ANDROID_BUILD_TOP")
171*115816f9SAndroid Build Coastguard Worker    if not top:
172*115816f9SAndroid Build Coastguard Worker        raise Exception("ANDROID_BUILD_TOP not specified")
173*115816f9SAndroid Build Coastguard Worker    os.chdir(top)
174*115816f9SAndroid Build Coastguard Worker
175*115816f9SAndroid Build Coastguard Worker    # Parse command line arguments.
176*115816f9SAndroid Build Coastguard Worker    args = parse_command_line_args(args)
177*115816f9SAndroid Build Coastguard Worker
178*115816f9SAndroid Build Coastguard Worker    # Make sure that the output directory does not already exist.
179*115816f9SAndroid Build Coastguard Worker    output_dir = Path(args.directory)
180*115816f9SAndroid Build Coastguard Worker    if output_dir.exists():
181*115816f9SAndroid Build Coastguard Worker        raise Exception(f"{output_dir} exists, please delete or change")
182*115816f9SAndroid Build Coastguard Worker
183*115816f9SAndroid Build Coastguard Worker    # Construct the list of targets to build, using defaults where required.
184*115816f9SAndroid Build Coastguard Worker    targets = construct_target_list(args, top)
185*115816f9SAndroid Build Coastguard Worker
186*115816f9SAndroid Build Coastguard Worker    # Build the targets.
187*115816f9SAndroid Build Coastguard Worker    build_targets(targets)
188*115816f9SAndroid Build Coastguard Worker
189*115816f9SAndroid Build Coastguard Worker    # Create the output directory and copy the targets into it.
190*115816f9SAndroid Build Coastguard Worker    copy_targets(output_dir, targets)
191*115816f9SAndroid Build Coastguard Worker
192*115816f9SAndroid Build Coastguard Worker
193*115816f9SAndroid Build Coastguard Workerdef copy_targets(output_dir, targets):
194*115816f9SAndroid Build Coastguard Worker    print(f"Making output directory: '{output_dir}'")
195*115816f9SAndroid Build Coastguard Worker    os.mkdir(output_dir)
196*115816f9SAndroid Build Coastguard Worker    print()
197*115816f9SAndroid Build Coastguard Worker    print(f"Copying the following targets into '{output_dir}':")
198*115816f9SAndroid Build Coastguard Worker    for t in targets:
199*115816f9SAndroid Build Coastguard Worker        print(f"    {t}")
200*115816f9SAndroid Build Coastguard Worker        shutil.copy(t, output_dir)
201*115816f9SAndroid Build Coastguard Worker    print()
202*115816f9SAndroid Build Coastguard Worker
203*115816f9SAndroid Build Coastguard Worker
204*115816f9SAndroid Build Coastguard Workerdef build_targets(targets):
205*115816f9SAndroid Build Coastguard Worker    print()
206*115816f9SAndroid Build Coastguard Worker    print("Building the following targets:")
207*115816f9SAndroid Build Coastguard Worker    for t in targets:
208*115816f9SAndroid Build Coastguard Worker        print(f"    {t}")
209*115816f9SAndroid Build Coastguard Worker    print()
210*115816f9SAndroid Build Coastguard Worker    subprocess.run(
211*115816f9SAndroid Build Coastguard Worker        ["build/soong/soong_ui.bash", "--make-mode"] + targets, check=True
212*115816f9SAndroid Build Coastguard Worker    )
213*115816f9SAndroid Build Coastguard Worker    print()
214*115816f9SAndroid Build Coastguard Worker
215*115816f9SAndroid Build Coastguard Worker
216*115816f9SAndroid Build Coastguard Workerif __name__ == "__main__":
217*115816f9SAndroid Build Coastguard Worker    main(sys.argv[1:])
218