[Python-checkins] r43654 - sandbox/trunk/welease/welease.py

anthony.baxter python-checkins at python.org
Wed Apr 5 04:43:10 CEST 2006


Author: anthony.baxter
Date: Wed Apr  5 04:43:09 2006
New Revision: 43654

Modified:
   sandbox/trunk/welease/welease.py
Log:
updates for a major release

Modified: sandbox/trunk/welease/welease.py
==============================================================================
--- sandbox/trunk/welease/welease.py	(original)
+++ sandbox/trunk/welease/welease.py	Wed Apr  5 04:43:09 2006
@@ -24,24 +24,27 @@
 # TODO:
 #   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)
+#   Refactor some of the ugliness.
 #
-# 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).
+#   Stage 2 of releases.
+#     Sign the releases (using pygpgme, or gnome-gpg?).
+#     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.
 # 
 # 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 Lib/idlelib/idlever.py (fatal)
 # Check Misc/NEWS and Lib/idlelib/NEWS.txt (fatal) 
-# Check PCbuild/BUILDno.txt ? [XXX]
-# Check Tools/msi/msi.py ? [XXX]
+# Check product_codes in Tools/msi/msi.py (fatal)
+# Check PCbuild/BUILDno.txt and PCbuild/pythoncore.vcproj [XXX] [2.4 only]
+# Check Doc/commontex/boilerplate.tex [XXX]
+# Check various release dates match [XXX]
 
 import gnome
 gnomeProgram = gnome.init("Welease", "0.1")
@@ -54,7 +57,7 @@
 gtk2reactor.install()
 from twisted.internet import reactor, protocol, defer
 
-import os, sys
+import os, sys, re
 
 cfg = None
 
@@ -279,6 +282,14 @@
                                                                          err)
         if not compareIdleVsPython(vers, self.newRelease):
             return self.warnPopup('Lib/idlelib/NEWS.txt has wrong version')
+        self.checkMsiFile()
+
+    def checkMsiFile(self):
+        checkout = cfg.CheckoutPaths[self.currentBranch]
+        msiDir = os.path.join(checkout, 'Tools/msi/')
+        version = checkMsiFileForVersion(msiDir, self.newRelease)
+        if version is None:
+            return self.warnPopup('Tools/msi/msi.py is missing product_code', fatal=False)
         self.checkReleaseDone()
 
     def checkReleaseDone(self):
@@ -434,15 +445,37 @@
             del sys.modules[mod]
 
 def compareIdleVsPython(idlever, pyver):
-        pyver = pyver.split('.')
-        idlever = idlever.split('.')
+        pyserial = idleserial = ''
+        # check for alpha/beta/rc
+        if pyver[-2] in 'abc':
+            pyver, pyserial = pyver[:-2], pyver[-2:]
+        if idlever[-2] in 'abc':
+            idlever, idleserial = idlever[:-2], idlever[-2:]
+        pyver = pyver.split('.') + [0,]
+        idlever = idlever.split('.') + [0,]
         if (int(pyver[0]) - 1  != int(idlever[0]) or 
             int(pyver[1]) - 3  != int(idlever[1]) or 
-            pyver[2] != idlever[2]):
+            pyver[2] != idlever[2] or
+            idleserial != pyserial):
             return False
         else:
             return True
 
+def parseReleaseLine(line):
+    # ick
+    vline = re.compile(r"^what's new in (python|idle) (?P<major>\d\.\d)( ?\(?(?P<level>alpha|beta|release candidate|final|rc|[abc]) ?(?P<serial>\d))?\)?\??", re.I)
+    levels = {'alpha':'a', 'beta':'b', 'rc':'c', 'release candidate':'c'}
+    m = vline.search(line)
+    if m:
+        major,level,serial=m.group('major'), m.group('level'), m.group('serial')        
+        if level and len(level) != 1:
+            level = levels.get(level)
+        if not serial and not level:
+            # final
+            return major
+        else:
+            return '%s%s%s'%(major, level, serial)
+
 
 def parseNewsFile(filename):
     import time
@@ -453,7 +486,7 @@
             if vers and not releasedate:
                 err = "no recognisable release date line"
                 break
-            vers = line.split()[-1].rstrip('?')
+            vers = parseReleaseLine(line)
         if line.lower().startswith("*release date:"):
             if vers is None:
                 err = "no 'whats new' line before release date"
@@ -468,6 +501,58 @@
             break
     return vers, releasedate, err
 
+
+# There has _got_ to be a better way to handle this!
+# Best would be if msi.py was at least importable on non-Windows.
+# Or I can parse the file by hand - blech.
+import compiler, compiler.ast
+
+def extractDictFromAST(ast, dictname):
+    import compiler, compiler.ast
+    products = None
+    for item in ast.getChildren():
+        if isinstance(item, compiler.ast.Assign):
+            kids = item.getChildren()
+            if ( isinstance(kids[0], compiler.ast.AssName) and 
+                 isinstance(kids[1], compiler.ast.Dict) and 
+                 kids[0].getChildren()[0] == dictname):
+                products = kids[1].getChildren()
+    if not products:
+        print "XXX FIXME"
+        return None
+    products = (x.getChildren()[0] for x in products)
+    dd = {}
+    while True:
+        try:
+            k, v = products.next(), products.next()
+            dd[k] = v
+        except StopIteration:
+            break
+    return dd
+
+def checkMsiFileForVersion(dirname, version):
+    if os.path.exists(os.path.join(dirname, 'uuids.py')):
+        sys.path.insert(0, dirname)
+        from uuids import product_codes
+        unimportModules('uuids')
+    else:
+        import compiler
+        filename = os.path.join(dirname, 'msi.py')
+        ast = compiler.parseFile(filename).getChildren()[1]
+        product_codes = extractDictFromAST(ast, 'product_codes')
+    #levels = extractDictFromAST(ast, 'levels')
+    levels = { 'a': '10', 'b': '11', 'c': '12', }
+    r = re.compile(r'(?P<major>[\d\.]+)(?P<serial>[abc]\d)?')
+    maj, serial = r.match(version).groups()
+    if len(maj) == 3:
+        maj = maj + '.'
+    if not serial:
+        code = maj + '150' # final, serial 0
+    else:
+        code = maj + levels[serial[0]] + serial[1:]
+    print code, product_codes
+    return product_codes.get(code)
+
 def main():
     global cfg
     import imp


More information about the Python-checkins mailing list