1*9e94795aSAndroid Build Coastguard Worker#!/usr/bin/env python3 2*9e94795aSAndroid Build Coastguard Worker# 3*9e94795aSAndroid Build Coastguard Worker# Copyright (C) 2023 The Android Open Source Project 4*9e94795aSAndroid Build Coastguard Worker# 5*9e94795aSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 6*9e94795aSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 7*9e94795aSAndroid Build Coastguard Worker# You may obtain a copy of the License at 8*9e94795aSAndroid Build Coastguard Worker# 9*9e94795aSAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 10*9e94795aSAndroid Build Coastguard Worker# 11*9e94795aSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 12*9e94795aSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 13*9e94795aSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14*9e94795aSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 15*9e94795aSAndroid Build Coastguard Worker# limitations under the License. 16*9e94795aSAndroid Build Coastguard Worker"""Create Aconfig value building rules. 17*9e94795aSAndroid Build Coastguard Worker 18*9e94795aSAndroid Build Coastguard WorkerThis script will help to create Aconfig flag value building rules. It will 19*9e94795aSAndroid Build Coastguard Workerparse necessary information in the value file to create the building rules, but 20*9e94795aSAndroid Build Coastguard Workerit will not validate the value file. The validation will defer to the building 21*9e94795aSAndroid Build Coastguard Workersystem. 22*9e94795aSAndroid Build Coastguard Worker""" 23*9e94795aSAndroid Build Coastguard Worker 24*9e94795aSAndroid Build Coastguard Workerimport argparse 25*9e94795aSAndroid Build Coastguard Workerimport pathlib 26*9e94795aSAndroid Build Coastguard Workerimport re 27*9e94795aSAndroid Build Coastguard Workerimport sys 28*9e94795aSAndroid Build Coastguard Worker 29*9e94795aSAndroid Build Coastguard Worker 30*9e94795aSAndroid Build Coastguard Worker_VALUE_LIST_TEMPLATE: str = """ 31*9e94795aSAndroid Build Coastguard WorkerACONFIG_VALUES_LIST_LOCAL = [{}] 32*9e94795aSAndroid Build Coastguard Worker""" 33*9e94795aSAndroid Build Coastguard Worker 34*9e94795aSAndroid Build Coastguard Worker_ACONFIG_VALUES_TEMPLATE: str = """ 35*9e94795aSAndroid Build Coastguard Workeraconfig_values {{ 36*9e94795aSAndroid Build Coastguard Worker name: "{}", 37*9e94795aSAndroid Build Coastguard Worker package: "{}", 38*9e94795aSAndroid Build Coastguard Worker srcs: [ 39*9e94795aSAndroid Build Coastguard Worker "{}", 40*9e94795aSAndroid Build Coastguard Worker ] 41*9e94795aSAndroid Build Coastguard Worker}} 42*9e94795aSAndroid Build Coastguard Worker""" 43*9e94795aSAndroid Build Coastguard Worker 44*9e94795aSAndroid Build Coastguard Worker_ACONFIG_VALUES_NAME_SUFFIX: str = "aconfig-local-override-{}" 45*9e94795aSAndroid Build Coastguard Worker 46*9e94795aSAndroid Build Coastguard Worker_PACKAGE_REGEX = re.compile(r"^package\:\s*\"([\w\d\.]+)\"") 47*9e94795aSAndroid Build Coastguard Worker_ANDROID_BP_FILE_NAME = r"Android.bp" 48*9e94795aSAndroid Build Coastguard Worker 49*9e94795aSAndroid Build Coastguard Worker 50*9e94795aSAndroid Build Coastguard Workerdef _parse_packages(file: pathlib.Path) -> set[str]: 51*9e94795aSAndroid Build Coastguard Worker packages = set() 52*9e94795aSAndroid Build Coastguard Worker with open(file) as f: 53*9e94795aSAndroid Build Coastguard Worker for line in f: 54*9e94795aSAndroid Build Coastguard Worker line = line.strip() 55*9e94795aSAndroid Build Coastguard Worker package_match = _PACKAGE_REGEX.match(line) 56*9e94795aSAndroid Build Coastguard Worker if package_match is None: 57*9e94795aSAndroid Build Coastguard Worker continue 58*9e94795aSAndroid Build Coastguard Worker package_name = package_match.group(1) 59*9e94795aSAndroid Build Coastguard Worker packages.add(package_name) 60*9e94795aSAndroid Build Coastguard Worker 61*9e94795aSAndroid Build Coastguard Worker return packages 62*9e94795aSAndroid Build Coastguard Worker 63*9e94795aSAndroid Build Coastguard Worker 64*9e94795aSAndroid Build Coastguard Workerdef _create_android_bp(packages: set[str], file_name: str) -> str: 65*9e94795aSAndroid Build Coastguard Worker android_bp = "" 66*9e94795aSAndroid Build Coastguard Worker value_list = ",\n ".join( 67*9e94795aSAndroid Build Coastguard Worker map(f'"{_ACONFIG_VALUES_NAME_SUFFIX}"'.format, packages) 68*9e94795aSAndroid Build Coastguard Worker ) 69*9e94795aSAndroid Build Coastguard Worker if value_list: 70*9e94795aSAndroid Build Coastguard Worker value_list = "\n " + value_list + "\n" 71*9e94795aSAndroid Build Coastguard Worker android_bp += _VALUE_LIST_TEMPLATE.format(value_list) + "\n" 72*9e94795aSAndroid Build Coastguard Worker 73*9e94795aSAndroid Build Coastguard Worker for package in packages: 74*9e94795aSAndroid Build Coastguard Worker android_bp += _ACONFIG_VALUES_TEMPLATE.format( 75*9e94795aSAndroid Build Coastguard Worker _ACONFIG_VALUES_NAME_SUFFIX.format(package), package, file_name 76*9e94795aSAndroid Build Coastguard Worker ) 77*9e94795aSAndroid Build Coastguard Worker android_bp += "\n" 78*9e94795aSAndroid Build Coastguard Worker 79*9e94795aSAndroid Build Coastguard Worker return android_bp 80*9e94795aSAndroid Build Coastguard Worker 81*9e94795aSAndroid Build Coastguard Worker 82*9e94795aSAndroid Build Coastguard Workerdef _write_android_bp(new_android_bp: str, out: pathlib.Path) -> None: 83*9e94795aSAndroid Build Coastguard Worker if not out.is_dir(): 84*9e94795aSAndroid Build Coastguard Worker out.mkdir(parents=True, exist_ok=True) 85*9e94795aSAndroid Build Coastguard Worker 86*9e94795aSAndroid Build Coastguard Worker output = out.joinpath(_ANDROID_BP_FILE_NAME) 87*9e94795aSAndroid Build Coastguard Worker with open(output, "r+", encoding="utf8") as file: 88*9e94795aSAndroid Build Coastguard Worker lines = [] 89*9e94795aSAndroid Build Coastguard Worker for line in file: 90*9e94795aSAndroid Build Coastguard Worker line = line.rstrip("\n") 91*9e94795aSAndroid Build Coastguard Worker if line.startswith("ACONFIG_VALUES_LIST_LOCAL"): 92*9e94795aSAndroid Build Coastguard Worker break 93*9e94795aSAndroid Build Coastguard Worker lines.append(line) 94*9e94795aSAndroid Build Coastguard Worker # Overwrite the file with the updated contents. 95*9e94795aSAndroid Build Coastguard Worker file.seek(0) 96*9e94795aSAndroid Build Coastguard Worker file.truncate() 97*9e94795aSAndroid Build Coastguard Worker file.write("\n".join(lines)) 98*9e94795aSAndroid Build Coastguard Worker file.write(new_android_bp) 99*9e94795aSAndroid Build Coastguard Worker 100*9e94795aSAndroid Build Coastguard Worker 101*9e94795aSAndroid Build Coastguard Workerdef main(args): 102*9e94795aSAndroid Build Coastguard Worker """Program entry point.""" 103*9e94795aSAndroid Build Coastguard Worker args_parser = argparse.ArgumentParser() 104*9e94795aSAndroid Build Coastguard Worker args_parser.add_argument( 105*9e94795aSAndroid Build Coastguard Worker "--overrides", 106*9e94795aSAndroid Build Coastguard Worker required=True, 107*9e94795aSAndroid Build Coastguard Worker help="The path to override file.", 108*9e94795aSAndroid Build Coastguard Worker ) 109*9e94795aSAndroid Build Coastguard Worker args_parser.add_argument( 110*9e94795aSAndroid Build Coastguard Worker "--out", 111*9e94795aSAndroid Build Coastguard Worker required=True, 112*9e94795aSAndroid Build Coastguard Worker help="The path to output directory.", 113*9e94795aSAndroid Build Coastguard Worker ) 114*9e94795aSAndroid Build Coastguard Worker 115*9e94795aSAndroid Build Coastguard Worker args = args_parser.parse_args(args) 116*9e94795aSAndroid Build Coastguard Worker file = pathlib.Path(args.overrides) 117*9e94795aSAndroid Build Coastguard Worker out = pathlib.Path(args.out) 118*9e94795aSAndroid Build Coastguard Worker if not file.is_file(): 119*9e94795aSAndroid Build Coastguard Worker raise FileNotFoundError(f"File '{file}' is not found") 120*9e94795aSAndroid Build Coastguard Worker 121*9e94795aSAndroid Build Coastguard Worker packages = _parse_packages(file) 122*9e94795aSAndroid Build Coastguard Worker new_android_bp = _create_android_bp(packages, file.name) 123*9e94795aSAndroid Build Coastguard Worker _write_android_bp(new_android_bp, out) 124*9e94795aSAndroid Build Coastguard Worker 125*9e94795aSAndroid Build Coastguard Worker 126*9e94795aSAndroid Build Coastguard Workerif __name__ == "__main__": 127*9e94795aSAndroid Build Coastguard Worker main(sys.argv[1:]) 128