[Jython-checkins] jython: Added two utility scripts for migrating the Jython specific changes in the

frank.wierzbicki jython-checkins at python.org
Wed Mar 14 04:09:32 CET 2012


http://hg.python.org/jython/rev/84b241e45cec
changeset:   6350:84b241e45cec
user:        Alex Grönholm <alex.gronholm at nextday.fi>
date:        Tue Mar 13 17:06:14 2012 -0700
summary:
  Added two utility scripts for migrating the Jython specific changes in the standard library to a newer CPython version

files:
  Misc/applypatches.py |  44 +++++++++++++++
  Misc/genpatches.py   |  92 ++++++++++++++++++++++++++++++++
  2 files changed, 136 insertions(+), 0 deletions(-)


diff --git a/Misc/applypatches.py b/Misc/applypatches.py
new file mode 100755
--- /dev/null
+++ b/Misc/applypatches.py
@@ -0,0 +1,44 @@
+#!/usr/bin/env python
+"""
+This script copies the relevant files from CPythonLib and applies the patches previously
+made with genpatches.py. You will probably need to tweak some patches by hand, or delete
+them entirely and do the migration for those modules manually.
+"""
+
+import os.path
+import sys
+import shutil
+
+
+if not os.path.exists('patches'):
+    print >>sys.stderr, 'Run genpatches.py first.'
+    sys.exit(1)
+
+succeeded = []
+failed = []
+for dirpath, dirnames, filenames in os.walk('patches'):
+    for filename in filenames:
+        realfilename = filename[:-6]
+        patchpath = os.path.join(dirpath, filename)
+        srcpath = os.path.join('CPythonLib', dirpath[8:], realfilename)
+        dstpath = srcpath.replace('CPythonLib', 'Lib')
+        print '\nCopying %s -> %s' % (srcpath, dstpath) 
+        shutil.copyfile(srcpath, dstpath)
+
+        retcode = os.system('patch -p1 -N <%s' % patchpath)
+        if retcode != 0:
+            failed.append(dstpath)
+        else:
+            succeeded.append(dstpath)
+
+if succeeded:
+    print '\nTh following files were successfully patched:'
+    for path in succeeded:
+        for path in succeeded:
+            print path
+
+if failed:
+    print '\nPatching failed for the following files:'
+    for path in failed:
+        print path
+    print '\nYou will need to migrate these modules manually.'
diff --git a/Misc/genpatches.py b/Misc/genpatches.py
new file mode 100755
--- /dev/null
+++ b/Misc/genpatches.py
@@ -0,0 +1,92 @@
+#!/usr/bin/env python
+"""
+This script generates patches containing the Jython-specific deviations from the stdlib
+modules. It looks for the string "svn.python.org" in the changeset summary and generates
+a patch for all the changes made after that in each module.
+
+The script expects to be run in the jython root directory and there should be a "cpython"
+directory in the parent directory. That directory should be a clone of the CPython release
+against which the modules in Lib/ have currently been patched.
+Only modules that are common to Lib/, CPythonLib/ and ../cpython/Lib will be included in
+the patches.
+"""
+from StringIO import StringIO
+import os.path
+import subprocess
+import sys
+import shutil
+
+
+def get_modules(path):
+    modules = set()
+    for dirpath, dirnames, filenames in os.walk(path):
+        for filename in filenames:
+            if filename.endswith('.py'):
+                cutoff = len(path) + 1
+                fullpath = os.path.join(dirpath[cutoff:], filename)
+                modules.add(fullpath)
+    return modules
+
+if not os.path.exists('CPythonLib'):
+    print >>sys.stderr, 'You need to run this script from the Jython root directory.'
+    sys.exit(1)
+
+if not os.path.exists('../cpython'):
+    print >>sys.stderr, 'You need to have the CPython clone in ../cpython.'
+    sys.exit(1)
+
+jymodules = get_modules(u'Lib')
+cpymodules = get_modules(u'CPythonLib')
+cpy25modules = get_modules(u'../cpython/Lib')
+common_modules = jymodules.intersection(cpy25modules).intersection(cpymodules)
+
+# Run mercurial to get the changesets where each file was last synced with CPython stdlib
+print 'Parsing mercurial logs for the last synchronized changesets'
+changesets = {}
+for mod in common_modules:
+    path = 'Lib/' + mod
+    pipe = subprocess.Popen(['hg', 'log', '-v', path], stdout=subprocess.PIPE)
+    stdoutdata, stderrdata = pipe.communicate()
+    if pipe.returncode != 0:
+        print >>sys.stderr, stderrdata
+        sys.exit(1)
+
+    buf = StringIO(stdoutdata)
+    changeset = None
+    found = False
+    iterator = iter(list(buf))
+    for line in iterator:
+        if line.startswith('changeset:'):
+            changeset = line.split(':')[1].strip()
+        if line.startswith('description:'):
+            for descline in iterator:
+                if descline == '\n':
+                    break
+                if 'svn.python.org' in descline:
+                    found = True
+                    break
+            if found:
+                break
+
+    if not found:
+        print >>sys.stderr,'No sync changeset found for %s' % path
+    else:
+        changesets[path] = changeset
+
+if os.path.exists('patches'):
+    shutil.rmtree('patches')
+os.mkdir('patches')
+
+print 'Generating patches'
+for path, changeset in changesets.iteritems():
+    patchname = 'patches/%s.patch' % path[4:]
+    patch_dir = os.path.dirname(patchname)
+    if not os.path.exists(patch_dir):
+        os.makedirs(patch_dir)
+
+    retcode = os.system('hg diff -r {} {} > {}'.format(changeset, path, patchname))
+    if retcode != 0:
+        print >>sys.stderr, "Error creating patch for %s" % path
+        sys.exit(3)
+
+print 'All done. You can now run applypatches.py to update and patch the modules.'

-- 
Repository URL: http://hg.python.org/jython


More information about the Jython-checkins mailing list