17db96d56Sopenharmony_ci#!/usr/bin/env python3 27db96d56Sopenharmony_ci 37db96d56Sopenharmony_ciimport argparse 47db96d56Sopenharmony_ciimport os 57db96d56Sopenharmony_ciimport pathlib 67db96d56Sopenharmony_ciimport sys 77db96d56Sopenharmony_ciimport time 87db96d56Sopenharmony_ciimport zipfile 97db96d56Sopenharmony_cifrom urllib.request import urlretrieve 107db96d56Sopenharmony_ci 117db96d56Sopenharmony_ci 127db96d56Sopenharmony_cidef fetch_zip(commit_hash, zip_dir, *, org='python', binary=False, verbose): 137db96d56Sopenharmony_ci repo = f'cpython-{"bin" if binary else "source"}-deps' 147db96d56Sopenharmony_ci url = f'https://github.com/{org}/{repo}/archive/{commit_hash}.zip' 157db96d56Sopenharmony_ci reporthook = None 167db96d56Sopenharmony_ci if verbose: 177db96d56Sopenharmony_ci reporthook = print 187db96d56Sopenharmony_ci zip_dir.mkdir(parents=True, exist_ok=True) 197db96d56Sopenharmony_ci filename, headers = urlretrieve( 207db96d56Sopenharmony_ci url, 217db96d56Sopenharmony_ci zip_dir / f'{commit_hash}.zip', 227db96d56Sopenharmony_ci reporthook=reporthook, 237db96d56Sopenharmony_ci ) 247db96d56Sopenharmony_ci return filename 257db96d56Sopenharmony_ci 267db96d56Sopenharmony_ci 277db96d56Sopenharmony_cidef extract_zip(externals_dir, zip_path): 287db96d56Sopenharmony_ci with zipfile.ZipFile(os.fspath(zip_path)) as zf: 297db96d56Sopenharmony_ci zf.extractall(os.fspath(externals_dir)) 307db96d56Sopenharmony_ci return externals_dir / zf.namelist()[0].split('/')[0] 317db96d56Sopenharmony_ci 327db96d56Sopenharmony_ci 337db96d56Sopenharmony_cidef parse_args(): 347db96d56Sopenharmony_ci p = argparse.ArgumentParser() 357db96d56Sopenharmony_ci p.add_argument('-v', '--verbose', action='store_true') 367db96d56Sopenharmony_ci p.add_argument('-b', '--binary', action='store_true', 377db96d56Sopenharmony_ci help='Is the dependency in the binary repo?') 387db96d56Sopenharmony_ci p.add_argument('-O', '--organization', 397db96d56Sopenharmony_ci help='Organization owning the deps repos', default='python') 407db96d56Sopenharmony_ci p.add_argument('-e', '--externals-dir', type=pathlib.Path, 417db96d56Sopenharmony_ci help='Directory in which to store dependencies', 427db96d56Sopenharmony_ci default=pathlib.Path(__file__).parent.parent / 'externals') 437db96d56Sopenharmony_ci p.add_argument('tag', 447db96d56Sopenharmony_ci help='tag of the dependency') 457db96d56Sopenharmony_ci return p.parse_args() 467db96d56Sopenharmony_ci 477db96d56Sopenharmony_ci 487db96d56Sopenharmony_cidef main(): 497db96d56Sopenharmony_ci args = parse_args() 507db96d56Sopenharmony_ci zip_path = fetch_zip( 517db96d56Sopenharmony_ci args.tag, 527db96d56Sopenharmony_ci args.externals_dir / 'zips', 537db96d56Sopenharmony_ci org=args.organization, 547db96d56Sopenharmony_ci binary=args.binary, 557db96d56Sopenharmony_ci verbose=args.verbose, 567db96d56Sopenharmony_ci ) 577db96d56Sopenharmony_ci final_name = args.externals_dir / args.tag 587db96d56Sopenharmony_ci extracted = extract_zip(args.externals_dir, zip_path) 597db96d56Sopenharmony_ci for wait in [1, 2, 3, 5, 8, 0]: 607db96d56Sopenharmony_ci try: 617db96d56Sopenharmony_ci extracted.replace(final_name) 627db96d56Sopenharmony_ci break 637db96d56Sopenharmony_ci except PermissionError as ex: 647db96d56Sopenharmony_ci retry = f" Retrying in {wait}s..." if wait else "" 657db96d56Sopenharmony_ci print(f"Encountered permission error '{ex}'.{retry}", file=sys.stderr) 667db96d56Sopenharmony_ci time.sleep(wait) 677db96d56Sopenharmony_ci else: 687db96d56Sopenharmony_ci print( 697db96d56Sopenharmony_ci f"ERROR: Failed to extract {final_name}.", 707db96d56Sopenharmony_ci "You may need to restart your build", 717db96d56Sopenharmony_ci file=sys.stderr, 727db96d56Sopenharmony_ci ) 737db96d56Sopenharmony_ci sys.exit(1) 747db96d56Sopenharmony_ci 757db96d56Sopenharmony_ci 767db96d56Sopenharmony_ciif __name__ == '__main__': 777db96d56Sopenharmony_ci main() 78