root/snakeoil/setup.py @ ferringb%2540gmail.com-20080318082158-2zsopkk5uxkpxboz

Revision ferringb%2540gmail.com-20080318082158-2zsopkk5uxkpxboz, 8.1 kB (checked in by Brian Harring <ferringb@…>, 8 months ago)

add build_api_docs into the sdist filelist targets

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_ext, build_py, build_scripts, install
11from stat import ST_MODE
12
13class OptionalExtension(core.Extension):
14    pass
15
16if os.name == "nt":
17    bzrbin = "bzr.bat"
18else:
19    bzrbin = "bzr"
20
21class mysdist(sdist.sdist):
22
23    """sdist command specifying the right files and generating ChangeLog."""
24
25    user_options = sdist.sdist.user_options + [
26        ('changelog', None, 'create a ChangeLog [default]'),
27        ('no-changelog', None, 'do not create the ChangeLog file'),
28        ]
29
30    boolean_options = sdist.sdist.boolean_options + ['changelog']
31
32    negative_opt = {'no-changelog': 'changelog'}
33    negative_opt.update(sdist.sdist.negative_opt)
34
35    default_format = dict(sdist.sdist.default_format)
36    default_format["posix"] = "bztar"
37
38    def initialize_options(self):
39        sdist.sdist.initialize_options(self)
40        self.changelog = True
41
42    def get_file_list(self):
43        """Get a filelist without doing anything involving MANIFEST files."""
44        # This is copied from the "Recreate manifest" bit of sdist.
45        self.filelist.findall()
46        if self.use_defaults:
47            self.add_defaults()
48
49        # This bit is roughly equivalent to a MANIFEST.in template file.
50        for key, globs in self.distribution.package_data.iteritems():
51            for pattern in globs:
52                self.filelist.include_pattern(os.path.join(key, pattern))
53
54        self.filelist.append("AUTHORS")
55        self.filelist.append("NOTES")
56        self.filelist.append("NEWS")
57        self.filelist.append("COPYING")
58
59        self.filelist.include_pattern('.c', prefix='src')
60        self.filelist.include_pattern('.h', prefix='include/snakeoil')
61
62        for prefix in ['doc', 'dev-notes']:
63            self.filelist.include_pattern('.rst', prefix=prefix)
64            self.filelist.exclude_pattern(os.path.sep + 'index.rst',
65                                          prefix=prefix)
66        self.filelist.append('build_docs.py')
67        self.filelist.append('build_api_docs.sh')
68        self.filelist.include_pattern('*', prefix='examples')
69        self.filelist.include_pattern('*', prefix='bin')
70
71        if self.prune:
72            self.prune_file_list()
73
74        # This is not optional: remove_duplicates needs sorted input.
75        self.filelist.sort()
76        self.filelist.remove_duplicates()
77
78    def make_release_tree(self, base_dir, files):
79        """Create and populate the directory tree that is put in source tars.
80
81        This copies or hardlinks "normal" source files that should go
82        into the release and adds generated files that should not
83        exist in a working tree.
84        """
85        sdist.sdist.make_release_tree(self, base_dir, files)
86        if self.changelog:
87            log.info("regenning ChangeLog (may take a while)")
88            if subprocess.call(
89                [bzrbin, 'log', '--verbose'],
90                stdout=open(os.path.join(base_dir, 'ChangeLog'), 'w')):
91                raise errors.DistutilsExecError('bzr log failed')
92        log.info('generating bzr_verinfo')
93        if subprocess.call(
94            [bzrbin, 'version-info', '--format=python'],
95            stdout=open(os.path.join(
96                    base_dir, 'snakeoil', 'bzr_verinfo.py'), 'w')):
97            raise errors.DistutilsExecError('bzr version-info failed')
98
99
100class snakeoil_build_py(build_py.build_py):
101
102    def run(self):
103        build_py.build_py.run(self)
104        bzr_ver = self.get_module_outfile(
105            self.build_lib, ('snakeoil',), 'bzr_verinfo')
106        if not os.path.exists(bzr_ver):
107            log.info('generating bzr_verinfo')
108            if subprocess.call(
109                [bzrbin, 'version-info', '--format=python'],
110                stdout=open(bzr_ver, 'w')):
111                # Not fatal, just less useful --version output.
112                log.warn('generating bzr_verinfo failed!')
113            else:
114                self.byte_compile([bzr_ver])
115
116class snakeoil_build_ext(build_ext.build_ext):
117
118    user_options = build_ext.build_ext.user_options + [
119        ("build-optional=", "o", "build optional C modules"),
120    ]
121
122    boolean_options = build.build.boolean_options + ["build-optional"]
123
124    def initialize_options(self):
125        build_ext.build_ext.initialize_options(self)
126        self.build_optional = None
127
128    def finalize_options(self):
129        build_ext.build_ext.finalize_options(self)
130        if self.build_optional is None:
131            self.build_optional = True
132        if not self.build_optional:
133            self.extensions = [ext for ext in self.extensions if not isinstance(ext, OptionalExtension)] or None
134
135class TestLoader(unittest.TestLoader):
136
137    """Test loader that knows how to recurse packages."""
138
139    def loadTestsFromModule(self, module):
140        """Recurses if module is actually a package."""
141        paths = getattr(module, '__path__', None)
142        tests = [unittest.TestLoader.loadTestsFromModule(self, module)]
143        if paths is None:
144            # Not a package.
145            return tests[0]
146        for path in paths:
147            for child in os.listdir(path):
148                if (child != '__init__.py' and child.endswith('.py') and
149                    child.startswith('test')):
150                    # Child module.
151                    childname = '%s.%s' % (module.__name__, child[:-3])
152                else:
153                    childpath = os.path.join(path, child)
154                    if not os.path.isdir(childpath):
155                        continue
156                    if not os.path.exists(os.path.join(childpath,
157                                                       '__init__.py')):
158                        continue
159                    # Subpackage.
160                    childname = '%s.%s' % (module.__name__, child)
161                tests.append(self.loadTestsFromName(childname))
162        return self.suiteClass(tests)
163
164
165testLoader = TestLoader()
166
167
168class test(core.Command):
169
170    """Run our unit tests in a built copy.
171
172    Based on code from setuptools.
173    """
174
175    user_options = []
176
177    def initialize_options(self):
178        # Options? What options?
179        pass
180
181    def finalize_options(self):
182        # Options? What options?
183        pass
184
185    def run(self):
186        build_ext = self.reinitialize_command('build_ext')
187        build_ext.inplace = True
188        self.run_command('build_ext')
189        # Somewhat hackish: this calls sys.exit.
190        unittest.main('snakeoil.test', argv=['setup.py', '-v'], testLoader=testLoader)
191
192
193packages = [
194    root.replace(os.path.sep, '.')
195    for root, dirs, files in os.walk('snakeoil')
196    if '__init__.py' in files]
197
198common_includes=[
199    'include/snakeoil/py24-compatibility.h',
200    'include/snakeoil/heapdef.h',
201    'include/snakeoil/common.h',
202    ]
203
204extra_kwargs = dict(
205    extra_compile_args=['-Wall'],
206    depends=common_includes,
207    include_dirs=['include'],
208    )
209
210extensions = []
211if sys.version_info < (2, 5):
212    # Almost unmodified copy from the python 2.5 source.
213    extensions.append(OptionalExtension(
214            'snakeoil._compatibility', ['src/compatibility.c'], **extra_kwargs))
215
216from snakeoil.version import __version__ as VERSION
217
218core.setup(
219    name='snakeoil',
220    version=VERSION,
221    description='misc common functionality, and useful optimizations',
222    url='http://www.pkgcore.org/',
223    packages=packages,
224    ext_modules=[
225        OptionalExtension(
226            'snakeoil.osutils._posix', ['src/posix.c'], **extra_kwargs),
227        OptionalExtension(
228            'snakeoil._klass', ['src/klass.c'], **extra_kwargs),
229        OptionalExtension(
230            'snakeoil._caching', ['src/caching.c'], **extra_kwargs),
231        OptionalExtension(
232            'snakeoil._lists', ['src/lists.c'], **extra_kwargs),
233        OptionalExtension(
234            'snakeoil.osutils._readdir', ['src/readdir.c'], **extra_kwargs),
235        OptionalExtension(
236            'snakeoil._formatters', ['src/formatters.c'], **extra_kwargs),
237        ] + extensions,
238    headers=common_includes,
239    cmdclass={
240        'sdist': mysdist,
241        'build_ext': snakeoil_build_ext,
242        'build_py': snakeoil_build_py,
243        'test': test,
244        },
245    )
Note: See TracBrowser for help on using the browser.