~mitya57/ubuntu/trusty/dh-python/tests-dependencies

« back to all changes in this revision

Viewing changes to dh_pypy

  • Committer: Package Import Robot
  • Author(s): Piotr Ożarowski
  • Date: 2013-07-07 21:47:50 UTC
  • Revision ID: package-import@ubuntu.com-20130707214750-d6wmodmuzp78kt75
Tags: upstream-1.0~b1
Import upstream version 1.0~b1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#! /usr/bin/python3
 
2
# vim: et ts=4 sw=4
 
3
 
 
4
# Copyright © 2013 Piotr Ożarowski <piotr@debian.org>
 
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
import logging
 
25
import os
 
26
import re
 
27
import sys
 
28
from optparse import OptionParser, SUPPRESS_HELP
 
29
from os.path import exists, join
 
30
from shutil import copy as fcopy
 
31
from dhpython.debhelper import DebHelper
 
32
from dhpython.depends import Dependencies
 
33
from dhpython.interpreter import Interpreter, EXTFILE_RE
 
34
from dhpython.version import supported, default, Version, VersionRange
 
35
from dhpython.pydist import validate as validate_pydist
 
36
from dhpython.fs import fix_locations, Scan
 
37
from dhpython.option import Option
 
38
 
 
39
# initialize script
 
40
logging.basicConfig(format='%(levelname).1s: dh_pypy '
 
41
                           '%(module)s:%(lineno)d: %(message)s')
 
42
log = logging.getLogger('dhpython')
 
43
os.umask(0o22)
 
44
DEFAULT = default('pypy')
 
45
SUPPORTED = supported('pypy')
 
46
 
 
47
 
 
48
class Scanner(Scan):
 
49
    def handle_ext(self, fpath):
 
50
        path, fname = fpath.rsplit('/', 1)
 
51
        tagver = EXTFILE_RE.search(fname)
 
52
        if tagver is None:
 
53
            return
 
54
        tagver = tagver.groupdict()['ver']
 
55
        if tagver is None:
 
56
            return
 
57
        tagver = Version("%s.%s" % (tagver[0], tagver[1]))
 
58
        return tagver
 
59
 
 
60
 
 
61
def main():
 
62
    usage = '%prog -p PACKAGE [-V [X.Y][-][A.B]] DIR [-X REGEXPR]\n'
 
63
    parser = OptionParser(usage, version='%prog DEVELV', option_class=Option)
 
64
    parser.add_option('--no-guessing-deps', action='store_false',
 
65
                      dest='guess_deps', default=True,
 
66
                      help='disable guessing dependencies')
 
67
    parser.add_option('--skip-private', action='store_true', default=False,
 
68
                      help='don\'t check private directories')
 
69
    parser.add_option('-v', '--verbose', action='store_true', default=False,
 
70
                      help='turn verbose mode on')
 
71
    # arch=False->arch:all only, arch=True->arch:any only, None->all of them
 
72
    parser.add_option('-i', '--indep', action='store_false',
 
73
                      dest='arch', default=None,
 
74
                      help='act on architecture independent packages')
 
75
    parser.add_option('-a', '-s', '--arch', action='store_true',
 
76
                      dest='arch', help='act on architecture dependent packages')
 
77
    parser.add_option('-q', '--quiet', action='store_false', dest='verbose',
 
78
                      help='be quiet')
 
79
    parser.add_option('-p', '--package', action='append',
 
80
                      help='act on the package named PACKAGE')
 
81
    parser.add_option('-N', '--no-package', action='append',
 
82
                      help='do not act on the specified package')
 
83
    parser.add_option('--compile-all', action='store_true', default=False,
 
84
                      help='compile all files from given private directory '
 
85
                           'in postinst, not just the ones provided by the '
 
86
                           'package')
 
87
    parser.add_option('-V', type='version_range', dest='vrange',
 
88
                      #help='specify list of supported PyPy versions. ' +
 
89
                      #     'See pypycompile(1) for examples',
 
90
                      help=SUPPRESS_HELP)
 
91
    parser.add_option('-X', '--exclude', action='append', dest='regexpr',
 
92
                      help='exclude items that match given REGEXPR. You may '
 
93
                           'use this option multiple times to build up a list'
 
94
                           ' of things to exclude.')
 
95
    parser.add_option('--depends', action='append',
 
96
                      help='translate given requirements into Debian '
 
97
                           'dependencies and add them to ${pypy:Depends}. '
 
98
                           'Use it for missing items in requires.txt.')
 
99
    parser.add_option('--recommends', action='append',
 
100
                      help='translate given requirements into Debian '
 
101
                           'dependencies and add them to ${pypy:Recommends}')
 
102
    parser.add_option('--suggests', action='append',
 
103
                      help='translate given requirements into Debian '
 
104
                           'dependencies and add them to ${pypy:Suggests}')
 
105
    parser.add_option('--shebang',
 
106
                      help='use given command as shebang in scripts')
 
107
    parser.add_option('--ignore-shebangs', action='store_true', default=False,
 
108
                      help='do not translate shebangs into Debian dependencies')
 
109
    parser.add_option('--no-dbg-cleaning', action='store_false',
 
110
                      dest='clean_dbg_pkg', default=True,
 
111
                      help='do not remove files from debug packages')
 
112
    parser.add_option('--no-shebang-rewrite', action='store_true',
 
113
                      default=False, help='do not rewrite shebangs')
 
114
    # ignore some debhelper options:
 
115
    parser.add_option('-O', help=SUPPRESS_HELP)
 
116
 
 
117
    options, args = parser.parse_args(sys.argv[1:] +
 
118
                                      os.environ.get('DH_OPTIONS', '').split())
 
119
    # regexpr option type is not used so lets check patterns here
 
120
    for pattern in options.regexpr or []:
 
121
        # fail now rather than at runtime
 
122
        try:
 
123
            pattern = re.compile(pattern)
 
124
        except Exception:
 
125
            log.error('regular expression is not valid: %s', pattern)
 
126
            exit(1)
 
127
 
 
128
    if not args:
 
129
        private_dir = None
 
130
    else:
 
131
        private_dir = args[0]
 
132
        if not private_dir.startswith('/'):
 
133
            # handle usr/share/foo dirs (without leading slash)
 
134
            private_dir = '/' + private_dir
 
135
    # TODO: support more than one private dir at the same time (see :meth:scan)
 
136
    if options.skip_private:
 
137
        private_dir = False
 
138
 
 
139
    if options.verbose or os.environ.get('DH_VERBOSE') == '1':
 
140
        log.setLevel(logging.DEBUG)
 
141
        log.debug('argv: %s', sys.argv)
 
142
        log.debug('options: %s', options)
 
143
        log.debug('args: %s', args)
 
144
        log.debug('supported PyPy versions: %s (default=%s)',
 
145
                  ','.join(str(v) for v in SUPPORTED), DEFAULT)
 
146
    else:
 
147
        log.setLevel(logging.INFO)
 
148
 
 
149
    try:
 
150
        dh = DebHelper(options, impl='pypy')
 
151
    except Exception as e:
 
152
        log.error('cannot initialize DebHelper: %s', e)
 
153
        exit(2)
 
154
    if not options.vrange and dh.python_version:
 
155
        options.vrange = VersionRange(dh.python_version)
 
156
 
 
157
    interpreter = Interpreter('pypy')
 
158
    for package, pdetails in dh.packages.items():
 
159
        if options.arch is False and pdetails['arch'] != 'all' or \
 
160
                options.arch is True and pdetails['arch'] == 'all':
 
161
            continue
 
162
        log.debug('processing package %s...', package)
 
163
        if package.endswith('-dbg'):
 
164
            interpreter.debug = True
 
165
 
 
166
        if not private_dir:
 
167
            fix_locations(package, interpreter, SUPPORTED)
 
168
        stats = Scanner(interpreter, package, private_dir, options).result
 
169
 
 
170
        dependencies = Dependencies(package, 'pypy')
 
171
        dependencies.parse(stats, options)
 
172
 
 
173
        if stats['ext_vers']:
 
174
            dh.addsubstvar(package, 'pypy:Versions',
 
175
                           ', '.join(str(v) for v in sorted(stats['ext_vers'])))
 
176
            ps = package.split('-', 1)
 
177
            if len(ps) > 1 and ps[0] == 'pypy':
 
178
                dh.addsubstvar(package, 'pypy:Provides',
 
179
                               ', '.join("pypy%s-%s" % (i, ps[1])
 
180
                               for i in sorted(stats['ext_vers'])))
 
181
 
 
182
        pypyclean_added = False  # invoke pypyclean only once in maintainer script
 
183
        if stats['compile']:
 
184
            args = ''
 
185
            if options.vrange:
 
186
                args += "-V %s" % options.vrange
 
187
            dh.autoscript(package, 'postinst', 'postinst-pypycompile', args)
 
188
            dh.autoscript(package, 'prerm', 'prerm-pypyclean', '')
 
189
            pypyclean_added = True
 
190
        for pdir, details in stats['private_dirs'].items():
 
191
            if not details.get('compile'):
 
192
                continue
 
193
            if not pypyclean_added:
 
194
                dh.autoscript(package, 'prerm', 'prerm-pypyclean', '')
 
195
                pypyclean_added = True
 
196
 
 
197
            args = pdir
 
198
 
 
199
            ext_for = details.get('ext_vers')
 
200
            ext_no_version = details.get('ext_no_version')
 
201
            if ext_for is None and not ext_no_version:  # no extension
 
202
                shebang_versions = list(i.version for i in details.get('shebangs', [])
 
203
                                        if i.version and i.version.minor)
 
204
                if not options.ignore_shebangs and len(shebang_versions) == 1:
 
205
                    # only one version from shebang
 
206
                    args += " -V %s" % shebang_versions[0]
 
207
                elif options.vrange and options.vrange != (None, None):
 
208
                    args += " -V %s" % options.vrange
 
209
            elif ext_no_version:
 
210
                # at least one extension's version not detected
 
211
                if options.vrange and '-' not in str(options.vrange):
 
212
                    ver = str(options.vrange)
 
213
                else:  # try shebang or default PyPy version
 
214
                    ver = (list(i.version for i in details.get('shebangs', [])
 
215
                                if i.version) or [None])[0] or DEFAULT
 
216
                dependencies.depend("pypy%s" % ver)
 
217
                args += " -V %s" % ver
 
218
            else:
 
219
                extensions = sorted(ext_for)
 
220
                vr = VersionRange(minver=extensions[0], maxver=extensions[-1])
 
221
                args += " -V %s" % vr
 
222
 
 
223
            for pattern in options.regexpr or []:
 
224
                args += " -X '%s'" % pattern.replace("'", r"'\''")
 
225
 
 
226
            dh.autoscript(package, 'postinst', 'postinst-pypycompile', args)
 
227
 
 
228
        dependencies.export_to(dh)
 
229
 
 
230
        pydist_file = join('debian', "%s.pydist" % package)
 
231
        if exists(pydist_file):
 
232
            if not validate_pydist(pydist_file):
 
233
                log.warning("%s.pydist file is invalid", package)
 
234
            else:
 
235
                dstdir = join('debian', package, 'usr/share/pypy/dist/')
 
236
                if not exists(dstdir):
 
237
                    os.makedirs(dstdir)
 
238
                fcopy(pydist_file, join(dstdir, package))
 
239
 
 
240
    dh.save()
 
241
 
 
242
if __name__ == '__main__':
 
243
    main()