1#!/usr/bin/env python
2
3descr = """Python interface to UMFPACK sparse direct solver."""
4
5DISTNAME            = 'scikit-umfpack'
6DESCRIPTION         = 'Python interface to UMFPACK sparse direct solver.'
7LONG_DESCRIPTION    = open('README.rst').read()
8MAINTAINER          = 'Robert Cimrman'
9MAINTAINER_EMAIL    = 'cimrman3@ntc.zcu.cz'
10URL                 = 'https://scikit-umfpack.github.io/scikit-umfpack'
11LICENSE             = 'BSD'
12DOWNLOAD_URL        = URL
13VERSION             = '0.3.2'
14ISRELEASED          = True
15
16import sys
17import os
18import shutil
19import subprocess
20from distutils.command.clean import clean as Clean
21
22# Return the git revision as a string
23def git_version():
24    def _minimal_ext_cmd(cmd):
25        # construct minimal environment
26        env = {}
27        for k in ['SYSTEMROOT', 'PATH']:
28            v = os.environ.get(k)
29            if v is not None:
30                env[k] = v
31        # LANGUAGE is used on win32
32        env['LANGUAGE'] = 'C'
33        env['LANG'] = 'C'
34        env['LC_ALL'] = 'C'
35        out = subprocess.Popen(cmd, stdout=subprocess.PIPE, env=env).communicate()[0]
36        return out
37
38    try:
39        out = _minimal_ext_cmd(['git', 'rev-parse', 'HEAD'])
40        GIT_REVISION = out.strip().decode('ascii')
41    except OSError:
42        GIT_REVISION = "Unknown"
43
44    return GIT_REVISION
45
46def get_version_info():
47    # Adding the git rev number needs to be done inside
48    # write_version_py(), otherwise the import of scikits.umfpack.version messes
49    # up the build under Python 3.
50    FULLVERSION = VERSION
51    if os.path.exists('.git'):
52        GIT_REVISION = git_version()
53    elif os.path.exists('scikits/umfpack/version.py'):
54        # must be a source distribution, use existing version file
55        # load it as a separate module to not load scikits/umfpack/__init__.py
56        import imp
57        version = imp.load_source('scikits.umfpack.version',
58                                  'scikits/umfpack/version.py')
59        GIT_REVISION = version.git_revision
60    else:
61        GIT_REVISION = "Unknown"
62
63    if not ISRELEASED:
64        FULLVERSION += '.dev0+' + GIT_REVISION[:7]
65
66    return FULLVERSION, GIT_REVISION
67
68def write_version_py(filename='scikits/umfpack/version.py'):
69    cnt = """# THIS FILE IS GENERATED FROM scikit-umfpack SETUP.PY
70short_version = '%(version)s'
71version = '%(version)s'
72full_version = '%(full_version)s'
73git_revision = '%(git_revision)s'
74release = %(isrelease)s
75
76if not release:
77    version = full_version
78"""
79    FULLVERSION, GIT_REVISION = get_version_info()
80
81    a = open(filename, 'w')
82    try:
83        a.write(cnt % {'version': VERSION,
84                       'full_version': FULLVERSION,
85                       'git_revision': GIT_REVISION,
86                       'isrelease': str(ISRELEASED)})
87    finally:
88        a.close()
89
90###############################################################################
91# Optional setuptools features
92# We need to import setuptools early, if we want setuptools features,
93# as it monkey-patches the 'setup' function
94
95# For some commands, use setuptools
96if len(set(('develop', 'release', 'bdist_egg', 'bdist_rpm',
97           'bdist_wininst', 'install_egg_info', 'build_sphinx',
98           'egg_info', 'easy_install', 'upload', 'bdist_wheel',
99           '--single-version-externally-managed',
100            )).intersection(sys.argv)) > 0:
101    import setuptools
102    extra_setuptools_args = dict(
103        zip_safe=False,  # the package can run out of an .egg file
104        include_package_data=True,
105    )
106else:
107    extra_setuptools_args = dict()
108
109
110###############################################################################
111
112class CleanCommand(Clean):
113    description = 'Remove build directories, and compiled file in the source tree'
114
115    def run(self):
116        Clean.run(self)
117        if os.path.exists('build'):
118            shutil.rmtree('build')
119        for dirpath, dirnames, filenames in os.walk('umfpack'):
120            for filename in filenames:
121                if (filename.endswith('.so') or filename.endswith('.pyd')
122                             or filename.endswith('.dll')
123                             or filename.endswith('.pyc')):
124                    os.unlink(os.path.join(dirpath, filename))
125            for dirname in dirnames:
126                if dirname == '__pycache__':
127                    shutil.rmtree(os.path.join(dirpath, dirname))
128
129###############################################################################
130def configuration(parent_package='', top_path=None):
131    if os.path.exists('MANIFEST'): os.remove('MANIFEST')
132
133    from numpy.distutils.misc_util import Configuration
134    config = Configuration(None, parent_package, top_path)
135
136    # Avoid non-useful msg:
137    # "Ignoring attempt to set 'name' (from ... "
138    config.set_options(ignore_setup_xxx_py=True,
139                       assume_default_configuration=True,
140                       delegate_options_to_subpackages=True,
141                       quiet=True)
142
143    config.add_subpackage('scikits.umfpack')
144    config.add_data_files('scikits/__init__.py')
145    config.add_data_files('MANIFEST.in')
146
147    return config
148
149def setup_package():
150    # Rewrite the version file every time
151    write_version_py()
152
153    cmdclass = {'clean': CleanCommand}
154    try:
155        from sphinx.setup_command import BuildDoc as SphinxBuildDoc
156        class BuildDoc(SphinxBuildDoc):
157            """Run in-place build before Sphinx doc build"""
158            def run(self):
159                ret = subprocess.call([sys.executable, sys.argv[0], 'build_ext', '-i'])
160                if ret != 0:
161                    raise RuntimeError("Building failed!")
162                SphinxBuildDoc.run(self)
163        cmdclass['build_sphinx'] = BuildDoc
164    except ImportError:
165        pass
166
167    if not 'sdist' in sys.argv[1:]:
168        try:
169            from setuptools.command.test import test as TestCommand
170            class NoseTestCommand(TestCommand):
171                def finalize_options(self):
172                    TestCommand.finalize_options(self)
173                    self.test_args = []
174                    self.test_suite = True
175
176                def run_tests(self):
177                    # Run nose ensuring that argv simulates running nosetests directly
178                    ret = subprocess.call([sys.executable, sys.argv[0], 'build_ext', '-i'])
179                    if ret != 0:
180                        raise RuntimeError("Building failed!")
181                    import nose
182                    nose.run_exit(argv=['nosetests'])
183            cmdclass['test'] = NoseTestCommand
184        except ImportError:
185            pass
186
187    try:
188        import numpy
189        INSTALL_REQUIRES = [
190            'numpy>=' + str(numpy.__version__),
191            'scipy>=1.0.0rc1',
192        ]
193    except ImportError:
194        INSTALL_REQUIRES = []
195
196    metadata = dict(name=DISTNAME,
197                    maintainer=MAINTAINER,
198                    maintainer_email=MAINTAINER_EMAIL,
199                    description=DESCRIPTION,
200                    license=LICENSE,
201                    url=URL,
202                    version=VERSION,
203                    download_url=DOWNLOAD_URL,
204                    long_description=LONG_DESCRIPTION,
205                    install_requires=INSTALL_REQUIRES,
206                    classifiers=[
207                        'Development Status :: 4 - Beta',
208                        'Environment :: Console',
209                        'Intended Audience :: Developers',
210                        'Intended Audience :: Science/Research',
211                        'License :: OSI Approved :: BSD License',
212                        'Topic :: Scientific/Engineering',
213                        'Programming Language :: C',
214                        'Programming Language :: Python',
215                        'Topic :: Software Development',
216                        'Topic :: Scientific/Engineering',
217                        'Operating System :: Microsoft :: Windows',
218                        'Operating System :: POSIX',
219                        'Operating System :: Unix',
220                        'Operating System :: MacOS',
221                    ],
222                    platforms = ['Linux', 'Mac OS-X', 'Windows'],
223                    test_suite='nose.collector',
224                    cmdclass=cmdclass,
225                    **extra_setuptools_args)
226
227    if (len(sys.argv) >= 2
228            and ('--help' in sys.argv[1:] or sys.argv[1]
229                 in ('--help-commands', 'egg_info', '--version', 'clean'))):
230
231        # For these actions, NumPy is not required.
232        #
233        # They are required to succeed without Numpy for example when
234        # pip is used to install Scikit when Numpy is not yet present in
235        # the system.
236        try:
237            from setuptools import setup
238        except ImportError:
239            from distutils.core import setup
240
241        metadata['version'] = VERSION
242    else:
243        from numpy.distutils.core import setup
244
245        metadata['configuration'] = configuration
246
247    setup(**metadata)
248
249if __name__ == '__main__':
250    setup_package()
251