mirror of
				https://github.com/python/cpython.git
				synced 2025-11-04 07:31:38 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			77 lines
		
	
	
	
		
			2.3 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable file
		
	
	
	
	
			
		
		
	
	
			77 lines
		
	
	
	
		
			2.3 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable file
		
	
	
	
	
#!/usr/bin/env python3
 | 
						|
 | 
						|
import argparse
 | 
						|
import os
 | 
						|
import pathlib
 | 
						|
import sys
 | 
						|
import time
 | 
						|
import zipfile
 | 
						|
from urllib.request import urlretrieve
 | 
						|
 | 
						|
 | 
						|
def fetch_zip(commit_hash, zip_dir, *, org='python', binary=False, verbose):
 | 
						|
    repo = f'cpython-{"bin" if binary else "source"}-deps'
 | 
						|
    url = f'https://github.com/{org}/{repo}/archive/{commit_hash}.zip'
 | 
						|
    reporthook = None
 | 
						|
    if verbose:
 | 
						|
        reporthook = print
 | 
						|
    zip_dir.mkdir(parents=True, exist_ok=True)
 | 
						|
    filename, headers = urlretrieve(
 | 
						|
        url,
 | 
						|
        zip_dir / f'{commit_hash}.zip',
 | 
						|
        reporthook=reporthook,
 | 
						|
    )
 | 
						|
    return filename
 | 
						|
 | 
						|
 | 
						|
def extract_zip(externals_dir, zip_path):
 | 
						|
    with zipfile.ZipFile(os.fspath(zip_path)) as zf:
 | 
						|
        zf.extractall(os.fspath(externals_dir))
 | 
						|
        return externals_dir / zf.namelist()[0].split('/')[0]
 | 
						|
 | 
						|
 | 
						|
def parse_args():
 | 
						|
    p = argparse.ArgumentParser()
 | 
						|
    p.add_argument('-v', '--verbose', action='store_true')
 | 
						|
    p.add_argument('-b', '--binary', action='store_true',
 | 
						|
                   help='Is the dependency in the binary repo?')
 | 
						|
    p.add_argument('-O', '--organization',
 | 
						|
                   help='Organization owning the deps repos', default='python')
 | 
						|
    p.add_argument('-e', '--externals-dir', type=pathlib.Path,
 | 
						|
                   help='Directory in which to store dependencies',
 | 
						|
                   default=pathlib.Path(__file__).parent.parent / 'externals')
 | 
						|
    p.add_argument('tag',
 | 
						|
                   help='tag of the dependency')
 | 
						|
    return p.parse_args()
 | 
						|
 | 
						|
 | 
						|
def main():
 | 
						|
    args = parse_args()
 | 
						|
    zip_path = fetch_zip(
 | 
						|
        args.tag,
 | 
						|
        args.externals_dir / 'zips',
 | 
						|
        org=args.organization,
 | 
						|
        binary=args.binary,
 | 
						|
        verbose=args.verbose,
 | 
						|
    )
 | 
						|
    final_name = args.externals_dir / args.tag
 | 
						|
    extracted = extract_zip(args.externals_dir, zip_path)
 | 
						|
    for wait in [1, 2, 3, 5, 8, 0]:
 | 
						|
        try:
 | 
						|
            extracted.replace(final_name)
 | 
						|
            break
 | 
						|
        except PermissionError as ex:
 | 
						|
            retry = f" Retrying in {wait}s..." if wait else ""
 | 
						|
            print(f"Encountered permission error '{ex}'.{retry}", file=sys.stderr)
 | 
						|
            time.sleep(wait)
 | 
						|
    else:
 | 
						|
        print(
 | 
						|
            f"ERROR: Failed to extract {final_name}.",
 | 
						|
            "You may need to restart your build",
 | 
						|
            file=sys.stderr,
 | 
						|
        )
 | 
						|
        sys.exit(1)
 | 
						|
 | 
						|
 | 
						|
if __name__ == '__main__':
 | 
						|
    main()
 |