diff options
Diffstat (limited to 'analyze_matrix/dump_hals_for_release.py')
-rwxr-xr-x | analyze_matrix/dump_hals_for_release.py | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/analyze_matrix/dump_hals_for_release.py b/analyze_matrix/dump_hals_for_release.py new file mode 100755 index 0000000..47519c6 --- /dev/null +++ b/analyze_matrix/dump_hals_for_release.py | |||
@@ -0,0 +1,110 @@ | |||
1 | #!/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 | # | ||
17 | |||
18 | """ | ||
19 | Dump new HIDL types that are introduced in each FCM version. | ||
20 | """ | ||
21 | |||
22 | from __future__ import print_function | ||
23 | |||
24 | import argparse | ||
25 | import collections | ||
26 | import json | ||
27 | import os | ||
28 | import subprocess | ||
29 | import sys | ||
30 | |||
31 | class Globals: | ||
32 | pass | ||
33 | |||
34 | def call(args): | ||
35 | if Globals.verbose: | ||
36 | print(' '.join(args), file=sys.stderr) | ||
37 | sp = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) | ||
38 | out, err = sp.communicate() | ||
39 | return sp.returncode, out.decode(), err.decode() | ||
40 | |||
41 | def check_call(args): | ||
42 | r, o, e = call(args) | ||
43 | assert not r, '`{}` returns {}'.format(' '.join(args), r) | ||
44 | return o, e | ||
45 | |||
46 | def lines(o): | ||
47 | return filter(lambda line: line, (line.strip() for line in o.split())) | ||
48 | |||
49 | def to_level(s): | ||
50 | if s == 'legacy': return 0 | ||
51 | if s == '': return float('inf') | ||
52 | return int(s) | ||
53 | |||
54 | def main(): | ||
55 | parser = argparse.ArgumentParser(description=__doc__) | ||
56 | parser.add_argument('--verbose', help='Verbose mode', action='store_true') | ||
57 | parser.add_argument('--pretty', help='Print pretty JSON', action='store_true') | ||
58 | parser.add_argument('--hidl-gen', help='Location of hidl-gen', required=True) | ||
59 | parser.add_argument('--analyze-matrix', help='Location of analyze_matrix', required=True) | ||
60 | parser.add_argument('--compatibility-matrix', metavar='FILE', | ||
61 | help='Location of framework compatibility matrices', nargs='+', required=True) | ||
62 | parser.add_argument('--package-root', metavar='PACKAGE:PATH', | ||
63 | help='package roots provided to hidl-gen, e.g. android.hardware:hardware/interfaces', | ||
64 | nargs='+') | ||
65 | parser.parse_args(namespace=Globals) | ||
66 | |||
67 | interfaces_for_level = dict() | ||
68 | for matrix_path in Globals.compatibility_matrix: | ||
69 | r, o, _ = call([Globals.analyze_matrix, '--input', matrix_path, '--level']) | ||
70 | if r: | ||
71 | # Not a compatibility matrix, ignore | ||
72 | continue | ||
73 | # stderr may contain warning message if level is empty | ||
74 | level = o.strip() | ||
75 | |||
76 | o, _ = check_call([Globals.analyze_matrix, '--input', matrix_path, '--interfaces']) | ||
77 | # stderr may contain warning message if no interfaces | ||
78 | |||
79 | interfaces = list(lines(o)) | ||
80 | if not interfaces: continue | ||
81 | |||
82 | if level not in interfaces_for_level: | ||
83 | interfaces_for_level[level] = set() | ||
84 | |||
85 | # Put top level interfaces | ||
86 | interfaces_for_level[level].update(interfaces) | ||
87 | |||
88 | # Put interfaces referenced by top level interfaces | ||
89 | args = [Globals.hidl_gen, '-Ldependencies'] | ||
90 | if Globals.package_root: | ||
91 | args.append('-R') | ||
92 | for package_root in Globals.package_root: | ||
93 | args.extend(['-r', package_root]) | ||
94 | args.extend(interfaces) | ||
95 | o, e = check_call(args) | ||
96 | assert not e, '`{}` has written to stderr:\n{}'.format(' '.join(args), e) | ||
97 | interfaces_for_level[level].update(lines(o)) | ||
98 | |||
99 | seen_interfaces = set() | ||
100 | new_interfaces_for_level = collections.OrderedDict() | ||
101 | for level, interfaces in sorted(interfaces_for_level.items(), key=lambda tup: to_level(tup[0])): | ||
102 | new_interfaces_for_level[level] = sorted(interfaces - seen_interfaces) | ||
103 | seen_interfaces.update(interfaces) | ||
104 | |||
105 | print(json.dumps(new_interfaces_for_level, | ||
106 | separators=None if Globals.pretty else (',',':'), | ||
107 | indent=4 if Globals.pretty else None)) | ||
108 | |||
109 | if __name__ == '__main__': | ||
110 | main() | ||