mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 05:31:20 +00:00 
			
		
		
		
	 50c0551f97
			
		
	
	
		50c0551f97
		
			
		
	
	
	
	
		
			
			Co-authored-by: Ćukasz Langa <lukasz@langa.pl>
(cherry picked from commit ef9e22b253)
Co-authored-by: Steve Dower <steve.dower@python.org>
		
	
			
		
			
				
	
	
		
			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()
 |