Skip to content

Commit

Permalink
Added dev argument to param.Version to support dev versions (#200)
Browse files Browse the repository at this point in the history
Accepts github tags like "v1.9.0dev3" or "v1.9.0.dev3", with the reported version string always following PEP440 ("1.9.0.dev3" in this case), and with comparisons correctly sorting dev releases before full releases.
  • Loading branch information
jlstevens authored and jbednar committed Oct 4, 2017
1 parent d79eab1 commit 64c8f7c
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 9 deletions.
48 changes: 39 additions & 9 deletions param/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,10 +107,13 @@ class Version(object):
compute the number of commits since the last version tag, the
short commit hash, and whether the commit is dirty (has changes
not yet committed). Version tags must start with a lowercase 'v'
and have a period in them, e.g. v2.0, v0.9.8, v0.1a, or v0.2beta.
Note that any non-numeric portion of the version ("a", "beta",
etc.) will currently be discarded for the purposes of numeric
comparisons.
and have a period in them, e.g. v2.0, v0.9.8 or v0.1.
Development versions are supported by setting the dev argument to an
appropriate dev version number. The corresponding tag can be PEP440
compliant (using .devX) of the form v0.1.dev3, v1.9.0.dev2 etc but
it doesn't have to be as the dot may be omitted i.e v0.1dev3,
v1.9.0dev2 etc.
Also note that when version control system (VCS) information is
used, the comparison operators take into account the number of
Expand All @@ -126,12 +129,14 @@ class Version(object):
__init__.py export-subst
"""

def __init__(self, release=None, fpath=None, commit=None, reponame=None, commit_count=0):
def __init__(self, release=None, fpath=None, commit=None,
reponame=None, dev=None, commit_count=0):
"""
:release: Release tuple (corresponding to the current VCS tag)
:commit Short SHA. Set to '$Format:%h$' for git archive support.
:fpath: Set to ``__file__`` to access version control information
:reponame: Used to verify VCS repository name.
:dev: Development version number. None if not a development version.
:commit_count Commits since last release. Set for dev releases.
"""
self.fpath = fpath
Expand All @@ -143,6 +148,7 @@ def __init__(self, release=None, fpath=None, commit=None, reponame=None, commit_
self._release = None
self._dirty = False
self.reponame = reponame
self.dev = dev

@property
def release(self):
Expand Down Expand Up @@ -211,7 +217,19 @@ def git_fetch(self, cmd='git'):
# If there is any other error, return (release value still useful)
return self

self._update_from_vcs(output)

def _update_from_vcs(self, output):
"Update state based on the VCS state e.g the output of git describe"
split = output[1:].split('-')
if 'dev' in split[0]:
dev_split = split[0].split('dev')
self.dev = int(dev_split[1])
split[0] = dev_split[0]
# Remove the pep440 dot if present
if split[0].endswith('.'):
split[0] = dev_split[0][:-1]

self._release = tuple(int(el) for el in split[0].split('.'))
self._commit_count = int(split[1])
self._commit = str(split[2][1:]) # Strip out 'g' prefix ('g'=>'git')
Expand All @@ -233,6 +251,7 @@ def __str__(self):
"""
if self.release is None: return 'None'
release = '.'.join(str(el) for el in self.release)
release = '%s.dev%d' % (release, self.dev) if self.dev is not None else release

if (self._expected_commit is not None) and ("$Format" not in self._expected_commit):
pass # Concrete commit supplied - print full version string
Expand All @@ -255,7 +274,6 @@ def abbrev(self,dev_suffix=""):
(dev_suffix if self.commit_count > 0 or self.dirty else "")



def __eq__(self, other):
"""
Two versions are considered equivalent if and only if they are
Expand All @@ -265,13 +283,25 @@ def __eq__(self, other):
changes even for the same release and commit count.
"""
if self.dirty or other.dirty: return False
return (self.release, self.commit_count) == (other.release, other.commit_count)
return ((self.release, self.commit_count, self.dev)
== (other.release, other.commit_count, other.dev))

def __gt__(self, other):
return (self.release, self.commit_count) > (other.release, other.commit_count)
if self.release == other.release:
if self.dev == other.dev:
return self.commit_count > other.commit_count
elif None in [self.dev, other.dev]:
return self.dev is None
else:
return self.dev > other.dev
else:
return (self.release, self.commit_count) > (other.release, other.commit_count)

def __lt__(self, other):
return (self.release, self.commit_count) < (other.release, other.commit_count)
if self==other:
return False
else:
return not (self > other)


def verify(self, string_version=None):
Expand Down
60 changes: 60 additions & 0 deletions tests/testversion.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ def test_repr_v101_10_commits(self):
v101 = Version(release=(1,0,1), commit_count=10, commit='aaaaaaa')
self.assertEqual(repr(v101), '1.0.1-10-gaaaaaaa')

def test_repr_v101dev4_10_commits(self):
v101 = Version(release=(1,0,1), commit_count=10, commit='aaaaaaa', dev=4)
self.assertEqual(repr(v101), '1.0.1.dev4-10-gaaaaaaa')

def test_version_init_v101(self):
Version(release=(1,0,1))

Expand All @@ -34,6 +38,10 @@ def test_version_str_v1(self):
v1 = Version(release=(1,0))
self.assertEqual(str(v1), '1.0')

def test_version_str_v1dev3(self):
v1 = Version(release=(1,0),dev=3)
self.assertEqual(str(v1), '1.0.dev3')

def test_version_v1_dirty(self):
v1 = Version(release=(1,0))
self.assertEqual(v1.dirty, False)
Expand Down Expand Up @@ -63,6 +71,34 @@ def test_version_commit(self):
v1 = Version(release=(1,0), commit='shortSHA')
self.assertEqual(v1.commit, 'shortSHA')

#===========================================#
# Update from VCS (currently git describe) #
#===========================================#

def test_version_simple_git_describe(self):
v105 = Version(release=(1,0,5))
v105._update_from_vcs('v1.0.5-42-gabcdefgh')
self.assertEqual(v105.release, (1,0,5))
self.assertEqual(v105.commit_count, 42)
self.assertEqual(v105.dev, None)
self.assertEqual(v105.commit, 'abcdefgh')

def test_version_dev_pep440_git_describe(self):
v105 = Version(release=(1,0,5), dev=4)
v105._update_from_vcs('v1.0.6.dev4-42-gabcdefgh')
self.assertEqual(v105.release, (1,0,6))
self.assertEqual(v105.commit_count, 42)
self.assertEqual(v105.dev, 4)
self.assertEqual(v105.commit, 'abcdefgh')

def test_version_dev_wo_pep440_git_describe(self):
v105 = Version(release=(1,0,5), dev=4)
v105._update_from_vcs('v1.0.6dev4-42-gabcdefgh')
self.assertEqual(v105.release, (1,0,6))
self.assertEqual(v105.commit_count, 42)
self.assertEqual(v105.dev, 4)
self.assertEqual(v105.commit, 'abcdefgh')

#===========================#
# Comparisons and equality #
#===========================#
Expand All @@ -72,11 +108,26 @@ def test_version_less_than(self):
v101 = Version(release=(1,0,1))
self.assertEqual((v1 < v101), True)

def test_version_less_than_dev(self):
v101 = Version(release=(1,0,1))
v101dev2 = Version(release=(1,0,1), dev=2)
self.assertEqual((v101dev2 < v101), True)

def test_version_less_than_dev_number(self):
v101dev1 = Version(release=(1,0,1), dev=1)
v101dev2 = Version(release=(1,0,1), dev=2)
self.assertEqual((v101dev1 < v101dev2), True)

def test_version_greater_than(self):
v1 = Version(release=(1,0))
v101 = Version(release=(1,0,1))
self.assertEqual((v1 > v101), False)

def test_version_greater_than_dev(self):
v101 = Version(release=(1,0,1))
v102dev3 = Version(release=(1,0,2), dev=3)
self.assertEqual((v102dev3 > v101), True)

def test_version_eq_v1(self):
v1 = Version(release=(1,0))
self.assertEqual(v1==v1, True)
Expand All @@ -85,6 +136,15 @@ def test_version_eq_v101(self):
v101 = Version(release=(1,0,1))
self.assertEqual(v101==v101, True)

def test_version_eq_v101_dev(self):
v101dev3 = Version(release=(1,0,1), dev=3)
self.assertEqual(v101dev3==v101dev3, True)

def test_version_neq_v101_dev(self):
v101dev2 = Version(release=(1,0,1), dev=2)
v101dev3 = Version(release=(1,0,1), dev=3)
self.assertEqual(v101dev2!=v101dev3, True)

def test_version_neq(self):
v1 = Version(release=(1,0))
v101 = Version(release=(1,0,1))
Expand Down

0 comments on commit 64c8f7c

Please sign in to comment.