[Python-checkins] r62212 - sandbox/trunk/release/release.py

barry.warsaw python-checkins at python.org
Mon Apr 7 20:10:35 CEST 2008


Author: barry.warsaw
Date: Mon Apr  7 20:10:22 2008
New Revision: 62212

Modified:
   sandbox/trunk/release/release.py
Log:
Lots of changes based on first use for 3.0a4 and 2.6a2.

Modified: sandbox/trunk/release/release.py
==============================================================================
--- sandbox/trunk/release/release.py	(original)
+++ sandbox/trunk/release/release.py	Mon Apr  7 20:10:22 2008
@@ -10,6 +10,13 @@
 import shutil
 import tempfile
 
+from hashlib import md5
+from string import Template
+from urlparse import urlsplit, urlunsplit
+
+SPACE = ' '
+
+
 # Ideas stolen from Mailman's release script, Lib/tokens.py and welease
 
 def error(*msgs):
@@ -18,8 +25,9 @@
         print >> sys.stderr, msg
     sys.exit(1)
 
+
 def run_cmd(args, silent=False):
-    cmd = " ".join(args)
+    cmd = SPACE.join(args)
     if not silent:
         print "Executing %s" % cmd
     try:
@@ -30,13 +38,15 @@
     except OSError:
         error("%s failed" % cmd)
 
+
 def check_env():
     if "EDITOR" not in os.environ:
         error("editor not detected.",
-            "Please set your EDITOR enviroment variable")
+              "Please set your EDITOR enviroment variable")
     if not os.path.exists(".svn"):
         error("CWD is not a Subversion checkout")
         
+
 def get_arg_parser():
     usage = "%prog [options] tagname"
     p = optparse.OptionParser(usage=usage)
@@ -54,20 +64,33 @@
         help="Tag the release in Subversion")
     return p
 
-def constant_replace(fn, updated_constants, comment_start="/*", comment_end="*/"):
+
+def constant_replace(fn, updated_constants,
+                     comment_start="/*", comment_end="*/"):
     "Inserts in between --start constant-- and --end constant-- in a file"
     start_tag = comment_start + "--start constants--" + comment_end
     end_tag = comment_start + "--end constants--" + comment_end
-    with open(fn) as fp:
-        lines = fp.read().splitlines()
-    try:
-        start = lines.index(start_tag) + 1
-        end = lines.index(end_tag)
-    except ValueError:
-        error("%s doesn't have constant tags" % fn)
-    lines[start:end] = [updated_constants]
-    with open(fn, "w") as fp:
-        fp.write("\n".join(lines))
+    with open(fn) as infile:
+        with open(fn + '.new', 'w') as outfile:
+            found_constants = False
+            waiting_for_end = False
+            for line in infile:
+                if line[:-1] == start_tag:
+                    print >> outfile, start_tag
+                    print >> outfile, updated_constants
+                    print >> outfile, end_tag
+                    waiting_for_end = True
+                    found_constants = True
+                elif line[:-1] == end_tag:
+                    waiting_for_end = False
+                elif waiting_for_end:
+                    pass
+                else:
+                    outfile.write(line)
+    if not found_constants:
+        error('Constant section delimiters not found: %s' % fn)
+    os.rename(fn + '.new', fn)
+
 
 def bump(tag):
     print "Bumping version to %s" % tag
@@ -90,20 +113,26 @@
     print "done"
     
     print "Updating Include/patchlevel.h...",
-    template = """#define PY_MAJOR_VERSION	[major]
-#define PY_MINOR_VERSION	[minor]
-#define PY_MICRO_VERSION	[patch]
-#define PY_RELEASE_LEVEL    [level]
-#define PY_RELEASE_SERIAL	[serial]
-#define PY_VERSION  \"[text]\""""
-    for what in ("major", "minor", "patch", "serial", "text"):
-        template = template.replace("[" + what + "]", str(getattr(tag, what)))
-    level_defines = {"a" : "PY_RELEASE_LEVEL_ALPHA",
-    "b" : "PY_RELEASE_LEVEL_BETA",
-    "c" : "PY_RELEASE_LEVEL_GAMMA",
-    "f" : "PY_RELEASE_LEVEL_FINAL"}
-    template = template.replace("[level]", level_defines[tag.level])
-    constant_replace("Include/patchlevel.h", template)
+    template = Template("""\
+#define PY_MAJOR_VERSION\t$major
+#define PY_MINOR_VERSION\t$minor
+#define PY_MICRO_VERSION\t$patch
+#define PY_RELEASE_LEVEL\t$level
+#define PY_RELEASE_SERIAL\t$serial
+
+/* Version as a string */
+#define PY_VERSION      \t\"$text\"""")
+    substitutions = {}
+    for what in ('major', 'minor', 'patch', 'serial', 'text'):
+        substitutions[what] = getattr(tag, what)
+    substitutions['level'] = dict(
+        a   = 'PY_RELEASE_LEVEL_ALPHA',
+        b   = 'PY_RELEASE_LEVEL_BETA',
+        c   = 'PY_RELEASE_LEVEL_GAMMA',
+        f   = 'PY_RELEASE_LEVEL_FINAL',
+        )[tag.level]
+    new_constants = template.substitute(substitutions)
+    constant_replace("Include/patchlevel.h", new_constants)
     print "done"
     
     print "Updating Lib/idlelib/idlever.py...",
@@ -129,42 +158,58 @@
     print "Bumped revision"
     print "Please commit and use --tag"
 
+
 def manual_edit(fn):
     run_cmd([os.environ["EDITOR"], fn])
 
+
 def export(tag):
-    temp_dir = tempfile.mkdtemp("pyrelease")
-    if not os.path.exists("dist") and not os.path.isdir("dist"):
+    if not os.path.exists('dist'):
         print "creating dist directory"
-        os.mkdir("dist")
+        os.mkdir('dist')
+    if not os.path.isdir('dist'):
+        error('dist/ is not a directory')
     tgz = "dist/Python-%s.tgz" % tag.text
     bz = "dist/Python-%s.tar.bz2" % tag.text
     old_cur = os.getcwd()
-    os.chdir(temp_dir)
     try:
+        print "chdir'ing to dist"
+        os.chdir('dist')
         try:
-            print "Exporting tag"
+            print 'Exporting tag:', tag.text
+            python = 'Python-%s' % tag.text
             run_cmd(["svn", "export",
-                "http://svn.python.org/projects/python/tags/r%s"
-                % tag.text.replace(".", ""), "release"])
+                     "http://svn.python.org/projects/python/tags/r%s"
+                     % tag.nickname, python])
             print "Making .tgz"
-            run_cmd(["tar cf - release | gzip -9 > release.tgz"])
+            run_cmd(["tar cf - %s | gzip -9 > %s.tgz" % (python, python)])
             print "Making .tar.bz2"
-            run_cmd(["tar cf - release "
-                "| bzip2 -9 > release.tar.bz2"])
+            run_cmd(["tar cf - %s | bzip2 -9 > %s.tar.bz2" %
+                     (python, python)])
         finally:
             os.chdir(old_cur)
         print "Moving files to dist"
-        os.rename(os.path.join(temp_dir, "release.tgz"), tgz)
-        os.rename(os.path.join(temp_dir, "release.tar.bz2"), bz)
     finally:
         print "Cleaning up"
-        shutil.rmtree(temp_dir)
-    print "Calculating md5sums"
-    run_cmd(["md5sum", tgz, ">", tgz + ".md5"])
-    run_cmd(["md5sum", bz, ">", bz + ".md5"])
+    print 'Calculating md5 sums'
+    md5sum_tgz = md5()
+    with open(tgz) as source:
+        md5sum_tgz.update(source.read())
+    md5sum_bz2 = md5()
+    with open(bz) as source:
+        md5sum_bz2.update(source.read())
+    print md5sum_tgz.hexdigest(), ' ', tgz
+    print md5sum_bz2.hexdigest(), ' ', bz
+    with open(tgz + '.md5', 'w') as md5file:
+        print >> md5file, md5sum_tgz.hexdigest()
+    with open(bz + '.md5', 'w') as md5file:
+        print >> md5file, md5sum_bz2.hexdigest()
+    print 'Signing tarballs'
+    os.system('gpg -bas ' + tgz)
+    os.system('gpg -bas ' + bz)
     print "**Now extract the archives and run the tests**"
 
+
 class Tag:
     def __init__(self, text, major, minor, patch, level, serial):
         self.text = text
@@ -174,11 +219,16 @@
         self.patch = patch
         self.level = level
         self.serial = serial
-        self.basic_version = major + "." + minor
+        self.basic_version = major + '.' + minor
     
     def __str__(self):
         return self.text
 
+    @property
+    def nickname(self):
+        return self.text.replace('.', '')
+
+
 def break_up_tag(tag):
     exp = re.compile(r"(\d+)(?:\.(\d+)(?:\.(\d+))?)?(?:([abc])(\d+))?")
     result = exp.search(tag)
@@ -194,6 +244,7 @@
             data[i] = 0
     return Tag(tag, *data)
 
+
 def branch(tag):
     if tag.minor > 0 or tag.patch > 0 or tag.level != "f":
         print "It doesn't look like your making a final release."
@@ -203,17 +254,22 @@
         "svn+ssh://svn.python.org/projects/python/branches/" 
             "release%s-maint" % (tag.major + tag.minor)])
 
+
 def get_current_location():
-    data = subprocess.Popen("svn info", shell=True,
-        stdout=subprocess.PIPE).stdout.read().splitlines()
+    proc = subprocess.Popen('svn info', shell=True, stdout=subprocess.PIPE)
+    data = proc.stdout.read().splitlines()
     for line in data:
-        if line.startswith("URL: "):
-            return line.lstrip("URL: ")
+        if line.startswith('URL: '):
+            return line.lstrip('URL: ')
+
 
 def make_tag(tag):
-    run_cmd(["svn", "copy", get_current_location(),
-        "svn+ssh://svn.python.org/projects/python/tags/r"
-        + tag.text.replace(".", "")])
+    url = urlsplit(get_current_location())
+    new_path = 'python/tags/r' + tag.nickname
+    tag_url = urlunsplit((url.scheme, url.netloc, new_path,
+                          url.query, url.fragment))
+    run_cmd(['svn', 'copy', get_current_location(), tag_url])
+
 
 def main(argv):
     parser = get_arg_parser()
@@ -233,5 +289,6 @@
     elif options.export:
         export(tag)
 
+
 if __name__ == "__main__":
     main(sys.argv)


More information about the Python-checkins mailing list