Paul Ganssle | cedfa88 | 2017-07-10 14:00:32 -0400 | [diff] [blame] | 1 | """ |
| 2 | Release script |
| 3 | """ |
| 4 | |
| 5 | import glob |
| 6 | import os |
| 7 | import shutil |
| 8 | import subprocess |
| 9 | import sys |
| 10 | |
| 11 | import click |
| 12 | |
| 13 | @click.group() |
| 14 | def cli(): |
| 15 | pass |
| 16 | |
| 17 | @cli.command() |
| 18 | def build(): |
| 19 | DIST_PATH = 'dist' |
| 20 | if os.path.exists(DIST_PATH) and os.listdir(DIST_PATH): |
| 21 | if click.confirm('{} is not empty - delete contents?'.format(DIST_PATH)): |
| 22 | shutil.rmtree(DIST_PATH) |
| 23 | os.makedirs(DIST_PATH) |
| 24 | else: |
| 25 | click.echo('Aborting') |
| 26 | sys.exit(1) |
| 27 | |
| 28 | subprocess.check_call(['python', 'setup.py', 'bdist_wheel']) |
| 29 | subprocess.check_call(['python', 'setup.py', 'sdist', |
| 30 | '--formats=gztar']) |
| 31 | |
| 32 | @cli.command() |
| 33 | def sign(): |
| 34 | # Sign all the distribution files |
| 35 | for fpath in glob.glob('dist/*'): |
| 36 | subprocess.check_call(['gpg', '--armor', '--output', fpath + '.asc', |
| 37 | '--detach-sig', fpath]) |
| 38 | |
| 39 | # Verify the distribution files |
| 40 | for fpath in glob.glob('dist/*'): |
| 41 | if fpath.endswith('.asc'): |
| 42 | continue |
| 43 | |
| 44 | subprocess.check_call(['gpg', '--verify', fpath + '.asc', fpath]) |
| 45 | |
| 46 | |
| 47 | @cli.command() |
| 48 | @click.option('--passfile', default=None) |
| 49 | @click.option('--release/--no-release', default=False) |
| 50 | def upload(passfile, release): |
| 51 | if release: |
| 52 | repository='pypi' |
| 53 | else: |
| 54 | repository='pypitest' |
| 55 | |
| 56 | env = os.environ.copy() |
| 57 | if passfile is not None: |
| 58 | gpg_call = subprocess.run(['gpg', '-d', passfile], |
| 59 | stdout=subprocess.PIPE, |
| 60 | stderr=subprocess.PIPE) |
| 61 | |
| 62 | username, password = gpg_call.stdout.decode('utf-8').split('\n') |
| 63 | env['TWINE_USERNAME'] = username |
| 64 | env['TWINE_PASSWORD'] = password |
| 65 | |
| 66 | dist_files = glob.glob('dist/*') |
| 67 | for dist_file in dist_files: |
| 68 | if dist_file.endswith('.asc'): |
| 69 | continue |
| 70 | if dist_file + '.asc' not in dist_files: |
| 71 | raise ValueError('Missing signature file for: {}'.format(dist_file)) |
| 72 | |
| 73 | args = ['twine', 'upload', '-r', repository] + dist_files |
| 74 | |
| 75 | p = subprocess.Popen(args, env=env) |
| 76 | p.wait() |
| 77 | |
| 78 | if __name__ == "__main__": |
| 79 | cli() |