Skip to content

Instantly share code, notes, and snippets.

@bsnacks000
Created December 1, 2022 13:33
Show Gist options
  • Select an option

  • Save bsnacks000/2fb43426539c064fc228f8dbd1e72e3e to your computer and use it in GitHub Desktop.

Select an option

Save bsnacks000/2fb43426539c064fc228f8dbd1e72e3e to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
""" standalone cli script for easy version bumping with pyproject.
"""
import argparse
import toml
import pathlib
import sys
import re
import os
import subprocess
semantic_pattern = re.compile(r"^[0-9]*\.[0-9.]*\.[0-9]*(dev)?(rc)?([0-9]*)?")
def bash_command(command: str):
process = subprocess.Popen(['bash', '-c', command], stdout=subprocess.PIPE)
out, err = process.communicate()
if process.returncode != 0:
print(f'{command} failed: {process.returncode} {out} {err}', file=sys.stderr)
sys.exit(2)
def main(package: str, version: str, git: bool=True):
# check given version is semantically correct
if not semantic_pattern.match(version):
print(f'semantic version does not match {semantic_pattern}', file=sys.stderr)
sys.exit(1)
# get the pyproject.toml
try:
with open('pyproject.toml', 'r') as f:
proj = toml.load(f)
except IOError:
print('pyproject.toml not found', file=sys.stderr)
sys.exit(1)
# set the internal _version.py
package_root_dir = pathlib.Path('.') / package
if not package_root_dir.is_dir():
print(f'{package} not found', file=sys.stderr)
sys.exit(1)
with open(package_root_dir / '_version.py', 'w') as f:
print('#~# generated by setversion.py #~#', file=f)
print(f'VERSION="{version}"', file=f)
# rewrite the pyproject with updated version
with open('pyproject.toml', 'w') as f:
proj['tool']['poetry']['version'] = version
toml.dump(proj, f)
print(f'new version: v{version}')
# make a git tag
if git:
commit_and_tag = f'git add -A && git commit -m "bumpversion -> v{version}" && git tag -a v{version} -m "v{version}"'
bash_command(commit_and_tag)
print(f'git tag: v{version}')
if __name__ == '__main__':
semantic_help = """The semantic version to be replaced. Should be one of:
<major>.<minor>.<patch>, <major>.<minor>.<patch>dev<N> or <major>.<minor>.<patch>rc<N>
"""
description = """ Replaces the semantic version both inside the package
and in the pyproject.toml. Optionally will also automatically
create a git commit and git tag after versioning.
"""
parser = argparse.ArgumentParser('setversion', description=description)
parser.add_argument('package', type=str, help='The package name in this directory to be versioned.')
parser.add_argument('version', type=str, help=semantic_help)
parser.add_argument('--git', action='store_true', help='Git commit and tag after setting version.')
args = parser.parse_args()
main(args.package, args.version, args.git)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment