Last active
February 21, 2018 22:02
-
-
Save mverleg/9988b44d57b63b0eef40dd9ce7b48e45 to your computer and use it in GitHub Desktop.
Git hook to automatically tag new versions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
# -*- coding: UTF-8 -*- | |
""" | |
This git hooks makes sure a tag is created each time the version is increased. | |
This version only works with version from `setup.py` and `settings.gradle`, but can be adapted. | |
To enable it on git 2.9+, use:: | |
chmod u+x dev/hooks/* | |
git config core.hooksPath dev/hooks | |
On older versions, copy or symlink the hooks to `.git/hooks` | |
https://gist.github.com/mverleg/9988b44d57b63b0eef40dd9ce7b48e45 | |
""" | |
from re import findall | |
from sys import stderr | |
from subprocess import Popen, PIPE | |
from os.path import exists | |
def git(cmd): | |
""" | |
Run a git command and return the output. | |
""" | |
out, err = Popen('git {0:s}'.format(cmd), shell=True, stdout=PIPE, stderr=PIPE).communicate() | |
assert not err.strip() | |
return out.decode('utf-8') | |
def get_existing_versions(): | |
""" | |
Get all versions for which there is a tag. | |
""" | |
return set(tag.strip().lstrip('v') for tag in | |
git('tag --list --format "%(refname:short)"').splitlines()) | |
def get_setup_py_version(): | |
if exists('setup.py'): | |
with open('setup.py', 'r') as fh: | |
res = findall(r'\n[^#\n]*version\s*=[\'"]([\w.-_]+)[\'"]', fh.read()) | |
assert len(res) != 0, 'Did not find version inside setup.py' | |
assert len(res) < 2, 'Found multiple versions inside setup.py' | |
return res[0].strip().lstrip('v') | |
return None | |
def get_settings_gradle_version(): | |
if exists('settings.gradle'): | |
with open('settings.gradle', 'r') as fh: | |
""" Only single-quotes supported, because double quotes may contain variables. """ | |
res = findall(r'\n\s*version\s*=\s*\'([\w.-_]+)\'', fh.read()) | |
assert len(res) != 0, 'Did not find version inside settings.gradle' | |
assert len(res) < 2, 'Found multiple versions inside settings.gradle' | |
return res[0].strip().lstrip('v') | |
return None | |
def get_current_version(): | |
""" | |
Get the current version of the project, according to package file. | |
PWD is the root of the git project. | |
""" | |
return get_setup_py_version() or get_settings_gradle_version() or None | |
def version_tag(): | |
""" | |
Create a tag for the current version if there isn't one yet. | |
""" | |
version = get_current_version() | |
if version is None: | |
""" No version found. """ | |
return | |
versions = get_existing_versions() | |
if version in versions: | |
""" Version already tagged. """ | |
return | |
print('CREATING TAG {0:} (use `git tag --delete {0:}` if not desired)'.format(version)) | |
git('tag v{0:}'.format(version)) | |
try: | |
exit(version_tag()) | |
except Exception as err: | |
stderr.write(err) | |
exit(1) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Used in json-tricks and Mango