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