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