blob: e24995ecb0c4196f35dd078829bba4f9b3c8b187 [file] [log] [blame]
Paul Duffindfa10832021-05-13 17:31:51 +01001#!/usr/bin/env python
2#
3# Copyright (C) 2018 The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16"""
17Verify that one set of hidden API flags is a subset of another.
18"""
19
20import argparse
21import csv
22
Paul Duffindfa10832021-05-13 17:31:51 +010023def dict_reader(input):
24 return csv.DictReader(input, delimiter=',', quotechar='|', fieldnames=['signature'])
25
Paul Duffin428c6512021-07-21 15:33:22 +010026def read_signature_csv_from_stream_as_dict(stream):
27 """
28 Read the csv contents from the stream into a dict. The first column is assumed to be the
29 signature and used as the key. The whole row is stored as the value.
30
31 :param stream: the csv contents to read
32 :return: the dict from signature to row.
33 """
34 dict = {}
35 reader = dict_reader(stream)
36 for row in reader:
Paul Duffindfa10832021-05-13 17:31:51 +010037 signature = row['signature']
Paul Duffin428c6512021-07-21 15:33:22 +010038 dict[signature] = row
39 return dict
Paul Duffindfa10832021-05-13 17:31:51 +010040
Paul Duffin428c6512021-07-21 15:33:22 +010041def read_signature_csv_from_file_as_dict(csvFile):
42 """
43 Read the csvFile into a dict. The first column is assumed to be the
44 signature and used as the key. The whole row is stored as the value.
45
46 :param csvFile: the csv file to read
47 :return: the dict from signature to row.
48 """
49 with open(csvFile, 'r') as f:
50 return read_signature_csv_from_stream_as_dict(f)
51
52def compare_signature_flags(monolithicFlagsDict, modularFlagsDict):
53 """
54 Compare the signature flags between the two dicts.
55
56 :param monolithicFlagsDict: the dict containing the subset of the monolithic
57 flags that should be equal to the modular flags.
58 :param modularFlagsDict:the dict containing the flags produced by a single
59 bootclasspath_fragment module.
60 :return: list of mismatches., each mismatch is a tuple where the first item
61 is the signature, and the second and third items are lists of the flags from
62 modular dict, and monolithic dict respectively.
63 """
Paul Duffindfa10832021-05-13 17:31:51 +010064 mismatchingSignatures = []
Paul Duffin428c6512021-07-21 15:33:22 +010065 for signature, modularRow in modularFlagsDict.items():
66 modularFlags = modularRow.get(None, [])
67 monolithicRow = monolithicFlagsDict.get(signature, {})
68 monolithicFlags = monolithicRow.get(None, [])
69 if monolithicFlags != modularFlags:
70 mismatchingSignatures.append((signature, modularFlags, monolithicFlags))
71 return mismatchingSignatures
Paul Duffindfa10832021-05-13 17:31:51 +010072
Paul Duffin428c6512021-07-21 15:33:22 +010073def main(argv):
74 args_parser = argparse.ArgumentParser(description='Verify that one set of hidden API flags is a subset of another.')
75 args_parser.add_argument('all', help='All the flags')
76 args_parser.add_argument('subsets', nargs=argparse.REMAINDER, help='Subsets of the flags')
77 args = args_parser.parse_args(argv[1:])
Paul Duffindfa10832021-05-13 17:31:51 +010078
Paul Duffin428c6512021-07-21 15:33:22 +010079 # Read in all the flags into a dict indexed by signature
80 allFlagsBySignature = read_signature_csv_from_file_as_dict(args.all)
Paul Duffindfa10832021-05-13 17:31:51 +010081
Paul Duffin428c6512021-07-21 15:33:22 +010082 failed = False
83 for subsetPath in args.subsets:
84 subsetDict = read_signature_csv_from_file_as_dict(subsetPath)
85 mismatchingSignatures = compare_signature_flags(allFlagsBySignature, subsetDict)
86 if mismatchingSignatures:
87 failed = True
88 print("ERROR: Hidden API flags are inconsistent:")
89 print("< " + subsetPath)
90 print("> " + args.all)
91 for mismatch in mismatchingSignatures:
92 signature = mismatch[0]
93 print()
94 print("< " + ",".join([signature]+ mismatch[1]))
95 print("> " + ",".join([signature]+ mismatch[2]))
96
97 if failed:
98 sys.exit(1)
99
100if __name__ == "__main__":
101 main(sys.argv)