##// END OF EJS Templates
Allow 'python setup.py install' to work correctly for either Python 2 or 3.
Thomas Kluyver -
Show More
@@ -0,0 +1,272 b''
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3 """Setup script for IPython.
4
5 Under Posix environments it works like a typical setup.py script.
6 Under Windows, the command sdist is not supported, since IPython
7 requires utilities which are not available under Windows."""
8
9 #-----------------------------------------------------------------------------
10 # Copyright (c) 2008-2011, IPython Development Team.
11 # Copyright (c) 2001-2007, Fernando Perez <fernando.perez@colorado.edu>
12 # Copyright (c) 2001, Janko Hauser <jhauser@zscout.de>
13 # Copyright (c) 2001, Nathaniel Gray <n8gray@caltech.edu>
14 #
15 # Distributed under the terms of the Modified BSD License.
16 #
17 # The full license is in the file COPYING.txt, distributed with this software.
18 #-----------------------------------------------------------------------------
19
20 #-----------------------------------------------------------------------------
21 # Minimal Python version sanity check
22 #-----------------------------------------------------------------------------
23
24 import sys
25
26 # This check is also made in IPython/__init__, don't forget to update both when
27 # changing Python version requirements.
28 if sys.version[0:3] < '2.6':
29 error = """\
30 ERROR: 'IPython requires Python Version 2.6 or above.'
31 Exiting."""
32 print >> sys.stderr, error
33 sys.exit(1)
34
35 # At least we're on the python version we need, move on.
36
37 #-------------------------------------------------------------------------------
38 # Imports
39 #-------------------------------------------------------------------------------
40
41 # Stdlib imports
42 import os
43 import shutil
44
45 from glob import glob
46
47 # BEFORE importing distutils, remove MANIFEST. distutils doesn't properly
48 # update it when the contents of directories change.
49 if os.path.exists('MANIFEST'): os.remove('MANIFEST')
50
51 from distutils.core import setup
52
53 # Our own imports
54 from IPython.utils.path import target_update
55
56 from setupbase import (
57 setup_args,
58 find_packages,
59 find_package_data,
60 find_scripts,
61 find_data_files,
62 check_for_dependencies,
63 record_commit_info,
64 )
65 from setupext import setupext
66
67 isfile = os.path.isfile
68 pjoin = os.path.join
69
70 #-----------------------------------------------------------------------------
71 # Function definitions
72 #-----------------------------------------------------------------------------
73
74 def cleanup():
75 """Clean up the junk left around by the build process"""
76 if "develop" not in sys.argv:
77 try:
78 shutil.rmtree('ipython.egg-info')
79 except:
80 try:
81 os.unlink('ipython.egg-info')
82 except:
83 pass
84
85 #-------------------------------------------------------------------------------
86 # Handle OS specific things
87 #-------------------------------------------------------------------------------
88
89 if os.name == 'posix':
90 os_name = 'posix'
91 elif os.name in ['nt','dos']:
92 os_name = 'windows'
93 else:
94 print 'Unsupported operating system:',os.name
95 sys.exit(1)
96
97 # Under Windows, 'sdist' has not been supported. Now that the docs build with
98 # Sphinx it might work, but let's not turn it on until someone confirms that it
99 # actually works.
100 if os_name == 'windows' and 'sdist' in sys.argv:
101 print 'The sdist command is not available under Windows. Exiting.'
102 sys.exit(1)
103
104 #-------------------------------------------------------------------------------
105 # Things related to the IPython documentation
106 #-------------------------------------------------------------------------------
107
108 # update the manuals when building a source dist
109 if len(sys.argv) >= 2 and sys.argv[1] in ('sdist','bdist_rpm'):
110 import textwrap
111
112 # List of things to be updated. Each entry is a triplet of args for
113 # target_update()
114 to_update = [
115 # FIXME - Disabled for now: we need to redo an automatic way
116 # of generating the magic info inside the rst.
117 #('docs/magic.tex',
118 #['IPython/Magic.py'],
119 #"cd doc && ./update_magic.sh" ),
120
121 ('docs/man/ipcluster.1.gz',
122 ['docs/man/ipcluster.1'],
123 'cd docs/man && gzip -9c ipcluster.1 > ipcluster.1.gz'),
124
125 ('docs/man/ipcontroller.1.gz',
126 ['docs/man/ipcontroller.1'],
127 'cd docs/man && gzip -9c ipcontroller.1 > ipcontroller.1.gz'),
128
129 ('docs/man/ipengine.1.gz',
130 ['docs/man/ipengine.1'],
131 'cd docs/man && gzip -9c ipengine.1 > ipengine.1.gz'),
132
133 ('docs/man/iplogger.1.gz',
134 ['docs/man/iplogger.1'],
135 'cd docs/man && gzip -9c iplogger.1 > iplogger.1.gz'),
136
137 ('docs/man/ipython.1.gz',
138 ['docs/man/ipython.1'],
139 'cd docs/man && gzip -9c ipython.1 > ipython.1.gz'),
140
141 ('docs/man/irunner.1.gz',
142 ['docs/man/irunner.1'],
143 'cd docs/man && gzip -9c irunner.1 > irunner.1.gz'),
144
145 ('docs/man/pycolor.1.gz',
146 ['docs/man/pycolor.1'],
147 'cd docs/man && gzip -9c pycolor.1 > pycolor.1.gz'),
148 ]
149
150 # Only build the docs if sphinx is present
151 try:
152 import sphinx
153 except ImportError:
154 pass
155 else:
156 # The Makefile calls the do_sphinx scripts to build html and pdf, so
157 # just one target is enough to cover all manual generation
158
159 # First, compute all the dependencies that can force us to rebuild the
160 # docs. Start with the main release file that contains metadata
161 docdeps = ['IPython/core/release.py']
162 # Inculde all the reST sources
163 pjoin = os.path.join
164 for dirpath,dirnames,filenames in os.walk('docs/source'):
165 if dirpath in ['_static','_templates']:
166 continue
167 docdeps += [ pjoin(dirpath,f) for f in filenames
168 if f.endswith('.txt') ]
169 # and the examples
170 for dirpath,dirnames,filenames in os.walk('docs/example'):
171 docdeps += [ pjoin(dirpath,f) for f in filenames
172 if not f.endswith('~') ]
173 # then, make them all dependencies for the main html docs
174 to_update.append(
175 ('docs/dist/index.html',
176 docdeps,
177 "cd docs && make dist")
178 )
179
180 [ target_update(*t) for t in to_update ]
181
182 #---------------------------------------------------------------------------
183 # Find all the packages, package data, and data_files
184 #---------------------------------------------------------------------------
185
186 packages = find_packages()
187 package_data = find_package_data()
188 data_files = find_data_files()
189
190 #---------------------------------------------------------------------------
191 # Handle scripts, dependencies, and setuptools specific things
192 #---------------------------------------------------------------------------
193
194 # For some commands, use setuptools. Note that we do NOT list install here!
195 # If you want a setuptools-enhanced install, just run 'setupegg.py install'
196 needs_setuptools = set(('develop', 'sdist', 'release', 'bdist_egg', 'bdist_rpm',
197 'bdist', 'bdist_dumb', 'bdist_wininst', 'install_egg_info',
198 'build_sphinx', 'egg_info', 'easy_install', 'upload',
199 ))
200 if sys.platform == 'win32':
201 # Depend on setuptools for install on *Windows only*
202 # If we get script-installation working without setuptools,
203 # then we can back off, but until then use it.
204 # See Issue #369 on GitHub for more
205 needs_setuptools.add('install')
206
207 if len(needs_setuptools.intersection(sys.argv)) > 0:
208 import setuptools
209
210 # This dict is used for passing extra arguments that are setuptools
211 # specific to setup
212 setuptools_extra_args = {}
213
214 if 'setuptools' in sys.modules:
215 setuptools_extra_args['zip_safe'] = False
216 setuptools_extra_args['entry_points'] = find_scripts(True)
217 setup_args['extras_require'] = dict(
218 parallel = 'pyzmq>=2.1.4',
219 zmq = 'pyzmq>=2.1.4',
220 doc = 'Sphinx>=0.3',
221 test = 'nose>=0.10.1',
222 notebook = 'tornado>=2.0'
223 )
224 requires = setup_args.setdefault('install_requires', [])
225 setupext.display_status = False
226 if not setupext.check_for_readline():
227 if sys.platform == 'darwin':
228 requires.append('readline')
229 elif sys.platform.startswith('win') and sys.maxsize < 2**32:
230 # only require pyreadline on 32b Windows, due to 64b bug in pyreadline:
231 # https://bugs.launchpad.net/pyreadline/+bug/787574
232 requires.append('pyreadline')
233 else:
234 pass
235 # do we want to install readline here?
236
237 # Script to be run by the windows binary installer after the default setup
238 # routine, to add shortcuts and similar windows-only things. Windows
239 # post-install scripts MUST reside in the scripts/ dir, otherwise distutils
240 # doesn't find them.
241 if 'bdist_wininst' in sys.argv:
242 if len(sys.argv) > 2 and \
243 ('sdist' in sys.argv or 'bdist_rpm' in sys.argv):
244 print >> sys.stderr, "ERROR: bdist_wininst must be run alone. Exiting."
245 sys.exit(1)
246 setup_args['scripts'] = [pjoin('scripts','ipython_win_post_install.py')]
247 setup_args['options'] = {"bdist_wininst":
248 {"install_script":
249 "ipython_win_post_install.py"}}
250 else:
251 # If we are running without setuptools, call this function which will
252 # check for dependencies an inform the user what is needed. This is
253 # just to make life easy for users.
254 check_for_dependencies()
255 setup_args['scripts'] = find_scripts(False)
256
257 #---------------------------------------------------------------------------
258 # Do the actual setup now
259 #---------------------------------------------------------------------------
260
261 setup_args['cmdclass'] = {'build_py': record_commit_info('IPython')}
262 setup_args['packages'] = packages
263 setup_args['package_data'] = package_data
264 setup_args['data_files'] = data_files
265 setup_args.update(setuptools_extra_args)
266
267 def main():
268 setup(**setup_args)
269 cleanup()
270
271 if __name__ == '__main__':
272 main()
@@ -1,270 +1,10 b''
1 #!/usr/bin/env python
1 """This calls the setup routine for Python 2 or 3 as required."""
2 # -*- coding: utf-8 -*-
3 """Setup script for IPython.
4
5 Under Posix environments it works like a typical setup.py script.
6 Under Windows, the command sdist is not supported, since IPython
7 requires utilities which are not available under Windows."""
8
9 #-----------------------------------------------------------------------------
10 # Copyright (c) 2008-2011, IPython Development Team.
11 # Copyright (c) 2001-2007, Fernando Perez <fernando.perez@colorado.edu>
12 # Copyright (c) 2001, Janko Hauser <jhauser@zscout.de>
13 # Copyright (c) 2001, Nathaniel Gray <n8gray@caltech.edu>
14 #
15 # Distributed under the terms of the Modified BSD License.
16 #
17 # The full license is in the file COPYING.txt, distributed with this software.
18 #-----------------------------------------------------------------------------
19
20 #-----------------------------------------------------------------------------
21 # Minimal Python version sanity check
22 #-----------------------------------------------------------------------------
23
2
24 import sys
3 import sys
25
4
26 # This check is also made in IPython/__init__, don't forget to update both when
5 if sys.version_info[0] >= 3:
27 # changing Python version requirements.
6 from setup3 import main
28 if sys.version[0:3] < '2.6':
29 error = """\
30 ERROR: 'IPython requires Python Version 2.6 or above.'
31 Exiting."""
32 print >> sys.stderr, error
33 sys.exit(1)
34
35 # At least we're on the python version we need, move on.
36
37 #-------------------------------------------------------------------------------
38 # Imports
39 #-------------------------------------------------------------------------------
40
41 # Stdlib imports
42 import os
43 import shutil
44
45 from glob import glob
46
47 # BEFORE importing distutils, remove MANIFEST. distutils doesn't properly
48 # update it when the contents of directories change.
49 if os.path.exists('MANIFEST'): os.remove('MANIFEST')
50
51 from distutils.core import setup
52
53 # Our own imports
54 from IPython.utils.path import target_update
55
56 from setupbase import (
57 setup_args,
58 find_packages,
59 find_package_data,
60 find_scripts,
61 find_data_files,
62 check_for_dependencies,
63 record_commit_info,
64 )
65 from setupext import setupext
66
67 isfile = os.path.isfile
68 pjoin = os.path.join
69
70 #-----------------------------------------------------------------------------
71 # Function definitions
72 #-----------------------------------------------------------------------------
73
74 def cleanup():
75 """Clean up the junk left around by the build process"""
76 if "develop" not in sys.argv:
77 try:
78 shutil.rmtree('ipython.egg-info')
79 except:
80 try:
81 os.unlink('ipython.egg-info')
82 except:
83 pass
84
85 #-------------------------------------------------------------------------------
86 # Handle OS specific things
87 #-------------------------------------------------------------------------------
88
89 if os.name == 'posix':
90 os_name = 'posix'
91 elif os.name in ['nt','dos']:
92 os_name = 'windows'
93 else:
94 print 'Unsupported operating system:',os.name
95 sys.exit(1)
96
97 # Under Windows, 'sdist' has not been supported. Now that the docs build with
98 # Sphinx it might work, but let's not turn it on until someone confirms that it
99 # actually works.
100 if os_name == 'windows' and 'sdist' in sys.argv:
101 print 'The sdist command is not available under Windows. Exiting.'
102 sys.exit(1)
103
104 #-------------------------------------------------------------------------------
105 # Things related to the IPython documentation
106 #-------------------------------------------------------------------------------
107
108 # update the manuals when building a source dist
109 if len(sys.argv) >= 2 and sys.argv[1] in ('sdist','bdist_rpm'):
110 import textwrap
111
112 # List of things to be updated. Each entry is a triplet of args for
113 # target_update()
114 to_update = [
115 # FIXME - Disabled for now: we need to redo an automatic way
116 # of generating the magic info inside the rst.
117 #('docs/magic.tex',
118 #['IPython/Magic.py'],
119 #"cd doc && ./update_magic.sh" ),
120
121 ('docs/man/ipcluster.1.gz',
122 ['docs/man/ipcluster.1'],
123 'cd docs/man && gzip -9c ipcluster.1 > ipcluster.1.gz'),
124
125 ('docs/man/ipcontroller.1.gz',
126 ['docs/man/ipcontroller.1'],
127 'cd docs/man && gzip -9c ipcontroller.1 > ipcontroller.1.gz'),
128
129 ('docs/man/ipengine.1.gz',
130 ['docs/man/ipengine.1'],
131 'cd docs/man && gzip -9c ipengine.1 > ipengine.1.gz'),
132
133 ('docs/man/iplogger.1.gz',
134 ['docs/man/iplogger.1'],
135 'cd docs/man && gzip -9c iplogger.1 > iplogger.1.gz'),
136
137 ('docs/man/ipython.1.gz',
138 ['docs/man/ipython.1'],
139 'cd docs/man && gzip -9c ipython.1 > ipython.1.gz'),
140
141 ('docs/man/irunner.1.gz',
142 ['docs/man/irunner.1'],
143 'cd docs/man && gzip -9c irunner.1 > irunner.1.gz'),
144
145 ('docs/man/pycolor.1.gz',
146 ['docs/man/pycolor.1'],
147 'cd docs/man && gzip -9c pycolor.1 > pycolor.1.gz'),
148 ]
149
150 # Only build the docs if sphinx is present
151 try:
152 import sphinx
153 except ImportError:
154 pass
155 else:
156 # The Makefile calls the do_sphinx scripts to build html and pdf, so
157 # just one target is enough to cover all manual generation
158
159 # First, compute all the dependencies that can force us to rebuild the
160 # docs. Start with the main release file that contains metadata
161 docdeps = ['IPython/core/release.py']
162 # Inculde all the reST sources
163 pjoin = os.path.join
164 for dirpath,dirnames,filenames in os.walk('docs/source'):
165 if dirpath in ['_static','_templates']:
166 continue
167 docdeps += [ pjoin(dirpath,f) for f in filenames
168 if f.endswith('.txt') ]
169 # and the examples
170 for dirpath,dirnames,filenames in os.walk('docs/example'):
171 docdeps += [ pjoin(dirpath,f) for f in filenames
172 if not f.endswith('~') ]
173 # then, make them all dependencies for the main html docs
174 to_update.append(
175 ('docs/dist/index.html',
176 docdeps,
177 "cd docs && make dist")
178 )
179
180 [ target_update(*t) for t in to_update ]
181
182 #---------------------------------------------------------------------------
183 # Find all the packages, package data, and data_files
184 #---------------------------------------------------------------------------
185
186 packages = find_packages()
187 package_data = find_package_data()
188 data_files = find_data_files()
189
190 #---------------------------------------------------------------------------
191 # Handle scripts, dependencies, and setuptools specific things
192 #---------------------------------------------------------------------------
193
194 # For some commands, use setuptools. Note that we do NOT list install here!
195 # If you want a setuptools-enhanced install, just run 'setupegg.py install'
196 needs_setuptools = set(('develop', 'sdist', 'release', 'bdist_egg', 'bdist_rpm',
197 'bdist', 'bdist_dumb', 'bdist_wininst', 'install_egg_info',
198 'build_sphinx', 'egg_info', 'easy_install', 'upload',
199 ))
200 if sys.platform == 'win32':
201 # Depend on setuptools for install on *Windows only*
202 # If we get script-installation working without setuptools,
203 # then we can back off, but until then use it.
204 # See Issue #369 on GitHub for more
205 needs_setuptools.add('install')
206
207 if len(needs_setuptools.intersection(sys.argv)) > 0:
208 import setuptools
209
210 # This dict is used for passing extra arguments that are setuptools
211 # specific to setup
212 setuptools_extra_args = {}
213
214 if 'setuptools' in sys.modules:
215 setuptools_extra_args['zip_safe'] = False
216 setuptools_extra_args['entry_points'] = find_scripts(True)
217 setup_args['extras_require'] = dict(
218 parallel = 'pyzmq>=2.1.4',
219 zmq = 'pyzmq>=2.1.4',
220 doc = 'Sphinx>=0.3',
221 test = 'nose>=0.10.1',
222 notebook = 'tornado>=2.0'
223 )
224 requires = setup_args.setdefault('install_requires', [])
225 setupext.display_status = False
226 if not setupext.check_for_readline():
227 if sys.platform == 'darwin':
228 requires.append('readline')
229 elif sys.platform.startswith('win') and sys.maxsize < 2**32:
230 # only require pyreadline on 32b Windows, due to 64b bug in pyreadline:
231 # https://bugs.launchpad.net/pyreadline/+bug/787574
232 requires.append('pyreadline')
233 else:
7 else:
234 pass
8 from setup2 import main
235 # do we want to install readline here?
236
237 # Script to be run by the windows binary installer after the default setup
238 # routine, to add shortcuts and similar windows-only things. Windows
239 # post-install scripts MUST reside in the scripts/ dir, otherwise distutils
240 # doesn't find them.
241 if 'bdist_wininst' in sys.argv:
242 if len(sys.argv) > 2 and \
243 ('sdist' in sys.argv or 'bdist_rpm' in sys.argv):
244 print >> sys.stderr, "ERROR: bdist_wininst must be run alone. Exiting."
245 sys.exit(1)
246 setup_args['scripts'] = [pjoin('scripts','ipython_win_post_install.py')]
247 setup_args['options'] = {"bdist_wininst":
248 {"install_script":
249 "ipython_win_post_install.py"}}
250 else:
251 # If we are running without setuptools, call this function which will
252 # check for dependencies an inform the user what is needed. This is
253 # just to make life easy for users.
254 check_for_dependencies()
255 setup_args['scripts'] = find_scripts(False)
256
257 #---------------------------------------------------------------------------
258 # Do the actual setup now
259 #---------------------------------------------------------------------------
260
261 setup_args['cmdclass'] = {'build_py': record_commit_info('IPython')}
262 setup_args['packages'] = packages
263 setup_args['package_data'] = package_data
264 setup_args['data_files'] = data_files
265 setup_args.update(setuptools_extra_args)
266
267
9
268 if __name__ == '__main__':
10 main()
269 setup(**setup_args)
270 cleanup()
@@ -1,9 +1,13 b''
1 import os.path
1 import os.path
2 from setuptools import setup
2 from setuptools import setup
3
3
4 from setupbase import (setup_args, find_scripts, find_packages)
4 from setupbase import (setup_args, find_scripts, find_packages)
5
5
6 setup_args['entry_points'] = find_scripts(True)
6 setup_args['entry_points'] = find_scripts(True, suffix='3')
7 setup_args['packages'] = find_packages()
7 setup_args['packages'] = find_packages()
8
8
9 def main():
9 setup(use_2to3 = True, **setup_args)
10 setup(use_2to3 = True, **setup_args)
11
12 if __name__ == "__main__":
13 main()
@@ -1,373 +1,376 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """
2 """
3 This module defines the things that are used in setup.py for building IPython
3 This module defines the things that are used in setup.py for building IPython
4
4
5 This includes:
5 This includes:
6
6
7 * The basic arguments to setup
7 * The basic arguments to setup
8 * Functions for finding things like packages, package data, etc.
8 * Functions for finding things like packages, package data, etc.
9 * A function for checking dependencies.
9 * A function for checking dependencies.
10 """
10 """
11 from __future__ import print_function
11 from __future__ import print_function
12
12
13 #-------------------------------------------------------------------------------
13 #-------------------------------------------------------------------------------
14 # Copyright (C) 2008 The IPython Development Team
14 # Copyright (C) 2008 The IPython Development Team
15 #
15 #
16 # Distributed under the terms of the BSD License. The full license is in
16 # Distributed under the terms of the BSD License. The full license is in
17 # the file COPYING, distributed as part of this software.
17 # the file COPYING, distributed as part of this software.
18 #-------------------------------------------------------------------------------
18 #-------------------------------------------------------------------------------
19
19
20 #-------------------------------------------------------------------------------
20 #-------------------------------------------------------------------------------
21 # Imports
21 # Imports
22 #-------------------------------------------------------------------------------
22 #-------------------------------------------------------------------------------
23 import os
23 import os
24 import sys
24 import sys
25
25
26 try:
26 try:
27 from configparser import ConfigParser
27 from configparser import ConfigParser
28 except:
28 except:
29 from ConfigParser import ConfigParser
29 from ConfigParser import ConfigParser
30 from distutils.command.build_py import build_py
30 from distutils.command.build_py import build_py
31 from glob import glob
31 from glob import glob
32
32
33 from setupext import install_data_ext
33 from setupext import install_data_ext
34
34
35 #-------------------------------------------------------------------------------
35 #-------------------------------------------------------------------------------
36 # Useful globals and utility functions
36 # Useful globals and utility functions
37 #-------------------------------------------------------------------------------
37 #-------------------------------------------------------------------------------
38
38
39 # A few handy globals
39 # A few handy globals
40 isfile = os.path.isfile
40 isfile = os.path.isfile
41 pjoin = os.path.join
41 pjoin = os.path.join
42
42
43 def oscmd(s):
43 def oscmd(s):
44 print(">", s)
44 print(">", s)
45 os.system(s)
45 os.system(s)
46
46
47 try:
47 try:
48 execfile
48 execfile
49 except NameError:
49 except NameError:
50 def execfile(fname, globs, locs=None):
50 def execfile(fname, globs, locs=None):
51 locs = locs or globs
51 locs = locs or globs
52 exec(compile(open(fname).read(), fname, "exec"), globs, locs)
52 exec(compile(open(fname).read(), fname, "exec"), globs, locs)
53
53
54 # A little utility we'll need below, since glob() does NOT allow you to do
54 # A little utility we'll need below, since glob() does NOT allow you to do
55 # exclusion on multiple endings!
55 # exclusion on multiple endings!
56 def file_doesnt_endwith(test,endings):
56 def file_doesnt_endwith(test,endings):
57 """Return true if test is a file and its name does NOT end with any
57 """Return true if test is a file and its name does NOT end with any
58 of the strings listed in endings."""
58 of the strings listed in endings."""
59 if not isfile(test):
59 if not isfile(test):
60 return False
60 return False
61 for e in endings:
61 for e in endings:
62 if test.endswith(e):
62 if test.endswith(e):
63 return False
63 return False
64 return True
64 return True
65
65
66 #---------------------------------------------------------------------------
66 #---------------------------------------------------------------------------
67 # Basic project information
67 # Basic project information
68 #---------------------------------------------------------------------------
68 #---------------------------------------------------------------------------
69
69
70 # release.py contains version, authors, license, url, keywords, etc.
70 # release.py contains version, authors, license, url, keywords, etc.
71 execfile(pjoin('IPython','core','release.py'), globals())
71 execfile(pjoin('IPython','core','release.py'), globals())
72
72
73 # Create a dict with the basic information
73 # Create a dict with the basic information
74 # This dict is eventually passed to setup after additional keys are added.
74 # This dict is eventually passed to setup after additional keys are added.
75 setup_args = dict(
75 setup_args = dict(
76 name = name,
76 name = name,
77 version = version,
77 version = version,
78 description = description,
78 description = description,
79 long_description = long_description,
79 long_description = long_description,
80 author = author,
80 author = author,
81 author_email = author_email,
81 author_email = author_email,
82 url = url,
82 url = url,
83 download_url = download_url,
83 download_url = download_url,
84 license = license,
84 license = license,
85 platforms = platforms,
85 platforms = platforms,
86 keywords = keywords,
86 keywords = keywords,
87 cmdclass = {'install_data': install_data_ext},
87 cmdclass = {'install_data': install_data_ext},
88 )
88 )
89
89
90
90
91 #---------------------------------------------------------------------------
91 #---------------------------------------------------------------------------
92 # Find packages
92 # Find packages
93 #---------------------------------------------------------------------------
93 #---------------------------------------------------------------------------
94
94
95 def find_packages():
95 def find_packages():
96 """
96 """
97 Find all of IPython's packages.
97 Find all of IPython's packages.
98 """
98 """
99 excludes = ['deathrow']
99 excludes = ['deathrow']
100 packages = []
100 packages = []
101 for dir,subdirs,files in os.walk('IPython'):
101 for dir,subdirs,files in os.walk('IPython'):
102 package = dir.replace(os.path.sep, '.')
102 package = dir.replace(os.path.sep, '.')
103 if any([ package.startswith('IPython.'+exc) for exc in excludes ]):
103 if any([ package.startswith('IPython.'+exc) for exc in excludes ]):
104 # package is to be excluded (e.g. deathrow)
104 # package is to be excluded (e.g. deathrow)
105 continue
105 continue
106 if '__init__.py' not in files:
106 if '__init__.py' not in files:
107 # not a package
107 # not a package
108 continue
108 continue
109 packages.append(package)
109 packages.append(package)
110 return packages
110 return packages
111
111
112 #---------------------------------------------------------------------------
112 #---------------------------------------------------------------------------
113 # Find package data
113 # Find package data
114 #---------------------------------------------------------------------------
114 #---------------------------------------------------------------------------
115
115
116 def find_package_data():
116 def find_package_data():
117 """
117 """
118 Find IPython's package_data.
118 Find IPython's package_data.
119 """
119 """
120 # This is not enough for these things to appear in an sdist.
120 # This is not enough for these things to appear in an sdist.
121 # We need to muck with the MANIFEST to get this to work
121 # We need to muck with the MANIFEST to get this to work
122
122
123 # walk notebook resources:
123 # walk notebook resources:
124 cwd = os.getcwd()
124 cwd = os.getcwd()
125 os.chdir(os.path.join('IPython', 'frontend', 'html', 'notebook'))
125 os.chdir(os.path.join('IPython', 'frontend', 'html', 'notebook'))
126 static_walk = list(os.walk('static'))
126 static_walk = list(os.walk('static'))
127 os.chdir(cwd)
127 os.chdir(cwd)
128 static_data = []
128 static_data = []
129 for parent, dirs, files in static_walk:
129 for parent, dirs, files in static_walk:
130 for f in files:
130 for f in files:
131 static_data.append(os.path.join(parent, f))
131 static_data.append(os.path.join(parent, f))
132
132
133 package_data = {
133 package_data = {
134 'IPython.config.profile' : ['README', '*/*.py'],
134 'IPython.config.profile' : ['README', '*/*.py'],
135 'IPython.testing' : ['*.txt'],
135 'IPython.testing' : ['*.txt'],
136 'IPython.frontend.html.notebook' : ['templates/*']+static_data
136 'IPython.frontend.html.notebook' : ['templates/*']+static_data
137 }
137 }
138 return package_data
138 return package_data
139
139
140
140
141 #---------------------------------------------------------------------------
141 #---------------------------------------------------------------------------
142 # Find data files
142 # Find data files
143 #---------------------------------------------------------------------------
143 #---------------------------------------------------------------------------
144
144
145 def make_dir_struct(tag,base,out_base):
145 def make_dir_struct(tag,base,out_base):
146 """Make the directory structure of all files below a starting dir.
146 """Make the directory structure of all files below a starting dir.
147
147
148 This is just a convenience routine to help build a nested directory
148 This is just a convenience routine to help build a nested directory
149 hierarchy because distutils is too stupid to do this by itself.
149 hierarchy because distutils is too stupid to do this by itself.
150
150
151 XXX - this needs a proper docstring!
151 XXX - this needs a proper docstring!
152 """
152 """
153
153
154 # we'll use these a lot below
154 # we'll use these a lot below
155 lbase = len(base)
155 lbase = len(base)
156 pathsep = os.path.sep
156 pathsep = os.path.sep
157 lpathsep = len(pathsep)
157 lpathsep = len(pathsep)
158
158
159 out = []
159 out = []
160 for (dirpath,dirnames,filenames) in os.walk(base):
160 for (dirpath,dirnames,filenames) in os.walk(base):
161 # we need to strip out the dirpath from the base to map it to the
161 # we need to strip out the dirpath from the base to map it to the
162 # output (installation) path. This requires possibly stripping the
162 # output (installation) path. This requires possibly stripping the
163 # path separator, because otherwise pjoin will not work correctly
163 # path separator, because otherwise pjoin will not work correctly
164 # (pjoin('foo/','/bar') returns '/bar').
164 # (pjoin('foo/','/bar') returns '/bar').
165
165
166 dp_eff = dirpath[lbase:]
166 dp_eff = dirpath[lbase:]
167 if dp_eff.startswith(pathsep):
167 if dp_eff.startswith(pathsep):
168 dp_eff = dp_eff[lpathsep:]
168 dp_eff = dp_eff[lpathsep:]
169 # The output path must be anchored at the out_base marker
169 # The output path must be anchored at the out_base marker
170 out_path = pjoin(out_base,dp_eff)
170 out_path = pjoin(out_base,dp_eff)
171 # Now we can generate the final filenames. Since os.walk only produces
171 # Now we can generate the final filenames. Since os.walk only produces
172 # filenames, we must join back with the dirpath to get full valid file
172 # filenames, we must join back with the dirpath to get full valid file
173 # paths:
173 # paths:
174 pfiles = [pjoin(dirpath,f) for f in filenames]
174 pfiles = [pjoin(dirpath,f) for f in filenames]
175 # Finally, generate the entry we need, which is a pari of (output
175 # Finally, generate the entry we need, which is a pari of (output
176 # path, files) for use as a data_files parameter in install_data.
176 # path, files) for use as a data_files parameter in install_data.
177 out.append((out_path, pfiles))
177 out.append((out_path, pfiles))
178
178
179 return out
179 return out
180
180
181
181
182 def find_data_files():
182 def find_data_files():
183 """
183 """
184 Find IPython's data_files.
184 Find IPython's data_files.
185
185
186 Most of these are docs.
186 Most of these are docs.
187 """
187 """
188
188
189 docdirbase = pjoin('share', 'doc', 'ipython')
189 docdirbase = pjoin('share', 'doc', 'ipython')
190 manpagebase = pjoin('share', 'man', 'man1')
190 manpagebase = pjoin('share', 'man', 'man1')
191
191
192 # Simple file lists can be made by hand
192 # Simple file lists can be made by hand
193 manpages = filter(isfile, glob(pjoin('docs','man','*.1.gz')))
193 manpages = filter(isfile, glob(pjoin('docs','man','*.1.gz')))
194 if not manpages:
194 if not manpages:
195 # When running from a source tree, the manpages aren't gzipped
195 # When running from a source tree, the manpages aren't gzipped
196 manpages = filter(isfile, glob(pjoin('docs','man','*.1')))
196 manpages = filter(isfile, glob(pjoin('docs','man','*.1')))
197 igridhelpfiles = filter(isfile,
197 igridhelpfiles = filter(isfile,
198 glob(pjoin('IPython','extensions','igrid_help.*')))
198 glob(pjoin('IPython','extensions','igrid_help.*')))
199
199
200 # For nested structures, use the utility above
200 # For nested structures, use the utility above
201 example_files = make_dir_struct(
201 example_files = make_dir_struct(
202 'data',
202 'data',
203 pjoin('docs','examples'),
203 pjoin('docs','examples'),
204 pjoin(docdirbase,'examples')
204 pjoin(docdirbase,'examples')
205 )
205 )
206 manual_files = make_dir_struct(
206 manual_files = make_dir_struct(
207 'data',
207 'data',
208 pjoin('docs','html'),
208 pjoin('docs','html'),
209 pjoin(docdirbase,'manual')
209 pjoin(docdirbase,'manual')
210 )
210 )
211
211
212 # And assemble the entire output list
212 # And assemble the entire output list
213 data_files = [ (manpagebase, manpages),
213 data_files = [ (manpagebase, manpages),
214 (pjoin(docdirbase, 'extensions'), igridhelpfiles),
214 (pjoin(docdirbase, 'extensions'), igridhelpfiles),
215 ] + manual_files + example_files
215 ] + manual_files + example_files
216
216
217 return data_files
217 return data_files
218
218
219
219
220 def make_man_update_target(manpage):
220 def make_man_update_target(manpage):
221 """Return a target_update-compliant tuple for the given manpage.
221 """Return a target_update-compliant tuple for the given manpage.
222
222
223 Parameters
223 Parameters
224 ----------
224 ----------
225 manpage : string
225 manpage : string
226 Name of the manpage, must include the section number (trailing number).
226 Name of the manpage, must include the section number (trailing number).
227
227
228 Example
228 Example
229 -------
229 -------
230
230
231 >>> make_man_update_target('ipython.1') #doctest: +NORMALIZE_WHITESPACE
231 >>> make_man_update_target('ipython.1') #doctest: +NORMALIZE_WHITESPACE
232 ('docs/man/ipython.1.gz',
232 ('docs/man/ipython.1.gz',
233 ['docs/man/ipython.1'],
233 ['docs/man/ipython.1'],
234 'cd docs/man && gzip -9c ipython.1 > ipython.1.gz')
234 'cd docs/man && gzip -9c ipython.1 > ipython.1.gz')
235 """
235 """
236 man_dir = pjoin('docs', 'man')
236 man_dir = pjoin('docs', 'man')
237 manpage_gz = manpage + '.gz'
237 manpage_gz = manpage + '.gz'
238 manpath = pjoin(man_dir, manpage)
238 manpath = pjoin(man_dir, manpage)
239 manpath_gz = pjoin(man_dir, manpage_gz)
239 manpath_gz = pjoin(man_dir, manpage_gz)
240 gz_cmd = ( "cd %(man_dir)s && gzip -9c %(manpage)s > %(manpage_gz)s" %
240 gz_cmd = ( "cd %(man_dir)s && gzip -9c %(manpage)s > %(manpage_gz)s" %
241 locals() )
241 locals() )
242 return (manpath_gz, [manpath], gz_cmd)
242 return (manpath_gz, [manpath], gz_cmd)
243
243
244 #---------------------------------------------------------------------------
244 #---------------------------------------------------------------------------
245 # Find scripts
245 # Find scripts
246 #---------------------------------------------------------------------------
246 #---------------------------------------------------------------------------
247
247
248 def find_scripts(entry_points=False):
248 def find_scripts(entry_points=False, suffix=''):
249 """Find IPython's scripts.
249 """Find IPython's scripts.
250
250
251 if entry_points is True:
251 if entry_points is True:
252 return setuptools entry_point-style definitions
252 return setuptools entry_point-style definitions
253 else:
253 else:
254 return file paths of plain scripts [default]
254 return file paths of plain scripts [default]
255
256 suffix is appended to script names if entry_points is True, so that the
257 Python 3 scripts get named "ipython3" etc.
255 """
258 """
256 if entry_points:
259 if entry_points:
257 console_scripts = [
260 console_scripts = [s % suffix for s in [
258 'ipython = IPython.frontend.terminal.ipapp:launch_new_instance',
261 'ipython%s = IPython.frontend.terminal.ipapp:launch_new_instance',
259 'pycolor = IPython.utils.PyColorize:main',
262 'pycolor%s = IPython.utils.PyColorize:main',
260 'ipcontroller = IPython.parallel.apps.ipcontrollerapp:launch_new_instance',
263 'ipcontroller%s = IPython.parallel.apps.ipcontrollerapp:launch_new_instance',
261 'ipengine = IPython.parallel.apps.ipengineapp:launch_new_instance',
264 'ipengine%s = IPython.parallel.apps.ipengineapp:launch_new_instance',
262 'iplogger = IPython.parallel.apps.iploggerapp:launch_new_instance',
265 'iplogger%s = IPython.parallel.apps.iploggerapp:launch_new_instance',
263 'ipcluster = IPython.parallel.apps.ipclusterapp:launch_new_instance',
266 'ipcluster%s = IPython.parallel.apps.ipclusterapp:launch_new_instance',
264 'iptest = IPython.testing.iptest:main',
267 'iptest%s = IPython.testing.iptest:main',
265 'irunner = IPython.lib.irunner:main'
268 'irunner%s = IPython.lib.irunner:main'
266 ]
269 ]]
267 gui_scripts = [
270 gui_scripts = [s % suffix for s in [
268 'ipython-qtconsole = IPython.frontend.qt.console.qtconsoleapp:main',
271 'ipython%s-qtconsole = IPython.frontend.qt.console.qtconsoleapp:main',
269 ]
272 ]]
270 scripts = dict(console_scripts=console_scripts, gui_scripts=gui_scripts)
273 scripts = dict(console_scripts=console_scripts, gui_scripts=gui_scripts)
271 else:
274 else:
272 parallel_scripts = pjoin('IPython','parallel','scripts')
275 parallel_scripts = pjoin('IPython','parallel','scripts')
273 main_scripts = pjoin('IPython','scripts')
276 main_scripts = pjoin('IPython','scripts')
274 scripts = [
277 scripts = [
275 pjoin(parallel_scripts, 'ipengine'),
278 pjoin(parallel_scripts, 'ipengine'),
276 pjoin(parallel_scripts, 'ipcontroller'),
279 pjoin(parallel_scripts, 'ipcontroller'),
277 pjoin(parallel_scripts, 'ipcluster'),
280 pjoin(parallel_scripts, 'ipcluster'),
278 pjoin(parallel_scripts, 'iplogger'),
281 pjoin(parallel_scripts, 'iplogger'),
279 pjoin(main_scripts, 'ipython'),
282 pjoin(main_scripts, 'ipython'),
280 pjoin(main_scripts, 'pycolor'),
283 pjoin(main_scripts, 'pycolor'),
281 pjoin(main_scripts, 'irunner'),
284 pjoin(main_scripts, 'irunner'),
282 pjoin(main_scripts, 'iptest')
285 pjoin(main_scripts, 'iptest')
283 ]
286 ]
284 return scripts
287 return scripts
285
288
286 #---------------------------------------------------------------------------
289 #---------------------------------------------------------------------------
287 # Verify all dependencies
290 # Verify all dependencies
288 #---------------------------------------------------------------------------
291 #---------------------------------------------------------------------------
289
292
290 def check_for_dependencies():
293 def check_for_dependencies():
291 """Check for IPython's dependencies.
294 """Check for IPython's dependencies.
292
295
293 This function should NOT be called if running under setuptools!
296 This function should NOT be called if running under setuptools!
294 """
297 """
295 from setupext.setupext import (
298 from setupext.setupext import (
296 print_line, print_raw, print_status,
299 print_line, print_raw, print_status,
297 check_for_sphinx, check_for_pygments,
300 check_for_sphinx, check_for_pygments,
298 check_for_nose, check_for_pexpect,
301 check_for_nose, check_for_pexpect,
299 check_for_pyzmq, check_for_readline
302 check_for_pyzmq, check_for_readline
300 )
303 )
301 print_line()
304 print_line()
302 print_raw("BUILDING IPYTHON")
305 print_raw("BUILDING IPYTHON")
303 print_status('python', sys.version)
306 print_status('python', sys.version)
304 print_status('platform', sys.platform)
307 print_status('platform', sys.platform)
305 if sys.platform == 'win32':
308 if sys.platform == 'win32':
306 print_status('Windows version', sys.getwindowsversion())
309 print_status('Windows version', sys.getwindowsversion())
307
310
308 print_raw("")
311 print_raw("")
309 print_raw("OPTIONAL DEPENDENCIES")
312 print_raw("OPTIONAL DEPENDENCIES")
310
313
311 check_for_sphinx()
314 check_for_sphinx()
312 check_for_pygments()
315 check_for_pygments()
313 check_for_nose()
316 check_for_nose()
314 check_for_pexpect()
317 check_for_pexpect()
315 check_for_pyzmq()
318 check_for_pyzmq()
316 check_for_readline()
319 check_for_readline()
317
320
318 def record_commit_info(pkg_dir, build_cmd=build_py):
321 def record_commit_info(pkg_dir, build_cmd=build_py):
319 """ Return extended build command class for recording commit
322 """ Return extended build command class for recording commit
320
323
321 The extended command tries to run git to find the current commit, getting
324 The extended command tries to run git to find the current commit, getting
322 the empty string if it fails. It then writes the commit hash into a file
325 the empty string if it fails. It then writes the commit hash into a file
323 in the `pkg_dir` path, named ``.git_commit_info.ini``.
326 in the `pkg_dir` path, named ``.git_commit_info.ini``.
324
327
325 In due course this information can be used by the package after it is
328 In due course this information can be used by the package after it is
326 installed, to tell you what commit it was installed from if known.
329 installed, to tell you what commit it was installed from if known.
327
330
328 To make use of this system, you need a package with a .git_commit_info.ini
331 To make use of this system, you need a package with a .git_commit_info.ini
329 file - e.g. ``myproject/.git_commit_info.ini`` - that might well look like
332 file - e.g. ``myproject/.git_commit_info.ini`` - that might well look like
330 this::
333 this::
331
334
332 # This is an ini file that may contain information about the code state
335 # This is an ini file that may contain information about the code state
333 [commit hash]
336 [commit hash]
334 # The line below may contain a valid hash if it has been substituted
337 # The line below may contain a valid hash if it has been substituted
335 # during 'git archive'
338 # during 'git archive'
336 archive_subst_hash=$Format:%h$
339 archive_subst_hash=$Format:%h$
337 # This line may be modified by the install process
340 # This line may be modified by the install process
338 install_hash=
341 install_hash=
339
342
340 The .git_commit_info file above is also designed to be used with git
343 The .git_commit_info file above is also designed to be used with git
341 substitution - so you probably also want a ``.gitattributes`` file in the
344 substitution - so you probably also want a ``.gitattributes`` file in the
342 root directory of your working tree that contains something like this::
345 root directory of your working tree that contains something like this::
343
346
344 myproject/.git_commit_info.ini export-subst
347 myproject/.git_commit_info.ini export-subst
345
348
346 That will cause the ``.git_commit_info.ini`` file to get filled in by ``git
349 That will cause the ``.git_commit_info.ini`` file to get filled in by ``git
347 archive`` - useful in case someone makes such an archive - for example with
350 archive`` - useful in case someone makes such an archive - for example with
348 via the github 'download source' button.
351 via the github 'download source' button.
349
352
350 Although all the above will work as is, you might consider having something
353 Although all the above will work as is, you might consider having something
351 like a ``get_info()`` function in your package to display the commit
354 like a ``get_info()`` function in your package to display the commit
352 information at the terminal. See the ``pkg_info.py`` module in the nipy
355 information at the terminal. See the ``pkg_info.py`` module in the nipy
353 package for an example.
356 package for an example.
354 """
357 """
355 class MyBuildPy(build_cmd):
358 class MyBuildPy(build_cmd):
356 ''' Subclass to write commit data into installation tree '''
359 ''' Subclass to write commit data into installation tree '''
357 def run(self):
360 def run(self):
358 build_py.run(self)
361 build_py.run(self)
359 import subprocess
362 import subprocess
360 proc = subprocess.Popen('git rev-parse --short HEAD',
363 proc = subprocess.Popen('git rev-parse --short HEAD',
361 stdout=subprocess.PIPE,
364 stdout=subprocess.PIPE,
362 stderr=subprocess.PIPE,
365 stderr=subprocess.PIPE,
363 shell=True)
366 shell=True)
364 repo_commit, _ = proc.communicate()
367 repo_commit, _ = proc.communicate()
365 # We write the installation commit even if it's empty
368 # We write the installation commit even if it's empty
366 cfg_parser = ConfigParser()
369 cfg_parser = ConfigParser()
367 cfg_parser.read(pjoin(pkg_dir, '.git_commit_info.ini'))
370 cfg_parser.read(pjoin(pkg_dir, '.git_commit_info.ini'))
368 cfg_parser.set('commit hash', 'install_hash', repo_commit)
371 cfg_parser.set('commit hash', 'install_hash', repo_commit)
369 out_pth = pjoin(self.build_lib, pkg_dir, '.git_commit_info.ini')
372 out_pth = pjoin(self.build_lib, pkg_dir, '.git_commit_info.ini')
370 out_file = open(out_pth, 'wt')
373 out_file = open(out_pth, 'wt')
371 cfg_parser.write(out_file)
374 cfg_parser.write(out_file)
372 out_file.close()
375 out_file.close()
373 return MyBuildPy
376 return MyBuildPy
General Comments 0
You need to be logged in to leave comments. Login now