xref: /aosp_15_r20/external/angle/src/tests/restricted_traces/gen_restricted_traces.py (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1#!/usr/bin/python3
2#
3# Copyright 2020 The ANGLE Project Authors. All rights reserved.
4# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
6#
7# gen_restricted_traces.py:
8#   Generates integration code for the restricted trace tests.
9
10import getpass
11import glob
12import fnmatch
13import re
14import json
15import os
16import sys
17
18CIPD_TRACE_PREFIX = 'angle/traces'
19EXPERIMENTAL_CIPD_PREFIX = 'experimental/google.com/%s/angle/traces'
20DEPS_PATH = '../../../DEPS'
21DEPS_START = '# === ANGLE Restricted Trace Generated Code Start ==='
22DEPS_END = '# === ANGLE Restricted Trace Generated Code End ==='
23DEPS_TEMPLATE = """\
24  'src/tests/restricted_traces/{trace}': {{
25      'packages': [
26        {{
27            'package': '{trace_prefix}/{trace}',
28            'version': 'version:{version}',
29        }},
30      ],
31      'dep_type': 'cipd',
32      'condition': 'checkout_angle_restricted_trace_{trace}',
33  }},
34"""
35
36DEPS_VAR_START = '# === ANGLE Restricted Trace Generated Var Start ==='
37DEPS_VAR_END = '# === ANGLE Restricted Trace Generated Var End ==='
38DEPS_VAR_TEMPLATE = """\
39  'checkout_angle_restricted_trace_{trace}': 'checkout_angle_restricted_traces',
40"""
41
42
43def reject_duplicate_keys(pairs):
44    found_keys = {}
45    for key, value in pairs:
46        if key in found_keys:
47            raise ValueError("duplicate key: %r" % (key,))
48        else:
49            found_keys[key] = value
50    return found_keys
51
52
53def read_json(json_file):
54    with open(json_file) as map_file:
55        return json.loads(map_file.read(), object_pairs_hook=reject_duplicate_keys)
56
57
58def write_json(json_file, data):
59    with open(json_file, 'w') as map_file:
60        json.dump(data, map_file, indent=4, sort_keys=True)
61
62
63def update_deps(trace_pairs):
64    # Generate substitution string
65    replacement = ""
66    for (trace, version) in trace_pairs:
67        if 'x' in version:
68            version = version.strip('x')
69            trace_prefix = EXPERIMENTAL_CIPD_PREFIX % getpass.getuser()
70        else:
71            trace_prefix = CIPD_TRACE_PREFIX
72        sub = {'trace': trace, 'version': version, 'trace_prefix': trace_prefix}
73        replacement += DEPS_TEMPLATE.format(**sub)
74
75    # Update DEPS to download CIPD dependencies
76    with open(DEPS_PATH) as f:
77        lines = f.readlines()
78
79    def slice_to_replace(lines, start_tag, end_tag):
80        start, end = [i for i, s in enumerate(lines) if start_tag in s or end_tag in s]
81        return slice(start + 1, end)
82
83    # Replace lines between DEPS_START and DEPS_END with new code
84    lines[slice_to_replace(lines, DEPS_START, DEPS_END)] = [replacement]
85
86    # Replace lines between DEPS_VAR_START and DEPS_VAR_END with new code
87    lines[slice_to_replace(lines, DEPS_VAR_START, DEPS_VAR_END)] = [
88        DEPS_VAR_TEMPLATE.format(trace=trace) for (trace, _) in trace_pairs
89    ]
90
91    with open(DEPS_PATH, 'w') as f:
92        f.write(''.join(lines))
93
94    return True
95
96
97def main():
98    json_file = 'restricted_traces.json'
99
100    json_data = read_json(json_file)
101    if 'traces' not in json_data:
102        print('Trace data missing traces key.')
103        return 1
104    trace_pairs = [trace.split(' ') for trace in json_data['traces']]
105    traces = [trace_pair[0] for trace_pair in trace_pairs]
106
107    # auto_script parameters.
108    if len(sys.argv) > 1:
109        inputs = [json_file]
110
111        # Note: we do not include DEPS in the list of outputs to simplify the integration.
112        # Otherwise we'd continually need to regenerate on any roll. We include .gitignore
113        # in the outputs so we have a placeholder value.
114        outputs = ['.gitignore']
115
116        if sys.argv[1] == 'inputs':
117            print(','.join(inputs))
118        elif sys.argv[1] == 'outputs':
119            print(','.join(outputs))
120        else:
121            print('Invalid script parameters.')
122            return 1
123        return 0
124
125    if not update_deps(trace_pairs):
126        print('DEPS file update failed')
127        return 1
128
129    return 0
130
131
132if __name__ == '__main__':
133    sys.exit(main())
134