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