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