xref: /aosp_15_r20/external/cronet/components/cronet/tools/generate_proguard_file.py (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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