1#!/usr/bin/env python3 2 3# We do not need to import built modules from PCbuild (duh), so 4# filter those out here to save Steve from debugging it yet again. 5import sys 6sys.path[:] = [p for p in sys.path if p and 'PCbuild' not in p] 7 8import argparse 9import os 10import pathlib 11import zipfile 12from urllib.request import urlretrieve 13 14def fetch_zip(commit_hash, zip_dir, *, org='python', binary=False, verbose): 15 repo = f'cpython-{"bin" if binary else "source"}-deps' 16 url = f'https://github.com/{org}/{repo}/archive/{commit_hash}.zip' 17 reporthook = None 18 if verbose: 19 reporthook = print 20 zip_dir.mkdir(parents=True, exist_ok=True) 21 filename, headers = urlretrieve( 22 url, 23 zip_dir / f'{commit_hash}.zip', 24 reporthook=reporthook, 25 ) 26 return filename 27 28 29def extract_zip(externals_dir, zip_path): 30 with zipfile.ZipFile(os.fspath(zip_path)) as zf: 31 zf.extractall(os.fspath(externals_dir)) 32 return externals_dir / zf.namelist()[0].split('/')[0] 33 34 35def parse_args(): 36 p = argparse.ArgumentParser() 37 p.add_argument('-v', '--verbose', action='store_true') 38 p.add_argument('-b', '--binary', action='store_true', 39 help='Is the dependency in the binary repo?') 40 p.add_argument('-O', '--organization', 41 help='Organization owning the deps repos', default='python') 42 p.add_argument('-e', '--externals-dir', type=pathlib.Path, 43 help='Directory in which to store dependencies', 44 default=pathlib.Path(__file__).parent.parent / 'externals') 45 p.add_argument('tag', 46 help='tag of the dependency') 47 return p.parse_args() 48 49 50def main(): 51 args = parse_args() 52 zip_path = fetch_zip( 53 args.tag, 54 args.externals_dir / 'zips', 55 org=args.organization, 56 binary=args.binary, 57 verbose=args.verbose, 58 ) 59 final_name = args.externals_dir / args.tag 60 extract_zip(args.externals_dir, zip_path).replace(final_name) 61 62 63if __name__ == '__main__': 64 main() 65