Browse Source

Implement `PathPatcher` abstraction, `clientversion.h` rewrite, and build numbering w/ unittests.

v1.0.9-lin
Nathan Wilcox 7 years ago
parent
commit
68ab915a24
  1. 141
      zcutil/make-release.py

141
zcutil/make-release.py

@ -10,6 +10,7 @@ import subprocess
import traceback
import unittest
import random
from cStringIO import StringIO
def main(args=sys.argv[1:]):
@ -34,7 +35,9 @@ def main(args=sys.argv[1:]):
# Top-level flow:
def main_logged(release, releaseprev):
verify_releaseprev_tag(releaseprev)
verify_git_clean_master()
initialize_git(release)
patch_version_in_files(release, releaseprev)
raise NotImplementedError(main_logged)
@ -81,7 +84,7 @@ def verify_releaseprev_tag(releaseprev):
)
def verify_git_clean_master():
def initialize_git(release):
junk = sh_out('git', 'status', '--porcelain')
if junk.strip():
raise SystemExit('There are uncommitted changes:\n' + junk)
@ -94,8 +97,18 @@ def verify_git_clean_master():
),
)
out = sh_out('git', 'pull', '--ff-only')
logging.debug('+ git pull --ff-only\n%s', out)
logging.info('Pulling to latest master.')
sh_out_logged('git', 'pull', '--ff-only')
branch = 'release-' + release.vtext
logging.info('Creating release branch: %r', branch)
sh_out_logged('git', 'checkout', '-b', branch)
return branch
def patch_version_in_files(release, releaseprev):
patch_README(release, releaseprev)
patch_clientversion_h(release, releaseprev)
# Helper code:
@ -106,6 +119,36 @@ def chdir_to_repo(repo):
os.chdir(repo)
def patch_README(release, releaseprev):
with PathPatcher('README.md') as (inf, outf):
firstline = inf.readline()
assert firstline == 'Zcash {}\n'.format(releaseprev.novtext), \
repr(firstline)
outf.write('Zcash {}\n'.format(release.novtext))
outf.write(inf.read())
def patch_clientversion_h(release, releaseprev):
rgx = re.compile(
r'^(#define CLIENT_VERSION_(MAJOR|MINOR|REVISION|BUILD)) \d+$'
)
with PathPatcher('src/clientversion.h') as (inf, outf):
for line in inf:
m = rgx.match(line)
if m:
prefix, label = m.groups()
repl = {
'MAJOR': release.major,
'MINOR': release.minor,
'REVISION': release.patch,
'BUILD': release.build,
}[label]
outf.write('{} {}\n'.format(prefix, repl))
else:
outf.write(line)
def initialize_logging():
TIME_FMT = '%Y-%m-%dT%H:%M:%S'
logname = './zcash-make-release.{}.log'.format(time.strftime(TIME_FMT))
@ -134,6 +177,12 @@ def sh_out(*args):
return subprocess.check_output(args)
def sh_out_logged(*args):
out = sh_out(*args)
logging.debug('Output:\n%s', out)
return out
class Version (object):
'''A release version.'''
@ -175,12 +224,22 @@ class Version (object):
self.betarc = betarc
self.hotfix = hotfix
self.vtext = 'v{}.{}.{}'.format(major, minor, patch)
if hotfix is not None:
self.vtext += '-{}{}'.format(
'' if betarc is None else betarc,
hotfix,
)
self.novtext = '{}.{}.{}'.format(major, minor, patch)
if hotfix is None:
self.build = 50
else:
assert hotfix > 0, hotfix
if betarc is None:
assert hotfix < 50, hotfix
self.build = 50 + hotfix
self.novtext += '-{}'.format(hotfix)
else:
assert hotfix < 26, hotfix
self.novtext += '-{}{}'.format(betarc, hotfix)
self.build = {'beta': 0, 'rc': 25}[betarc] + hotfix - 1
self.vtext = 'v' + self.novtext
def __repr__(self):
return '<Version {}>'.format(self.vtext)
@ -203,26 +262,49 @@ class Version (object):
return cmp(self._sort_tup(), other._sort_tup())
class PathPatcher (object):
def __init__(self, path):
self._path = path
def __enter__(self):
logging.info('Patching %r', self._path)
self._inf = file(self._path, 'r')
self._outf = StringIO()
return (self._inf, self._outf)
def __exit__(self, et, ev, tb):
if (et, ev, tb) == (None, None, None):
self._inf.close()
with file(self._path, 'w') as f:
f.write(self._outf.getvalue())
# Unit Tests
class TestVersion (unittest.TestCase):
ValidVersions = [
ValidVersionsAndBuilds = [
# These are taken from: git tag --list | grep '^v1'
'v1.0.0-beta1',
'v1.0.0-beta2',
'v1.0.0-rc1',
'v1.0.0-rc2',
'v1.0.0-rc3',
'v1.0.0-rc4',
'v1.0.0',
'v1.0.1',
'v1.0.2',
'v1.0.3',
'v1.0.4',
'v1.0.5',
'v1.0.6',
'v1.0.7-1',
'v1.0.8',
'v1.0.8-1',
('v1.0.0-beta1', 0),
('v1.0.0-beta2', 1),
('v1.0.0-rc1', 25),
('v1.0.0-rc2', 26),
('v1.0.0-rc3', 27),
('v1.0.0-rc4', 28),
('v1.0.0', 50),
('v1.0.1', 50),
('v1.0.2', 50),
('v1.0.3', 50),
('v1.0.4', 50),
('v1.0.5', 50),
('v1.0.6', 50),
('v1.0.7-1', 51),
('v1.0.8', 50),
('v1.0.8-1', 51),
]
ValidVersions = [
v
for (v, _)
in ValidVersionsAndBuilds
]
def test_arg_parse_and_vtext_identity(self):
@ -259,6 +341,11 @@ class TestVersion (unittest.TestCase):
vec.sort()
self.assertEqual(vec, expected)
def test_build_nums(self):
for (text, expected) in self.ValidVersionsAndBuilds:
version = Version.parse_arg(text)
self.assertEqual(version.build, expected)
if __name__ == '__main__':
if len(sys.argv) == 2 and sys.argv[1] == '--help':

Loading…
Cancel
Save