Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)
at release-19.03 79 lines 2.7 kB view raw
1import argparse 2import concurrent.futures 3import json 4import os 5import subprocess 6import sys 7 8updates = {} 9 10def eprint(*args, **kwargs): 11 print(*args, file=sys.stderr, **kwargs) 12 13def run_update_script(package): 14 eprint(f" - {package['name']}: UPDATING ...") 15 16 subprocess.run(package['updateScript'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, check=True) 17 18 19def main(max_workers, keep_going, packages): 20 with open(sys.argv[1]) as f: 21 packages = json.load(f) 22 23 eprint() 24 eprint('Going to be running update for following packages:') 25 for package in packages: 26 eprint(f" - {package['name']}") 27 eprint() 28 29 confirm = input('Press Enter key to continue...') 30 if confirm == '': 31 eprint() 32 eprint('Running update for:') 33 34 with concurrent.futures.ProcessPoolExecutor(max_workers=max_workers) as executor: 35 for package in packages: 36 updates[executor.submit(run_update_script, package)] = package 37 38 for future in concurrent.futures.as_completed(updates): 39 package = updates[future] 40 41 try: 42 future.result() 43 eprint(f" - {package['name']}: DONE.") 44 except subprocess.CalledProcessError as e: 45 eprint(f" - {package['name']}: ERROR") 46 eprint() 47 eprint(f"--- SHOWING ERROR LOG FOR {package['name']} ----------------------") 48 eprint() 49 eprint(e.stdout.decode('utf-8')) 50 with open(f"{package['pname']}.log", 'wb') as f: 51 f.write(e.stdout) 52 eprint() 53 eprint(f"--- SHOWING ERROR LOG FOR {package['name']} ----------------------") 54 55 if not keep_going: 56 sys.exit(1) 57 58 eprint() 59 eprint('Packages updated!') 60 sys.exit() 61 else: 62 eprint('Aborting!') 63 sys.exit(130) 64 65parser = argparse.ArgumentParser(description='Update packages') 66parser.add_argument('--max-workers', '-j', dest='max_workers', type=int, help='Number of updates to run concurrently', nargs='?', default=4) 67parser.add_argument('--keep-going', '-k', dest='keep_going', action='store_true', help='Do not stop after first failure') 68parser.add_argument('packages', help='JSON file containing the list of package names and their update scripts') 69 70if __name__ == '__main__': 71 args = parser.parse_args() 72 73 try: 74 main(args.max_workers, args.keep_going, args.packages) 75 except (KeyboardInterrupt, SystemExit) as e: 76 for update in updates: 77 update.cancel() 78 79 sys.exit(e.code if isinstance(e, SystemExit) else 130)