import sys, os, string, re, urllib2 if string.find(os.path.abspath(sys.argv[0]), os.sep+'Twisted') != -1: sys.path.insert(0, os.path.normpath(os.path.join(os.path.abspath(sys.argv[0] ), os.pardir, os.pardir, os.pardir))) from twisted.python import usage class Options(usage.Options): updates = ('README', 'twisted/copyright.py', 'admin/twisted.spec', 'ChangeLog') optParameters = [ ["type", "t", "alpha", "Type of release -- alpha, RC or final"], ["qotr", "q", None, "Quote of the release"], ] optFlags = [ ["head", "h", "Start from HEAD"], ["manual-changelog", "c", "Enter changelog entry in editor"], ["dry-run", "n", "Do nothing"], ] def opt_update(self, file): self.updates = self.updates+(file,) def getrevision(): text = urllib2.urlopen('http://cvs.twistedmatrix.com/cvs/README') while 1: line = text.readline() if not line: break if line.startswith("<br>CVS Tags:"): text.readline() tag = parsetag(text.readline()) if tag: break text.close() return tag def parsetag(tag): tag = tag[tag.index('=')+1:] tag = tag[tag.index('=')+1:tag.rindex('"')] if not tag.startswith('release-'): return major, minor, patch = tag[tag.index('-')+1:].split('_') try: patch = int(patch) except ValueError: m = re.match('(\d+)(.+?)(\d+)', patch) patch = m.groups() else: patch = str(patch), 'final', 1 return tag, (major, minor, patch) def strtag(major, minor, patch): spatch = ''.join(patch) if patch[1]=='final': if patch[2]=='1': spatch = patch[0] else: spatch = str(int(patch[0])+1) return '.'.join([major, minor, spatch]) def calcnext(version, type): major, minor, patch = version order=['alpha', 'rc', 'final'] then, now = order.index(patch[1]), order.index(type) if now>then: patch = patch[0], type, '1' elif now<then: patch = str(int(patch[0])+1), type, '1' else: patch = patch[0], type, str(int(patch[2])+1) return strtag(major, minor, patch) def system(command, do): print "running", repr(command) if not do: return n = os.system(command) if n: sys.exit(n) def setqotr(qotr, do): if qotr is None: return print "setting quote to", repr(qotr) if not do: return res = [] fp = iter(file("README")) for line in fp: res.append(line) if line=="Quote of the Release:\n": res.append(fp.next()) # blank line res.append(qotr) for line in fp: if line=='\n': break res.append(line) res = ''.join(res) file("README", 'w').write(res) def run(config): tag, version = getrevision() command = 'cvs -d :ext:cvs.twistedmatrix.com:/cvs co -d Twisted.CVS' if not config['head']: command += " -r %s" % tag do = not config['dry-run'] system(command, do) old = strtag(*version) tag = calcnext(version, config['type']) print "next version is", tag if config.updates: system("cd Twisted.CVS && cvs up -A %s" % ' '.join(config.updates), do) command = "cd Twisted.CVS && ./admin/change" if not config['manual-changelog']: command += " -m 'Releasing Twisted %s'" % tag command += " ." system(command, do) system("Twisted.CVS/admin/release-twisted -o %s -V %s --upver" % (old, tag), do) setqotr(config['qotr'], do) def main(): c = Options() c.parseOptions() run(c) if __name__=='__main__': main()