Add version sorting, assert that RELEASE_PREV is the most recent release.
This commit is contained in:
parent
7f53785735
commit
3250b3d34e
|
@ -6,7 +6,10 @@ import sys
|
||||||
import time
|
import time
|
||||||
import logging
|
import logging
|
||||||
import argparse
|
import argparse
|
||||||
|
import subprocess
|
||||||
|
import traceback
|
||||||
import unittest
|
import unittest
|
||||||
|
import random
|
||||||
|
|
||||||
|
|
||||||
def main(args=sys.argv[1:]):
|
def main(args=sys.argv[1:]):
|
||||||
|
@ -17,9 +20,61 @@ def main(args=sys.argv[1:]):
|
||||||
opts = parse_args(args)
|
opts = parse_args(args)
|
||||||
initialize_logging()
|
initialize_logging()
|
||||||
logging.debug('argv %r parsed %r', sys.argv, opts)
|
logging.debug('argv %r parsed %r', sys.argv, opts)
|
||||||
raise NotImplementedError((main, opts))
|
|
||||||
|
try:
|
||||||
|
main_logged(opts.RELEASE_VERSION, opts.RELEASE_PREV)
|
||||||
|
except SystemExit as e:
|
||||||
|
logging.error(str(e))
|
||||||
|
raise
|
||||||
|
except:
|
||||||
|
logging.error(traceback.format_exc())
|
||||||
|
raise
|
||||||
|
|
||||||
|
|
||||||
|
# Top-level flow:
|
||||||
|
def main_logged(release, releaseprev):
|
||||||
|
verify_releaseprev_tag(releaseprev)
|
||||||
|
raise NotImplementedError(main_logged)
|
||||||
|
|
||||||
|
|
||||||
|
def parse_args(args):
|
||||||
|
p = argparse.ArgumentParser(description=main.__doc__)
|
||||||
|
p.add_argument(
|
||||||
|
'RELEASE_VERSION',
|
||||||
|
type=Version.parse_arg,
|
||||||
|
help='The release version: vX.Y.Z-N',
|
||||||
|
)
|
||||||
|
p.add_argument(
|
||||||
|
'RELEASE_PREV',
|
||||||
|
type=Version.parse_arg,
|
||||||
|
help='The previously released version.',
|
||||||
|
)
|
||||||
|
return p.parse_args(args)
|
||||||
|
|
||||||
|
|
||||||
|
def verify_releaseprev_tag(releaseprev):
|
||||||
|
candidates = []
|
||||||
|
for tag in sh_out('git', 'tag', '--list').splitlines():
|
||||||
|
if tag.startswith('v1'): # Ignore v0.* bitcoin tags and other stuff.
|
||||||
|
candidates.append(Version.parse_arg(tag))
|
||||||
|
|
||||||
|
candidates.sort()
|
||||||
|
try:
|
||||||
|
latest = candidates[-1]
|
||||||
|
except IndexError:
|
||||||
|
raise SystemExit('No previous releases found by `git tag --list`.')
|
||||||
|
|
||||||
|
if releaseprev != latest:
|
||||||
|
raise SystemExit(
|
||||||
|
'The latest candidate in `git tag --list` is {} not {}'
|
||||||
|
.format(
|
||||||
|
latest.vtext,
|
||||||
|
releaseprev.vtext,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# Helper code:
|
||||||
def chdir_to_repo():
|
def chdir_to_repo():
|
||||||
dn = os.path.dirname
|
dn = os.path.dirname
|
||||||
repodir = dn(dn(os.path.abspath(sys.argv[0])))
|
repodir = dn(dn(os.path.abspath(sys.argv[0])))
|
||||||
|
@ -49,14 +104,9 @@ def initialize_logging():
|
||||||
logging.info('zcash make-release.py logging to: %r', logname)
|
logging.info('zcash make-release.py logging to: %r', logname)
|
||||||
|
|
||||||
|
|
||||||
def parse_args(args):
|
def sh_out(*args):
|
||||||
p = argparse.ArgumentParser(description=main.__doc__)
|
logging.debug('Run: %r', args)
|
||||||
p.add_argument(
|
return subprocess.check_output(args)
|
||||||
'RELEASE_VERSION',
|
|
||||||
type=Version.parse_arg,
|
|
||||||
help='The release version: vX.Y.Z-N',
|
|
||||||
)
|
|
||||||
return p.parse_args(args)
|
|
||||||
|
|
||||||
|
|
||||||
class Version (object):
|
class Version (object):
|
||||||
|
@ -91,6 +141,8 @@ class Version (object):
|
||||||
assert type(i) is int, i
|
assert type(i) is int, i
|
||||||
assert betarc in {None, 'rc', 'beta'}, betarc
|
assert betarc in {None, 'rc', 'beta'}, betarc
|
||||||
assert hotfix is None or type(hotfix) is int, hotfix
|
assert hotfix is None or type(hotfix) is int, hotfix
|
||||||
|
if betarc is not None:
|
||||||
|
assert hotfix is not None, (betarc, hotfix)
|
||||||
|
|
||||||
self.major = major
|
self.major = major
|
||||||
self.minor = minor
|
self.minor = minor
|
||||||
|
@ -108,24 +160,35 @@ class Version (object):
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return '<Version {}>'.format(self.vtext)
|
return '<Version {}>'.format(self.vtext)
|
||||||
|
|
||||||
|
def _sort_tup(self):
|
||||||
|
if self.hotfix is None:
|
||||||
|
prio = 2
|
||||||
|
else:
|
||||||
|
prio = {'beta': 0, 'rc': 1, None: 3}[self.betarc]
|
||||||
|
|
||||||
|
return (
|
||||||
|
self.major,
|
||||||
|
self.minor,
|
||||||
|
self.patch,
|
||||||
|
prio,
|
||||||
|
self.hotfix,
|
||||||
|
)
|
||||||
|
|
||||||
|
def __cmp__(self, other):
|
||||||
|
return cmp(self._sort_tup(), other._sort_tup())
|
||||||
|
|
||||||
|
|
||||||
# Unit Tests
|
# Unit Tests
|
||||||
class TestVersion (unittest.TestCase):
|
class TestVersion (unittest.TestCase):
|
||||||
def test_arg_parse_and_vtext_identity(self):
|
ValidVersions = [
|
||||||
cases = [
|
|
||||||
'v0.0.0',
|
|
||||||
'v1.0.0',
|
|
||||||
'v1.0.0-7',
|
|
||||||
'v1.2.3-1',
|
|
||||||
|
|
||||||
# These are taken from: git tag --list | grep '^v1'
|
# These are taken from: git tag --list | grep '^v1'
|
||||||
'v1.0.0',
|
|
||||||
'v1.0.0-beta1',
|
'v1.0.0-beta1',
|
||||||
'v1.0.0-beta2',
|
'v1.0.0-beta2',
|
||||||
'v1.0.0-rc1',
|
'v1.0.0-rc1',
|
||||||
'v1.0.0-rc2',
|
'v1.0.0-rc2',
|
||||||
'v1.0.0-rc3',
|
'v1.0.0-rc3',
|
||||||
'v1.0.0-rc4',
|
'v1.0.0-rc4',
|
||||||
|
'v1.0.0',
|
||||||
'v1.0.1',
|
'v1.0.1',
|
||||||
'v1.0.2',
|
'v1.0.2',
|
||||||
'v1.0.3',
|
'v1.0.3',
|
||||||
|
@ -137,7 +200,8 @@ class TestVersion (unittest.TestCase):
|
||||||
'v1.0.8-1',
|
'v1.0.8-1',
|
||||||
]
|
]
|
||||||
|
|
||||||
for case in cases:
|
def test_arg_parse_and_vtext_identity(self):
|
||||||
|
for case in self.ValidVersions:
|
||||||
v = Version.parse_arg(case)
|
v = Version.parse_arg(case)
|
||||||
self.assertEqual(v.vtext, case)
|
self.assertEqual(v.vtext, case)
|
||||||
|
|
||||||
|
@ -158,6 +222,18 @@ class TestVersion (unittest.TestCase):
|
||||||
case,
|
case,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_version_sort(self):
|
||||||
|
expected = [Version.parse_arg(v) for v in self.ValidVersions]
|
||||||
|
|
||||||
|
rng = random.Random()
|
||||||
|
rng.seed(0)
|
||||||
|
|
||||||
|
for _ in range(1024):
|
||||||
|
vec = list(expected)
|
||||||
|
rng.shuffle(vec)
|
||||||
|
vec.sort()
|
||||||
|
self.assertEqual(vec, expected)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
if len(sys.argv) >= 2 and sys.argv[1] == 'test':
|
if len(sys.argv) >= 2 and sys.argv[1] == 'test':
|
||||||
|
|
Loading…
Reference in New Issue