1#===----------------------------------------------------------------------===## 2# 3# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4# See https://llvm.org/LICENSE.txt for license information. 5# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6# 7#===----------------------------------------------------------------------===## 8 9"""run.py is a utility for running a program. 10 11It can perform code signing, forward arguments to the program, and return the 12program's error code. 13""" 14 15import argparse 16import os 17import shutil 18import subprocess 19import sys 20import tempfile 21 22 23def main(): 24 parser = argparse.ArgumentParser() 25 parser.add_argument('--codesign_identity', type=str, required=False, default=None) 26 parser.add_argument('--dependencies', type=str, nargs='*', required=False, default=[]) 27 parser.add_argument('--env', type=str, nargs='*', required=False, default=dict()) 28 (args, remaining) = parser.parse_known_args(sys.argv[1:]) 29 30 if len(remaining) < 2: 31 sys.stderr.write('Missing actual commands to run') 32 exit(1) 33 remaining = remaining[1:] # Skip the '--' 34 35 # Do any necessary codesigning. 36 if args.codesign_identity: 37 exe = remaining[0] 38 rc = subprocess.call(['xcrun', 'codesign', '-f', '-s', args.codesign_identity, exe], env={}) 39 if rc != 0: 40 sys.stderr.write('Failed to codesign: ' + exe) 41 return rc 42 43 # Extract environment variables into a dictionary 44 env = {k : v for (k, v) in map(lambda s: s.split('=', 1), args.env)} 45 46 try: 47 tmpDir = tempfile.mkdtemp() 48 49 # Ensure the file dependencies exist and copy them to a temporary directory. 50 for dep in args.dependencies: 51 if not os.path.exists(dep): 52 sys.stderr.write('Missing file or directory "{}" marked as a dependency of a test'.format(dep)) 53 exit(1) 54 if os.path.isdir(dep): 55 shutil.copytree(dep, os.path.join(tmpDir, os.path.basename(dep)), symlinks=True) 56 else: 57 shutil.copy2(dep, tmpDir) 58 59 # Run the executable with the given environment in the temporary directory. 60 return subprocess.call(' '.join(remaining), cwd=tmpDir, env=env, shell=True) 61 finally: 62 shutil.rmtree(tmpDir) 63 64if __name__ == '__main__': 65 exit(main()) 66