#!/usr/bin/env python3 import re from os.path import join from subprocess import check_call, check_output from sys import argv from tempfile import TemporaryDirectory TARGETS = ['', 'dev', 'docs'] # the empty string is used for the project itself def print_packages(packages, heading): print(f'{heading}:') print(' ', end='') print('\n '.join(packages)) # would be nice if there was a cleaner way to get this, but I've not found a # more reliable one. with open('setup.py') as fh: match = re.search(r"name='(?P[\w-]+)',", fh.read()) if not match: raise Exception('failed to determine our package name') our_package_name = match.group('pkg') print(f'our_package_name: {our_package_name}') with TemporaryDirectory() as tmpdir: check_call(['python3', '-m', 'venv', tmpdir]) for target in TARGETS: to_install = f'.[{target}]' if target else '.' check_call([join(tmpdir, 'bin', 'pip'), 'install', to_install]) frozen = check_output([join(tmpdir, 'bin', 'pip'), 'freeze']) frozen = set(frozen.decode('utf-8').strip().split('\n')) # pip installs the module itself along with deps so we need to get that out of # our list by finding the thing that was file installed during dev frozen = sorted( [p for p in frozen if not p.startswith(our_package_name)] ) print_packages(frozen, f'{target}-frozen') script = argv[0] with open( f'requirements{"-" + target if target else ""}.txt', 'w' ) as fh: fh.write( f'# DO NOT EDIT THIS FILE DIRECTLY - use {script} to update\n' ) fh.write('\n'.join(frozen)) fh.write('\n')