Build scope targets corresponding to each module sdk.

In order to detect the addition of any new APIs in any mainline module,
an API diff file (current module sdk vs the last finalized module sdk)
needs to be generated correpsonding to each module sdk.

To obtain the list of APIs in the last finalized module sdk, the latest
build targets correpsonding to each scope of each module sdk are
obtained and needs to be built.

This CL is fetching all the module sdk scope targets from the .info
file corresponding to each module sdk file and then building all those
targets.

This CL is also adding changes to the test file
mainline_modules_sdks_test.py to mock the generation of module sdk
snapshot info files and the latest api text files for module sdk
scope targets.

The follow up CLs will generate the API diff files corresponding to
each module sdk and copy that to the out/dist directory. And will
also contain the tests to verify the generation of api diff files.

Bug: 230609867
Test: build packages/modules/common/build/mainline_modules_sdks.py
successfully and builds all the scope targets for each module sdk.
"atest mainline_modules_sdks_test" passes

Change-Id: I9e0c08d3a8bbf60e9b5cb61389c155948c4c171e
This commit is contained in:
Gurpreet Singh
2022-05-20 16:08:30 +00:00
parent 1ce8f0edaf
commit 571ce869cc
2 changed files with 106 additions and 0 deletions

View File

@@ -21,6 +21,7 @@ the APEXes in it are built, otherwise all configured SDKs are built.
import argparse
import dataclasses
import io
import json
import os
import re
import shutil
@@ -221,6 +222,11 @@ def sdk_snapshot_zip_file(snapshots_dir, sdk_name, sdk_version):
return os.path.join(snapshots_dir, f"{sdk_name}-{sdk_version}.zip")
def sdk_snapshot_info_file(snapshots_dir, sdk_name, sdk_version):
"""Get the path to the sdk snapshot info file."""
return os.path.join(snapshots_dir, f"{sdk_name}-{sdk_version}.info")
@dataclasses.dataclass()
class SnapshotBuilder:
"""Builds sdk snapshots"""
@@ -381,6 +387,48 @@ java_sdk_library_import {{
return r_snapshot_dir
@staticmethod
def does_sdk_library_support_latest_api(sdk_library):
# TODO(b/235330409): remove service art from the exception list once
# this bug is fixed.
if sdk_library == "service-art" or \
sdk_library == "conscrypt.module.platform.api":
return False
return True
def latest_api_file_targets(self, sdk_info_file):
# Read the sdk info file and fetch the latest scope targets.
with open(sdk_info_file, "r") as sdk_info_file_object:
sdk_info_file_json = json.loads(sdk_info_file_object.read())
target_paths = []
for jsonItem in sdk_info_file_json:
if not jsonItem["@type"] == "java_sdk_library":
continue
if not self.does_sdk_library_support_latest_api(jsonItem["@name"]):
continue
for scope in jsonItem["scopes"]:
target_paths.append(jsonItem["scopes"][scope]["latest_api"])
target_paths.append(
jsonItem["scopes"][scope]["latest_removed_api"])
return target_paths
def build_sdk_scope_targets(self, build_release, sdk_version, modules):
# Build the latest scope targets for each module sdk
# Compute the paths to all the latest scope targets for each module sdk.
target_paths = []
for module in modules:
for sdk in module.sdks:
if "host-exports" in sdk or "test-exports" in sdk:
continue
sdk_info_file = sdk_snapshot_info_file(self.mainline_sdks_dir,
sdk, sdk_version)
target_paths.extend(self.latest_api_file_targets(sdk_info_file))
self.build_target_paths(build_release, sdk_version, target_paths)
# A list of the sdk versions to build. Usually just current but can include a
# numeric version too.
@@ -856,6 +904,9 @@ class SdkDistProducer:
sdk_versions = build_release.sdk_versions
snapshots_dir = self.snapshot_builder.build_snapshots(
build_release, sdk_versions, modules)
if build_release.name == LATEST:
self.snapshot_builder.build_sdk_scope_targets(
build_release, sdk_versions[0], modules)
self.populate_unbundled_dist(build_release, sdk_versions, modules,
snapshots_dir)
return snapshots_dir
@@ -875,6 +926,8 @@ class SdkDistProducer:
for module in modules:
for sdk_version in sdk_versions:
for sdk in module.sdks:
# TODO(b/230609867): create API diff file for each module
# sdk.
sdk_dist_dir = os.path.join(build_release_dist_dir,
sdk_version)
self.populate_dist_snapshot(build_release, module, sdk,

View File

@@ -74,6 +74,59 @@ class FakeSnapshotBuilder(mm.SnapshotBuilder):
module.for_r_build)
return sdks_out_dir
def get_art_module_info_file_data(self):
info_file_data = f"""[
{{
"@type": "java_sdk_library",
"@name": "art.module.public.api",
"@deps": [
"libcore_license"
],
"dist_stem": "art",
"scopes": {{
"public": {{
"current_api": "sdk_library/public/art.module.public.api.txt",
"latest_api": "{Path(self.mainline_sdks_dir).joinpath("test")}/prebuilts/sdk/art.api.public.latest/gen/art.api.public.latest",
"latest_removed_api": "{Path(self.mainline_sdks_dir).joinpath("test")}/prebuilts/sdk/art-removed.api.public.latest/gen/art-removed.api.public.latest",
"removed_api": "sdk_library/public/art.module.public.api-removed.txt"
}}
}}
}}
]
"""
return info_file_data
@staticmethod
def write_data_to_file(file, data):
with open(file, "w") as file:
file.write(data)
def create_snapshot_info_file(self, module, sdk_info_file):
if module == MAINLINE_MODULES_BY_APEX["com.android.art"]:
self.write_data_to_file(sdk_info_file,
self.get_art_module_info_file_data())
else:
# For rest of the modules, generate an empty .info file.
self.write_data_to_file(sdk_info_file, "[]")
def build_sdk_scope_targets(self, build_release, sdk_version, modules):
target_paths = []
for module in modules:
for sdk in module.sdks:
if "host-exports" in sdk or "test-exports" in sdk:
continue
sdk_info_file = mm.sdk_snapshot_info_file(
Path(self.mainline_sdks_dir).joinpath("test"), sdk,
sdk_version)
self.create_snapshot_info_file(module, sdk_info_file)
target_paths.extend(self.latest_api_file_targets(sdk_info_file))
for target_path in target_paths:
os.makedirs(os.path.split(target_path)[0])
self.write_data_to_file(target_path, "")
# TODO(b/230609867): Add test to verify api diff file generation.
class TestProduceDist(unittest.TestCase):