Skip to content

Instantly share code, notes, and snippets.

@mverleg
Last active February 21, 2018 22:02
Show Gist options
  • Save mverleg/9988b44d57b63b0eef40dd9ce7b48e45 to your computer and use it in GitHub Desktop.
Save mverleg/9988b44d57b63b0eef40dd9ce7b48e45 to your computer and use it in GitHub Desktop.
Git hook to automatically tag new versions
#!/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)
@mverleg
Copy link
Author

mverleg commented Feb 21, 2018

Used in json-tricks and Mango

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment