[Python-checkins] r43401 - sandbox/trunk/welease/welease.glade sandbox/trunk/welease/welease.py

anthony.baxter python-checkins at python.org
Tue Mar 28 16:29:26 CEST 2006


Author: anthony.baxter
Date: Tue Mar 28 16:29:25 2006
New Revision: 43401

Modified:
   sandbox/trunk/welease/welease.glade
   sandbox/trunk/welease/welease.py
Log:
uses a ~/.weleaserc config file (a default one is created if necessary)
checks Misc/NEWS and Lib/idlelib/NEWS.txt for correct versions and that 
the release date is filled in. 


Modified: sandbox/trunk/welease/welease.glade
==============================================================================
--- sandbox/trunk/welease/welease.glade	(original)
+++ sandbox/trunk/welease/welease.glade	Tue Mar 28 16:29:25 2006
@@ -578,7 +578,7 @@
 	      <property name="visible">True</property>
 	      <property name="can_focus">True</property>
 	      <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
-	      <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+	      <property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property>
 	      <property name="shadow_type">GTK_SHADOW_IN</property>
 	      <property name="window_placement">GTK_CORNER_TOP_RIGHT</property>
 

Modified: sandbox/trunk/welease/welease.py
==============================================================================
--- sandbox/trunk/welease/welease.py	(original)
+++ sandbox/trunk/welease/welease.py	Tue Mar 28 16:29:25 2006
@@ -18,23 +18,30 @@
 
 # This isn't the prettiest code in the world, but it should be good enough.
 # It was written in the space of a couple of hours, and could (and will) get
-# a refactoring as I add things to it.
+# a refactoring as I add things to it. Don't look too closely at some of it,
+# it's got some ugly bits.
 
 # TODO:
-#   Fix the scrolling in the output box
-#   Move configuration out to a .weleasewc (and maybe a prefs panel? naaah)
-#   Add a *lot* more checks to the Check Release stage.
+#   Lock out the current button so you don't run the same stage repeatedly.
+#   Add more checks to the Check Release stage (see XXX in the list below)
+#
+# Stage 2 of releases.
+#   Sign the releases (using pygpgme).
+#   Check the signatures.
+#   Update the webpage 'Downloads' section.
+#   Upload the releases.
+#   Format and send the release email. (Just kidding).
 
 # Check Release steps:
 # XXX = not implemented yet.
 # 
-# Checks Include/patchlevel.h (fatal if wrong)
-# Checks for uncommitted changes in the checkout (nonfatal)
-# Checks Lib/idlelib/idlever.py (fatal)
-# Checks the revision in the checkout is the same as repository HEAD (fatal)
-# Checks Misc/NEWS and Lib/idlelib/NEWS.txt (nonfatal) [XXX]
-# Checks PCbuild/BUILDno.txt ? [XXX]
-# Checks Tools/msi/msi.py ? [XXX]
+# Check Include/patchlevel.h (fatal if wrong)
+# Check for uncommitted changes in the checkout (nonfatal)
+# Check Lib/idlelib/idlever.py (fatal)
+# Check the revision in the checkout is the same as repository HEAD (fatal)
+# Check Misc/NEWS and Lib/idlelib/NEWS.txt (fatal) 
+# Check PCbuild/BUILDno.txt ? [XXX]
+# Check Tools/msi/msi.py ? [XXX]
 
 import gnome
 gnomeProgram = gnome.init("Welease", "0.1")
@@ -49,21 +56,7 @@
 
 import os, sys
 
-# Config section. This should all be put into a config file or something
-CheckoutHome = '/home/anthony/projects/python'
-CheckoutPaths = {
-    'trunk': CheckoutHome + '/pytrunk/python',
-    'release24-maint': CheckoutHome + '/release24-maint',
-    'release25-maint': CheckoutHome + '/release25-maint',
-}
-SVNROOT = 'svn+ssh://pythondev@svn.python.org/python'
-SvnPaths = {
-    'trunk': SVNROOT + '/trunk',
-    'release24-maint': SVNROOT + '/branches/release24-maint',
-    'release25-maint': SVNROOT + '/branches/release25-maint',
-}
-BuildPath = '/home/anthony/projects/python/build'
-# End config
+cfg = None
 
 def buildEnv():
     envVars = 'SSH_AUTH_SOCK', 'PATH', 'SSH_AGENT_PID'
@@ -183,7 +176,7 @@
         self.checkReleaseBuildTestVersion()
 
     def checkReleaseBuildTestVersion(self):
-        checkout = CheckoutPaths[self.currentBranch]
+        checkout = cfg.CheckoutPaths[self.currentBranch]
         buildtest = "/tmp/welease_testversion%s"%(os.getpid())
         open("%s.c"%(buildtest), "w").write(TestVersionCode)
         d = self.do_command(["gcc", "-I%s"%checkout, "-o", buildtest,
@@ -194,13 +187,13 @@
     def checkReleaseTestVersion(self, (output, error)):
         if output != '%s %s\n'%(self.newRelease, self.newRelease):
             return self.warnPopup('Include/patchlevel.h is not correct')
-        checkout = CheckoutPaths[self.currentBranch]
+        checkout = cfg.CheckoutPaths[self.currentBranch]
         os.chdir(checkout)
         d = self.do_command(["svn", "stat"], capture=True)
         d.addCallback(self.checkReleaseFindUnmergedChanges)
 
     def checkReleaseFindUnmergedChanges(self, (stdout, stderr)):
-        checkout = CheckoutPaths[self.currentBranch]
+        checkout = cfg.CheckoutPaths[self.currentBranch]
         unmerged = set()
         badstats = ('M', 'A', 'C', 'D', 'G', 'R', '~', '!')
         for line in stdout.splitlines():
@@ -222,33 +215,29 @@
             return
 
     def checkReleaseIdlelibVer(self):
-        checkout = CheckoutPaths[self.currentBranch]
+        checkout = cfg.CheckoutPaths[self.currentBranch]
         libpath = os.path.join(checkout, 'Lib')
         if libpath in sys.modules:
             print "already added %s to sys.path??"%libpath
         else:
             sys.path.insert(0, libpath)
         from idlelib.idlever import IDLE_VERSION
-        # Now compare Python and Idle versions.
-        pyver = self.newRelease.split('.')
-        idlever = IDLE_VERSION.split('.')
         unimportModules('idlelib', 'idlelib.idlever')
-        if (int(pyver[0]) - 1  != int(idlever[0]) or 
-            int(pyver[1]) - 3  != int(idlever[1]) or 
-            pyver[2] != idlever[2]):
+        # Now compare Python and Idle versions.
+        if not compareIdleVsPython(IDLE_VERSION, self.newRelease):
             return self.warnPopup('Lib/idlelib/idlever.py is not correct')
         self.checkReleaseGetSvnRevisions()
 
     def checkReleaseGetSvnRevisions(self):
-        checkout = CheckoutPaths[self.currentBranch]
-        reposurl = SvnPaths[self.currentBranch]
+        checkout = cfg.CheckoutPaths[self.currentBranch]
+        reposurl = cfg.SvnPaths[self.currentBranch]
         d = self.do_command(["svn", "info", reposurl, checkout], capture=True)
         d.addCallback(self.checkReleaseCurrentSvn)
 
     def checkReleaseCurrentSvn(self, (stdout,stderr)):
         # Examine the "svn info" output, compare the revisions.
-        checkout = CheckoutPaths[self.currentBranch]
-        reposurl = SvnPaths[self.currentBranch]
+        checkout = cfg.CheckoutPaths[self.currentBranch]
+        reposurl = cfg.SvnPaths[self.currentBranch]
         crev = localrev = reposrev = None
         for line in stdout.splitlines():
             line = line.strip().split(':', 1)
@@ -275,7 +264,21 @@
         self.checkReleaseCheckNewsFiles()
     
     def checkReleaseCheckNewsFiles(self):
-        checkout = CheckoutPaths[self.currentBranch]
+        checkout = cfg.CheckoutPaths[self.currentBranch]
+        vers, date, err = parseNewsFile(os.path.join(checkout, "Misc/NEWS"))
+        if err:
+            return self.warnPopup('Checking Misc/NEWS, got error\n' + err)
+        if vers != self.newRelease:
+            return self.warnPopup('Misc/NEWS has version %s, not %s\n'%(vers,
+                                                            self.newRelease))
+
+        vers, date, err = parseNewsFile(os.path.join(checkout, 
+                                                     "Lib/idlelib/NEWS.txt"))
+        if err:
+            return self.warnPopup('Checking Lib/idlelib/NEWS.txt, error:\n' + 
+                                                                         err)
+        if not compareIdleVsPython(vers, self.newRelease):
+            return self.warnPopup('Lib/idlelib/NEWS.txt has wrong version')
         self.checkReleaseDone()
 
     def checkReleaseDone(self):
@@ -289,7 +292,7 @@
 
     def on_makeTagButton_clicked(self, e):
         tagName = 'r' + self.newRelease.replace('.', '')
-        self.tagPath = '%s/tags/%s'%(SVNROOT, tagName)
+        self.tagPath = '%s/tags/%s'%(cfg.SVNROOT, tagName)
         d = self.do_command(['svn', 'info', self.tagPath], capture=True)
         d.addCallback(self.makeTagCheckSvnExists)
 
@@ -301,7 +304,7 @@
             d.addCallback(lambda x: x==True and self.makeTagDone(0))
             return
 
-        svnroot = SvnPaths[self.currentBranch]
+        svnroot = cfg.SvnPaths[self.currentBranch]
         tagName = 'r' + self.newRelease.replace('.', '')
 
         d = self.do_command(['svn', 'cp',
@@ -317,7 +320,7 @@
             self.warnPopup("svn cp exited with code %d"%(exitval))
 
     def on_exportSvnButton_clicked(self, e):
-        self.exportPath = BuildPath + '/Python-%s'%(self.newRelease)
+        self.exportPath = cfg.BuildHome + '/Python-%s'%(self.newRelease)
         if os.path.exists(self.exportPath):
             d = self.warnPopup('%s already exists'%self.exportPath, fatal=False)
             d.addCallback(lambda x: x==True and self.exportSvnDone(0))
@@ -333,7 +336,7 @@
             self.warnPopup("svn export exited with code %d"%(exitval))
 
     def on_buildTarballsButton_clicked(self, e):
-        os.chdir(BuildPath)
+        os.chdir(cfg.BuildHome)
         rdir = 'Python-%s'%self.newRelease
         d = self.do_command(["tar", "--gzip", "-cf", "%s.tgz"%rdir, rdir])
         d.addCallback(lambda x: x == 0 and self.do_command(
@@ -377,13 +380,8 @@
         if lines > self.MAXLINES:
             b.delete(b.get_start_iter(),
                      b.get_iter_at_line_offset(self.DELETECHUNK,0))
-        # Doesn't sodding work...
-        b.place_cursor(b.get_end_iter())
-        self.widget.place_cursor_onscreen()
-        #if self.scroll is not None:
-        #    print "scrolling"
-        #    adj = self.scroll.get_vadjustment()
-        #    adj.set_value(adj.upper)
+        mark = b.create_mark("end", b.get_end_iter(), False)
+        self.widget.scroll_to_mark(mark, 0.05, True, 0.0, 1.0)
 
     def flush(self):
         pass
@@ -435,9 +433,56 @@
         if mod in sys.modules:
             del sys.modules[mod]
 
+def compareIdleVsPython(idlever, pyver):
+        pyver = pyver.split('.')
+        idlever = idlever.split('.')
+        if (int(pyver[0]) - 1  != int(idlever[0]) or 
+            int(pyver[1]) - 3  != int(idlever[1]) or 
+            pyver[2] != idlever[2]):
+            return False
+        else:
+            return True
+
+
+def parseNewsFile(filename):
+    import time
+    vers = releasedate = err = None
+    for line in open(filename):
+        line = line.strip()
+        if line.lower().startswith("what's new in "):
+            if vers and not releasedate:
+                err = "no recognisable release date line"
+                break
+            vers = line.split()[-1].rstrip('?')
+        if line.lower().startswith("*release date:"):
+            if vers is None:
+                err = "no 'whats new' line before release date"
+            date = line.split()[-1].rstrip('*')
+            try:
+                date = time.strptime(date, '%d-%b-%Y')
+                releasedate = time.strftime('%d-%b-%Y', date)
+            except ValueError:
+                err = "failed to parse %s"%date
+                break
+        if vers and releasedate:
+            break
+    return vers, releasedate, err
 
 def main():
+    global cfg
+    import imp
+    cfgFileName = os.path.expanduser('~/.weleaserc')
+
     win = WeleaseWindow()
+
+    if not os.path.exists(cfgFileName):
+        open(cfgFileName, 'w').write(DefaultConfig)
+        win.warnPopup('Default config file written to %s. You will need to '
+                      'edit this, then restart this program'%cfgFileName)
+    # Eurgh.
+    cfg = imp.load_module('cfg', open(cfgFileName), cfgFileName, ('.py','U',1))
+    # End eurgh.
+
     curpath = os.getcwd()
     reactor.run()
     os.chdir(curpath)
@@ -489,5 +534,32 @@
 }
 """
 
+# Default config file.
+DefaultConfig = """
+from os.path import expanduser
+
+# CheckoutPaths is where the local checkouts for the trunk and branches live
+# You almost certainly will want to change these.
+
+CheckoutHome = expanduser('~/projects/python')
+CheckoutPaths = {
+    'trunk': CheckoutHome + '/pytrunk/python',
+    'release24-maint': CheckoutHome + '/release24-maint',
+    'release25-maint': CheckoutHome + '/release25-maint',
+}
+
+# You probably don't need to change these.
+SVNROOT = 'svn+ssh://pythondev@svn.python.org/python'
+SvnPaths = {
+    'trunk': SVNROOT + '/trunk',
+    'release24-maint': SVNROOT + '/branches/release24-maint',
+    'release25-maint': SVNROOT + '/branches/release25-maint',
+}
+
+# BuildHome is where the builds will happen. It can be an empty directory.
+BuildHome = expanduser('~/projects/python/build')
+"""
+# End config
+
 if __name__ == "__main__":
     main()


More information about the Python-checkins mailing list