/pkg-python/python-defaults-debian

To get this branch, use:
bzr branch https://alioth.debian.org/scm/loggerhead/pkg-python/python-defaults-debian
41 by Matthias Klose
package version python-defaults-2.6.5-1
1
#! /usr/bin/python
2
# -*- coding: UTF-8 -*- vim: et ts=4 sw=4
3
330 by Piotr Ożarowski
update copyright years
4
# Copyright © 2010-2012 Piotr Ożarowski <piotr@debian.org>
41 by Matthias Klose
package version python-defaults-2.6.5-1
5
#
6
# Permission is hereby granted, free of charge, to any person obtaining a copy
7
# of this software and associated documentation files (the "Software"), to deal
8
# in the Software without restriction, including without limitation the rights
9
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
# copies of the Software, and to permit persons to whom the Software is
11
# furnished to do so, subject to the following conditions:
12
#
13
# The above copyright notice and this permission notice shall be included in
14
# all copies or substantial portions of the Software.
15
#
16
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
# THE SOFTWARE.
23
24
from __future__ import with_statement
25
import logging
26
import os
27
import re
28
import sys
182 by Piotr Ożarowski
dh_python2: replace a file with a symlink also if there's a matching one in pyshared directory already
29
from filecmp import dircmp, cmpfiles, cmp as fcmp
64 by Piotr Ożarowski
dh_python2:
30
from optparse import OptionParser, SUPPRESS_HELP
251 by Piotr Ożarowski
dh_python2:
31
from os.path import isabs, isdir, islink, exists, join, normpath, realpath,\
32
 split
41 by Matthias Klose
package version python-defaults-2.6.5-1
33
from shutil import rmtree, copy as fcopy
34
from stat import ST_MODE, S_IXUSR, S_IXGRP, S_IXOTH
35
from debpython.debhelper import DebHelper
99 by Piotr Ożarowski
block python package transitions via ${python:Breaks} or ${python:Depends}
36
from debpython.depends import Dependencies
41 by Matthias Klose
package version python-defaults-2.6.5-1
37
from debpython.version import SUPPORTED, DEFAULT, \
38
    debsorted, getver, vrepr, parse_pycentral_vrange, \
39
    get_requested_versions, parse_vrange, vrange_str
210 by Piotr Ożarowski
dh_python2, pycompile, pyclean: add "namespace" feature:
40
import debpython.namespace as ns
99 by Piotr Ożarowski
block python package transitions via ${python:Breaks} or ${python:Depends}
41
from debpython.pydist import validate as validate_pydist, \
42
                             PUBLIC_DIR_RE
46 by Piotr Ożarowski
add initial .pydist support
43
from debpython.tools import sitedir, relative_symlink, \
317 by Piotr Ożarowski
* dh_python2:
44
                            fix_shebang, shebang2pyver, \
45
                            so2pyver, clean_egg_name, \
165 by Piotr Ożarowski
remove public modules listed in debian/pkg.pyremove
46
                            pyinstall, pyremove
41 by Matthias Klose
package version python-defaults-2.6.5-1
47
from debpython.option import Option
48
49
# initialize script
42.1.2 by Piotr Ożarowski
generate rtscript only if there are .py files to bytecompile
50
logging.basicConfig(format='%(levelname).1s: %(module)s:%(lineno)d: '
41 by Matthias Klose
package version python-defaults-2.6.5-1
51
                           '%(message)s')
155 by Piotr Ożarowski
disable PyDist feature if dh_pydeb is in debian/rules
52
log = logging.getLogger(__name__)
41 by Matthias Klose
package version python-defaults-2.6.5-1
53
os.umask(022)
45 by Piotr Ożarowski
* dh_python2: Create extension symlinks in /usr/lib/pyshared/pythonX.Y
54
EGGnPTH_RE = re.compile(r'(.*?)(-py\d\.\d+)?(.*?)(\.egg-info|\.pth)$')
41 by Matthias Klose
package version python-defaults-2.6.5-1
55
56
# naming conventions used in the file:
57
# * version - tuple of integers
58
# * ver - string representation of version
59
# * vrange - version range, pair of max and min versions
60
# * fn - file name (without path)
61
# * fpath - file path
62
63
64
### FILES ######################################################
65
def fix_locations(package):
66
    """Move files to the right location."""
67
    found_versions = {}
68
    for version in SUPPORTED:
69
        ver = vrepr(version)
70
        to_check = [i % ver for i in (\
71
                    'usr/local/lib/python%s/site-packages',
52 by Piotr Ożarowski
* Python3 support removed (now available in python3-defaults)
72
                    'usr/local/lib/python%s/dist-packages',
41 by Matthias Klose
package version python-defaults-2.6.5-1
73
                    'var/lib/python-support/python%s',
74
                    'usr/lib/pymodules/python%s')]
75
        if version >= (2, 6):
76
            to_check.append("usr/lib/python%s/site-packages" % ver)
77
        dstdir = sitedir(version, package)
78
79
        for location in to_check:
80
            srcdir = "debian/%s/%s" % (package, location)
81
            if isdir(srcdir):
82
                if ver in found_versions:
83
                    log.error('files for version %s '
84
                              'found in two locations:\n %s\n %s',
85
                              ver, location, found_versions[ver])
64 by Piotr Ożarowski
dh_python2:
86
                    exit(2)
365 by Piotr Ożarowski
dh_python2: warnings about --install-layout=deb and translating
87
                log.info('Python %s should install files in %s. '
86 by Piotr Ożarowski
suggest --install-layout=deb
88
                         'Did you forget "--install-layout=deb"?',
89
                         ver, sitedir(version))
41 by Matthias Klose
package version python-defaults-2.6.5-1
90
                if not isdir(dstdir):
91
                    os.makedirs(dstdir)
92
                # TODO: what about relative symlinks?
93
                log.debug('moving files from %s to %s', srcdir, dstdir)
94
                os.renames(srcdir, dstdir)
95
                found_versions[ver] = location
96
97
        # do the same with debug locations
98
        dbg_to_check = ['usr/lib/debug/%s' % i for i in to_check]
99
        dbg_to_check.append("usr/lib/debug/usr/lib/pyshared/python%s" % ver)
100
        dstdir = sitedir(version, package, gdb=True)
101
178 by Piotr Ożarowski
dh_python2: fix moving files from old debug locations (due to typo)
102
        for location in dbg_to_check:
41 by Matthias Klose
package version python-defaults-2.6.5-1
103
            srcdir = "debian/%s/%s" % (package, location)
104
            if isdir(srcdir):
105
                if not isdir(dstdir):
106
                    os.makedirs(dstdir)
107
                log.debug('moving files from %s to %s', srcdir, dstdir)
108
                os.renames(srcdir, dstdir)
109
110
111
### SHARING FILES ##############################################
112
def share(package, stats, options):
113
    """Move files to /usr/share/pyshared/ if possible."""
114
    if package.endswith('-dbg'):
115
        # nothing to share in debug packages
116
        return
64 by Piotr Ożarowski
dh_python2:
117
    pubvers = debsorted(i for i in stats['public_vers'] if i[0] == 2)
118
    if len(pubvers) > 1:
119
        for pos, version1 in enumerate(pubvers):
41 by Matthias Klose
package version python-defaults-2.6.5-1
120
            dir1 = sitedir(version1, package)
64 by Piotr Ożarowski
dh_python2:
121
            for version2 in pubvers[pos + 1:]:
41 by Matthias Klose
package version python-defaults-2.6.5-1
122
                dir2 = sitedir(version2, package)
123
                dc = dircmp(dir1, dir2)
124
                share_2x(dir1, dir2, dc)
64 by Piotr Ożarowski
dh_python2:
125
    elif len(pubvers) == 1:
378 by Matthias Klose
* dh_python2: no longer move files to /usr/share/pyshared, don't create
126
        # don't install into pyshared anymore
127
        pass
45 by Piotr Ożarowski
* dh_python2: Create extension symlinks in /usr/lib/pyshared/pythonX.Y
128
64 by Piotr Ożarowski
dh_python2:
129
    if options.guess_versions and pubvers:
162 by Piotr Ożarowski
dh_python2: install files listed in debian/package.pyinstall file
130
        for version in get_requested_versions(options.vrange):
64 by Piotr Ożarowski
dh_python2:
131
            if version not in pubvers:
41 by Matthias Klose
package version python-defaults-2.6.5-1
132
                log.debug('guessing files for Python %s', vrepr(version))
64 by Piotr Ożarowski
dh_python2:
133
                versions_without_ext = debsorted(set(pubvers) -\
233 by Piotr Ożarowski
rename public_ext to ext (to avoid confusion in private dir stats)
134
                                                 stats['ext'])
41 by Matthias Klose
package version python-defaults-2.6.5-1
135
                if not versions_without_ext:
209 by Scott Kitterman
Remove stray comma in dh_python2 as requested by POX.
136
                    log.error('extension for python%s is missing. '
210 by Piotr Ożarowski
dh_python2, pycompile, pyclean: add "namespace" feature:
137
                              'Build extensions for all supported Python '
138
                              'versions (`pyversions -vr`) or adjust '
139
                              'X-Python-Version field or pass '
140
                              '--no-guessing-versions to dh_python2',
161 by Piotr Ożarowski
Make the error message about missing extension more clear
141
                              vrepr(version))
162 by Piotr Ożarowski
dh_python2: install files listed in debian/package.pyinstall file
142
                    exit(3)
41 by Matthias Klose
package version python-defaults-2.6.5-1
143
                srcver = versions_without_ext[0]
144
                if srcver in stats['public_vers']:
145
                    stats['public_vers'].add(version)
146
                share_2x(sitedir(srcver, package), sitedir(version, package))
170 by Piotr Ożarowski
adjust stats['public_vers'] after creating links from /usr/share/pyshared
147
    # remove duplicates
148
    stats['requires.txt'] = set(realpath(i) for i in stats['requires.txt'])
207 by Piotr Ożarowski
py_builddir: strip "python" form the argument (if set)
149
    stats['nsp.txt'] = set(realpath(i) for i in stats['nsp.txt'])
41 by Matthias Klose
package version python-defaults-2.6.5-1
150
151
152
def move_to_pyshared(dir1):
153
    # dir1 starts with debian/packagename/usr/lib/pythonX.Y/*-packages/
154
    debian, package, path = dir1.split('/', 2)
45 by Piotr Ożarowski
* dh_python2: Create extension symlinks in /usr/lib/pyshared/pythonX.Y
155
    dstdir = join(debian, package, 'usr/share/pyshared/', \
41 by Matthias Klose
package version python-defaults-2.6.5-1
156
                  '/'.join(dir1.split('/')[6:]))
157
158
    fext = lambda fname: fname.rsplit('.', 1)[-1]
159
160
    for i in os.listdir(dir1):
161
        fpath1 = join(dir1, i)
226 by Piotr Ożarowski
deal with original symlinks more carefully
162
        if isdir(fpath1) and not islink(fpath1):
41 by Matthias Klose
package version python-defaults-2.6.5-1
163
            if any(fn for fn in os.listdir(fpath1) if fext(fn) != 'so'):
164
                # at least one file that is not an extension
165
                move_to_pyshared(join(dir1, i))
166
        else:
167
            if fext(i) == 'so':
168
                continue
169
            fpath2 = join(dstdir, i)
170
            if not exists(fpath2):
45 by Piotr Ożarowski
* dh_python2: Create extension symlinks in /usr/lib/pyshared/pythonX.Y
171
                if not exists(dstdir):
172
                    os.makedirs(dstdir)
226 by Piotr Ożarowski
deal with original symlinks more carefully
173
                if islink(fpath1):
174
                    fpath1_target = os.readlink(fpath1)
175
                    if isabs(fpath1_target):
176
                        os.symlink(fpath1_target, fpath2)
177
                    else:
178
                        fpath1_target = normpath(join(dir1, fpath1_target))
179
                        relative_symlink(fpath1_target, fpath2)
180
                    os.remove(fpath1)
181
                else:
182
                    os.rename(fpath1, fpath2)
41 by Matthias Klose
package version python-defaults-2.6.5-1
183
                relative_symlink(fpath2, fpath1)
184
185
45 by Piotr Ożarowski
* dh_python2: Create extension symlinks in /usr/lib/pyshared/pythonX.Y
186
def create_ext_links(dir1):
187
    """Create extension symlinks in /usr/lib/pyshared/pythonX.Y.
188
189
    These symlinks are used to let dpkg detect file conflicts with
190
    python-support and python-central packages.
191
    """
192
193
    debian, package, path = dir1.split('/', 2)
194
    python, _, module_subpath = path[8:].split('/', 2)
195
    dstdir = join(debian, package, 'usr/lib/pyshared/', python, module_subpath)
196
197
    for i in os.listdir(dir1):
198
        fpath1 = join(dir1, i)
199
        if isdir(fpath1):
200
            create_ext_links(fpath1)
201
        elif i.rsplit('.', 1)[-1] == 'so':
202
            fpath2 = join(dstdir, i)
203
            if exists(fpath2):
204
                continue
205
            if not exists(dstdir):
206
                os.makedirs(dstdir)
207
            relative_symlink(fpath1, join(dstdir, i))
208
209
169 by Piotr Ożarowski
dh_python2: create symlinks for files installed into /usr/share/pyshared/
210
def create_public_links(dir1, vrange, root=''):
211
    """Create public module symlinks for given directory."""
212
213
    debian, package, path = dir1.split('/', 2)
214
    versions = get_requested_versions(vrange)
215
216
    for fn in os.listdir(dir1):
217
        fpath1 = join(dir1, fn)
218
        if isdir(fpath1):
219
            create_public_links(fpath1, vrange, join(root, fn))
220
        else:
221
            for version in versions:
222
                dstdir = join(sitedir(version, package), root)
223
                if not exists(dstdir):
224
                    os.makedirs(dstdir)
225
                relative_symlink(fpath1, join(dstdir, fn))
226
227
41 by Matthias Klose
package version python-defaults-2.6.5-1
228
def share_2x(dir1, dir2, dc=None):
229
    """Move common files to pyshared and create symlinks in original
230
    locations."""
68 by Piotr Ożarowski
typo
231
    debian, package, path = dir2.split('/', 2)
41 by Matthias Klose
package version python-defaults-2.6.5-1
232
    # dir1 starts with debian/packagename/usr/lib/pythonX.Y/*-packages/
64 by Piotr Ożarowski
dh_python2:
233
    dstdir = join(debian, package, 'usr/share/pyshared/', \
41 by Matthias Klose
package version python-defaults-2.6.5-1
234
                  '/'.join(dir1.split('/')[6:]))
226 by Piotr Ożarowski
deal with original symlinks more carefully
235
    if not exists(dstdir) and not islink(dir1):
41 by Matthias Klose
package version python-defaults-2.6.5-1
236
        os.makedirs(dstdir)
237
    if dc is None:  # guess/copy mode
238
        if not exists(dir2):
239
            os.makedirs(dir2)
240
        common_dirs = []
241
        common_files = []
242
        for i in os.listdir(dir1):
226 by Piotr Ożarowski
deal with original symlinks more carefully
243
            subdir1 = join(dir1, i)
244
            if isdir(subdir1) and not islink(subdir1):
41 by Matthias Klose
package version python-defaults-2.6.5-1
245
                common_dirs.append([i, None])
246
            else:
247
                # directories with .so files will be blocked earlier
248
                common_files.append(i)
226 by Piotr Ożarowski
deal with original symlinks more carefully
249
    elif islink(dir1):
231 by Piotr Ożarowski
add --ignore-namespace option that will disable handling
250
        # skip this symlink in pyshared
251
        # (dpkg has problems with symlinks anyway)
226 by Piotr Ożarowski
deal with original symlinks more carefully
252
        common_dirs = []
253
        common_files = []
41 by Matthias Klose
package version python-defaults-2.6.5-1
254
    else:
255
        common_dirs = dc.subdirs.iteritems()
256
        common_files = dc.common_files
257
        # dircmp returns common names only, lets check files more carefully...
139 by Piotr Ożarowski
dh_python2: pass shallow=False to cmpfiles to make sure only exactly the same files are moved to pyshared
258
        common_files = cmpfiles(dir1, dir2, common_files, shallow=False)[0]
41 by Matthias Klose
package version python-defaults-2.6.5-1
259
260
    for fn in common_files:
251 by Piotr Ożarowski
dh_python2:
261
        if 'so' in fn.split('.'):  # foo.so, bar.so.0.1.2, etc.
177 by Piotr Ożarowski
* dh_python2: fix a crash in packages with private extension (closes: 607555)
262
            # in unlikely case where extensions are exactly the same
263
            continue
41 by Matthias Klose
package version python-defaults-2.6.5-1
264
        fpath1 = join(dir1, fn)
265
        fpath2 = join(dir2, fn)
266
        fpath3 = join(dstdir, fn)
267
        # do not touch symlinks created by previous loop or other tools
268
        if dc and not islink(fpath1):
269
            # replace with a link to pyshared
182 by Piotr Ożarowski
dh_python2: replace a file with a symlink also if there's a matching one in pyshared directory already
270
            if not exists(fpath3):
271
                os.rename(fpath1, fpath3)
272
                relative_symlink(fpath3, fpath1)
273
            elif fcmp(fpath3, fpath1, shallow=False):
274
                os.remove(fpath1)
275
                relative_symlink(fpath3, fpath1)
41 by Matthias Klose
package version python-defaults-2.6.5-1
276
        if dc is None:  # guess/copy mode
277
            if islink(fpath1):
278
                # ralative links will work as well, it's always the same level
279
                os.symlink(os.readlink(fpath1), fpath2)
280
            else:
281
                if exists(fpath3):
282
                    # cannot share it, pyshared contains another copy
283
                    fcopy(fpath1, fpath2)
284
                else:
285
                    # replace with a link to pyshared
286
                    os.rename(fpath1, fpath3)
287
                    relative_symlink(fpath3, fpath1)
288
                    relative_symlink(fpath3, fpath2)
186 by Piotr Ożarowski
make sure fpath2 and fpath3 exists before comparing
289
        elif exists(fpath2) and exists(fpath3) and \
290
             fcmp(fpath2, fpath3, shallow=False):
41 by Matthias Klose
package version python-defaults-2.6.5-1
291
            os.remove(fpath2)
292
            relative_symlink(fpath3, fpath2)
293
    for dn, dc in common_dirs:
294
        share_2x(join(dir1, dn), join(dir2, dn), dc)
295
296
297
### PACKAGE DETAILS ############################################
317 by Piotr Ożarowski
* dh_python2:
298
def scan(package, dname=None, options=None):
41 by Matthias Klose
package version python-defaults-2.6.5-1
299
    """Gather statistics about Python files in given package."""
300
    r = {'requires.txt': set(),
207 by Piotr Ożarowski
py_builddir: strip "python" form the argument (if set)
301
         'nsp.txt': set(),
41 by Matthias Klose
package version python-defaults-2.6.5-1
302
         'shebangs': set(),
303
         'public_vers': set(),
304
         'private_dirs': {},
305
         'compile': False,
233 by Piotr Ożarowski
rename public_ext to ext (to avoid confusion in private dir stats)
306
         'ext': set()}
41 by Matthias Klose
package version python-defaults-2.6.5-1
307
308
    dbg_package = package.endswith('-dbg')
309
310
    if not dname:
311
        proot = "debian/%s" % package
312
        if dname is False:
313
            private_to_check = []
314
        else:
315
            private_to_check = [i % package for i in
52 by Piotr Ożarowski
* Python3 support removed (now available in python3-defaults)
316
                                ('usr/lib/%s', 'usr/lib/games/%s',
317
                                'usr/share/%s', 'usr/share/games/%s')]
41 by Matthias Klose
package version python-defaults-2.6.5-1
318
    else:
169 by Piotr Ożarowski
dh_python2: create symlinks for files installed into /usr/share/pyshared/
319
        # scan private directory *only*
337 by Piotr Ożarowski
dh_python2: no longer sensitive to trailing slash in private dir names
320
        dname = dname.strip('/')
321
        proot = join('debian', package, dname)
322
        private_to_check = [dname]
41 by Matthias Klose
package version python-defaults-2.6.5-1
323
324
    for root, dirs, file_names in os.walk(proot):
52 by Piotr Ożarowski
* Python3 support removed (now available in python3-defaults)
325
        # ignore Python 3.X locations
326
        if '/usr/lib/python3' in root or\
327
           '/usr/local/lib/python3' in root:
328
            # warn only once
272 by Piotr Ożarowski
update TransitionToDHPython2 wiki URL
329
            if root[root.find('/lib/python'):].count('/') == 2:
52 by Piotr Ożarowski
* Python3 support removed (now available in python3-defaults)
330
                log.warning('Python 3.x location detected, '
331
                            'please use dh_python3: %s', root)
332
            continue
333
41 by Matthias Klose
package version python-defaults-2.6.5-1
334
        bin_dir = private_dir = None
335
        public_dir = PUBLIC_DIR_RE.match(root)
336
        if public_dir:
337
            version = getver(public_dir.group(1))
338
            if root.endswith('-packages'):
339
                r['public_vers'].add(version)
340
        else:
177 by Piotr Ożarowski
* dh_python2: fix a crash in packages with private extension (closes: 607555)
341
            # TODO: find a way to specify Python version private
342
            # extension was build for
41 by Matthias Klose
package version python-defaults-2.6.5-1
343
            version = False
344
            for i in private_to_check:
345
                if root.startswith(join('debian', package, i)):
346
                    private_dir = '/' + i
347
                    break
348
            else:  # i.e. not public_dir and not private_dir
349
                if len(root.split('/', 6)) < 6 and (\
119 by Piotr Ożarowski
dh_python2: add {/usr,}/sbin to the list of directories with checked shebangs
350
                   root.endswith('/sbin') or root.endswith('/bin') or\
351
                   root.endswith('/usr/games')):
157 by Piotr Ożarowski
dh_python2: egg renaming fixed
352
                   # /(s)bin or /usr/(s)bin or /usr/games
41 by Matthias Klose
package version python-defaults-2.6.5-1
353
                    bin_dir = root
354
355
        # handle some EGG related data (.egg-info dirs)
356
        for name in dirs:
157 by Piotr Ożarowski
dh_python2: egg renaming fixed
357
            if name.endswith('.egg-info'):
317 by Piotr Ożarowski
* dh_python2:
358
                if dbg_package and options.clean_dbg_pkg:
41 by Matthias Klose
package version python-defaults-2.6.5-1
359
                    rmtree(join(root, name))
251 by Piotr Ożarowski
dh_python2:
360
                    dirs.remove(name)
41 by Matthias Klose
package version python-defaults-2.6.5-1
361
                    continue
157 by Piotr Ożarowski
dh_python2: egg renaming fixed
362
                clean_name = clean_egg_name(name)
363
                if clean_name != name:
364
                    log.info('renaming %s to %s', name, clean_name)
365
                    os.rename(join(root, name), join(root, clean_name))
224 by Piotr Ożarowski
update dirs item anme after fixing .egg-info directory name (thanks to Arnaud Fontaine for the patch)
366
                    dirs[dirs.index(name)] = clean_name
207 by Piotr Ożarowski
py_builddir: strip "python" form the argument (if set)
367
        if root.endswith('.egg-info'):
368
            if 'requires.txt' in file_names:
369
                r['requires.txt'].add(join(root, 'requires.txt'))
370
            if 'namespace_packages.txt' in file_names:
371
                r['nsp.txt'].add(join(root, 'namespace_packages.txt'))
41 by Matthias Klose
package version python-defaults-2.6.5-1
372
            continue
373
374
        # check files
279 by Piotr Ożarowski
really fix removing .so.foo symlinks twice issue
375
        for fn in sorted(file_names):
376
            # sorted() to make sure .so files are handled before .so.foo
377
            fpath = join(root, fn)
378
            if not exists(fpath):
379
                # could be removed while handling .so symlinks
316 by Piotr Ożarowski
dh_python2: remove even more \.so.* dangling symlinks, thanks to Stefano Rivera for providing a test case
380
                if islink(fpath) and '.so.' in split(fpath)[-1]:
381
                    # dangling symlink to (now removed/renamed) .so file
382
                    # which wasn't removed yet (see test3's quux.so.0)
383
                    log.info('removing symlink: %s', fpath)
384
                    os.remove(fpath)
279 by Piotr Ożarowski
really fix removing .so.foo symlinks twice issue
385
                continue
41 by Matthias Klose
package version python-defaults-2.6.5-1
386
            fext = fn.rsplit('.', 1)[-1]
387
            if fext in ('pyc', 'pyo'):
279 by Piotr Ożarowski
really fix removing .so.foo symlinks twice issue
388
                os.remove(fpath)
41 by Matthias Klose
package version python-defaults-2.6.5-1
389
                continue
390
            if public_dir:
251 by Piotr Ożarowski
dh_python2:
391
                if fext == 'so' and islink(fpath):
392
                    dstfpath = fpath
393
                    links = set()
394
                    while islink(dstfpath):
395
                        links.add(dstfpath)
396
                        dstfpath = join(root, os.readlink(dstfpath))
397
                    if exists(dstfpath) and '.so.' in split(dstfpath)[-1]:
398
                        # rename .so.$FOO symlinks, remove other ones
399
                        for lpath in links:
400
                            log.info('removing symlink: %s', lpath)
401
                            os.remove(lpath)
402
                        log.info('renaming %s to %s', dstfpath, fn)
403
                        os.rename(dstfpath, fpath)
317 by Piotr Ożarowski
* dh_python2:
404
                if dbg_package and options.clean_dbg_pkg and \
405
                   fext not in ('so', 'h'):
41 by Matthias Klose
package version python-defaults-2.6.5-1
406
                    os.remove(join(root, fn))
407
                    continue
408
409
            elif private_dir:
317 by Piotr Ożarowski
* dh_python2:
410
                if exists(fpath):
411
                    mode = os.stat(fpath)[ST_MODE]
201 by Piotr Ożarowski
do not try to check dangling symlinks's shebang (closes: 619005)
412
                    if mode & S_IXUSR or mode & S_IXGRP or mode & S_IXOTH:
317 by Piotr Ożarowski
* dh_python2:
413
                        if (options.no_shebang_rewrite or \
414
                            fix_shebang(fpath, options.shebang)) and \
415
                           not options.ignore_shebangs:
416
                            res = shebang2pyver(fpath)
417
                            if res:
418
                                r['private_dirs'].setdefault(private_dir, {})\
419
                                    .setdefault('shebangs', set()).add(res)
41 by Matthias Klose
package version python-defaults-2.6.5-1
420
421
            if public_dir or private_dir:
422
                if fext == 'so':
238 by Piotr Ożarowski
warn if public Python extension is linked to libpython2.X, fail if it's linked to a wrong version
423
                    so_version = so2pyver(join(root, fn))
424
                    if so_version:
425
                        if public_dir:
426
                            if version != so_version:
427
                                log.error('extension linked to libpython%s '
428
                                          'and shipped in python%s\'s dist-'
429
                                          'packages: %s', vrepr(so_version),
430
                                          vrepr(version), fn)
431
                                exit(7)
432
                            log.warn('public extension linked with '
433
                                     'libpython%s: %s', vrepr(so_version), fn)
434
                        elif not version:
435
                            version = so_version
436
41 by Matthias Klose
package version python-defaults-2.6.5-1
437
                    (r if public_dir else
438
                     r['private_dirs'].setdefault(private_dir, {}))\
233 by Piotr Ożarowski
rename public_ext to ext (to avoid confusion in private dir stats)
439
                    .setdefault('ext', set()).add(version)
41 by Matthias Klose
package version python-defaults-2.6.5-1
440
                    continue
441
                elif fext == 'py':
442
                    (r if public_dir else
443
                     r['private_dirs'].setdefault(private_dir, {}))\
444
                    ['compile'] = True
445
                    continue
446
447
            # .egg-info files
157 by Piotr Ożarowski
dh_python2: egg renaming fixed
448
            if fn.endswith('.egg-info'):
449
                clean_name = clean_egg_name(fn)
450
                if clean_name != fn:
451
                    log.info('renaming %s to %s', fn, clean_name)
452
                    os.rename(join(root, fn), join(root, clean_name))
41 by Matthias Klose
package version python-defaults-2.6.5-1
453
                continue
454
            # search for scripts in bin dirs
455
            if bin_dir:
317 by Piotr Ożarowski
* dh_python2:
456
                if (options.no_shebang_rewrite or \
457
                    fix_shebang(fpath, options.shebang)) and \
458
                   not options.ignore_shebangs:
459
                     res = shebang2pyver(fpath)
460
                     if res:
461
                         r['shebangs'].add(res)
41 by Matthias Klose
package version python-defaults-2.6.5-1
462
317 by Piotr Ożarowski
* dh_python2:
463
    if dbg_package and options.clean_dbg_pkg:
41 by Matthias Klose
package version python-defaults-2.6.5-1
464
        # remove empty directories in -dbg packages
45 by Piotr Ożarowski
* dh_python2: Create extension symlinks in /usr/lib/pyshared/pythonX.Y
465
        proot = proot + '/usr/lib'
41 by Matthias Klose
package version python-defaults-2.6.5-1
466
        for root, dirs, file_names in os.walk(proot, topdown=False):
45 by Piotr Ożarowski
* dh_python2: Create extension symlinks in /usr/lib/pyshared/pythonX.Y
467
            if '-packages/' in root and not file_names:
41 by Matthias Klose
package version python-defaults-2.6.5-1
468
                try:
469
                    os.rmdir(root)
280 by Piotr Ożarowski
avoid catching KeyboardInterrupt
470
                except Exception:
41 by Matthias Klose
package version python-defaults-2.6.5-1
471
                    pass
472
473
    log.debug("package %s details = %s", package, r)
474
    return r
475
476
477
################################################################
478
def main():
401 by Piotr Ożarowski
dh_python2: add a warning abount missing dh-python in Build-Depends
479
    log.warn('Please add dh-python package to Build-Depends')
193 by Piotr Ożarowski
add test4 to test handling private directories
480
    usage = '%prog -p PACKAGE [-V [X.Y][-][A.B]] DIR [-X REGEXPR]\n'
331 by Piotr Ożarowski
bump dh_python2 version to 2.1
481
    parser = OptionParser(usage, version='%prog 2.1',
41 by Matthias Klose
package version python-defaults-2.6.5-1
482
                                   option_class=Option)
483
    parser.add_option('--no-guessing-versions', action='store_false',
484
        dest='guess_versions', default=True,
129 by Piotr Ożarowski
* Add manpage for dh_python2, pycompile and pyclean
485
        help='disable guessing other supported Python versions')
41 by Matthias Klose
package version python-defaults-2.6.5-1
486
    parser.add_option('--no-guessing-deps', action='store_false',
129 by Piotr Ożarowski
* Add manpage for dh_python2, pycompile and pyclean
487
        dest='guess_deps', default=True, help='disable guessing dependencies')
223 by Piotr Ożarowski
dh_python2: no longer generates maintainer scripts that invoke pycentral's
488
    parser.add_option('--skip-private', action='store_true', default=False,
41 by Matthias Klose
package version python-defaults-2.6.5-1
489
        help='don\'t check private directories')
223 by Piotr Ożarowski
dh_python2: no longer generates maintainer scripts that invoke pycentral's
490
    parser.add_option('-v', '--verbose', action='store_true', default=False,
491
        help='turn verbose mode on')
41 by Matthias Klose
package version python-defaults-2.6.5-1
492
    # arch=False->arch:all only, arch=True->arch:any only, None->all of them
493
    parser.add_option('-i', '--indep', action='store_false',
64 by Piotr Ożarowski
dh_python2:
494
        dest='arch', default=None,
129 by Piotr Ożarowski
* Add manpage for dh_python2, pycompile and pyclean
495
        help='act on architecture independent packages')
191 by Piotr Ożarowski
add -s option as an synonym to -a
496
    parser.add_option('-a', '-s', '--arch', action='store_true',
129 by Piotr Ożarowski
* Add manpage for dh_python2, pycompile and pyclean
497
        dest='arch', help='act on architecture dependent packages')
41 by Matthias Klose
package version python-defaults-2.6.5-1
498
    parser.add_option('-q', '--quiet', action='store_false', dest='verbose',
138 by Piotr Ożarowski
verbose mode should be off by default
499
        help='be quiet')
223 by Piotr Ożarowski
dh_python2: no longer generates maintainer scripts that invoke pycentral's
500
    parser.add_option('-p', '--package', action='append',
129 by Piotr Ożarowski
* Add manpage for dh_python2, pycompile and pyclean
501
        help='act on the package named PACKAGE')
223 by Piotr Ożarowski
dh_python2: no longer generates maintainer scripts that invoke pycentral's
502
    parser.add_option('-N', '--no-package', action='append',
129 by Piotr Ożarowski
* Add manpage for dh_python2, pycompile and pyclean
503
        help='do not act on the specified package')
258 by Piotr Ożarowski
* dh_python2:
504
    parser.add_option('--compile-all', action='store_true', default=False,
505
        help='compile all files from given private directory in postinst, '
506
             'not just the ones provided by the package')
41 by Matthias Klose
package version python-defaults-2.6.5-1
507
    parser.add_option('-V', type='version_range', dest='vrange',
508
        help='specify list of supported Python versions. ' +\
509
             'See pycompile(1) for examples')
64 by Piotr Ożarowski
dh_python2:
510
    parser.add_option('-X', '--exclude', action='append', dest='regexpr',
140 by Piotr Ożarowski
dh_python2: typo in --help output fixed (thanks to Adam D. Barratt)
511
        help='exclude items that match given REGEXPR. You may use this option '
41 by Matthias Klose
package version python-defaults-2.6.5-1
512
             'multiple times to build up a list of things to exclude.')
223 by Piotr Ożarowski
dh_python2: no longer generates maintainer scripts that invoke pycentral's
513
    parser.add_option('--depends', action='append',
121 by Piotr Ożarowski
add --recommend and --suggest command line options
514
        help='translate given requirements into Debian dependencies '
515
             'and add them to ${python:Depends}. '
516
             'Use it for missing items in requires.txt.')
223 by Piotr Ożarowski
dh_python2: no longer generates maintainer scripts that invoke pycentral's
517
    parser.add_option('--recommends', action='append',
121 by Piotr Ożarowski
add --recommend and --suggest command line options
518
        help='translate given requirements into Debian '
519
             'dependencies and add them to ${python:Recommends}')
223 by Piotr Ożarowski
dh_python2: no longer generates maintainer scripts that invoke pycentral's
520
    parser.add_option('--suggests', action='append',
121 by Piotr Ożarowski
add --recommend and --suggest command line options
521
        help='translate given requirements into Debian '
522
             'dependencies and add them to ${python:Suggests}')
207 by Piotr Ożarowski
py_builddir: strip "python" form the argument (if set)
523
    parser.add_option('--namespace', action='append', dest='namespaces',
524
        help='recreate __init__.py files for given namespaces at install time')
223 by Piotr Ożarowski
dh_python2: no longer generates maintainer scripts that invoke pycentral's
525
    parser.add_option('--clean-pycentral', action='store_true', default=False,
526
        help='generate maintainer script that will remove pycentral files')
317 by Piotr Ożarowski
* dh_python2:
527
    parser.add_option('--shebang',
528
        help='use given command as shebang in scripts')
230 by Piotr Ożarowski
add --ignore-shebangs option that will disable translating shebangs into
529
    parser.add_option('--ignore-shebangs', action='store_true', default=False,
530
        help='do not translate shebangs into Debian dependencies')
231 by Piotr Ożarowski
add --ignore-namespace option that will disable handling
531
    parser.add_option('--ignore-namespace', action='store_true', default=False,
532
        help="ignore Egg's namespace_packages.txt file and --namespace option")
259 by Piotr Ożarowski
add --no-dbg-cleaning option (to disable removing files from debug
533
    parser.add_option('--no-dbg-cleaning', action='store_false',
534
            dest='clean_dbg_pkg', default=True,
535
        help='do not remove files from debug packages')
317 by Piotr Ożarowski
* dh_python2:
536
    parser.add_option('--no-shebang-rewrite', action='store_true',
537
            default=False, help='do not rewrite shebangs')
64 by Piotr Ożarowski
dh_python2:
538
    # ignore some debhelper options:
539
    parser.add_option('-O', help=SUPPRESS_HELP)
41 by Matthias Klose
package version python-defaults-2.6.5-1
540
223 by Piotr Ożarowski
dh_python2: no longer generates maintainer scripts that invoke pycentral's
541
    options, args = parser.parse_args(sys.argv[1:] + \
542
                    os.environ.get('DH_OPTIONS', '').split())
41 by Matthias Klose
package version python-defaults-2.6.5-1
543
    # regexpr option type is not used so lets check patterns here
544
    for pattern in options.regexpr or []:
545
        # fail now rather than at runtime
546
        try:
547
            pattern = re.compile(pattern)
280 by Piotr Ożarowski
avoid catching KeyboardInterrupt
548
        except Exception:
41 by Matthias Klose
package version python-defaults-2.6.5-1
549
            log.error('regular expression is not valid: %s', pattern)
64 by Piotr Ożarowski
dh_python2:
550
            exit(1)
41 by Matthias Klose
package version python-defaults-2.6.5-1
551
552
    if not options.vrange and exists('debian/pyversions'):
553
        log.debug('parsing version range from debian/pyversions')
554
        with open('debian/pyversions') as fp:
555
            for line in fp:
556
                line = line.strip()
135.1.1 by Piotr Ożarowski
dh_python2: Add support for X-Python-Version
557
                if line and not line.startswith('#'):
41 by Matthias Klose
package version python-defaults-2.6.5-1
558
                    options.vrange = parse_vrange(line)
559
                    break
560
155 by Piotr Ożarowski
disable PyDist feature if dh_pydeb is in debian/rules
561
    # disable PyDist if dh_pydeb is used
562
    if options.guess_deps:
563
        try:
235 by Piotr Ożarowski
check if pyshared dir exists, fix indentation
564
            rules = open('debian/rules', 'r').read()
155 by Piotr Ożarowski
disable PyDist feature if dh_pydeb is in debian/rules
565
        except IOError:
566
            log.warning('cannot open debian/rules file')
567
        else:
234 by Piotr Ożarowski
disable PyDist feature if dh sequencer is invoked --with pydeb
568
            if re.search('\n\s*dh_pydeb', rules) or \
235 by Piotr Ożarowski
check if pyshared dir exists, fix indentation
569
               re.search('\n\s*dh\s+[^#]*--with[^#]+pydeb', rules):
155 by Piotr Ożarowski
disable PyDist feature if dh_pydeb is in debian/rules
570
                log.warning('dh_pydeb detected, PyDist feature disabled')
571
                options.guess_deps = False
572
270 by Piotr Ożarowski
handle private dir paths without leading slash
573
    if not args:
574
        private_dir = None
575
    else:
576
        private_dir = args[0]
577
        if not private_dir.startswith('/'):
578
            # handle usr/share/foo dirs (without leading slash)
579
            private_dir = '/' + private_dir
41 by Matthias Klose
package version python-defaults-2.6.5-1
580
    # TODO: support more than one private dir at the same time (see :meth:scan)
581
    if options.skip_private:
582
        private_dir = False
583
115 by Piotr Ożarowski
few minor fixes
584
    if options.verbose or os.environ.get('DH_VERBOSE') == '1':
41 by Matthias Klose
package version python-defaults-2.6.5-1
585
        log.setLevel(logging.DEBUG)
586
        log.debug('argv: %s', sys.argv)
587
        log.debug('options: %s', options)
588
        log.debug('args: %s', args)
589
258 by Piotr Ożarowski
* dh_python2:
590
    dh = DebHelper(options)
41 by Matthias Klose
package version python-defaults-2.6.5-1
591
    if not options.vrange and dh.python_version:
592
        options.vrange = parse_pycentral_vrange(dh.python_version)
593
594
    for package, pdetails in dh.packages.iteritems():
595
        if options.arch is False and pdetails['arch'] != 'all' or \
596
           options.arch is True and pdetails['arch'] == 'all':
597
            continue
598
        log.debug('processing package %s...', package)
169 by Piotr Ożarowski
dh_python2: create symlinks for files installed into /usr/share/pyshared/
599
        if not private_dir:
600
            if not pyinstall(package, options.vrange):
601
                exit(4)
602
            if not pyremove(package, options.vrange):
603
                exit(5)
604
            fix_locations(package)
317 by Piotr Ożarowski
* dh_python2:
605
        stats = scan(package, private_dir, options)
169 by Piotr Ożarowski
dh_python2: create symlinks for files installed into /usr/share/pyshared/
606
        if not private_dir:
607
            share(package, stats, options)
608
            pyshared_dir = "debian/%s/usr/share/pyshared/" % package
609
            if not stats['public_vers'] and exists(pyshared_dir):
610
                create_public_links(pyshared_dir, options.vrange)
170 by Piotr Ożarowski
adjust stats['public_vers'] after creating links from /usr/share/pyshared
611
                stats['public_vers'] = get_requested_versions(options.vrange)
198 by Piotr Ożarowski
dh_python2: print help message for missing extensions even without --verbose message,
612
                stats['compile'] = True
41 by Matthias Klose
package version python-defaults-2.6.5-1
613
197 by Piotr Ożarowski
* dh_python2:
614
        dependencies = Dependencies(package)
99 by Piotr Ożarowski
block python package transitions via ${python:Breaks} or ${python:Depends}
615
        dependencies.parse(stats, options)
41 by Matthias Klose
package version python-defaults-2.6.5-1
616
617
        if stats['public_vers']:
64 by Piotr Ożarowski
dh_python2:
618
            dh.addsubstvar(package, 'python:Versions', \
41 by Matthias Klose
package version python-defaults-2.6.5-1
619
                           ', '.join(sorted(vrepr(stats['public_vers']))))
620
            ps = package.split('-', 1)
52 by Piotr Ożarowski
* Python3 support removed (now available in python3-defaults)
621
            if len(ps) > 1 and ps[0] == 'python':
64 by Piotr Ożarowski
dh_python2:
622
                dh.addsubstvar(package, 'python:Provides', \
52 by Piotr Ożarowski
* Python3 support removed (now available in python3-defaults)
623
                           ', '.join("python%s-%s" % (i, ps[1])\
41 by Matthias Klose
package version python-defaults-2.6.5-1
624
                           for i in sorted(vrepr(stats['public_vers']))))
625
52 by Piotr Ożarowski
* Python3 support removed (now available in python3-defaults)
626
        pyclean_added = False  # invoke pyclean only once in maintainer script
41 by Matthias Klose
package version python-defaults-2.6.5-1
627
        if stats['compile']:
223 by Piotr Ożarowski
dh_python2: no longer generates maintainer scripts that invoke pycentral's
628
            if options.clean_pycentral:
231 by Piotr Ożarowski
add --ignore-namespace option that will disable handling
629
                dh.autoscript(package, 'preinst',
630
                              'preinst-pycentral-clean', '')
59 by Piotr Ożarowski
* add dh sequence file
631
            dh.autoscript(package, 'postinst', 'postinst-pycompile', '')
52 by Piotr Ożarowski
* Python3 support removed (now available in python3-defaults)
632
            dh.autoscript(package, 'prerm', 'prerm-pyclean', '')
633
            pyclean_added = True
634
59 by Piotr Ożarowski
* add dh sequence file
635
        for pdir, details in stats['private_dirs'].iteritems():
41 by Matthias Klose
package version python-defaults-2.6.5-1
636
            if not details.get('compile'):
637
                continue
52 by Piotr Ożarowski
* Python3 support removed (now available in python3-defaults)
638
            if not pyclean_added:
639
                dh.autoscript(package, 'prerm', 'prerm-pyclean', '')
640
                pyclean_added = True
641
59 by Piotr Ożarowski
* add dh sequence file
642
            args = pdir
41 by Matthias Klose
package version python-defaults-2.6.5-1
643
233 by Piotr Ożarowski
rename public_ext to ext (to avoid confusion in private dir stats)
644
            ext_for = details.get('ext')
41 by Matthias Klose
package version python-defaults-2.6.5-1
645
            if ext_for is None:  # no extension
288 by Piotr Ożarowski
if there's only one shebang in private dir, generate the same -V option for postinst as in rtupdate
646
                shebangs = list(v for i, v in details.get('shebangs', []) if v)
647
                if not options.ignore_shebangs and len(shebangs) == 1:
648
                    # only one version from shebang
289 by Piotr Ożarowski
typo fixed
649
                    args += " -V %s" % vrepr(shebangs[0])
288 by Piotr Ożarowski
if there's only one shebang in private dir, generate the same -V option for postinst as in rtupdate
650
                elif options.vrange and options.vrange != (None, None):
52 by Piotr Ożarowski
* Python3 support removed (now available in python3-defaults)
651
                    args += " -V %s" % vrange_str(options.vrange)
177 by Piotr Ożarowski
* dh_python2: fix a crash in packages with private extension (closes: 607555)
652
            elif False in ext_for:
653
                # at least one extension's version not detected
41 by Matthias Klose
package version python-defaults-2.6.5-1
654
                if options.vrange and '-' not in vrange_str(options.vrange):
655
                    ver = vrange_str(options.vrange)
68 by Piotr Ożarowski
typo
656
                else:  # try shebang or default Python version
64 by Piotr Ożarowski
dh_python2:
657
                    ver = (list(v for i, v in details.get('shebangs', [])
658
                           if v) or [None])[0] or DEFAULT
236 by Piotr Ożarowski
ver is a string
659
                    ver = vrepr(ver)
660
                dependencies.depend("python%s" % ver)
52 by Piotr Ożarowski
* Python3 support removed (now available in python3-defaults)
661
                args += " -V %s" % vrepr(ver)
41 by Matthias Klose
package version python-defaults-2.6.5-1
662
            else:
213.1.1 by Piotr Ożarowski
generate more strict dependencies for packages with private extensions
663
                version = ext_for.pop()
664
                args += " -V %s" % vrepr(version)
224 by Piotr Ożarowski
update dirs item anme after fixing .egg-info directory name (thanks to Arnaud Fontaine for the patch)
665
                dependencies.depend("python%d.%d" % version)
41 by Matthias Klose
package version python-defaults-2.6.5-1
666
667
            for pattern in options.regexpr or []:
225 by Piotr Ożarowski
apostrophe is escaped properly in -X arguments (thanks to Jakub Wilk for the patch)
668
                args += " -X '%s'" % pattern.replace("'", r"'\''")
41 by Matthias Klose
package version python-defaults-2.6.5-1
669
52 by Piotr Ożarowski
* Python3 support removed (now available in python3-defaults)
670
            dh.autoscript(package, 'postinst', 'postinst-pycompile', args)
46 by Piotr Ożarowski
add initial .pydist support
671
213.1.1 by Piotr Ożarowski
generate more strict dependencies for packages with private extensions
672
        dependencies.export_to(dh)
673
46 by Piotr Ożarowski
add initial .pydist support
674
        pydist_file = join('debian', "%s.pydist" % package)
75 by Piotr Ożarowski
Remove '-V' option from pyclean call in runtime.d/public_modules.rtremove
675
        if exists(pydist_file):
283 by Piotr Ożarowski
no longer exits in the library
676
            if not validate_pydist(pydist_file):
75 by Piotr Ożarowski
Remove '-V' option from pyclean call in runtime.d/public_modules.rtremove
677
                log.warning("%s.pydist file is invalid", package)
678
            else:
679
                dstdir = join('debian', package, 'usr/share/python/dist/')
680
                if not exists(dstdir):
681
                    os.makedirs(dstdir)
682
                fcopy(pydist_file, join(dstdir, package))
46 by Piotr Ożarowski
add initial .pydist support
683
207 by Piotr Ożarowski
py_builddir: strip "python" form the argument (if set)
684
        # namespace feature - recreate __init__.py files at install time
231 by Piotr Ożarowski
add --ignore-namespace option that will disable handling
685
        if options.ignore_namespace:
686
            nsp = None
687
        else:
688
            nsp = ns.parse(stats['nsp.txt'], options.namespaces)
210 by Piotr Ożarowski
dh_python2, pycompile, pyclean: add "namespace" feature:
689
        # note that pycompile/pyclean is already added to maintainer scripts
690
        # and it should remain there even if __init__.py was the only .py file
231 by Piotr Ożarowski
add --ignore-namespace option that will disable handling
691
        if nsp:
692
            try:
693
                nsp = ns.remove_from_package(package, nsp,
694
                                             stats['public_vers'])
695
            except (IOError, OSError), e:
696
                log.error('cannot remove __init__.py from package: %s', e)
697
                exit(6)
207 by Piotr Ożarowski
py_builddir: strip "python" form the argument (if set)
698
        if nsp:
699
            dstdir = join('debian', package, 'usr/share/python/ns/')
700
            if not exists(dstdir):
701
                os.makedirs(dstdir)
210 by Piotr Ożarowski
dh_python2, pycompile, pyclean: add "namespace" feature:
702
            with open(join(dstdir, package), 'a') as fp:
207 by Piotr Ożarowski
py_builddir: strip "python" form the argument (if set)
703
                fp.writelines("%s\n" % i for i in nsp)
704
234 by Piotr Ożarowski
disable PyDist feature if dh sequencer is invoked --with pydeb
705
        pyshared = join('debian', package, 'usr/share/pyshared/')
235 by Piotr Ożarowski
check if pyshared dir exists, fix indentation
706
        if isdir(pyshared) and not os.listdir(pyshared):
234 by Piotr Ożarowski
disable PyDist feature if dh sequencer is invoked --with pydeb
707
            # remove empty pyshared directory
708
            os.rmdir(pyshared)
709
41 by Matthias Klose
package version python-defaults-2.6.5-1
710
    dh.save()
711
712
if __name__ == '__main__':
713
    main()