From ff7bbab22b7f74aedb6f79799c8cf5c45972c91b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Piotr=20O=C5=BCarowski?= <piotr@debian.org>
Date: Sun, 21 Nov 2010 23:54:19 +0100
Subject: [PATCH] dh_python2: install files listed in debian/package.pyinstall
 file as public modules for all requested Python versions (use dh_install's
 package.install files for private modules)

---
 debian/changelog   |  5 +++-
 debpython/tools.py | 66 ++++++++++++++++++++++++++++++++++++++++++++--
 dh_python2         | 10 ++++---
 3 files changed, 74 insertions(+), 7 deletions(-)

diff --git a/debian/changelog b/debian/changelog
index 64cda10..67a2a3b 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -2,8 +2,11 @@ python-defaults (2.6.6-6) UNRELEASED; urgency=low
 
   * Make the error message about missing extension more clear
     (and more verbose in --verbose mode)
+  * dh_python2: install files listed in debian/package.pyinstall file
+    as public modules for all requested Python versions (use dh_install's
+    package.install files for private modules)
 
- -- Piotr Ożarowski <piotr@debian.org>  Sat, 06 Nov 2010 00:19:39 +0100
+ -- Piotr Ożarowski <piotr@debian.org>  Sun, 21 Nov 2010 23:49:32 +0100
 
 python-defaults (2.6.6-5) experimental; urgency=low
 
diff --git a/debpython/tools.py b/debpython/tools.py
index f2e2310..fc62f88 100644
--- a/debpython/tools.py
+++ b/debpython/tools.py
@@ -20,15 +20,25 @@
 # THE SOFTWARE.
 
 from __future__ import with_statement
+import codecs
 import logging
 import re
 from cPickle import dumps
-from os import symlink
-from debpython.version import getver
+from glob import glob
+from os import link, makedirs, symlink
+from os.path import exists, join, split
+from debpython.version import RANGE_PATTERN, getver, get_requested_versions
 
 log = logging.getLogger(__name__)
 EGGnPTH_RE = re.compile(r'(.*?)(-py\d\.\d(?:-[^.]*)?)?(\.egg-info|\.pth)$')
 SHEBANG_RE = re.compile(r'^#!\s*/usr/bin/(?:env\s+)?(python(\d+\.\d+)?(?:-dbg)?).*')
+INSTALL_RE = re.compile(r"""
+    (?P<pattern>.+?)  # file pattern
+    \s*  # optional Python module name:
+    (?P<module>[A-Za-z][A-Za-z0-9_.]*)?
+    \s*  # optional version range:
+    (?P<vrange>%s)?$
+""" % RANGE_PATTERN, re.VERBOSE)
 
 
 def sitedir(version, package=None, gdb=False):
@@ -118,3 +128,55 @@ class memoize(object):
         if key not in self.cache:
             self.cache[key] = self.func(*args, **kwargs)
         return self.cache[key]
+
+
+def pyinstall(package, vrange):
+    """Install local files listed in .pyinstall files as public modules."""
+    status = True
+    srcfpath = "./debian/%s.pyinstall" % package
+    if not exists(srcfpath):
+        return status
+    versions = get_requested_versions(vrange)
+
+    for line in codecs.open(srcfpath, encoding='utf-8'):
+        if not line or line.startswith('#'):
+            continue
+        details = INSTALL_RE.match(line)
+        if not details:
+            status = False
+            log.warn('%s.pyinstall: unrecognized line: %s',
+                     package, line)
+            continue
+        details = details.groupdict()
+        if details['module']:
+            details['module'] = details['module'].replace('.', '/')
+        #line = line.strip()
+        myvers = versions & get_requested_versions(details['vrange'])
+        files = glob(details['pattern'])
+        if not files:
+            status = False
+            log.error('%s.pyinstall: file not found: %s',
+                      package, details['pattern'])
+            continue
+        for fpath in files:
+            fpath = fpath.lstrip('/.')
+            if details['module']:
+                dstname = join(details['module'], split(fpath)[1])
+            elif fpath.startswith('debian/'):
+                dstname = fpath[7:]
+            else:
+                dstname = fpath
+            for version in myvers:
+                dstfpath = join(sitedir(version, package), dstname)
+                dstdir = split(dstfpath)[0]
+                if not exists(dstdir):
+                    try:
+                        makedirs(dstdir)
+                    except:
+                        log.error('cannot create %s directory', dstdir)
+                        return False
+                try:
+                    link(fpath, dstfpath)
+                except:
+                    log.error('cannot copy %f file to %s', fpath, dstdir)
+    return status
diff --git a/dh_python2 b/dh_python2
index dda61aa..d838cb8 100755
--- a/dh_python2
+++ b/dh_python2
@@ -40,7 +40,8 @@ from debpython.version import SUPPORTED, DEFAULT, \
 from debpython.pydist import validate as validate_pydist, \
                              PUBLIC_DIR_RE
 from debpython.tools import sitedir, relative_symlink, \
-                            shebang2pyver, clean_egg_name
+                            shebang2pyver, clean_egg_name,\
+                            pyinstall
 from debpython.option import Option
 
 # initialize script
@@ -135,8 +136,7 @@ def share(package, stats, options):
         create_ext_links(sitedir(version, package))
 
     if options.guess_versions and pubvers:
-        versions = get_requested_versions(options.vrange)
-        for version in (i for i in versions if i[0] == 2):
+        for version in get_requested_versions(options.vrange):
             if version not in pubvers:
                 log.debug('guessing files for Python %s', vrepr(version))
                 versions_without_ext = debsorted(set(pubvers) -\
@@ -149,7 +149,7 @@ def share(package, stats, options):
                              '(`pyversions -vr`); '
                              'adjusting X-Python-Version field; '
                              'passing --no-guessing-versions to dh_python2')
-                    exit(12)
+                    exit(3)
                 srcver = versions_without_ext[0]
                 if srcver in stats['public_vers']:
                     stats['public_vers'].add(version)
@@ -484,6 +484,8 @@ def main():
            options.arch is True and pdetails['arch'] == 'all':
             continue
         log.debug('processing package %s...', package)
+        if not pyinstall(package, options.vrange):
+            exit(4)
         fix_locations(package)
         stats = scan(package, private_dir)
         share(package, stats, options)
-- 
GitLab