1#!/usr/bin/env python3 2# 3# Copyright 2016 The Chromium Authors 4# Use of this source code is governed by a BSD-style license that can be 5# found in the LICENSE file. 6 7# Tool that combines a sequence of input proguard files and outputs a single 8# proguard file. 9# 10# The final output file is formed by concatenating all of the 11# input proguard files. 12 13 14import argparse 15import pathlib 16import os 17import sys 18import json 19REPOSITORY_ROOT = os.path.abspath( 20 os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, os.pardir)) 21 22sys.path.insert(0, os.path.join(REPOSITORY_ROOT, 'build')) 23import action_helpers # pylint: disable=wrong-import-position 24 25def _ReadFile(path): 26 """Reads a file as a string.""" 27 return pathlib.Path(path).read_text() 28 29 30def ReadProguardConfigsPath(build_config_path): 31 """ 32 Reads the transitive proguard configs path of target whose build 33 config path is `build_config_path` 34 35 @param path: The path to the initial build_config 36 @returns A set of the proguard config paths found during traversal. 37 """ 38 proguard_configs_path = set() 39 with open(build_config_path, 'r') as f: 40 build_config = json.load(f) 41 proguard_configs_path.update(build_config["deps_info"].get( 42 "proguard_all_configs", set())) 43 # java_library targets don't have `proguard_all_configs` so we need 44 # to look at `proguard_configs` field instead. 45 proguard_configs_path.update(build_config["deps_info"].get( 46 "proguard_configs", set())) 47 return proguard_configs_path 48 49def main(): 50 parser = argparse.ArgumentParser() 51 parser.add_argument('--output_file', 52 help='Output file for the generated proguard file') 53 parser.add_argument('--dep_file', 54 help='Depfile path to write the implicit inputs') 55 56 args, input_files = parser.parse_known_args() 57 # Fetch all proguard configs 58 all_proguard_configs_path = set() 59 for input_file in input_files: 60 all_proguard_configs_path.update(ReadProguardConfigsPath(input_file)) 61 # Concatenate all proguard rules 62 with open(args.output_file, 'w') as target: 63 # Sort to maintain deterministic output. 64 for proguard_config_path in sorted(all_proguard_configs_path): 65 target.write( 66 f"# -------- Config Path: {proguard_config_path.replace('../', '')} --------\n" 67 ) 68 target.write(_ReadFile(proguard_config_path)) 69 action_helpers.write_depfile( 70 args.dep_file, args.output_file, all_proguard_configs_path) 71 72 73 74if __name__ == '__main__': 75 sys.exit(main()) 76