root/releases/pkgcore/0.2.2/setup.py @ ferringb%2540gmail.com-20070122100007-o357p1h86dtscjol

Revision ferringb%2540gmail.com-20070122100007-o357p1h86dtscjol, 12.3 kB (checked in by Brian Harring <ferringb@…>, 22 months ago)

make test run verbose

Line 
1#!/usr/bin/env python
2
3import os
4import sys
5import errno
6import subprocess
7import unittest
8
9from distutils import core, ccompiler, log, errors
10from distutils.command import build, sdist, build_py, build_scripts, install
11from stat import ST_MODE
12
13
14class mysdist(sdist.sdist):
15
16    """sdist command specifying the right files and generating ChangeLog."""
17
18    user_options = sdist.sdist.user_options + [
19        ('changelog', None, 'create a ChangeLog [default]'),
20        ('no-changelog', None, 'do not create the ChangeLog file'),
21        ]
22
23    boolean_options = sdist.sdist.boolean_options + ['changelog']
24
25    negative_opt = {'no-changelog': 'changelog'}
26    negative_opt.update(sdist.sdist.negative_opt)
27
28    default_format = dict(sdist.sdist.default_format)
29    default_format["posix"] = "bztar"
30
31    def initialize_options(self):
32        sdist.sdist.initialize_options(self)
33        self.changelog = True
34
35    def get_file_list(self):
36        """Get a filelist without doing anything involving MANIFEST files."""
37        # This is copied from the "Recreate manifest" bit of sdist.
38        self.filelist.findall()
39        if self.use_defaults:
40            self.add_defaults()
41
42        # This bit is roughly equivalent to a MANIFEST.in template file.
43        for key, globs in self.distribution.package_data.iteritems():
44            for pattern in globs:
45                self.filelist.include_pattern(os.path.join(key, pattern))
46
47        self.filelist.append("AUTHORS")
48        self.filelist.append("NOTES")
49        self.filelist.append("COPYING")
50
51        self.filelist.include_pattern('.[ch]', prefix='src')
52
53        for prefix in ['doc', 'dev-notes']:
54            self.filelist.include_pattern('.rst', prefix=prefix)
55            self.filelist.exclude_pattern(os.path.sep + 'index.rst',
56                                          prefix=prefix)
57        self.filelist.append('build_docs.py')
58        self.filelist.include_pattern('*', prefix='examples')
59        self.filelist.include_pattern('*', prefix='bin')
60
61        if self.prune:
62            self.prune_file_list()
63
64        # This is not optional: remove_duplicates needs sorted input.
65        self.filelist.sort()
66        self.filelist.remove_duplicates()
67
68    def make_release_tree(self, base_dir, files):
69        """Create and populate the directory tree that is put in source tars.
70
71        This copies or hardlinks "normal" source files that should go
72        into the release and adds generated files that should not
73        exist in a working tree.
74        """
75        sdist.sdist.make_release_tree(self, base_dir, files)
76        if self.changelog:
77            log.info("regenning ChangeLog (may take a while)")
78            if subprocess.call(
79                ['bzr', 'log', '--verbose'],
80                stdout=open(os.path.join(base_dir, 'ChangeLog'), 'w')):
81                raise errors.DistutilsExecError('bzr log failed')
82        log.info('generating bzr_verinfo')
83        if subprocess.call(
84            ['bzr', 'version-info', '--format=python'],
85            stdout=open(os.path.join(
86                    base_dir, 'pkgcore', 'bzr_verinfo.py'), 'w')):
87            raise errors.DistutilsExecError('bzr version-info failed')
88
89
90class pkgcore_build_scripts(build_scripts.build_scripts):
91
92    """Build (modify #! line) the pwrapper_installed script."""
93
94    def finalize_options(self):
95        build_scripts.build_scripts.finalize_options(self)
96        self.scripts = [os.path.join('bin', 'pwrapper_installed')]
97
98# pkgcore_{build,install}_scripts are registered as separate commands
99# instead of overriding the default {build,install}_scripts because
100# those are only run if the "scripts" arg to setup is not empty.
101
102build.build.sub_commands.append(('pkgcore_build_scripts', None))
103
104
105class pkgcore_install_scripts(core.Command):
106
107    """Install symlinks to the pwrapper_installed script.
108
109    Adapted from distutils install_scripts.
110    """
111
112    user_options = [
113        ('install-dir=', 'd', "directory to install scripts to"),
114        ('build-dir=','b', "build directory (where to install from)"),
115        ('force', 'f', "force installation (overwrite existing files)"),
116        ('skip-build', None, "skip the build steps"),
117        ]
118
119    boolean_options = ['force', 'skip-build']
120
121    def initialize_options(self):
122        self.install_dir = None
123        self.force = 0
124        self.build_dir = None
125        self.skip_build = None
126
127    def finalize_options(self):
128        self.set_undefined_options('build', ('build_scripts', 'build_dir'))
129        self.set_undefined_options('install',
130                                   ('install_scripts', 'install_dir'),
131                                   ('force', 'force'),
132                                   ('skip_build', 'skip_build'),
133                                   )
134        self.scripts = [
135            path for path in os.listdir('bin')
136            if path not in ('pwrapper', 'pwrapper_installed')]
137
138    def run(self):
139        if not self.skip_build:
140            self.run_command('pkgcore_build_scripts')
141        self.mkpath(self.install_dir)
142        if os.name == 'posix':
143            # Copy the wrapper once.
144            copyname = os.path.join(self.install_dir, self.scripts[0])
145            self.copy_file(os.path.join(self.build_dir, 'pwrapper_installed'),
146                           copyname)
147            # Set the executable bits (owner, group, and world).
148            if self.dry_run:
149                log.info("changing mode of %s", copyname)
150            else:
151                mode = ((os.stat(copyname)[ST_MODE]) | 0555) & 07777
152                log.info("changing mode of %s to %o", copyname, mode)
153                os.chmod(copyname, mode)
154            # Use symlinks for the other scripts.
155            for script in self.scripts[1:]:
156                # We do not use self.copy_file(link='sym') because we
157                # want to make a relative link and copy_file requires
158                # the "source" to be an actual file.
159                dest = os.path.join(self.install_dir, script)
160                log.info('symlinking %s to %s', dest, self.scripts[0])
161                try:
162                    os.symlink(self.scripts[0], dest)
163                except (IOError, OSError), e:
164                    if e.errno != errno.EEXIST:
165                        raise
166                    os.remove(dest)
167                    os.symlink(self.scripts[0], dest)
168        else:
169            # Just copy all the scripts.
170            for script in self.scripts:
171                self.copy_file(
172                    os.path.join(self.build_dir, 'pwrapper_installed'),
173                    os.path.join(self.install_dir, script))
174
175    def get_inputs(self):
176        return self.scripts
177
178    def get_outputs(self):
179        return self.scripts
180
181install.install.sub_commands.append(('pkgcore_install_scripts', None))
182
183
184class pkgcore_build_py(build_py.build_py):
185
186    def run(self):
187        build_py.build_py.run(self)
188        bzr_ver = self.get_module_outfile(
189            self.build_lib, ('pkgcore',), 'bzr_verinfo')
190        if not os.path.exists(bzr_ver):
191            log.info('generating bzr_verinfo')
192            if subprocess.call(
193                ['bzr', 'version-info', '--format=python'],
194                stdout=open(bzr_ver, 'w')):
195                # Not fatal, just less useful --version output.
196                log.warn('generating bzr_verinfo failed!')
197            else:
198                self.byte_compile([bzr_ver])
199
200        fp = os.path.join(self.build_lib, "pkgcore", "bin", "ebuild-helpers")
201        for f in os.listdir(fp):
202            self.set_chmod(os.path.join(fp, f))
203        fp = os.path.join(self.build_lib, "pkgcore", "bin", "ebuild-env")
204        for f in ("ebuild.sh", "ebuild-daemon.sh"):
205            self.set_chmod(os.path.join(fp, f))
206
207    def set_chmod(self, path):
208        if self.dry_run:
209            log.info("changing mode of %s", path)
210        else:
211            mode = ((os.stat(path)[ST_MODE]) | 0555) & 07777
212            log.info("changing mode of %s to %o", path, mode)
213            os.chmod(path, mode)
214
215
216
217class TestLoader(unittest.TestLoader):
218
219    """Test loader that knows how to recurse packages."""
220
221    def loadTestsFromModule(self, module):
222        """Recurses if module is actually a package."""
223        paths = getattr(module, '__path__', None)
224        tests = [unittest.TestLoader.loadTestsFromModule(self, module)]
225        if paths is None:
226            # Not a package.
227            return tests[0]
228        for path in paths:
229            for child in os.listdir(path):
230                if (child != '__init__.py' and child.endswith('.py') and
231                    child.startswith('test')):
232                    # Child module.
233                    childname = '%s.%s' % (module.__name__, child[:-3])
234                else:
235                    childpath = os.path.join(path, child)
236                    if not os.path.isdir(childpath):
237                        continue
238                    if not os.path.exists(os.path.join(childpath,
239                                                       '__init__.py')):
240                        continue
241                    # Subpackage.
242                    childname = '%s.%s' % (module.__name__, child)
243                tests.append(self.loadTestsFromName(childname))
244        return self.suiteClass(tests)
245
246
247testLoader = TestLoader()
248
249
250class test(core.Command):
251
252    """Run our unit tests in a built copy.
253
254    Based on code from setuptools.
255    """
256
257    user_options = []
258
259    def initialize_options(self):
260        # Options? What options?
261        pass
262
263    def finalize_options(self):
264        # Options? What options?
265        pass
266
267    def run(self):
268        build_ext = self.reinitialize_command('build_ext')
269        build_ext.inplace = True
270        self.run_command('build_ext')
271        # Somewhat hackish: this calls sys.exit.
272        unittest.main('pkgcore.test', argv=['setup.py', '-v'], testLoader=testLoader)
273
274
275packages = [
276    root.replace(os.path.sep, '.')
277    for root, dirs, files in os.walk('pkgcore')
278    if '__init__.py' in files]
279
280extra_flags = ['-Wall']
281common_includes = ['src/py24-compatibility.h',
282                   'src/heapdef.h',
283                   'src/common.h',
284                   ]
285
286extensions = []
287if sys.version_info < (2, 5):
288    # Almost unmodified copy from the python 2.5 source.
289    extensions.append(core.Extension(
290            'pkgcore.util._functools', ['src/functoolsmodule.c'],
291            extra_compile_args=extra_flags, depends=common_includes))
292
293from pkgcore.const import VERSION
294core.setup(
295    name='pkgcore',
296    version=VERSION,
297    description='package managing framework',
298    url='http://www.pkgcore.org/',
299    packages=packages,
300    package_data={
301        'pkgcore': [
302            'bin/ebuild-env/*',
303            'bin/ebuild-helpers/*',
304            ],
305        },
306    ext_modules=[
307        core.Extension(
308            'pkgcore.util.osutils._posix', ['src/posix.c'],
309            extra_compile_args=extra_flags, depends=common_includes),
310        core.Extension(
311            'pkgcore.util._klass', ['src/klass.c'],
312            extra_compile_args=extra_flags, depends=common_includes),
313        core.Extension(
314            'pkgcore.util._caching', ['src/caching.c'],
315            extra_compile_args=extra_flags, depends=common_includes),
316        core.Extension(
317            'pkgcore.util._lists', ['src/lists.c'],
318            extra_compile_args=extra_flags, depends=common_includes),
319        core.Extension(
320            'pkgcore.ebuild._cpv', ['src/cpv.c'],
321            extra_compile_args=extra_flags, depends=common_includes),
322        core.Extension(
323            'pkgcore.ebuild._depset', ['src/depset.c'],
324            extra_compile_args=extra_flags, depends=common_includes),
325        core.Extension(
326            'pkgcore.ebuild._atom', ['src/atom.c'],
327            extra_compile_args=extra_flags, depends=common_includes),
328        core.Extension(
329            'pkgcore.restrictions._restrictions', ['src/restrictions.c'],
330            extra_compile_args=extra_flags, depends=common_includes),
331        core.Extension(
332            'pkgcore.ebuild._filter_env', [
333                'src/filter_env.c', 'src/bmh_search.c'],
334            extra_compile_args=extra_flags, depends=common_includes),
335        core.Extension(
336            'pkgcore.util.osutils._readdir', ['src/readdir.c'],
337            extra_compile_args=extra_flags, depends=common_includes),
338        ] + extensions,
339    cmdclass={
340        'sdist': mysdist,
341        'build_py': pkgcore_build_py,
342        'test': test,
343        'pkgcore_build_scripts': pkgcore_build_scripts,
344        'pkgcore_install_scripts': pkgcore_install_scripts,
345        },
346    )
Note: See TracBrowser for help on using the browser.