Skip to content

Commit

Permalink
setup.py: another attempt at improving versioning
Browse files Browse the repository at this point in the history
- support tagged x.y.z.devX releases (omit SHA1 in this case)
- add a full datetimestamp when the checkout is dirty
  • Loading branch information
brechtm committed Sep 18, 2020
1 parent 73ed88f commit f9d5f34
Showing 1 changed file with 42 additions and 30 deletions.
72 changes: 42 additions & 30 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@

import sys

import pkg_resources

from pkg_resources import safe_version
from setuptools import setup, find_packages
from setuptools.command.build_py import build_py

Expand All @@ -20,54 +19,67 @@
def get_version():
import sys

from datetime import date
from subprocess import check_output, CalledProcessError, DEVNULL
from datetime import datetime

VERSION = '0.4.3.dev'

try:
is_dirty = check_output(['git', 'status', '--porcelain'],
stderr=DEVNULL).decode('utf-8')
except CalledProcessError:
is_dirty = None # not running from a git checkout

if len(sys.argv) > 1 and sys.argv[1] == 'develop':
# 'pip install -e' or 'python setup.py develop'
print('Installing in develop mode')
version = 'dev'
elif VERSION.endswith('.dev'): # development distribution
if is_dirty is None:
version = version_from_pkginfo() or VERSION
else:
print('Attempting to get commit SHA1 from git...')
git_sha1 = check_output(['git', 'rev-parse', '--short', 'HEAD'])
version = '{}+{}'.format(VERSION, git_sha1.strip().decode('ascii'))
if is_dirty:
version += '.dirty{}'.format(date.today().strftime('%Y%m%d'))
else: # release distribution
if is_dirty is None:
assert version_from_pkginfo() in (VERSION, None)
elif is_dirty:
print(is_dirty)
assert False
version = VERSION
return pkg_resources.safe_version(version)
return '0.0.0.dev'

version = version_from_pkginfo()
is_dirty = git('status', '--porcelain')
if version: # source distribution
assert is_dirty is None
return version

# assuming git checkout
tag = git('describe', '--exact-match', '--tags', 'HEAD')
if tag:
print('Working directory is a git tag checkout...')
assert tag[0] == 'v'
version = tag[1:]
assert (version.startswith(VERSION) if VERSION.endswith('.dev')
else version == VERSION)
else:
last_tag = git('describe', '--tags', '--always', 'HEAD')
assert last_tag[0] == 'v'
version = last_tag[1:].replace('-', '+', 1)
if is_dirty:
print('Checkout is dirty, adding timestamp to version string...')
now = datetime.utcnow()
sep = '-' if '+' in version else '+'
version += '{}dirty{}'.format(sep, now.strftime('%Y%m%d%H%M%S'))

return safe_version(version)


def version_from_pkginfo():
"""Retrieve the version from an sdist's PKG-INFO file or None on failure"""
from email.parser import HeaderParser

parser = HeaderParser()
try:
with open('PKG-INFO') as file:
pkg_info = parser.parse(file)
except FileNotFoundError:
print('This is not a regular source distribution!')
return None
print('Retrieving the distribution version from PKG-SOURCES.')
print('Retrieving the distribution version from PKG-INFO.')
return pkg_info['Version']


def git(*args):
"""Run git and return its stripped output or None on failure"""
from subprocess import check_output, CalledProcessError, DEVNULL

try:
stdout = check_output(['git', *args], stderr=DEVNULL)
except CalledProcessError:
return None
return stdout.strip().decode('utf-8')


def long_description():
import os

Expand Down

0 comments on commit f9d5f34

Please sign in to comment.