#!/usr/bin/env python2 # Copyright 2016 Lars Wirzenius # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # # =*= License: GPL-3+ =*= import re import time import cliapp class Bumper(cliapp.Application): def process_args(self, args): version = args[0] print 'Preparing release version', version filename = self.find_version_py() print 'Setting version in', filename self.write_version_py(filename, version, '') print 'Updating debian/changelog' self.update_debian_changelog(version, 'New upstream version.') self.release_debian_changelog() print 'Updating NEWS' self.update_NEWS_for_release(version) print 'Committing version updates to git' self.commit(version, 'Prepare to release version {}'.format(version)) print 'Making release tag' self.make_release_tag(version) gitversion = version + '+git' print 'Updating in-development version to', gitversion print 'Setting version in', filename self.write_version_py(filename, version, '+git') print 'Updating debian/changelog' self.update_debian_changelog(gitversion, '') print 'Updating NEWS' self.update_NEWS_for_git(gitversion) print 'Committing development version changes' self.commit( version, 'Bump version number post-release to {}'.format(gitversion)) def find_version_py(self): output = cliapp.runcmd(['git', 'ls-files']) filenames = [x.strip() for x in output.splitlines()] version_pys = [x for x in filenames if x.endswith('/version.py')] if len(version_pys) == 0: raise cliapp.AppException('No version.py in project') elif len(version_pys) > 1: raise cliapp.AppException('Too many version.py in project') return version_pys[0] def update_debian_changelog(self, version, msg): debian_version = '{}-1'.format(version) cliapp.runcmd(['dch', '-v', debian_version, msg]) def release_debian_changelog(self): cliapp.runcmd(['dch', '-r', '']) def update_NEWS_for_release(self, version): with open('NEWS') as f: text = f.read() date = time.strftime('%Y-%m-%d') pattern = r'^Version \d+(\.\d+)*(\+git)?, not yet released$' replacement = 'Version {}, released {}'.format(version, date) updated = re.sub(pattern, replacement, text, flags=re.M) with open('NEWS', 'w') as f: f.write(updated) def update_NEWS_for_git(self, version): with open('NEWS') as f: text = f.read() pattern = r'^Version \d+(\.\d+)*, released \d\d\d\d-\d\d-\d\d$' replacement = 'Version {}, not yet released'.format(version) updated = re.sub(pattern, replacement, text, flags=re.M) with open('NEWS', 'w') as f: f.write(updated) def commit(self, version, msg): cliapp.runcmd(['git', 'commit', '-am', msg]) def make_release_tag(self, version): name = self.get_project_name() tag_name = '{}-{}'.format(name, version) msg = 'Release version {}'.format(version) cliapp.runcmd(['git', 'tag', '-sam', msg, tag_name]) def get_project_name(self): output = cliapp.runcmd(['python', 'setup.py', '--name']) return output.strip() def write_version_py(self, filename, version, suffix): version_info = self.parse_version_info(version, suffix) with open(filename, 'w') as f: f.write('__version__ = "{}"\n'.format(version + suffix)) f.write('__version_info__ = {!r}\n'.format(version_info)) def parse_version_info(self, version, suffix): parts = version.split('.') result = [] for part in parts: try: result.append(int(part)) except ValueError: result.append(part) if suffix: result.append(suffix) return tuple(result) Bumper().run()