##// END OF EJS Templates
enable uploading wininst to PyPI with tools/release_windows.py...
MinRK -
Show More
@@ -1,259 +1,285 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-2011, IPython Development Team.
10 # Copyright (c) 2008-2011, IPython Development Team.
11 # Copyright (c) 2001-2007, Fernando Perez <fernando.perez@colorado.edu>
11 # Copyright (c) 2001-2007, Fernando Perez <fernando.perez@colorado.edu>
12 # Copyright (c) 2001, Janko Hauser <jhauser@zscout.de>
12 # Copyright (c) 2001, Janko Hauser <jhauser@zscout.de>
13 # Copyright (c) 2001, Nathaniel Gray <n8gray@caltech.edu>
13 # Copyright (c) 2001, Nathaniel Gray <n8gray@caltech.edu>
14 #
14 #
15 # Distributed under the terms of the Modified BSD License.
15 # Distributed under the terms of the Modified BSD License.
16 #
16 #
17 # The full license is in the file COPYING.txt, distributed with this software.
17 # The full license is in the file COPYING.txt, distributed with this software.
18 #-----------------------------------------------------------------------------
18 #-----------------------------------------------------------------------------
19
19
20 #-----------------------------------------------------------------------------
20 #-----------------------------------------------------------------------------
21 # Minimal Python version sanity check
21 # Minimal Python version sanity check
22 #-----------------------------------------------------------------------------
22 #-----------------------------------------------------------------------------
23 from __future__ import print_function
23 from __future__ import print_function
24
24
25 import sys
25 import sys
26
26
27 # This check is also made in IPython/__init__, don't forget to update both when
27 # This check is also made in IPython/__init__, don't forget to update both when
28 # changing Python version requirements.
28 # changing Python version requirements.
29 #~ if sys.version[0:3] < '2.6':
29 #~ if sys.version[0:3] < '2.6':
30 #~ error = """\
30 #~ error = """\
31 #~ ERROR: 'IPython requires Python Version 2.6 or above.'
31 #~ ERROR: 'IPython requires Python Version 2.6 or above.'
32 #~ Exiting."""
32 #~ Exiting."""
33 #~ print >> sys.stderr, error
33 #~ print >> sys.stderr, error
34 #~ sys.exit(1)
34 #~ sys.exit(1)
35
35
36 PY3 = (sys.version_info[0] >= 3)
36 PY3 = (sys.version_info[0] >= 3)
37
37
38 # At least we're on the python version we need, move on.
38 # At least we're on the python version we need, move on.
39
39
40 #-------------------------------------------------------------------------------
40 #-------------------------------------------------------------------------------
41 # Imports
41 # Imports
42 #-------------------------------------------------------------------------------
42 #-------------------------------------------------------------------------------
43
43
44 # Stdlib imports
44 # Stdlib imports
45 import os
45 import os
46 import shutil
46 import shutil
47
47
48 from glob import glob
48 from glob import glob
49
49
50 # BEFORE importing distutils, remove MANIFEST. distutils doesn't properly
50 # BEFORE importing distutils, remove MANIFEST. distutils doesn't properly
51 # update it when the contents of directories change.
51 # update it when the contents of directories change.
52 if os.path.exists('MANIFEST'): os.remove('MANIFEST')
52 if os.path.exists('MANIFEST'): os.remove('MANIFEST')
53
53
54 from distutils.core import setup
54 from distutils.core import setup
55 from distutils.command.upload import upload
55
56
56 # On Python 3, we need distribute (new setuptools) to do the 2to3 conversion
57 # On Python 3, we need distribute (new setuptools) to do the 2to3 conversion
57 if PY3:
58 if PY3:
58 import setuptools
59 import setuptools
59
60
60 # Our own imports
61 # Our own imports
61 from setupbase import target_update
62 from setupbase import target_update
62
63
63 from setupbase import (
64 from setupbase import (
64 setup_args,
65 setup_args,
65 find_packages,
66 find_packages,
66 find_package_data,
67 find_package_data,
67 find_scripts,
68 find_scripts,
68 find_data_files,
69 find_data_files,
69 check_for_dependencies,
70 check_for_dependencies,
70 record_commit_info,
71 record_commit_info,
71 )
72 )
72 from setupext import setupext
73 from setupext import setupext
73
74
74 isfile = os.path.isfile
75 isfile = os.path.isfile
75 pjoin = os.path.join
76 pjoin = os.path.join
76
77
77 #-----------------------------------------------------------------------------
78 #-----------------------------------------------------------------------------
78 # Function definitions
79 # Function definitions
79 #-----------------------------------------------------------------------------
80 #-----------------------------------------------------------------------------
80
81
81 def cleanup():
82 def cleanup():
82 """Clean up the junk left around by the build process"""
83 """Clean up the junk left around by the build process"""
83 if "develop" not in sys.argv:
84 if "develop" not in sys.argv:
84 try:
85 try:
85 shutil.rmtree('ipython.egg-info')
86 shutil.rmtree('ipython.egg-info')
86 except:
87 except:
87 try:
88 try:
88 os.unlink('ipython.egg-info')
89 os.unlink('ipython.egg-info')
89 except:
90 except:
90 pass
91 pass
91
92
92 #-------------------------------------------------------------------------------
93 #-------------------------------------------------------------------------------
93 # Handle OS specific things
94 # Handle OS specific things
94 #-------------------------------------------------------------------------------
95 #-------------------------------------------------------------------------------
95
96
96 if os.name == 'posix':
97 if os.name == 'posix':
97 os_name = 'posix'
98 os_name = 'posix'
98 elif os.name in ['nt','dos']:
99 elif os.name in ['nt','dos']:
99 os_name = 'windows'
100 os_name = 'windows'
100 else:
101 else:
101 print('Unsupported operating system:',os.name)
102 print('Unsupported operating system:',os.name)
102 sys.exit(1)
103 sys.exit(1)
103
104
104 # Under Windows, 'sdist' has not been supported. Now that the docs build with
105 # Under Windows, 'sdist' has not been supported. Now that the docs build with
105 # Sphinx it might work, but let's not turn it on until someone confirms that it
106 # Sphinx it might work, but let's not turn it on until someone confirms that it
106 # actually works.
107 # actually works.
107 if os_name == 'windows' and 'sdist' in sys.argv:
108 if os_name == 'windows' and 'sdist' in sys.argv:
108 print('The sdist command is not available under Windows. Exiting.')
109 print('The sdist command is not available under Windows. Exiting.')
109 sys.exit(1)
110 sys.exit(1)
110
111
111 #-------------------------------------------------------------------------------
112 #-------------------------------------------------------------------------------
112 # Things related to the IPython documentation
113 # Things related to the IPython documentation
113 #-------------------------------------------------------------------------------
114 #-------------------------------------------------------------------------------
114
115
115 # update the manuals when building a source dist
116 # update the manuals when building a source dist
116 if len(sys.argv) >= 2 and sys.argv[1] in ('sdist','bdist_rpm'):
117 if len(sys.argv) >= 2 and sys.argv[1] in ('sdist','bdist_rpm'):
117 import textwrap
118 import textwrap
118
119
119 # List of things to be updated. Each entry is a triplet of args for
120 # List of things to be updated. Each entry is a triplet of args for
120 # target_update()
121 # target_update()
121 to_update = [
122 to_update = [
122 # FIXME - Disabled for now: we need to redo an automatic way
123 # FIXME - Disabled for now: we need to redo an automatic way
123 # of generating the magic info inside the rst.
124 # of generating the magic info inside the rst.
124 #('docs/magic.tex',
125 #('docs/magic.tex',
125 #['IPython/Magic.py'],
126 #['IPython/Magic.py'],
126 #"cd doc && ./update_magic.sh" ),
127 #"cd doc && ./update_magic.sh" ),
127
128
128 ('docs/man/ipcluster.1.gz',
129 ('docs/man/ipcluster.1.gz',
129 ['docs/man/ipcluster.1'],
130 ['docs/man/ipcluster.1'],
130 'cd docs/man && gzip -9c ipcluster.1 > ipcluster.1.gz'),
131 'cd docs/man && gzip -9c ipcluster.1 > ipcluster.1.gz'),
131
132
132 ('docs/man/ipcontroller.1.gz',
133 ('docs/man/ipcontroller.1.gz',
133 ['docs/man/ipcontroller.1'],
134 ['docs/man/ipcontroller.1'],
134 'cd docs/man && gzip -9c ipcontroller.1 > ipcontroller.1.gz'),
135 'cd docs/man && gzip -9c ipcontroller.1 > ipcontroller.1.gz'),
135
136
136 ('docs/man/ipengine.1.gz',
137 ('docs/man/ipengine.1.gz',
137 ['docs/man/ipengine.1'],
138 ['docs/man/ipengine.1'],
138 'cd docs/man && gzip -9c ipengine.1 > ipengine.1.gz'),
139 'cd docs/man && gzip -9c ipengine.1 > ipengine.1.gz'),
139
140
140 ('docs/man/iplogger.1.gz',
141 ('docs/man/iplogger.1.gz',
141 ['docs/man/iplogger.1'],
142 ['docs/man/iplogger.1'],
142 'cd docs/man && gzip -9c iplogger.1 > iplogger.1.gz'),
143 'cd docs/man && gzip -9c iplogger.1 > iplogger.1.gz'),
143
144
144 ('docs/man/ipython.1.gz',
145 ('docs/man/ipython.1.gz',
145 ['docs/man/ipython.1'],
146 ['docs/man/ipython.1'],
146 'cd docs/man && gzip -9c ipython.1 > ipython.1.gz'),
147 'cd docs/man && gzip -9c ipython.1 > ipython.1.gz'),
147
148
148 ('docs/man/irunner.1.gz',
149 ('docs/man/irunner.1.gz',
149 ['docs/man/irunner.1'],
150 ['docs/man/irunner.1'],
150 'cd docs/man && gzip -9c irunner.1 > irunner.1.gz'),
151 'cd docs/man && gzip -9c irunner.1 > irunner.1.gz'),
151
152
152 ('docs/man/pycolor.1.gz',
153 ('docs/man/pycolor.1.gz',
153 ['docs/man/pycolor.1'],
154 ['docs/man/pycolor.1'],
154 'cd docs/man && gzip -9c pycolor.1 > pycolor.1.gz'),
155 'cd docs/man && gzip -9c pycolor.1 > pycolor.1.gz'),
155 ]
156 ]
156
157
157
158
158 [ target_update(*t) for t in to_update ]
159 [ target_update(*t) for t in to_update ]
159
160
160 #---------------------------------------------------------------------------
161 #---------------------------------------------------------------------------
161 # Find all the packages, package data, and data_files
162 # Find all the packages, package data, and data_files
162 #---------------------------------------------------------------------------
163 #---------------------------------------------------------------------------
163
164
164 packages = find_packages()
165 packages = find_packages()
165 package_data = find_package_data()
166 package_data = find_package_data()
166 data_files = find_data_files()
167 data_files = find_data_files()
167
168
168 setup_args['cmdclass'] = {'build_py': record_commit_info('IPython')}
169 setup_args['cmdclass'] = {'build_py': record_commit_info('IPython')}
169 setup_args['packages'] = packages
170 setup_args['packages'] = packages
170 setup_args['package_data'] = package_data
171 setup_args['package_data'] = package_data
171 setup_args['data_files'] = data_files
172 setup_args['data_files'] = data_files
172
173
173 #---------------------------------------------------------------------------
174 #---------------------------------------------------------------------------
175 # custom upload_wininst command
176 #---------------------------------------------------------------------------
177
178 class UploadWindowsInstallers(upload):
179
180 description = "Upload Windows installers to PyPI (only used from tools/release_windows.py)"
181 user_options = upload.user_options + [
182 ('files=', 'f', 'exe file (or glob) to upload')
183 ]
184 def initialize_options(self):
185 upload.initialize_options(self)
186 meta = self.distribution.metadata
187 base = '{name}-{version}'.format(
188 name=meta.get_name(),
189 version=meta.get_version()
190 )
191 self.files = os.path.join('dist', '%s.*.exe' % base)
192
193 def run(self):
194 for dist_file in glob(self.files):
195 self.upload_file('bdist_wininst', 'any', dist_file)
196
197 setup_args['cmdclass']['upload_wininst'] = UploadWindowsInstallers
198
199 #---------------------------------------------------------------------------
174 # Handle scripts, dependencies, and setuptools specific things
200 # Handle scripts, dependencies, and setuptools specific things
175 #---------------------------------------------------------------------------
201 #---------------------------------------------------------------------------
176
202
177 # For some commands, use setuptools. Note that we do NOT list install here!
203 # For some commands, use setuptools. Note that we do NOT list install here!
178 # If you want a setuptools-enhanced install, just run 'setupegg.py install'
204 # If you want a setuptools-enhanced install, just run 'setupegg.py install'
179 needs_setuptools = set(('develop', 'release', 'bdist_egg', 'bdist_rpm',
205 needs_setuptools = set(('develop', 'release', 'bdist_egg', 'bdist_rpm',
180 'bdist', 'bdist_dumb', 'bdist_wininst', 'install_egg_info',
206 'bdist', 'bdist_dumb', 'bdist_wininst', 'install_egg_info',
181 'egg_info', 'easy_install', 'upload',
207 'egg_info', 'easy_install', 'upload',
182 ))
208 ))
183 if sys.platform == 'win32':
209 if sys.platform == 'win32':
184 # Depend on setuptools for install on *Windows only*
210 # Depend on setuptools for install on *Windows only*
185 # If we get script-installation working without setuptools,
211 # If we get script-installation working without setuptools,
186 # then we can back off, but until then use it.
212 # then we can back off, but until then use it.
187 # See Issue #369 on GitHub for more
213 # See Issue #369 on GitHub for more
188 needs_setuptools.add('install')
214 needs_setuptools.add('install')
189
215
190 if len(needs_setuptools.intersection(sys.argv)) > 0:
216 if len(needs_setuptools.intersection(sys.argv)) > 0:
191 import setuptools
217 import setuptools
192
218
193 # This dict is used for passing extra arguments that are setuptools
219 # This dict is used for passing extra arguments that are setuptools
194 # specific to setup
220 # specific to setup
195 setuptools_extra_args = {}
221 setuptools_extra_args = {}
196
222
197 if 'setuptools' in sys.modules:
223 if 'setuptools' in sys.modules:
198 setuptools_extra_args['zip_safe'] = False
224 setuptools_extra_args['zip_safe'] = False
199 setuptools_extra_args['entry_points'] = find_scripts(True)
225 setuptools_extra_args['entry_points'] = find_scripts(True)
200 setup_args['extras_require'] = dict(
226 setup_args['extras_require'] = dict(
201 parallel = 'pyzmq>=2.1.4',
227 parallel = 'pyzmq>=2.1.4',
202 zmq = 'pyzmq>=2.1.4',
228 zmq = 'pyzmq>=2.1.4',
203 doc = 'Sphinx>=0.3',
229 doc = 'Sphinx>=0.3',
204 test = 'nose>=0.10.1',
230 test = 'nose>=0.10.1',
205 notebook = 'tornado>=2.0'
231 notebook = 'tornado>=2.0'
206 )
232 )
207 requires = setup_args.setdefault('install_requires', [])
233 requires = setup_args.setdefault('install_requires', [])
208 setupext.display_status = False
234 setupext.display_status = False
209 if not setupext.check_for_readline():
235 if not setupext.check_for_readline():
210 if sys.platform == 'darwin':
236 if sys.platform == 'darwin':
211 requires.append('readline')
237 requires.append('readline')
212 elif sys.platform.startswith('win'):
238 elif sys.platform.startswith('win'):
213 # Pyreadline 64 bit windows issue solved in versions >=1.7.1
239 # Pyreadline 64 bit windows issue solved in versions >=1.7.1
214 # Also solves issues with some older versions of pyreadline that
240 # Also solves issues with some older versions of pyreadline that
215 # satisfy the unconstrained depdendency.
241 # satisfy the unconstrained depdendency.
216 requires.append('pyreadline>=1.7.1')
242 requires.append('pyreadline>=1.7.1')
217 else:
243 else:
218 pass
244 pass
219 # do we want to install readline here?
245 # do we want to install readline here?
220
246
221 # Script to be run by the windows binary installer after the default setup
247 # Script to be run by the windows binary installer after the default setup
222 # routine, to add shortcuts and similar windows-only things. Windows
248 # routine, to add shortcuts and similar windows-only things. Windows
223 # post-install scripts MUST reside in the scripts/ dir, otherwise distutils
249 # post-install scripts MUST reside in the scripts/ dir, otherwise distutils
224 # doesn't find them.
250 # doesn't find them.
225 if 'bdist_wininst' in sys.argv:
251 if 'bdist_wininst' in sys.argv:
226 if len(sys.argv) > 2 and \
252 if len(sys.argv) > 2 and \
227 ('sdist' in sys.argv or 'bdist_rpm' in sys.argv):
253 ('sdist' in sys.argv or 'bdist_rpm' in sys.argv):
228 print >> sys.stderr, "ERROR: bdist_wininst must be run alone. Exiting."
254 print >> sys.stderr, "ERROR: bdist_wininst must be run alone. Exiting."
229 sys.exit(1)
255 sys.exit(1)
230 setup_args['scripts'] = [pjoin('scripts','ipython_win_post_install.py')]
256 setup_args['scripts'] = [pjoin('scripts','ipython_win_post_install.py')]
231 setup_args['options'] = {"bdist_wininst":
257 setup_args['options'] = {"bdist_wininst":
232 {"install_script":
258 {"install_script":
233 "ipython_win_post_install.py"}}
259 "ipython_win_post_install.py"}}
234
260
235 if PY3:
261 if PY3:
236 setuptools_extra_args['use_2to3'] = True
262 setuptools_extra_args['use_2to3'] = True
237 from setuptools.command.build_py import build_py
263 from setuptools.command.build_py import build_py
238 setup_args['cmdclass'] = {'build_py': record_commit_info('IPython', build_cmd=build_py)}
264 setup_args['cmdclass'] = {'build_py': record_commit_info('IPython', build_cmd=build_py)}
239 setuptools_extra_args['entry_points'] = find_scripts(True, suffix='3')
265 setuptools_extra_args['entry_points'] = find_scripts(True, suffix='3')
240 setuptools._dont_write_bytecode = True
266 setuptools._dont_write_bytecode = True
241 else:
267 else:
242 # If we are running without setuptools, call this function which will
268 # If we are running without setuptools, call this function which will
243 # check for dependencies an inform the user what is needed. This is
269 # check for dependencies an inform the user what is needed. This is
244 # just to make life easy for users.
270 # just to make life easy for users.
245 check_for_dependencies()
271 check_for_dependencies()
246 setup_args['scripts'] = find_scripts(False)
272 setup_args['scripts'] = find_scripts(False)
247
273
248 #---------------------------------------------------------------------------
274 #---------------------------------------------------------------------------
249 # Do the actual setup now
275 # Do the actual setup now
250 #---------------------------------------------------------------------------
276 #---------------------------------------------------------------------------
251
277
252 setup_args.update(setuptools_extra_args)
278 setup_args.update(setuptools_extra_args)
253
279
254 def main():
280 def main():
255 setup(**setup_args)
281 setup(**setup_args)
256 cleanup()
282 cleanup()
257
283
258 if __name__ == '__main__':
284 if __name__ == '__main__':
259 main()
285 main()
@@ -1,51 +1,52 b''
1 """
1 """
2 build [and upload] Windows IPython releases
2 build [and upload] Windows IPython releases
3
3
4 usage:
4 usage:
5
5
6 python tools/release_windows.py [--github] [--pypi]
6 python tools/release_windows.py [--github] [--pypi]
7
7
8 Meant to be run on Windows
8 Meant to be run on Windows
9
9
10 Requires that you have python and python3 on your PATH
10 Requires that you have python and python3 on your PATH
11 """
11 """
12
12
13 import glob
13 import glob
14 import os
14 import os
15 import shutil
15 import shutil
16 import sys
16 import sys
17
17
18 from toollib import sh
18 from toollib import sh
19 try:
19 try:
20 import gh_api
20 import gh_api
21 except ImportError:
21 except ImportError:
22 gh_api = None
22 gh_api = None
23
23
24 github = '--github' in sys.argv
24 github = '--github' in sys.argv
25
25
26 cmd_t = "{py} setup.py bdist_wininst --plat-name={plat}"
26 cmd_t = "{py} setup.py bdist_wininst --plat-name={plat}"
27
27
28 if '--pypi' in sys.argv:
28 pypi = '--pypi' in sys.argv
29 raise NotImplementedError("pypi upload doesn't work yet")
29 pypi_cmd_t = "python setup.py upload_wininst -f {fname}"
30 cmd_t += ' upload'
31
30
32 for py in ['python', 'python3']:
31 for py in ['python', 'python3']:
33 # deliberately mangle the name,
32 # deliberately mangle the name,
34 # so easy_install doesn't find these and do horrible wrong things
33 # so easy_install doesn't find these and do horrible wrong things
35 v = 3 if py.endswith('3') else 2
34 v = 3 if py.endswith('3') else 2
36 try:
35 try:
37 shutil.rmtree('build')
36 shutil.rmtree('build')
38 except OSError:
37 except OSError:
39 pass
38 pass
40 for plat in ['win32', 'win-amd64']:
39 for plat in ['win32', 'win-amd64']:
41 cmd = cmd_t.format(**locals())
40 cmd = cmd_t.format(**locals())
42 sh(cmd)
41 sh(cmd)
43 orig = glob.glob(os.path.join('dist', 'ipython-*.{plat}.exe'.format(**locals())))[0]
42 orig = glob.glob(os.path.join('dist', 'ipython-*.{plat}.exe'.format(**locals())))[0]
44 mangled = orig.replace('.{plat}.exe'.format(**locals()),
43 mangled = orig.replace('.{plat}.exe'.format(**locals()),
45 '.py{v}-{plat}.exe'.format(**locals())
44 '.py{v}-{plat}.exe'.format(**locals())
46 )
45 )
47 os.rename(orig, mangled)
46 os.rename(orig, mangled)
47 if pypi:
48 sh(pypi_cmd_t.format(fname=mangled))
48 if github and gh_api:
49 if github and gh_api:
49 print ("Uploading %s to GitHub" % mangled)
50 print ("Uploading %s to GitHub" % mangled)
50 desc = "IPython Installer for Python {v}.x on {plat}".format(**locals())
51 desc = "IPython Installer for Python {v}.x on {plat}".format(**locals())
51 gh_api.post_download('ipython/ipython', mangled, description=desc)
52 gh_api.post_download('ipython/ipython', mangled, description=desc)
General Comments 0
You need to be logged in to leave comments. Login now