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