diff options
| author | Takeshi KOMIYA <i.tkomiya@gmail.com> | 2017-01-21 19:45:09 +0900 |
|---|---|---|
| committer | Takeshi KOMIYA <i.tkomiya@gmail.com> | 2017-01-21 19:45:35 +0900 |
| commit | 3f17bebecbd5bef6d7425a17e813090cff295730 (patch) | |
| tree | b6fbb948a2759d6d8d75c3670719574f17ecec86 | |
| parent | 765b00fc306c25c3bb1a16e1ea7c046f759f251e (diff) | |
| download | sphinx-git-3f17bebecbd5bef6d7425a17e813090cff295730.tar.gz | |
Add bump_version.py
| -rw-r--r-- | utils/CHANGES_template | 17 | ||||
| -rwxr-xr-x | utils/bump_vesion.py | 170 | ||||
| -rw-r--r-- | utils/release-checklist | 7 |
3 files changed, 191 insertions, 3 deletions
diff --git a/utils/CHANGES_template b/utils/CHANGES_template new file mode 100644 index 000000000..344a49eae --- /dev/null +++ b/utils/CHANGES_template @@ -0,0 +1,17 @@ +Release x.y.z (in development) +============================== + +Incompatible changes +-------------------- + +Deprecated +---------- + +Features added +-------------- + +Bugs fixed +---------- + +Testing +-------- diff --git a/utils/bump_vesion.py b/utils/bump_vesion.py new file mode 100755 index 000000000..617c33c0c --- /dev/null +++ b/utils/bump_vesion.py @@ -0,0 +1,170 @@ +#!/usr/bin/env python + +from __future__ import print_function + +import os +import re +import sys +from datetime import datetime +from contextlib import contextmanager + +script_dir = os.path.dirname(__file__) +package_dir = os.path.abspath(os.path.join(script_dir, '..')) + +RELEASE_TYPE = {'a': 'alpha', 'b': 'beta'} + + +def stringify_version(version_info): + if version_info[2] == 0: + return '.'.join(str(v) for v in version_info[:2]) + else: + return '.'.join(str(v) for v in version_info[:3]) + + +def bump_version(path, version_info): + version = stringify_version(version_info) + release = version + if version_info[3] != 'final': + version += '+' + + with open(path, 'r+') as f: + body = f.read() + body = re.sub("(?<=__version__ = ')[^']+", version, body) + body = re.sub("(?<=__released__ = ')[^']+", release, body) + body = re.sub("(?<=version_info = )\(.*\)", str(version_info), body) + + f.seek(0) + f.truncate(0) + f.write(body) + + +def parse_version(version): + matched = re.search('^(\d+)\.(\d+)$', version) + if matched: + major, minor = matched.groups() + return (int(major), int(minor), 0, 'final', 0) + + matched = re.search('^(\d+)\.(\d+)\.(\d+)$', version) + if matched: + major, minor, rev = matched.groups() + return (int(major), int(minor), int(rev), 'final', 0) + + matched = re.search('^(\d+)\.(\d+)\s*(a|b|alpha|beta)(\d+)$', version) + if matched: + major, minor, typ, relver = matched.groups() + release = RELEASE_TYPE.get(typ, typ) + return (int(major), int(minor), 0, release, int(relver)) + + matched = re.search('^(\d+)\.(\d+)\.(\d+)\s*(a|b|alpha|beta)(\d+)$', version) + if matched: + major, minor, rev, typ, relver = matched.groups() + release = RELEASE_TYPE.get(typ, typ) + return (int(major), int(minor), int(rev), release, int(relver)) + + raise RuntimeError('Unknown vesion: %s' % version) + + +class Skip(Exception): + pass + + +@contextmanager +def processing(message): + try: + print(message + ' ... ', end='') + yield + except Skip as exc: + print('skip: %s' % exc) + except: + print('error') + raise + else: + print('done') + + +class Changes(object): + def __init__(self, path): + self.path = path + self.fetch_version() + + def fetch_version(self): + with open(self.path) as f: + version = f.readline().strip() + matched = re.search('^Release (.*) \((.*)\)$', version) + if matched is None: + raise RuntimeError('Unknown CHANGES format: %s' % version) + + self.version, self.release_date = matched.groups() + self.version_info = parse_version(self.version) + if self.release_date == 'in development': + self.in_development = True + else: + self.in_development = False + + def finalize_release_date(self): + release_date = datetime.now().strftime('%b %d, %Y') + heading = 'Release %s (released %s)' % (self.version, release_date) + + with open(self.path, 'r+') as f: + f.readline() # skip first two lines + f.readline() + body = f.read() + + f.seek(0) + f.truncate(0) + f.write(heading + '\n') + f.write('=' * len(heading) + '\n') + f.write(body) + + def add_release(self, version_info): + if version_info[-2:] in (('beta', 0), ('final', 0)): + version = stringify_version(version_info) + else: + reltype = version_info[3] + version = '%s %s%s' % (stringify_version(version_info), + RELEASE_TYPE.get(reltype, reltype), + version_info[4] or '') + heading = 'Release %s (in development)' % version + + with open(os.path.join(script_dir, 'CHANGES_template')) as f: + f.readline() # skip first two lines + f.readline() + tmpl = f.read() + + with open(self.path, 'r+') as f: + body = f.read() + + f.seek(0) + f.truncate(0) + f.write(heading + '\n') + f.write('=' * len(heading) + '\n') + f.write(tmpl) + f.write('\n') + f.write(body) + + +def main(): + if len(sys.argv) != 2: + print("bump_version.py [version]") + return -1 + + version_info = parse_version(sys.argv[-1]) + + with processing("Rewriting sphinx/__init__.py"): + bump_version(os.path.join(package_dir, 'sphinx/__init__.py'), version_info) + + with processing('Rewriting CHANGES'): + changes = Changes(os.path.join(package_dir, 'CHANGES')) + if changes.version_info == version_info: + if changes.in_development: + changes.finalize_release_date() + else: + raise Skip('version not changed') + else: + if changes.in_development: + print('WARNING: last version is not released yet: %s' % changes.version) + changes.add_release(version_info) + + +if __name__ == '__main__': + main() diff --git a/utils/release-checklist b/utils/release-checklist index c4c9f48bf..610ab9d19 100644 --- a/utils/release-checklist +++ b/utils/release-checklist @@ -9,8 +9,8 @@ Release checklist * Run `(cd sphinx/locale; tx pull -a -f)` * Run `python setup.py compile_catalog` -* Update version info in sphinx/__init__.py -* Update release date in CHANGES +* `python utils/bump_version.py x.y.z` +* Check diff by `git diff` * `git commit -am 'Bump to x.y.z final'` * `make clean` * `python setup.py compile_grammar` @@ -21,7 +21,8 @@ Release checklist * `git push origin stable --tags` * open https://readthedocs.org/dashboard/sphinx/versions/ and enable the released version * Add new version/milestone to tracker categories -* Update version info, add new CHANGES entry for next version +* `python utils/bump_version.py a.b.cb0` (ex. 1.5.3b0) +* Check diff by `git diff` * `git commit -am 'Bump version'` * `git push origin stable` * `git checkout master` |
