1*8975f5c5SAndroid Build Coastguard Worker#!/usr/bin/python3 2*8975f5c5SAndroid Build Coastguard Worker# 3*8975f5c5SAndroid Build Coastguard Worker# Copyright 2017 The ANGLE Project Authors. All rights reserved. 4*8975f5c5SAndroid Build Coastguard Worker# Use of this source code is governed by a BSD-style license that can be 5*8975f5c5SAndroid Build Coastguard Worker# found in the LICENSE file. 6*8975f5c5SAndroid Build Coastguard Worker# 7*8975f5c5SAndroid Build Coastguard Worker# run_code_generation.py: 8*8975f5c5SAndroid Build Coastguard Worker# Runs ANGLE format table and other script code generation scripts. 9*8975f5c5SAndroid Build Coastguard Worker 10*8975f5c5SAndroid Build Coastguard Workerimport argparse 11*8975f5c5SAndroid Build Coastguard Workerfrom concurrent import futures 12*8975f5c5SAndroid Build Coastguard Workerimport hashlib 13*8975f5c5SAndroid Build Coastguard Workerimport json 14*8975f5c5SAndroid Build Coastguard Workerimport os 15*8975f5c5SAndroid Build Coastguard Workerimport subprocess 16*8975f5c5SAndroid Build Coastguard Workerimport sys 17*8975f5c5SAndroid Build Coastguard Workerimport platform 18*8975f5c5SAndroid Build Coastguard Worker 19*8975f5c5SAndroid Build Coastguard Workerscript_dir = sys.path[0] 20*8975f5c5SAndroid Build Coastguard Workerroot_dir = os.path.abspath(os.path.join(script_dir, '..')) 21*8975f5c5SAndroid Build Coastguard Worker 22*8975f5c5SAndroid Build Coastguard Workerhash_dir = os.path.join(script_dir, 'code_generation_hashes') 23*8975f5c5SAndroid Build Coastguard Worker 24*8975f5c5SAndroid Build Coastguard Worker 25*8975f5c5SAndroid Build Coastguard Workerdef get_child_script_dirname(script): 26*8975f5c5SAndroid Build Coastguard Worker # All script names are relative to ANGLE's root 27*8975f5c5SAndroid Build Coastguard Worker return os.path.dirname(os.path.abspath(os.path.join(root_dir, script))) 28*8975f5c5SAndroid Build Coastguard Worker 29*8975f5c5SAndroid Build Coastguard Worker 30*8975f5c5SAndroid Build Coastguard Workerdef get_executable_name(script): 31*8975f5c5SAndroid Build Coastguard Worker with open(script, 'r') as f: 32*8975f5c5SAndroid Build Coastguard Worker # Check shebang 33*8975f5c5SAndroid Build Coastguard Worker binary = os.path.basename(f.readline().strip().replace(' ', '/')) 34*8975f5c5SAndroid Build Coastguard Worker assert binary in ['python3', 'vpython3'] 35*8975f5c5SAndroid Build Coastguard Worker if platform.system() == 'Windows': 36*8975f5c5SAndroid Build Coastguard Worker return binary + '.bat' 37*8975f5c5SAndroid Build Coastguard Worker else: 38*8975f5c5SAndroid Build Coastguard Worker return binary 39*8975f5c5SAndroid Build Coastguard Worker 40*8975f5c5SAndroid Build Coastguard Worker 41*8975f5c5SAndroid Build Coastguard Workerdef paths_from_auto_script(script, param): 42*8975f5c5SAndroid Build Coastguard Worker script_dir = get_child_script_dirname(script) 43*8975f5c5SAndroid Build Coastguard Worker # python3 (not vpython3) to get inputs/outputs faster 44*8975f5c5SAndroid Build Coastguard Worker exe = 'python3' 45*8975f5c5SAndroid Build Coastguard Worker try: 46*8975f5c5SAndroid Build Coastguard Worker res = subprocess.check_output([exe, os.path.basename(script), param], 47*8975f5c5SAndroid Build Coastguard Worker cwd=script_dir).decode().strip() 48*8975f5c5SAndroid Build Coastguard Worker except Exception: 49*8975f5c5SAndroid Build Coastguard Worker print('Error with auto_script %s: %s, executable %s' % (param, script, exe)) 50*8975f5c5SAndroid Build Coastguard Worker raise 51*8975f5c5SAndroid Build Coastguard Worker if res == '': 52*8975f5c5SAndroid Build Coastguard Worker return [] 53*8975f5c5SAndroid Build Coastguard Worker return [ 54*8975f5c5SAndroid Build Coastguard Worker os.path.relpath(os.path.join(script_dir, path), root_dir).replace("\\", "/") 55*8975f5c5SAndroid Build Coastguard Worker for path in res.split(',') 56*8975f5c5SAndroid Build Coastguard Worker ] 57*8975f5c5SAndroid Build Coastguard Worker 58*8975f5c5SAndroid Build Coastguard Worker 59*8975f5c5SAndroid Build Coastguard Worker# auto_script is a standard way for scripts to return their inputs and outputs. 60*8975f5c5SAndroid Build Coastguard Workerdef auto_script(script): 61*8975f5c5SAndroid Build Coastguard Worker info = { 62*8975f5c5SAndroid Build Coastguard Worker 'inputs': paths_from_auto_script(script, 'inputs'), 63*8975f5c5SAndroid Build Coastguard Worker 'outputs': paths_from_auto_script(script, 'outputs') 64*8975f5c5SAndroid Build Coastguard Worker } 65*8975f5c5SAndroid Build Coastguard Worker return info 66*8975f5c5SAndroid Build Coastguard Worker 67*8975f5c5SAndroid Build Coastguard Worker 68*8975f5c5SAndroid Build Coastguard Workergenerators = { 69*8975f5c5SAndroid Build Coastguard Worker 'ANGLE format': 70*8975f5c5SAndroid Build Coastguard Worker 'src/libANGLE/renderer/gen_angle_format_table.py', 71*8975f5c5SAndroid Build Coastguard Worker 'ANGLE load functions table': 72*8975f5c5SAndroid Build Coastguard Worker 'src/libANGLE/renderer/gen_load_functions_table.py', 73*8975f5c5SAndroid Build Coastguard Worker 'ANGLE shader preprocessor': 74*8975f5c5SAndroid Build Coastguard Worker 'src/compiler/preprocessor/generate_parser.py', 75*8975f5c5SAndroid Build Coastguard Worker 'ANGLE shader translator': 76*8975f5c5SAndroid Build Coastguard Worker 'src/compiler/translator/generate_parser.py', 77*8975f5c5SAndroid Build Coastguard Worker 'D3D11 blit shader selection': 78*8975f5c5SAndroid Build Coastguard Worker 'src/libANGLE/renderer/d3d/d3d11/gen_blit11helper.py', 79*8975f5c5SAndroid Build Coastguard Worker 'D3D11 format': 80*8975f5c5SAndroid Build Coastguard Worker 'src/libANGLE/renderer/d3d/d3d11/gen_texture_format_table.py', 81*8975f5c5SAndroid Build Coastguard Worker 'DXGI format': 82*8975f5c5SAndroid Build Coastguard Worker 'src/libANGLE/renderer/gen_dxgi_format_table.py', 83*8975f5c5SAndroid Build Coastguard Worker 'DXGI format support': 84*8975f5c5SAndroid Build Coastguard Worker 'src/libANGLE/renderer/gen_dxgi_support_tables.py', 85*8975f5c5SAndroid Build Coastguard Worker 'Emulated HLSL functions': 86*8975f5c5SAndroid Build Coastguard Worker 'src/compiler/translator/hlsl/gen_emulated_builtin_function_tables.py', 87*8975f5c5SAndroid Build Coastguard Worker 'Extension files': 88*8975f5c5SAndroid Build Coastguard Worker 'src/libANGLE/gen_extensions.py', 89*8975f5c5SAndroid Build Coastguard Worker 'GL copy conversion table': 90*8975f5c5SAndroid Build Coastguard Worker 'src/libANGLE/gen_copy_conversion_table.py', 91*8975f5c5SAndroid Build Coastguard Worker 'GL CTS (dEQP) build files': 92*8975f5c5SAndroid Build Coastguard Worker 'scripts/gen_vk_gl_cts_build.py', 93*8975f5c5SAndroid Build Coastguard Worker 'GL/EGL/WGL loader': 94*8975f5c5SAndroid Build Coastguard Worker 'scripts/generate_loader.py', 95*8975f5c5SAndroid Build Coastguard Worker 'GL/EGL entry points': 96*8975f5c5SAndroid Build Coastguard Worker 'scripts/generate_entry_points.py', 97*8975f5c5SAndroid Build Coastguard Worker 'GLenum value to string map': 98*8975f5c5SAndroid Build Coastguard Worker 'scripts/gen_gl_enum_utils.py', 99*8975f5c5SAndroid Build Coastguard Worker 'GL format map': 100*8975f5c5SAndroid Build Coastguard Worker 'src/libANGLE/gen_format_map.py', 101*8975f5c5SAndroid Build Coastguard Worker 'interpreter utils': 102*8975f5c5SAndroid Build Coastguard Worker 'scripts/gen_interpreter_utils.py', 103*8975f5c5SAndroid Build Coastguard Worker 'Metal format table': 104*8975f5c5SAndroid Build Coastguard Worker 'src/libANGLE/renderer/metal/gen_mtl_format_table.py', 105*8975f5c5SAndroid Build Coastguard Worker 'Metal default shaders': 106*8975f5c5SAndroid Build Coastguard Worker 'src/libANGLE/renderer/metal/shaders/gen_mtl_internal_shaders.py', 107*8975f5c5SAndroid Build Coastguard Worker 'OpenGL dispatch table': 108*8975f5c5SAndroid Build Coastguard Worker 'src/libANGLE/renderer/gl/generate_gl_dispatch_table.py', 109*8975f5c5SAndroid Build Coastguard Worker 'overlay fonts': 110*8975f5c5SAndroid Build Coastguard Worker 'src/libANGLE/gen_overlay_fonts.py', 111*8975f5c5SAndroid Build Coastguard Worker 'overlay widgets': 112*8975f5c5SAndroid Build Coastguard Worker 'src/libANGLE/gen_overlay_widgets.py', 113*8975f5c5SAndroid Build Coastguard Worker 'packed enum': 114*8975f5c5SAndroid Build Coastguard Worker 'src/common/gen_packed_gl_enums.py', 115*8975f5c5SAndroid Build Coastguard Worker 'proc table': 116*8975f5c5SAndroid Build Coastguard Worker 'scripts/gen_proc_table.py', 117*8975f5c5SAndroid Build Coastguard Worker 'restricted traces': 118*8975f5c5SAndroid Build Coastguard Worker 'src/tests/restricted_traces/gen_restricted_traces.py', 119*8975f5c5SAndroid Build Coastguard Worker 'SPIR-V helpers': 120*8975f5c5SAndroid Build Coastguard Worker 'src/common/spirv/gen_spirv_builder_and_parser.py', 121*8975f5c5SAndroid Build Coastguard Worker 'Static builtins': 122*8975f5c5SAndroid Build Coastguard Worker 'src/compiler/translator/gen_builtin_symbols.py', 123*8975f5c5SAndroid Build Coastguard Worker 'uniform type': 124*8975f5c5SAndroid Build Coastguard Worker 'src/common/gen_uniform_type_table.py', 125*8975f5c5SAndroid Build Coastguard Worker 'Vulkan format': 126*8975f5c5SAndroid Build Coastguard Worker 'src/libANGLE/renderer/vulkan/gen_vk_format_table.py', 127*8975f5c5SAndroid Build Coastguard Worker 'Vulkan internal shader programs': 128*8975f5c5SAndroid Build Coastguard Worker 'src/libANGLE/renderer/vulkan/gen_vk_internal_shaders.py', 129*8975f5c5SAndroid Build Coastguard Worker 'Vulkan mandatory format support table': 130*8975f5c5SAndroid Build Coastguard Worker 'src/libANGLE/renderer/vulkan/gen_vk_mandatory_format_support_table.py', 131*8975f5c5SAndroid Build Coastguard Worker 'WebGPU format': 132*8975f5c5SAndroid Build Coastguard Worker 'src/libANGLE/renderer/wgpu/gen_wgpu_format_table.py', 133*8975f5c5SAndroid Build Coastguard Worker} 134*8975f5c5SAndroid Build Coastguard Worker 135*8975f5c5SAndroid Build Coastguard Worker 136*8975f5c5SAndroid Build Coastguard Worker# Fast and supports --verify-only without hashes. 137*8975f5c5SAndroid Build Coastguard Workerhashless_generators = { 138*8975f5c5SAndroid Build Coastguard Worker 'ANGLE features': 'include/platform/gen_features.py', 139*8975f5c5SAndroid Build Coastguard Worker 'Test spec JSON': 'infra/specs/generate_test_spec_json.py', 140*8975f5c5SAndroid Build Coastguard Worker} 141*8975f5c5SAndroid Build Coastguard Worker 142*8975f5c5SAndroid Build Coastguard Worker 143*8975f5c5SAndroid Build Coastguard Workerdef md5(fname): 144*8975f5c5SAndroid Build Coastguard Worker hash_md5 = hashlib.md5() 145*8975f5c5SAndroid Build Coastguard Worker with open(fname, 'rb') as f: 146*8975f5c5SAndroid Build Coastguard Worker if sys.platform.startswith('win') or sys.platform == 'cygwin': 147*8975f5c5SAndroid Build Coastguard Worker # Beware: Windows crlf + git behavior + unicode in some files 148*8975f5c5SAndroid Build Coastguard Worker hash_md5.update(f.read().replace(b'\r\n', b'\n')) 149*8975f5c5SAndroid Build Coastguard Worker else: 150*8975f5c5SAndroid Build Coastguard Worker for chunk in iter(lambda: f.read(4096), b''): 151*8975f5c5SAndroid Build Coastguard Worker hash_md5.update(chunk) 152*8975f5c5SAndroid Build Coastguard Worker return hash_md5.hexdigest() 153*8975f5c5SAndroid Build Coastguard Worker 154*8975f5c5SAndroid Build Coastguard Worker 155*8975f5c5SAndroid Build Coastguard Workerdef get_hash_file_name(name): 156*8975f5c5SAndroid Build Coastguard Worker return name.replace(' ', '_').replace('/', '_') + '.json' 157*8975f5c5SAndroid Build Coastguard Worker 158*8975f5c5SAndroid Build Coastguard Worker 159*8975f5c5SAndroid Build Coastguard Workerdef any_hash_dirty(name, filenames, new_hashes, old_hashes): 160*8975f5c5SAndroid Build Coastguard Worker found_dirty_hash = False 161*8975f5c5SAndroid Build Coastguard Worker 162*8975f5c5SAndroid Build Coastguard Worker for fname in filenames: 163*8975f5c5SAndroid Build Coastguard Worker if not os.path.isfile(os.path.join(root_dir, fname)): 164*8975f5c5SAndroid Build Coastguard Worker print('File not found: "%s". Code gen dirty for %s' % (fname, name)) 165*8975f5c5SAndroid Build Coastguard Worker found_dirty_hash = True 166*8975f5c5SAndroid Build Coastguard Worker else: 167*8975f5c5SAndroid Build Coastguard Worker new_hashes[fname] = md5(fname) 168*8975f5c5SAndroid Build Coastguard Worker if (not fname in old_hashes) or (old_hashes[fname] != new_hashes[fname]): 169*8975f5c5SAndroid Build Coastguard Worker print('Hash for "%s" dirty for %s generator.' % (fname, name)) 170*8975f5c5SAndroid Build Coastguard Worker found_dirty_hash = True 171*8975f5c5SAndroid Build Coastguard Worker return found_dirty_hash 172*8975f5c5SAndroid Build Coastguard Worker 173*8975f5c5SAndroid Build Coastguard Worker 174*8975f5c5SAndroid Build Coastguard Workerdef any_old_hash_missing(all_new_hashes, all_old_hashes): 175*8975f5c5SAndroid Build Coastguard Worker result = False 176*8975f5c5SAndroid Build Coastguard Worker for file, old_hashes in all_old_hashes.items(): 177*8975f5c5SAndroid Build Coastguard Worker if file not in all_new_hashes: 178*8975f5c5SAndroid Build Coastguard Worker print('"%s" does not exist. Code gen dirty.' % file) 179*8975f5c5SAndroid Build Coastguard Worker result = True 180*8975f5c5SAndroid Build Coastguard Worker else: 181*8975f5c5SAndroid Build Coastguard Worker for name, _ in old_hashes.items(): 182*8975f5c5SAndroid Build Coastguard Worker if name not in all_new_hashes[file]: 183*8975f5c5SAndroid Build Coastguard Worker print('Hash for %s is missing from "%s". Code gen is dirty.' % (name, file)) 184*8975f5c5SAndroid Build Coastguard Worker result = True 185*8975f5c5SAndroid Build Coastguard Worker return result 186*8975f5c5SAndroid Build Coastguard Worker 187*8975f5c5SAndroid Build Coastguard Worker 188*8975f5c5SAndroid Build Coastguard Workerdef update_output_hashes(script, outputs, new_hashes): 189*8975f5c5SAndroid Build Coastguard Worker for output in outputs: 190*8975f5c5SAndroid Build Coastguard Worker if not os.path.isfile(output): 191*8975f5c5SAndroid Build Coastguard Worker print('Output is missing from %s: %s' % (script, output)) 192*8975f5c5SAndroid Build Coastguard Worker sys.exit(1) 193*8975f5c5SAndroid Build Coastguard Worker new_hashes[output] = md5(output) 194*8975f5c5SAndroid Build Coastguard Worker 195*8975f5c5SAndroid Build Coastguard Worker 196*8975f5c5SAndroid Build Coastguard Workerdef load_hashes(): 197*8975f5c5SAndroid Build Coastguard Worker hashes = {} 198*8975f5c5SAndroid Build Coastguard Worker for file in os.listdir(hash_dir): 199*8975f5c5SAndroid Build Coastguard Worker hash_fname = os.path.join(hash_dir, file) 200*8975f5c5SAndroid Build Coastguard Worker with open(hash_fname) as hash_file: 201*8975f5c5SAndroid Build Coastguard Worker try: 202*8975f5c5SAndroid Build Coastguard Worker hashes[file] = json.load(hash_file) 203*8975f5c5SAndroid Build Coastguard Worker except ValueError: 204*8975f5c5SAndroid Build Coastguard Worker raise Exception("Could not decode JSON from %s" % file) 205*8975f5c5SAndroid Build Coastguard Worker return hashes 206*8975f5c5SAndroid Build Coastguard Worker 207*8975f5c5SAndroid Build Coastguard Worker 208*8975f5c5SAndroid Build Coastguard Workerdef main(): 209*8975f5c5SAndroid Build Coastguard Worker all_old_hashes = load_hashes() 210*8975f5c5SAndroid Build Coastguard Worker all_new_hashes = {} 211*8975f5c5SAndroid Build Coastguard Worker any_dirty = False 212*8975f5c5SAndroid Build Coastguard Worker format_workaround = False 213*8975f5c5SAndroid Build Coastguard Worker 214*8975f5c5SAndroid Build Coastguard Worker parser = argparse.ArgumentParser(description='Generate ANGLE internal code.') 215*8975f5c5SAndroid Build Coastguard Worker parser.add_argument( 216*8975f5c5SAndroid Build Coastguard Worker '-v', 217*8975f5c5SAndroid Build Coastguard Worker '--verify-no-dirty', 218*8975f5c5SAndroid Build Coastguard Worker dest='verify_only', 219*8975f5c5SAndroid Build Coastguard Worker action='store_true', 220*8975f5c5SAndroid Build Coastguard Worker help='verify hashes are not dirty') 221*8975f5c5SAndroid Build Coastguard Worker parser.add_argument( 222*8975f5c5SAndroid Build Coastguard Worker '-g', '--generator', action='append', nargs='*', type=str, dest='specified_generators'), 223*8975f5c5SAndroid Build Coastguard Worker 224*8975f5c5SAndroid Build Coastguard Worker args = parser.parse_args() 225*8975f5c5SAndroid Build Coastguard Worker 226*8975f5c5SAndroid Build Coastguard Worker ranGenerators = generators 227*8975f5c5SAndroid Build Coastguard Worker runningSingleGenerator = False 228*8975f5c5SAndroid Build Coastguard Worker if (args.specified_generators): 229*8975f5c5SAndroid Build Coastguard Worker ranGenerators = {k: v for k, v in generators.items() if k in args.specified_generators[0]} 230*8975f5c5SAndroid Build Coastguard Worker runningSingleGenerator = True 231*8975f5c5SAndroid Build Coastguard Worker 232*8975f5c5SAndroid Build Coastguard Worker if len(ranGenerators) == 0: 233*8975f5c5SAndroid Build Coastguard Worker print("No valid generators specified.") 234*8975f5c5SAndroid Build Coastguard Worker return 1 235*8975f5c5SAndroid Build Coastguard Worker 236*8975f5c5SAndroid Build Coastguard Worker # Just get 'inputs' and 'outputs' from scripts but this runs the scripts so it's a bit slow 237*8975f5c5SAndroid Build Coastguard Worker infos = {} 238*8975f5c5SAndroid Build Coastguard Worker with futures.ThreadPoolExecutor(max_workers=8) as executor: 239*8975f5c5SAndroid Build Coastguard Worker for _, script in sorted(ranGenerators.items()): 240*8975f5c5SAndroid Build Coastguard Worker infos[script] = executor.submit(auto_script, script) 241*8975f5c5SAndroid Build Coastguard Worker 242*8975f5c5SAndroid Build Coastguard Worker for name, script in sorted(ranGenerators.items()): 243*8975f5c5SAndroid Build Coastguard Worker info = infos[script].result() 244*8975f5c5SAndroid Build Coastguard Worker fname = get_hash_file_name(name) 245*8975f5c5SAndroid Build Coastguard Worker filenames = info['inputs'] + info['outputs'] + [script] 246*8975f5c5SAndroid Build Coastguard Worker new_hashes = {} 247*8975f5c5SAndroid Build Coastguard Worker if fname not in all_old_hashes: 248*8975f5c5SAndroid Build Coastguard Worker all_old_hashes[fname] = {} 249*8975f5c5SAndroid Build Coastguard Worker if any_hash_dirty(name, filenames, new_hashes, all_old_hashes[fname]): 250*8975f5c5SAndroid Build Coastguard Worker any_dirty = True 251*8975f5c5SAndroid Build Coastguard Worker if "preprocessor" in name: 252*8975f5c5SAndroid Build Coastguard Worker format_workaround = True 253*8975f5c5SAndroid Build Coastguard Worker 254*8975f5c5SAndroid Build Coastguard Worker if not args.verify_only: 255*8975f5c5SAndroid Build Coastguard Worker print('Running ' + name + ' code generator') 256*8975f5c5SAndroid Build Coastguard Worker 257*8975f5c5SAndroid Build Coastguard Worker exe = get_executable_name(script) 258*8975f5c5SAndroid Build Coastguard Worker subprocess.check_call([exe, os.path.basename(script)], 259*8975f5c5SAndroid Build Coastguard Worker cwd=get_child_script_dirname(script)) 260*8975f5c5SAndroid Build Coastguard Worker 261*8975f5c5SAndroid Build Coastguard Worker # Update the hash dictionary. 262*8975f5c5SAndroid Build Coastguard Worker all_new_hashes[fname] = new_hashes 263*8975f5c5SAndroid Build Coastguard Worker 264*8975f5c5SAndroid Build Coastguard Worker if not runningSingleGenerator and any_old_hash_missing(all_new_hashes, all_old_hashes): 265*8975f5c5SAndroid Build Coastguard Worker any_dirty = True 266*8975f5c5SAndroid Build Coastguard Worker 267*8975f5c5SAndroid Build Coastguard Worker # Handle hashless_generators separately as these don't have hash maps. 268*8975f5c5SAndroid Build Coastguard Worker hashless_generators_dirty = False 269*8975f5c5SAndroid Build Coastguard Worker for name, script in sorted(hashless_generators.items()): 270*8975f5c5SAndroid Build Coastguard Worker cmd = [get_executable_name(script), os.path.basename(script)] 271*8975f5c5SAndroid Build Coastguard Worker rc = subprocess.call(cmd + ['--verify-only'], cwd=get_child_script_dirname(script)) 272*8975f5c5SAndroid Build Coastguard Worker if rc != 0: 273*8975f5c5SAndroid Build Coastguard Worker print(name + ' generator dirty') 274*8975f5c5SAndroid Build Coastguard Worker # Don't set any_dirty as we don't need git cl format in this case. 275*8975f5c5SAndroid Build Coastguard Worker hashless_generators_dirty = True 276*8975f5c5SAndroid Build Coastguard Worker 277*8975f5c5SAndroid Build Coastguard Worker if not args.verify_only: 278*8975f5c5SAndroid Build Coastguard Worker print('Running ' + name + ' code generator') 279*8975f5c5SAndroid Build Coastguard Worker subprocess.check_call(cmd, cwd=get_child_script_dirname(script)) 280*8975f5c5SAndroid Build Coastguard Worker 281*8975f5c5SAndroid Build Coastguard Worker if args.verify_only: 282*8975f5c5SAndroid Build Coastguard Worker return int(any_dirty or hashless_generators_dirty) 283*8975f5c5SAndroid Build Coastguard Worker 284*8975f5c5SAndroid Build Coastguard Worker if any_dirty: 285*8975f5c5SAndroid Build Coastguard Worker args = ['git.bat'] if os.name == 'nt' else ['git'] 286*8975f5c5SAndroid Build Coastguard Worker args += ['cl', 'format'] 287*8975f5c5SAndroid Build Coastguard Worker print('Calling git cl format') 288*8975f5c5SAndroid Build Coastguard Worker subprocess.check_call(args) 289*8975f5c5SAndroid Build Coastguard Worker if format_workaround: 290*8975f5c5SAndroid Build Coastguard Worker # Some formattings fail, and thus we can never submit such a cl because 291*8975f5c5SAndroid Build Coastguard Worker # of vicious circle of needing clean formatting but formatting not generating 292*8975f5c5SAndroid Build Coastguard Worker # clean formatting. 293*8975f5c5SAndroid Build Coastguard Worker print('Calling git cl format again') 294*8975f5c5SAndroid Build Coastguard Worker subprocess.check_call(args) 295*8975f5c5SAndroid Build Coastguard Worker 296*8975f5c5SAndroid Build Coastguard Worker 297*8975f5c5SAndroid Build Coastguard Worker # Update the output hashes again since they can be formatted. 298*8975f5c5SAndroid Build Coastguard Worker for name, script in sorted(ranGenerators.items()): 299*8975f5c5SAndroid Build Coastguard Worker info = auto_script(script) 300*8975f5c5SAndroid Build Coastguard Worker fname = get_hash_file_name(name) 301*8975f5c5SAndroid Build Coastguard Worker update_output_hashes(name, info['outputs'], all_new_hashes[fname]) 302*8975f5c5SAndroid Build Coastguard Worker 303*8975f5c5SAndroid Build Coastguard Worker for fname, new_hashes in all_new_hashes.items(): 304*8975f5c5SAndroid Build Coastguard Worker hash_fname = os.path.join(hash_dir, fname) 305*8975f5c5SAndroid Build Coastguard Worker with open(hash_fname, "w") as f: 306*8975f5c5SAndroid Build Coastguard Worker json.dump(new_hashes, f, indent=2, sort_keys=True, separators=(',', ':\n ')) 307*8975f5c5SAndroid Build Coastguard Worker f.write('\n') # json.dump doesn't end with newline 308*8975f5c5SAndroid Build Coastguard Worker 309*8975f5c5SAndroid Build Coastguard Worker return 0 310*8975f5c5SAndroid Build Coastguard Worker 311*8975f5c5SAndroid Build Coastguard Worker 312*8975f5c5SAndroid Build Coastguard Workerif __name__ == '__main__': 313*8975f5c5SAndroid Build Coastguard Worker sys.exit(main()) 314