#!/usr/bin/env python """Tag and branch schooltool releases. Based on the build-debs.py script by Gintautas Miliauskas. """ import re import os import sys import optparse import shutil # # Globals # TRUNK = "svn+ssh://source.schooltool.org/svn/schooltool/trunk/schooltool" BRANCHES = "svn+ssh://source.schooltool.org/svn/schooltool/branches/schooltool-" TAGS = "svn+ssh://source.schooltool.org/svn/schooltool/tags/schooltool-" actions = {} # # Utility functions # def runcmd(cmd): """Run `cmd` on the shell.""" print "=== Running command: '%s' ===" % cmd retval = os.system(cmd) if retval: print "%s failed!" % cmd sys.exit(3) return retval def svncopy(sourceurl, desturl, version, msg, tag=False): """Copy one subversion url to another setting the version number. Interactively asks for confirmation. """ answer = raw_input(""" About to copy %s to %s for version %s You may want to update the RELEASE.txt files for SB and ST before running. Proceed (y/n)? """ % (sourceurl, desturl, version)) if answer != 'y': sys.exit(3) print "Copying %s to %s" % (sourceurl, desturl) runcmd('rm -rf tmp') runcmd('svn cp %s %s -m "%s"' % (sourceurl, desturl, msg)) # We modify tags in place to set the version number. People might frown # on this, but I think it's OK to do in this situation. print "Setting version number" runcmd('svn checkout %s tmp' % desturl) init_code_fn = 'tmp/src/schooltool/version.txt' f = file(init_code_fn, 'w') f.write(version) f.close() if tag: print "Removing setup.cfg for a real release" runcmd('svn rm tmp/setup.cfg') runcmd('cd tmp && svn ci -m "Set version number as %s"' % version) shutil.rmtree('tmp') # # action handlers # def tag_from_branch(options): print "tagging %s from branch %s" % (options.to_version, options.from_version) svncopy(BRANCHES + options.from_version, TAGS + options.to_version, options.to_version, "Tagging %s" % options.to_version, tag=True) actions['tag-from-branch'] = tag_from_branch def branch_from_trunk(options): print "branching %s from trunk" % options.to_version svncopy(TRUNK, BRANCHES + options.to_version, options.to_version, "Branching %s" % options.to_version) actions['branch-from-trunk'] = branch_from_trunk def tag_from_trunk(options): print "tagging %s from trunk" % options.to_version svncopy(TRUNK, TAGS + options.to_version, options.to_version, "Tagging %s" % options.to_version, tag=True) actions['tag-from-trunk'] = tag_from_trunk # # Parse options and run an action # def parse_args(argv): parser = optparse.OptionParser( usage="usage: %prog [options]") parser.add_option("-a", "--action", dest="action", help="what action to perform, values: %s" % actions.keys(), choices=actions.keys(), type="choice") parser.add_option("--from", dest="from_version", help="what branch version to work on (not required for " " actions from the trunk)") parser.add_option("--to", dest="to_version", help="what is the version of the product (required)") options, args = parser.parse_args(argv) assert options.action is not None assert options.to_version is not None assert options.from_version is not None \ or options.action in ["tag-from-trunk", "branch-from-trunk"] return options def main(argv): options = parse_args(argv) actions[options.action](options) if __name__ == '__main__': main(sys.argv)