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