##// END OF EJS Templates
remove unused check_for_readline
Min RK -
Show More
@@ -1,291 +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.rst, 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 v = sys.version_info
30 30 if v[:2] < (2,7) or (v[0] >= 3 and v[:2] < (3,3)):
31 31 error = "ERROR: IPython requires Python version 2.7 or 3.3 or above."
32 32 print(error, file=sys.stderr)
33 33 sys.exit(1)
34 34
35 35 PY3 = (sys.version_info[0] >= 3)
36 36
37 37 # At least we're on the python version we need, move on.
38 38
39 39 #-------------------------------------------------------------------------------
40 40 # Imports
41 41 #-------------------------------------------------------------------------------
42 42
43 43 # Stdlib imports
44 44 import os
45 45 import shutil
46 46
47 47 from glob import glob
48 48
49 49 # BEFORE importing distutils, remove MANIFEST. distutils doesn't properly
50 50 # update it when the contents of directories change.
51 51 if os.path.exists('MANIFEST'): os.remove('MANIFEST')
52 52
53 53 from distutils.core import setup
54 54
55 55 # Our own imports
56 56 from setupbase import target_update
57 57
58 58 from setupbase import (
59 59 setup_args,
60 60 find_packages,
61 61 find_package_data,
62 62 check_package_data_first,
63 63 find_entry_points,
64 64 build_scripts_entrypt,
65 65 find_data_files,
66 check_for_readline,
67 66 git_prebuild,
68 67 install_symlinked,
69 68 install_lib_symlink,
70 69 install_scripts_for_symlink,
71 70 unsymlink,
72 71 )
73 72
74 73 isfile = os.path.isfile
75 74 pjoin = os.path.join
76 75
77 76 #-------------------------------------------------------------------------------
78 77 # Handle OS specific things
79 78 #-------------------------------------------------------------------------------
80 79
81 80 if os.name in ('nt','dos'):
82 81 os_name = 'windows'
83 82 else:
84 83 os_name = os.name
85 84
86 85 # Under Windows, 'sdist' has not been supported. Now that the docs build with
87 86 # Sphinx it might work, but let's not turn it on until someone confirms that it
88 87 # actually works.
89 88 if os_name == 'windows' and 'sdist' in sys.argv:
90 89 print('The sdist command is not available under Windows. Exiting.')
91 90 sys.exit(1)
92 91
93 92
94 93 #-------------------------------------------------------------------------------
95 94 # Things related to the IPython documentation
96 95 #-------------------------------------------------------------------------------
97 96
98 97 # update the manuals when building a source dist
99 98 if len(sys.argv) >= 2 and sys.argv[1] in ('sdist','bdist_rpm'):
100 99
101 100 # List of things to be updated. Each entry is a triplet of args for
102 101 # target_update()
103 102 to_update = [
104 103 ('docs/man/ipython.1.gz',
105 104 ['docs/man/ipython.1'],
106 105 'cd docs/man && gzip -9c ipython.1 > ipython.1.gz'),
107 106 ]
108 107
109 108
110 109 [ target_update(*t) for t in to_update ]
111 110
112 111 #---------------------------------------------------------------------------
113 112 # Find all the packages, package data, and data_files
114 113 #---------------------------------------------------------------------------
115 114
116 115 packages = find_packages()
117 116 package_data = find_package_data()
118 117
119 118 data_files = find_data_files()
120 119
121 120 setup_args['packages'] = packages
122 121 setup_args['package_data'] = package_data
123 122 setup_args['data_files'] = data_files
124 123
125 124 #---------------------------------------------------------------------------
126 125 # custom distutils commands
127 126 #---------------------------------------------------------------------------
128 127 # imports here, so they are after setuptools import if there was one
129 128 from distutils.command.sdist import sdist
130 129 from distutils.command.upload import upload
131 130
132 131 class UploadWindowsInstallers(upload):
133 132
134 133 description = "Upload Windows installers to PyPI (only used from tools/release_windows.py)"
135 134 user_options = upload.user_options + [
136 135 ('files=', 'f', 'exe file (or glob) to upload')
137 136 ]
138 137 def initialize_options(self):
139 138 upload.initialize_options(self)
140 139 meta = self.distribution.metadata
141 140 base = '{name}-{version}'.format(
142 141 name=meta.get_name(),
143 142 version=meta.get_version()
144 143 )
145 144 self.files = os.path.join('dist', '%s.*.exe' % base)
146 145
147 146 def run(self):
148 147 for dist_file in glob(self.files):
149 148 self.upload_file('bdist_wininst', 'any', dist_file)
150 149
151 150 setup_args['cmdclass'] = {
152 151 'build_py': \
153 152 check_package_data_first(git_prebuild('IPython')),
154 153 'sdist' : git_prebuild('IPython', sdist),
155 154 'upload_wininst' : UploadWindowsInstallers,
156 155 'symlink': install_symlinked,
157 156 'install_lib_symlink': install_lib_symlink,
158 157 'install_scripts_sym': install_scripts_for_symlink,
159 158 'unsymlink': unsymlink,
160 159 }
161 160
162 161 ### Temporarily disable install while it's broken during the big split
163 162 from textwrap import dedent
164 163 from distutils.command.install import install
165 164
166 165 class DisabledInstall(install):
167 166 def run(self):
168 167 msg = dedent("""
169 168 While we are in the midst of The Big Split,
170 169 IPython cannot be installed from master.
171 170 You can use `pip install -e .` for an editable install,
172 171 which still works.
173 172 """)
174 173 print(msg, file=sys.stderr)
175 174 raise SystemExit(1)
176 175
177 176 setup_args['cmdclass']['install'] = DisabledInstall
178 177
179 178
180 179 #---------------------------------------------------------------------------
181 180 # Handle scripts, dependencies, and setuptools specific things
182 181 #---------------------------------------------------------------------------
183 182
184 183 # For some commands, use setuptools. Note that we do NOT list install here!
185 184 # If you want a setuptools-enhanced install, just run 'setupegg.py install'
186 185 needs_setuptools = set(('develop', 'release', 'bdist_egg', 'bdist_rpm',
187 186 'bdist', 'bdist_dumb', 'bdist_wininst', 'bdist_wheel',
188 187 'egg_info', 'easy_install', 'upload', 'install_egg_info',
189 188 ))
190 189
191 190 if len(needs_setuptools.intersection(sys.argv)) > 0:
192 191 import setuptools
193 192
194 193 # This dict is used for passing extra arguments that are setuptools
195 194 # specific to setup
196 195 setuptools_extra_args = {}
197 196
198 197 # setuptools requirements
199 198
200 199 extras_require = dict(
201 200 parallel = ['ipyparallel'],
202 201 qtconsole = ['qtconsole'],
203 202 doc = ['Sphinx>=1.1', 'numpydoc'],
204 203 test = ['nose>=0.10.1', 'requests', 'testpath'],
205 204 terminal = [],
206 205 kernel = ['ipykernel'],
207 206 nbformat = ['nbformat'],
208 207 notebook = ['notebook'],
209 208 nbconvert = ['nbconvert'],
210 209 )
211 210 install_requires = [
212 211 'decorator',
213 212 'pickleshare',
214 213 'simplegeneric>0.8',
215 214 'traitlets',
216 215 ]
217 216
218 217 # Platform-specific dependencies:
219 218 # This is the correct way to specify these,
220 219 # but requires pip >= 6. pip < 6 ignores these.
221 220 extras_require.update({
222 221 ':sys_platform != "win32"': ['pexpect'],
223 222 ':sys_platform == "darwin"': ['appnope', 'gnureadline'],
224 223 'terminal:sys_platform == "win32"': ['pyreadline>=2'],
225 224 'test:python_version == "2.7"': ['mock'],
226 225 })
227 226 # FIXME: re-specify above platform dependencies for pip < 6
228 227 # These would result in non-portable bdists.
229 228 if not any(arg.startswith('bdist') for arg in sys.argv):
230 229 if sys.version_info < (3, 3):
231 230 extras_require['test'].append('mock')
232 231
233 232 if sys.platform == 'darwin':
234 233 install_requires.extend(['appnope', 'gnureadline'])
235 234
236 235 if sys.platform.startswith('win'):
237 236 extras_require['terminal'].append('pyreadline>=2.0')
238 237 else:
239 238 install_requires.append('pexpect')
240 239
241 240 everything = set()
242 241 for deps in extras_require.values():
243 242 everything.update(deps)
244 243 extras_require['all'] = everything
245 244
246 245 if 'setuptools' in sys.modules:
247 246 setuptools_extra_args['zip_safe'] = False
248 247 setuptools_extra_args['entry_points'] = {
249 248 'console_scripts': find_entry_points(),
250 249 'pygments.lexers': [
251 250 'ipythonconsole = IPython.lib.lexers:IPythonConsoleLexer',
252 251 'ipython = IPython.lib.lexers:IPythonLexer',
253 252 'ipython3 = IPython.lib.lexers:IPython3Lexer',
254 253 ],
255 254 }
256 255 setup_args['extras_require'] = extras_require
257 256 requires = setup_args['install_requires'] = install_requires
258 257
259 258 # Script to be run by the windows binary installer after the default setup
260 259 # routine, to add shortcuts and similar windows-only things. Windows
261 260 # post-install scripts MUST reside in the scripts/ dir, otherwise distutils
262 261 # doesn't find them.
263 262 if 'bdist_wininst' in sys.argv:
264 263 if len(sys.argv) > 2 and \
265 264 ('sdist' in sys.argv or 'bdist_rpm' in sys.argv):
266 265 print("ERROR: bdist_wininst must be run alone. Exiting.", file=sys.stderr)
267 266 sys.exit(1)
268 267 setup_args['data_files'].append(
269 268 ['Scripts', ('scripts/ipython.ico', 'scripts/ipython_nb.ico')])
270 269 setup_args['scripts'] = [pjoin('scripts','ipython_win_post_install.py')]
271 270 setup_args['options'] = {"bdist_wininst":
272 271 {"install_script":
273 272 "ipython_win_post_install.py"}}
274 273
275 274 else:
276 275 # scripts has to be a non-empty list, or install_scripts isn't called
277 276 setup_args['scripts'] = [e.split('=')[0].strip() for e in find_entry_points()]
278 277
279 278 setup_args['cmdclass']['build_scripts'] = build_scripts_entrypt
280 279
281 280 #---------------------------------------------------------------------------
282 281 # Do the actual setup now
283 282 #---------------------------------------------------------------------------
284 283
285 284 setup_args.update(setuptools_extra_args)
286 285
287 286 def main():
288 287 setup(**setup_args)
289 288
290 289 if __name__ == '__main__':
291 290 main()
@@ -1,487 +1,466 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
12 12 # Copyright (c) IPython Development Team.
13 13 # Distributed under the terms of the Modified BSD License.
14 14
15 15 from __future__ import print_function
16 16
17 17 import errno
18 18 import os
19 19 import sys
20 20
21 21 from distutils import log
22 22 from distutils.command.build_py import build_py
23 23 from distutils.command.build_scripts import build_scripts
24 24 from distutils.command.install import install
25 25 from distutils.command.install_scripts import install_scripts
26 26 from distutils.cmd import Command
27 27 from distutils.errors import DistutilsExecError
28 28 from fnmatch import fnmatch
29 29 from glob import glob
30 30 from subprocess import Popen, PIPE
31 31
32 32 from setupext import install_data_ext
33 33
34 34 #-------------------------------------------------------------------------------
35 35 # Useful globals and utility functions
36 36 #-------------------------------------------------------------------------------
37 37
38 38 # A few handy globals
39 39 isfile = os.path.isfile
40 40 pjoin = os.path.join
41 41 repo_root = os.path.dirname(os.path.abspath(__file__))
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(repo_root, '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 package_data = {
128 128 'IPython.core' : ['profile/README*'],
129 129 'IPython.core.tests' : ['*.png', '*.jpg'],
130 130 'IPython.lib.tests' : ['*.wav'],
131 131 'IPython.testing.plugin' : ['*.txt'],
132 132 }
133 133
134 134 return package_data
135 135
136 136
137 137 def check_package_data(package_data):
138 138 """verify that package_data globs make sense"""
139 139 print("checking package data")
140 140 for pkg, data in package_data.items():
141 141 pkg_root = pjoin(*pkg.split('.'))
142 142 for d in data:
143 143 path = pjoin(pkg_root, d)
144 144 if '*' in path:
145 145 assert len(glob(path)) > 0, "No files match pattern %s" % path
146 146 else:
147 147 assert os.path.exists(path), "Missing package data: %s" % path
148 148
149 149
150 150 def check_package_data_first(command):
151 151 """decorator for checking package_data before running a given command
152 152
153 153 Probably only needs to wrap build_py
154 154 """
155 155 class DecoratedCommand(command):
156 156 def run(self):
157 157 check_package_data(self.package_data)
158 158 command.run(self)
159 159 return DecoratedCommand
160 160
161 161
162 162 #---------------------------------------------------------------------------
163 163 # Find data files
164 164 #---------------------------------------------------------------------------
165 165
166 166 def make_dir_struct(tag,base,out_base):
167 167 """Make the directory structure of all files below a starting dir.
168 168
169 169 This is just a convenience routine to help build a nested directory
170 170 hierarchy because distutils is too stupid to do this by itself.
171 171
172 172 XXX - this needs a proper docstring!
173 173 """
174 174
175 175 # we'll use these a lot below
176 176 lbase = len(base)
177 177 pathsep = os.path.sep
178 178 lpathsep = len(pathsep)
179 179
180 180 out = []
181 181 for (dirpath,dirnames,filenames) in os.walk(base):
182 182 # we need to strip out the dirpath from the base to map it to the
183 183 # output (installation) path. This requires possibly stripping the
184 184 # path separator, because otherwise pjoin will not work correctly
185 185 # (pjoin('foo/','/bar') returns '/bar').
186 186
187 187 dp_eff = dirpath[lbase:]
188 188 if dp_eff.startswith(pathsep):
189 189 dp_eff = dp_eff[lpathsep:]
190 190 # The output path must be anchored at the out_base marker
191 191 out_path = pjoin(out_base,dp_eff)
192 192 # Now we can generate the final filenames. Since os.walk only produces
193 193 # filenames, we must join back with the dirpath to get full valid file
194 194 # paths:
195 195 pfiles = [pjoin(dirpath,f) for f in filenames]
196 196 # Finally, generate the entry we need, which is a pari of (output
197 197 # path, files) for use as a data_files parameter in install_data.
198 198 out.append((out_path, pfiles))
199 199
200 200 return out
201 201
202 202
203 203 def find_data_files():
204 204 """
205 205 Find IPython's data_files.
206 206
207 207 Just man pages at this point.
208 208 """
209 209
210 210 manpagebase = pjoin('share', 'man', 'man1')
211 211
212 212 # Simple file lists can be made by hand
213 213 manpages = [f for f in glob(pjoin('docs','man','*.1.gz')) if isfile(f)]
214 214 if not manpages:
215 215 # When running from a source tree, the manpages aren't gzipped
216 216 manpages = [f for f in glob(pjoin('docs','man','*.1')) if isfile(f)]
217 217
218 218 # And assemble the entire output list
219 219 data_files = [ (manpagebase, manpages) ]
220 220
221 221 return data_files
222 222
223 223
224 224 def make_man_update_target(manpage):
225 225 """Return a target_update-compliant tuple for the given manpage.
226 226
227 227 Parameters
228 228 ----------
229 229 manpage : string
230 230 Name of the manpage, must include the section number (trailing number).
231 231
232 232 Example
233 233 -------
234 234
235 235 >>> make_man_update_target('ipython.1') #doctest: +NORMALIZE_WHITESPACE
236 236 ('docs/man/ipython.1.gz',
237 237 ['docs/man/ipython.1'],
238 238 'cd docs/man && gzip -9c ipython.1 > ipython.1.gz')
239 239 """
240 240 man_dir = pjoin('docs', 'man')
241 241 manpage_gz = manpage + '.gz'
242 242 manpath = pjoin(man_dir, manpage)
243 243 manpath_gz = pjoin(man_dir, manpage_gz)
244 244 gz_cmd = ( "cd %(man_dir)s && gzip -9c %(manpage)s > %(manpage_gz)s" %
245 245 locals() )
246 246 return (manpath_gz, [manpath], gz_cmd)
247 247
248 248 # The two functions below are copied from IPython.utils.path, so we don't need
249 249 # to import IPython during setup, which fails on Python 3.
250 250
251 251 def target_outdated(target,deps):
252 252 """Determine whether a target is out of date.
253 253
254 254 target_outdated(target,deps) -> 1/0
255 255
256 256 deps: list of filenames which MUST exist.
257 257 target: single filename which may or may not exist.
258 258
259 259 If target doesn't exist or is older than any file listed in deps, return
260 260 true, otherwise return false.
261 261 """
262 262 try:
263 263 target_time = os.path.getmtime(target)
264 264 except os.error:
265 265 return 1
266 266 for dep in deps:
267 267 dep_time = os.path.getmtime(dep)
268 268 if dep_time > target_time:
269 269 #print "For target",target,"Dep failed:",dep # dbg
270 270 #print "times (dep,tar):",dep_time,target_time # dbg
271 271 return 1
272 272 return 0
273 273
274 274
275 275 def target_update(target,deps,cmd):
276 276 """Update a target with a given command given a list of dependencies.
277 277
278 278 target_update(target,deps,cmd) -> runs cmd if target is outdated.
279 279
280 280 This is just a wrapper around target_outdated() which calls the given
281 281 command if target is outdated."""
282 282
283 283 if target_outdated(target,deps):
284 284 os.system(cmd)
285 285
286 286 #---------------------------------------------------------------------------
287 287 # Find scripts
288 288 #---------------------------------------------------------------------------
289 289
290 290 def find_entry_points():
291 291 """Defines the command line entry points for IPython
292 292
293 293 This always uses setuptools-style entry points. When setuptools is not in
294 294 use, our own build_scripts_entrypt class below parses these and builds
295 295 command line scripts.
296 296
297 297 Each of our entry points gets both a plain name, e.g. ipython, and one
298 298 suffixed with the Python major version number, e.g. ipython3.
299 299 """
300 300 ep = [
301 301 'ipython%s = IPython:start_ipython',
302 302 'iptest%s = IPython.testing.iptestcontroller:main',
303 303 ]
304 304 suffix = str(sys.version_info[0])
305 305 return [e % '' for e in ep] + [e % suffix for e in ep]
306 306
307 307 script_src = """#!{executable}
308 308 # This script was automatically generated by setup.py
309 309 if __name__ == '__main__':
310 310 from {mod} import {func}
311 311 {func}()
312 312 """
313 313
314 314 class build_scripts_entrypt(build_scripts):
315 315 """Build the command line scripts
316 316
317 317 Parse setuptools style entry points and write simple scripts to run the
318 318 target functions.
319 319
320 320 On Windows, this also creates .cmd wrappers for the scripts so that you can
321 321 easily launch them from a command line.
322 322 """
323 323 def run(self):
324 324 self.mkpath(self.build_dir)
325 325 outfiles = []
326 326 for script in find_entry_points():
327 327 name, entrypt = script.split('=')
328 328 name = name.strip()
329 329 entrypt = entrypt.strip()
330 330 outfile = os.path.join(self.build_dir, name)
331 331 outfiles.append(outfile)
332 332 print('Writing script to', outfile)
333 333
334 334 mod, func = entrypt.split(':')
335 335 with open(outfile, 'w') as f:
336 336 f.write(script_src.format(executable=sys.executable,
337 337 mod=mod, func=func))
338 338
339 339 if sys.platform == 'win32':
340 340 # Write .cmd wrappers for Windows so 'ipython' etc. work at the
341 341 # command line
342 342 cmd_file = os.path.join(self.build_dir, name + '.cmd')
343 343 cmd = '@"{python}" "%~dp0\{script}" %*\r\n'.format(
344 344 python=sys.executable, script=name)
345 345 log.info("Writing %s wrapper script" % cmd_file)
346 346 with open(cmd_file, 'w') as f:
347 347 f.write(cmd)
348 348
349 349 return outfiles, outfiles
350 350
351 351 class install_lib_symlink(Command):
352 352 user_options = [
353 353 ('install-dir=', 'd', "directory to install to"),
354 354 ]
355 355
356 356 def initialize_options(self):
357 357 self.install_dir = None
358 358
359 359 def finalize_options(self):
360 360 self.set_undefined_options('symlink',
361 361 ('install_lib', 'install_dir'),
362 362 )
363 363
364 364 def run(self):
365 365 if sys.platform == 'win32':
366 366 raise Exception("This doesn't work on Windows.")
367 367 pkg = os.path.join(os.getcwd(), 'IPython')
368 368 dest = os.path.join(self.install_dir, 'IPython')
369 369 if os.path.islink(dest):
370 370 print('removing existing symlink at %s' % dest)
371 371 os.unlink(dest)
372 372 print('symlinking %s -> %s' % (pkg, dest))
373 373 os.symlink(pkg, dest)
374 374
375 375 class unsymlink(install):
376 376 def run(self):
377 377 dest = os.path.join(self.install_lib, 'IPython')
378 378 if os.path.islink(dest):
379 379 print('removing symlink at %s' % dest)
380 380 os.unlink(dest)
381 381 else:
382 382 print('No symlink exists at %s' % dest)
383 383
384 384 class install_symlinked(install):
385 385 def run(self):
386 386 if sys.platform == 'win32':
387 387 raise Exception("This doesn't work on Windows.")
388 388
389 389 # Run all sub-commands (at least those that need to be run)
390 390 for cmd_name in self.get_sub_commands():
391 391 self.run_command(cmd_name)
392 392
393 393 # 'sub_commands': a list of commands this command might have to run to
394 394 # get its work done. See cmd.py for more info.
395 395 sub_commands = [('install_lib_symlink', lambda self:True),
396 396 ('install_scripts_sym', lambda self:True),
397 397 ]
398 398
399 399 class install_scripts_for_symlink(install_scripts):
400 400 """Redefined to get options from 'symlink' instead of 'install'.
401 401
402 402 I love distutils almost as much as I love setuptools.
403 403 """
404 404 def finalize_options(self):
405 405 self.set_undefined_options('build', ('build_scripts', 'build_dir'))
406 406 self.set_undefined_options('symlink',
407 407 ('install_scripts', 'install_dir'),
408 408 ('force', 'force'),
409 409 ('skip_build', 'skip_build'),
410 410 )
411 411
412 #---------------------------------------------------------------------------
413 # Verify all dependencies
414 #---------------------------------------------------------------------------
415
416 def check_for_readline():
417 """Check for GNU readline"""
418 try:
419 import gnureadline as readline
420 except ImportError:
421 pass
422 else:
423 return True
424 try:
425 import readline
426 except ImportError:
427 return False
428 else:
429 if sys.platform == 'darwin' and 'libedit' in readline.__doc__:
430 print("Ignoring readline linked to libedit", file=sys.stderr)
431 return False
432 return True
433 412
434 413 #---------------------------------------------------------------------------
435 414 # VCS related
436 415 #---------------------------------------------------------------------------
437 416
438 417
439 418 def git_prebuild(pkg_dir, build_cmd=build_py):
440 419 """Return extended build or sdist command class for recording commit
441 420
442 421 records git commit in IPython.utils._sysinfo.commit
443 422
444 423 for use in IPython.utils.sysinfo.sys_info() calls after installation.
445 424 """
446 425
447 426 class MyBuildPy(build_cmd):
448 427 ''' Subclass to write commit data into installation tree '''
449 428 def run(self):
450 429 build_cmd.run(self)
451 430 # this one will only fire for build commands
452 431 if hasattr(self, 'build_lib'):
453 432 self._record_commit(self.build_lib)
454 433
455 434 def make_release_tree(self, base_dir, files):
456 435 # this one will fire for sdist
457 436 build_cmd.make_release_tree(self, base_dir, files)
458 437 self._record_commit(base_dir)
459 438
460 439 def _record_commit(self, base_dir):
461 440 import subprocess
462 441 proc = subprocess.Popen('git rev-parse --short HEAD',
463 442 stdout=subprocess.PIPE,
464 443 stderr=subprocess.PIPE,
465 444 shell=True)
466 445 repo_commit, _ = proc.communicate()
467 446 repo_commit = repo_commit.strip().decode("ascii")
468 447
469 448 out_pth = pjoin(base_dir, pkg_dir, 'utils', '_sysinfo.py')
470 449 if os.path.isfile(out_pth) and not repo_commit:
471 450 # nothing to write, don't clobber
472 451 return
473 452
474 453 print("writing git commit '%s' to %s" % (repo_commit, out_pth))
475 454
476 455 # remove to avoid overwriting original via hard link
477 456 try:
478 457 os.remove(out_pth)
479 458 except (IOError, OSError):
480 459 pass
481 460 with open(out_pth, 'w') as out_file:
482 461 out_file.writelines([
483 462 '# GENERATED BY setup.py\n',
484 463 'commit = u"%s"\n' % repo_commit,
485 464 ])
486 465 return MyBuildPy
487 466
General Comments 0
You need to be logged in to leave comments. Login now