Mercurial > libervia-backend
annotate distribute_setup.py @ 853:c2f6ada7858f
core (sqlite): automatic database update:
- new Updater class check database consistency (by calculating a hash on the .schema), and updates base if necessary
- database now has a version (1 for current, 0 will be for 0.3's database), for each change this version will be increased
- creation statements and update statements are in the form of dict of dict with tuples. There is a help text at the top of the module to explain how it works
- if we are on a development version, the updater try to update the database automaticaly (without deleting table or columns). The Updater.generateUpdateData method can be used to ease the creation of update data (i.e. the dictionary at the top, see the one for the key 1 for an example).
- if there is an inconsistency, an exception is raised, and a message indicate the SQL statements that should fix the situation.
- well... this is rather complicated, a KISS method would maybe have been better. The future will say if we need to simplify it :-/
- new DatabaseError exception
author | Goffi <goffi@goffi.org> |
---|---|
date | Sun, 23 Feb 2014 23:30:32 +0100 |
parents | efd92a645220 |
children |
rev | line source |
---|---|
231 | 1 #!python |
2 """Bootstrap distribute installation | |
3 | |
4 If you want to use setuptools in your package's setup.py, just include this | |
5 file in the same directory with it, and add this to the top of your setup.py:: | |
6 | |
7 from distribute_setup import use_setuptools | |
8 use_setuptools() | |
9 | |
10 If you want to require a specific version of setuptools, set a download | |
11 mirror, or use an alternate download directory, you can do so by supplying | |
12 the appropriate options to ``use_setuptools()``. | |
13 | |
14 This file can also be run as a script to install or upgrade setuptools. | |
15 """ | |
16 import os | |
843
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
17 import shutil |
231 | 18 import sys |
19 import time | |
20 import fnmatch | |
21 import tempfile | |
22 import tarfile | |
843
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
23 import optparse |
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
24 |
231 | 25 from distutils import log |
26 | |
27 try: | |
28 from site import USER_SITE | |
29 except ImportError: | |
30 USER_SITE = None | |
31 | |
32 try: | |
33 import subprocess | |
34 | |
35 def _python_cmd(*args): | |
843
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
36 args = (sys.executable,) + args |
231 | 37 return subprocess.call(args) == 0 |
38 | |
39 except ImportError: | |
40 # will be used for python 2.3 | |
41 def _python_cmd(*args): | |
843
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
42 args = (sys.executable,) + args |
231 | 43 # quoting arguments if windows |
44 if sys.platform == 'win32': | |
45 def quote(arg): | |
46 if ' ' in arg: | |
47 return '"%s"' % arg | |
48 return arg | |
49 args = [quote(arg) for arg in args] | |
50 return os.spawnl(os.P_WAIT, sys.executable, *args) == 0 | |
51 | |
843
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
52 DEFAULT_VERSION = "0.6.49" |
231 | 53 DEFAULT_URL = "http://pypi.python.org/packages/source/d/distribute/" |
54 SETUPTOOLS_FAKED_VERSION = "0.6c11" | |
55 | |
56 SETUPTOOLS_PKG_INFO = """\ | |
57 Metadata-Version: 1.0 | |
58 Name: setuptools | |
59 Version: %s | |
60 Summary: xxxx | |
61 Home-page: xxx | |
62 Author: xxx | |
63 Author-email: xxx | |
64 License: xxx | |
65 Description: xxx | |
66 """ % SETUPTOOLS_FAKED_VERSION | |
67 | |
68 | |
843
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
69 def _install(tarball, install_args=()): |
231 | 70 # extracting the tarball |
71 tmpdir = tempfile.mkdtemp() | |
72 log.warn('Extracting in %s', tmpdir) | |
73 old_wd = os.getcwd() | |
74 try: | |
75 os.chdir(tmpdir) | |
76 tar = tarfile.open(tarball) | |
77 _extractall(tar) | |
78 tar.close() | |
79 | |
80 # going in the directory | |
81 subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0]) | |
82 os.chdir(subdir) | |
83 log.warn('Now working in %s', subdir) | |
84 | |
85 # installing | |
86 log.warn('Installing Distribute') | |
843
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
87 if not _python_cmd('setup.py', 'install', *install_args): |
231 | 88 log.warn('Something went wrong during the installation.') |
89 log.warn('See the error message above.') | |
843
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
90 # exitcode will be 2 |
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
91 return 2 |
231 | 92 finally: |
93 os.chdir(old_wd) | |
843
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
94 shutil.rmtree(tmpdir) |
231 | 95 |
96 | |
97 def _build_egg(egg, tarball, to_dir): | |
98 # extracting the tarball | |
99 tmpdir = tempfile.mkdtemp() | |
100 log.warn('Extracting in %s', tmpdir) | |
101 old_wd = os.getcwd() | |
102 try: | |
103 os.chdir(tmpdir) | |
104 tar = tarfile.open(tarball) | |
105 _extractall(tar) | |
106 tar.close() | |
107 | |
108 # going in the directory | |
109 subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0]) | |
110 os.chdir(subdir) | |
111 log.warn('Now working in %s', subdir) | |
112 | |
113 # building an egg | |
114 log.warn('Building a Distribute egg in %s', to_dir) | |
115 _python_cmd('setup.py', '-q', 'bdist_egg', '--dist-dir', to_dir) | |
116 | |
117 finally: | |
118 os.chdir(old_wd) | |
843
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
119 shutil.rmtree(tmpdir) |
231 | 120 # returning the result |
121 log.warn(egg) | |
122 if not os.path.exists(egg): | |
123 raise IOError('Could not build the egg.') | |
124 | |
125 | |
126 def _do_download(version, download_base, to_dir, download_delay): | |
127 egg = os.path.join(to_dir, 'distribute-%s-py%d.%d.egg' | |
128 % (version, sys.version_info[0], sys.version_info[1])) | |
129 if not os.path.exists(egg): | |
130 tarball = download_setuptools(version, download_base, | |
131 to_dir, download_delay) | |
132 _build_egg(egg, tarball, to_dir) | |
133 sys.path.insert(0, egg) | |
134 import setuptools | |
135 setuptools.bootstrap_install_from = egg | |
136 | |
137 | |
138 def use_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL, | |
139 to_dir=os.curdir, download_delay=15, no_fake=True): | |
140 # making sure we use the absolute path | |
141 to_dir = os.path.abspath(to_dir) | |
142 was_imported = 'pkg_resources' in sys.modules or \ | |
143 'setuptools' in sys.modules | |
144 try: | |
145 try: | |
146 import pkg_resources | |
843
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
147 |
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
148 # Setuptools 0.7b and later is a suitable (and preferable) |
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
149 # substitute for any Distribute version. |
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
150 try: |
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
151 pkg_resources.require("setuptools>=0.7b") |
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
152 return |
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
153 except (pkg_resources.DistributionNotFound, |
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
154 pkg_resources.VersionConflict): |
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
155 pass |
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
156 |
231 | 157 if not hasattr(pkg_resources, '_distribute'): |
158 if not no_fake: | |
159 _fake_setuptools() | |
160 raise ImportError | |
161 except ImportError: | |
162 return _do_download(version, download_base, to_dir, download_delay) | |
163 try: | |
586
6a718ede8be1
Fix coding style in setup.py.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
231
diff
changeset
|
164 pkg_resources.require("distribute>=" + version) |
231 | 165 return |
166 except pkg_resources.VersionConflict: | |
167 e = sys.exc_info()[1] | |
168 if was_imported: | |
169 sys.stderr.write( | |
843
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
170 "The required version of distribute (>=%s) is not available,\n" |
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
171 "and can't be installed while this script is running. Please\n" |
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
172 "install a more recent version first, using\n" |
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
173 "'easy_install -U distribute'." |
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
174 "\n\n(Currently using %r)\n" % (version, e.args[0])) |
231 | 175 sys.exit(2) |
176 else: | |
177 del pkg_resources, sys.modules['pkg_resources'] # reload ok | |
178 return _do_download(version, download_base, to_dir, | |
179 download_delay) | |
180 except pkg_resources.DistributionNotFound: | |
181 return _do_download(version, download_base, to_dir, | |
182 download_delay) | |
183 finally: | |
184 if not no_fake: | |
185 _create_fake_setuptools_pkg_info(to_dir) | |
186 | |
586
6a718ede8be1
Fix coding style in setup.py.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
231
diff
changeset
|
187 |
231 | 188 def download_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL, |
189 to_dir=os.curdir, delay=15): | |
190 """Download distribute from a specified location and return its filename | |
191 | |
192 `version` should be a valid distribute version number that is available | |
193 as an egg for download under the `download_base` URL (which should end | |
194 with a '/'). `to_dir` is the directory where the egg will be downloaded. | |
195 `delay` is the number of seconds to pause before an actual download | |
196 attempt. | |
197 """ | |
198 # making sure we use the absolute path | |
199 to_dir = os.path.abspath(to_dir) | |
200 try: | |
201 from urllib.request import urlopen | |
202 except ImportError: | |
203 from urllib2 import urlopen | |
204 tgz_name = "distribute-%s.tar.gz" % version | |
205 url = download_base + tgz_name | |
206 saveto = os.path.join(to_dir, tgz_name) | |
207 src = dst = None | |
208 if not os.path.exists(saveto): # Avoid repeated downloads | |
209 try: | |
210 log.warn("Downloading %s", url) | |
211 src = urlopen(url) | |
212 # Read/write all in one block, so we don't create a corrupt file | |
213 # if the download is interrupted. | |
214 data = src.read() | |
215 dst = open(saveto, "wb") | |
216 dst.write(data) | |
217 finally: | |
218 if src: | |
219 src.close() | |
220 if dst: | |
221 dst.close() | |
222 return os.path.realpath(saveto) | |
223 | |
586
6a718ede8be1
Fix coding style in setup.py.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
231
diff
changeset
|
224 |
231 | 225 def _no_sandbox(function): |
226 def __no_sandbox(*args, **kw): | |
227 try: | |
228 from setuptools.sandbox import DirectorySandbox | |
229 if not hasattr(DirectorySandbox, '_old'): | |
230 def violation(*args): | |
231 pass | |
232 DirectorySandbox._old = DirectorySandbox._violation | |
233 DirectorySandbox._violation = violation | |
234 patched = True | |
235 else: | |
236 patched = False | |
237 except ImportError: | |
238 patched = False | |
239 | |
240 try: | |
241 return function(*args, **kw) | |
242 finally: | |
243 if patched: | |
244 DirectorySandbox._violation = DirectorySandbox._old | |
245 del DirectorySandbox._old | |
246 | |
247 return __no_sandbox | |
248 | |
586
6a718ede8be1
Fix coding style in setup.py.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
231
diff
changeset
|
249 |
231 | 250 def _patch_file(path, content): |
251 """Will backup the file then patch it""" | |
843
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
252 f = open(path) |
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
253 existing_content = f.read() |
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
254 f.close() |
231 | 255 if existing_content == content: |
256 # already patched | |
257 log.warn('Already patched.') | |
258 return False | |
259 log.warn('Patching...') | |
260 _rename_path(path) | |
261 f = open(path, 'w') | |
262 try: | |
263 f.write(content) | |
264 finally: | |
265 f.close() | |
266 return True | |
267 | |
268 _patch_file = _no_sandbox(_patch_file) | |
269 | |
586
6a718ede8be1
Fix coding style in setup.py.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
231
diff
changeset
|
270 |
231 | 271 def _same_content(path, content): |
843
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
272 f = open(path) |
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
273 existing_content = f.read() |
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
274 f.close() |
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
275 return existing_content == content |
231 | 276 |
586
6a718ede8be1
Fix coding style in setup.py.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
231
diff
changeset
|
277 |
231 | 278 def _rename_path(path): |
279 new_name = path + '.OLD.%s' % time.time() | |
843
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
280 log.warn('Renaming %s to %s', path, new_name) |
231 | 281 os.rename(path, new_name) |
282 return new_name | |
283 | |
586
6a718ede8be1
Fix coding style in setup.py.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
231
diff
changeset
|
284 |
231 | 285 def _remove_flat_installation(placeholder): |
286 if not os.path.isdir(placeholder): | |
287 log.warn('Unkown installation at %s', placeholder) | |
288 return False | |
289 found = False | |
290 for file in os.listdir(placeholder): | |
291 if fnmatch.fnmatch(file, 'setuptools*.egg-info'): | |
292 found = True | |
293 break | |
294 if not found: | |
295 log.warn('Could not locate setuptools*.egg-info') | |
296 return | |
297 | |
843
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
298 log.warn('Moving elements out of the way...') |
231 | 299 pkg_info = os.path.join(placeholder, file) |
300 if os.path.isdir(pkg_info): | |
301 patched = _patch_egg_dir(pkg_info) | |
302 else: | |
303 patched = _patch_file(pkg_info, SETUPTOOLS_PKG_INFO) | |
304 | |
305 if not patched: | |
306 log.warn('%s already patched.', pkg_info) | |
307 return False | |
308 # now let's move the files out of the way | |
309 for element in ('setuptools', 'pkg_resources.py', 'site.py'): | |
310 element = os.path.join(placeholder, element) | |
311 if os.path.exists(element): | |
312 _rename_path(element) | |
313 else: | |
314 log.warn('Could not find the %s element of the ' | |
315 'Setuptools distribution', element) | |
316 return True | |
317 | |
318 _remove_flat_installation = _no_sandbox(_remove_flat_installation) | |
319 | |
586
6a718ede8be1
Fix coding style in setup.py.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
231
diff
changeset
|
320 |
231 | 321 def _after_install(dist): |
322 log.warn('After install bootstrap.') | |
323 placeholder = dist.get_command_obj('install').install_purelib | |
324 _create_fake_setuptools_pkg_info(placeholder) | |
325 | |
586
6a718ede8be1
Fix coding style in setup.py.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
231
diff
changeset
|
326 |
231 | 327 def _create_fake_setuptools_pkg_info(placeholder): |
328 if not placeholder or not os.path.exists(placeholder): | |
329 log.warn('Could not find the install location') | |
330 return | |
331 pyver = '%s.%s' % (sys.version_info[0], sys.version_info[1]) | |
332 setuptools_file = 'setuptools-%s-py%s.egg-info' % \ | |
843
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
333 (SETUPTOOLS_FAKED_VERSION, pyver) |
231 | 334 pkg_info = os.path.join(placeholder, setuptools_file) |
335 if os.path.exists(pkg_info): | |
336 log.warn('%s already exists', pkg_info) | |
337 return | |
338 | |
339 log.warn('Creating %s', pkg_info) | |
843
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
340 try: |
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
341 f = open(pkg_info, 'w') |
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
342 except EnvironmentError: |
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
343 log.warn("Don't have permissions to write %s, skipping", pkg_info) |
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
344 return |
231 | 345 try: |
346 f.write(SETUPTOOLS_PKG_INFO) | |
347 finally: | |
348 f.close() | |
349 | |
350 pth_file = os.path.join(placeholder, 'setuptools.pth') | |
351 log.warn('Creating %s', pth_file) | |
352 f = open(pth_file, 'w') | |
353 try: | |
354 f.write(os.path.join(os.curdir, setuptools_file)) | |
355 finally: | |
356 f.close() | |
357 | |
843
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
358 _create_fake_setuptools_pkg_info = _no_sandbox( |
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
359 _create_fake_setuptools_pkg_info |
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
360 ) |
231 | 361 |
586
6a718ede8be1
Fix coding style in setup.py.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
231
diff
changeset
|
362 |
231 | 363 def _patch_egg_dir(path): |
364 # let's check if it's already patched | |
365 pkg_info = os.path.join(path, 'EGG-INFO', 'PKG-INFO') | |
366 if os.path.exists(pkg_info): | |
367 if _same_content(pkg_info, SETUPTOOLS_PKG_INFO): | |
368 log.warn('%s already patched.', pkg_info) | |
369 return False | |
370 _rename_path(path) | |
371 os.mkdir(path) | |
372 os.mkdir(os.path.join(path, 'EGG-INFO')) | |
373 pkg_info = os.path.join(path, 'EGG-INFO', 'PKG-INFO') | |
374 f = open(pkg_info, 'w') | |
375 try: | |
376 f.write(SETUPTOOLS_PKG_INFO) | |
377 finally: | |
378 f.close() | |
379 return True | |
380 | |
381 _patch_egg_dir = _no_sandbox(_patch_egg_dir) | |
382 | |
586
6a718ede8be1
Fix coding style in setup.py.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
231
diff
changeset
|
383 |
231 | 384 def _before_install(): |
385 log.warn('Before install bootstrap.') | |
386 _fake_setuptools() | |
387 | |
388 | |
389 def _under_prefix(location): | |
390 if 'install' not in sys.argv: | |
391 return True | |
586
6a718ede8be1
Fix coding style in setup.py.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
231
diff
changeset
|
392 args = sys.argv[sys.argv.index('install') + 1:] |
231 | 393 for index, arg in enumerate(args): |
394 for option in ('--root', '--prefix'): | |
395 if arg.startswith('%s=' % option): | |
396 top_dir = arg.split('root=')[-1] | |
397 return location.startswith(top_dir) | |
398 elif arg == option: | |
399 if len(args) > index: | |
586
6a718ede8be1
Fix coding style in setup.py.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
231
diff
changeset
|
400 top_dir = args[index + 1] |
231 | 401 return location.startswith(top_dir) |
402 if arg == '--user' and USER_SITE is not None: | |
403 return location.startswith(USER_SITE) | |
404 return True | |
405 | |
406 | |
407 def _fake_setuptools(): | |
408 log.warn('Scanning installed packages') | |
409 try: | |
410 import pkg_resources | |
411 except ImportError: | |
412 # we're cool | |
413 log.warn('Setuptools or Distribute does not seem to be installed.') | |
414 return | |
415 ws = pkg_resources.working_set | |
416 try: | |
843
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
417 setuptools_dist = ws.find( |
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
418 pkg_resources.Requirement.parse('setuptools', replacement=False) |
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
419 ) |
231 | 420 except TypeError: |
421 # old distribute API | |
843
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
422 setuptools_dist = ws.find( |
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
423 pkg_resources.Requirement.parse('setuptools') |
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
424 ) |
231 | 425 |
426 if setuptools_dist is None: | |
427 log.warn('No setuptools distribution found') | |
428 return | |
429 # detecting if it was already faked | |
430 setuptools_location = setuptools_dist.location | |
431 log.warn('Setuptools installation detected at %s', setuptools_location) | |
432 | |
433 # if --root or --preix was provided, and if | |
434 # setuptools is not located in them, we don't patch it | |
435 if not _under_prefix(setuptools_location): | |
436 log.warn('Not patching, --root or --prefix is installing Distribute' | |
437 ' in another location') | |
438 return | |
439 | |
440 # let's see if its an egg | |
441 if not setuptools_location.endswith('.egg'): | |
442 log.warn('Non-egg installation') | |
443 res = _remove_flat_installation(setuptools_location) | |
444 if not res: | |
445 return | |
446 else: | |
447 log.warn('Egg installation') | |
448 pkg_info = os.path.join(setuptools_location, 'EGG-INFO', 'PKG-INFO') | |
449 if (os.path.exists(pkg_info) and | |
843
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
450 _same_content(pkg_info, SETUPTOOLS_PKG_INFO)): |
231 | 451 log.warn('Already patched.') |
452 return | |
453 log.warn('Patching...') | |
454 # let's create a fake egg replacing setuptools one | |
455 res = _patch_egg_dir(setuptools_location) | |
456 if not res: | |
457 return | |
843
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
458 log.warn('Patching complete.') |
231 | 459 _relaunch() |
460 | |
461 | |
462 def _relaunch(): | |
463 log.warn('Relaunching...') | |
464 # we have to relaunch the process | |
465 # pip marker to avoid a relaunch bug | |
843
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
466 _cmd1 = ['-c', 'install', '--single-version-externally-managed'] |
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
467 _cmd2 = ['-c', 'install', '--record'] |
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
468 if sys.argv[:3] == _cmd1 or sys.argv[:3] == _cmd2: |
231 | 469 sys.argv[0] = 'setup.py' |
470 args = [sys.executable] + sys.argv | |
471 sys.exit(subprocess.call(args)) | |
472 | |
473 | |
474 def _extractall(self, path=".", members=None): | |
475 """Extract all members from the archive to the current working | |
476 directory and set owner, modification time and permissions on | |
477 directories afterwards. `path' specifies a different directory | |
478 to extract to. `members' is optional and must be a subset of the | |
479 list returned by getmembers(). | |
480 """ | |
481 import copy | |
482 import operator | |
483 from tarfile import ExtractError | |
484 directories = [] | |
485 | |
486 if members is None: | |
487 members = self | |
488 | |
489 for tarinfo in members: | |
490 if tarinfo.isdir(): | |
491 # Extract directories with a safe mode. | |
492 directories.append(tarinfo) | |
493 tarinfo = copy.copy(tarinfo) | |
586
6a718ede8be1
Fix coding style in setup.py.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
231
diff
changeset
|
494 tarinfo.mode = 448 # decimal for oct 0700 |
231 | 495 self.extract(tarinfo, path) |
496 | |
497 # Reverse sort directories. | |
498 if sys.version_info < (2, 4): | |
499 def sorter(dir1, dir2): | |
500 return cmp(dir1.name, dir2.name) | |
501 directories.sort(sorter) | |
502 directories.reverse() | |
503 else: | |
504 directories.sort(key=operator.attrgetter('name'), reverse=True) | |
505 | |
506 # Set correct owner, mtime and filemode on directories. | |
507 for tarinfo in directories: | |
508 dirpath = os.path.join(path, tarinfo.name) | |
509 try: | |
510 self.chown(tarinfo, dirpath) | |
511 self.utime(tarinfo, dirpath) | |
512 self.chmod(tarinfo, dirpath) | |
513 except ExtractError: | |
514 e = sys.exc_info()[1] | |
515 if self.errorlevel > 1: | |
516 raise | |
517 else: | |
518 self._dbg(1, "tarfile: %s" % e) | |
519 | |
520 | |
843
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
521 def _build_install_args(options): |
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
522 """ |
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
523 Build the arguments to 'python setup.py install' on the distribute package |
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
524 """ |
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
525 install_args = [] |
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
526 if options.user_install: |
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
527 if sys.version_info < (2, 6): |
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
528 log.warn("--user requires Python 2.6 or later") |
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
529 raise SystemExit(1) |
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
530 install_args.append('--user') |
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
531 return install_args |
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
532 |
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
533 def _parse_args(): |
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
534 """ |
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
535 Parse the command line for options |
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
536 """ |
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
537 parser = optparse.OptionParser() |
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
538 parser.add_option( |
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
539 '--user', dest='user_install', action='store_true', default=False, |
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
540 help='install in user site package (requires Python 2.6 or later)') |
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
541 parser.add_option( |
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
542 '--download-base', dest='download_base', metavar="URL", |
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
543 default=DEFAULT_URL, |
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
544 help='alternative URL from where to download the distribute package') |
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
545 options, args = parser.parse_args() |
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
546 # positional arguments are ignored |
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
547 return options |
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
548 |
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
549 def main(version=DEFAULT_VERSION): |
231 | 550 """Install or upgrade setuptools and EasyInstall""" |
843
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
551 options = _parse_args() |
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
552 tarball = download_setuptools(download_base=options.download_base) |
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
553 return _install(tarball, _build_install_args(options)) |
231 | 554 |
555 if __name__ == '__main__': | |
843
efd92a645220
misc: update distribute_setup.py to version 0.6.49
Thomas Preud'homme <robotux@celest.fr>
parents:
586
diff
changeset
|
556 sys.exit(main()) |