|
1 #!/usr/bin/env python2.6 |
|
2 ## WARNING: This file is generated |
|
3 #!/usr/bin/env python |
|
4 """Create a "virtual" Python installation |
|
5 """ |
|
6 |
|
7 virtualenv_version = "1.4.9" |
|
8 |
|
9 import sys |
|
10 import os |
|
11 import optparse |
|
12 import re |
|
13 import shutil |
|
14 import logging |
|
15 import tempfile |
|
16 import distutils.sysconfig |
|
17 try: |
|
18 import subprocess |
|
19 except ImportError, e: |
|
20 if sys.version_info <= (2, 3): |
|
21 print 'ERROR: %s' % e |
|
22 print 'ERROR: this script requires Python 2.4 or greater; or at least the subprocess module.' |
|
23 print 'If you copy subprocess.py from a newer version of Python this script will probably work' |
|
24 sys.exit(101) |
|
25 else: |
|
26 raise |
|
27 try: |
|
28 set |
|
29 except NameError: |
|
30 from sets import Set as set |
|
31 |
|
32 join = os.path.join |
|
33 py_version = 'python%s.%s' % (sys.version_info[0], sys.version_info[1]) |
|
34 is_jython = sys.platform.startswith('java') |
|
35 expected_exe = is_jython and 'jython' or 'python' |
|
36 |
|
37 REQUIRED_MODULES = ['os', 'posix', 'posixpath', 'nt', 'ntpath', 'genericpath', |
|
38 'fnmatch', 'locale', 'encodings', 'codecs', |
|
39 'stat', 'UserDict', 'readline', 'copy_reg', 'types', |
|
40 're', 'sre', 'sre_parse', 'sre_constants', 'sre_compile', |
|
41 'lib-dynload', 'config', 'zlib'] |
|
42 |
|
43 if sys.version_info[:2] >= (2, 6): |
|
44 REQUIRED_MODULES.extend(['warnings', 'linecache', '_abcoll', 'abc']) |
|
45 if sys.version_info[:2] <= (2, 3): |
|
46 REQUIRED_MODULES.extend(['sets', '__future__']) |
|
47 |
|
48 class Logger(object): |
|
49 |
|
50 """ |
|
51 Logging object for use in command-line script. Allows ranges of |
|
52 levels, to avoid some redundancy of displayed information. |
|
53 """ |
|
54 |
|
55 DEBUG = logging.DEBUG |
|
56 INFO = logging.INFO |
|
57 NOTIFY = (logging.INFO+logging.WARN)/2 |
|
58 WARN = WARNING = logging.WARN |
|
59 ERROR = logging.ERROR |
|
60 FATAL = logging.FATAL |
|
61 |
|
62 LEVELS = [DEBUG, INFO, NOTIFY, WARN, ERROR, FATAL] |
|
63 |
|
64 def __init__(self, consumers): |
|
65 self.consumers = consumers |
|
66 self.indent = 0 |
|
67 self.in_progress = None |
|
68 self.in_progress_hanging = False |
|
69 |
|
70 def debug(self, msg, *args, **kw): |
|
71 self.log(self.DEBUG, msg, *args, **kw) |
|
72 def info(self, msg, *args, **kw): |
|
73 self.log(self.INFO, msg, *args, **kw) |
|
74 def notify(self, msg, *args, **kw): |
|
75 self.log(self.NOTIFY, msg, *args, **kw) |
|
76 def warn(self, msg, *args, **kw): |
|
77 self.log(self.WARN, msg, *args, **kw) |
|
78 def error(self, msg, *args, **kw): |
|
79 self.log(self.WARN, msg, *args, **kw) |
|
80 def fatal(self, msg, *args, **kw): |
|
81 self.log(self.FATAL, msg, *args, **kw) |
|
82 def log(self, level, msg, *args, **kw): |
|
83 if args: |
|
84 if kw: |
|
85 raise TypeError( |
|
86 "You may give positional or keyword arguments, not both") |
|
87 args = args or kw |
|
88 rendered = None |
|
89 for consumer_level, consumer in self.consumers: |
|
90 if self.level_matches(level, consumer_level): |
|
91 if (self.in_progress_hanging |
|
92 and consumer in (sys.stdout, sys.stderr)): |
|
93 self.in_progress_hanging = False |
|
94 sys.stdout.write('\n') |
|
95 sys.stdout.flush() |
|
96 if rendered is None: |
|
97 if args: |
|
98 rendered = msg % args |
|
99 else: |
|
100 rendered = msg |
|
101 rendered = ' '*self.indent + rendered |
|
102 if hasattr(consumer, 'write'): |
|
103 consumer.write(rendered+'\n') |
|
104 else: |
|
105 consumer(rendered) |
|
106 |
|
107 def start_progress(self, msg): |
|
108 assert not self.in_progress, ( |
|
109 "Tried to start_progress(%r) while in_progress %r" |
|
110 % (msg, self.in_progress)) |
|
111 if self.level_matches(self.NOTIFY, self._stdout_level()): |
|
112 sys.stdout.write(msg) |
|
113 sys.stdout.flush() |
|
114 self.in_progress_hanging = True |
|
115 else: |
|
116 self.in_progress_hanging = False |
|
117 self.in_progress = msg |
|
118 |
|
119 def end_progress(self, msg='done.'): |
|
120 assert self.in_progress, ( |
|
121 "Tried to end_progress without start_progress") |
|
122 if self.stdout_level_matches(self.NOTIFY): |
|
123 if not self.in_progress_hanging: |
|
124 # Some message has been printed out since start_progress |
|
125 sys.stdout.write('...' + self.in_progress + msg + '\n') |
|
126 sys.stdout.flush() |
|
127 else: |
|
128 sys.stdout.write(msg + '\n') |
|
129 sys.stdout.flush() |
|
130 self.in_progress = None |
|
131 self.in_progress_hanging = False |
|
132 |
|
133 def show_progress(self): |
|
134 """If we are in a progress scope, and no log messages have been |
|
135 shown, write out another '.'""" |
|
136 if self.in_progress_hanging: |
|
137 sys.stdout.write('.') |
|
138 sys.stdout.flush() |
|
139 |
|
140 def stdout_level_matches(self, level): |
|
141 """Returns true if a message at this level will go to stdout""" |
|
142 return self.level_matches(level, self._stdout_level()) |
|
143 |
|
144 def _stdout_level(self): |
|
145 """Returns the level that stdout runs at""" |
|
146 for level, consumer in self.consumers: |
|
147 if consumer is sys.stdout: |
|
148 return level |
|
149 return self.FATAL |
|
150 |
|
151 def level_matches(self, level, consumer_level): |
|
152 """ |
|
153 >>> l = Logger() |
|
154 >>> l.level_matches(3, 4) |
|
155 False |
|
156 >>> l.level_matches(3, 2) |
|
157 True |
|
158 >>> l.level_matches(slice(None, 3), 3) |
|
159 False |
|
160 >>> l.level_matches(slice(None, 3), 2) |
|
161 True |
|
162 >>> l.level_matches(slice(1, 3), 1) |
|
163 True |
|
164 >>> l.level_matches(slice(2, 3), 1) |
|
165 False |
|
166 """ |
|
167 if isinstance(level, slice): |
|
168 start, stop = level.start, level.stop |
|
169 if start is not None and start > consumer_level: |
|
170 return False |
|
171 if stop is not None or stop <= consumer_level: |
|
172 return False |
|
173 return True |
|
174 else: |
|
175 return level >= consumer_level |
|
176 |
|
177 #@classmethod |
|
178 def level_for_integer(cls, level): |
|
179 levels = cls.LEVELS |
|
180 if level < 0: |
|
181 return levels[0] |
|
182 if level >= len(levels): |
|
183 return levels[-1] |
|
184 return levels[level] |
|
185 |
|
186 level_for_integer = classmethod(level_for_integer) |
|
187 |
|
188 def mkdir(path): |
|
189 if not os.path.exists(path): |
|
190 logger.info('Creating %s', path) |
|
191 os.makedirs(path) |
|
192 else: |
|
193 logger.info('Directory %s already exists', path) |
|
194 |
|
195 def copyfile(src, dest, symlink=True): |
|
196 if not os.path.exists(src): |
|
197 # Some bad symlink in the src |
|
198 logger.warn('Cannot find file %s (bad symlink)', src) |
|
199 return |
|
200 if os.path.exists(dest): |
|
201 logger.debug('File %s already exists', dest) |
|
202 return |
|
203 if not os.path.exists(os.path.dirname(dest)): |
|
204 logger.info('Creating parent directories for %s' % os.path.dirname(dest)) |
|
205 os.makedirs(os.path.dirname(dest)) |
|
206 if symlink and hasattr(os, 'symlink'): |
|
207 logger.info('Symlinking %s', dest) |
|
208 os.symlink(os.path.abspath(src), dest) |
|
209 else: |
|
210 logger.info('Copying to %s', dest) |
|
211 if os.path.isdir(src): |
|
212 shutil.copytree(src, dest, True) |
|
213 else: |
|
214 shutil.copy2(src, dest) |
|
215 |
|
216 def writefile(dest, content, overwrite=True): |
|
217 if not os.path.exists(dest): |
|
218 logger.info('Writing %s', dest) |
|
219 f = open(dest, 'wb') |
|
220 f.write(content) |
|
221 f.close() |
|
222 return |
|
223 else: |
|
224 f = open(dest, 'rb') |
|
225 c = f.read() |
|
226 f.close() |
|
227 if c != content: |
|
228 if not overwrite: |
|
229 logger.notify('File %s exists with different content; not overwriting', dest) |
|
230 return |
|
231 logger.notify('Overwriting %s with new content', dest) |
|
232 f = open(dest, 'wb') |
|
233 f.write(content) |
|
234 f.close() |
|
235 else: |
|
236 logger.info('Content %s already in place', dest) |
|
237 |
|
238 def rmtree(dir): |
|
239 if os.path.exists(dir): |
|
240 logger.notify('Deleting tree %s', dir) |
|
241 shutil.rmtree(dir) |
|
242 else: |
|
243 logger.info('Do not need to delete %s; already gone', dir) |
|
244 |
|
245 def make_exe(fn): |
|
246 if hasattr(os, 'chmod'): |
|
247 oldmode = os.stat(fn).st_mode & 07777 |
|
248 newmode = (oldmode | 0555) & 07777 |
|
249 os.chmod(fn, newmode) |
|
250 logger.info('Changed mode of %s to %s', fn, oct(newmode)) |
|
251 |
|
252 def _find_file(filename, dirs): |
|
253 for dir in dirs: |
|
254 if os.path.exists(join(dir, filename)): |
|
255 return join(dir, filename) |
|
256 return filename |
|
257 |
|
258 def _install_req(py_executable, unzip=False, distribute=False): |
|
259 if not distribute: |
|
260 setup_fn = 'setuptools-0.6c11-py%s.egg' % sys.version[:3] |
|
261 project_name = 'setuptools' |
|
262 bootstrap_script = EZ_SETUP_PY |
|
263 source = None |
|
264 else: |
|
265 setup_fn = None |
|
266 source = 'distribute-0.6.8.tar.gz' |
|
267 project_name = 'distribute' |
|
268 bootstrap_script = DISTRIBUTE_SETUP_PY |
|
269 try: |
|
270 # check if the global Python has distribute installed or plain |
|
271 # setuptools |
|
272 import pkg_resources |
|
273 if not hasattr(pkg_resources, '_distribute'): |
|
274 location = os.path.dirname(pkg_resources.__file__) |
|
275 logger.notify("A globally installed setuptools was found (in %s)" % location) |
|
276 logger.notify("Use the --no-site-packages option to use distribute in " |
|
277 "the virtualenv.") |
|
278 except ImportError: |
|
279 pass |
|
280 |
|
281 search_dirs = file_search_dirs() |
|
282 |
|
283 if setup_fn is not None: |
|
284 setup_fn = _find_file(setup_fn, search_dirs) |
|
285 |
|
286 if source is not None: |
|
287 source = _find_file(source, search_dirs) |
|
288 |
|
289 if is_jython and os._name == 'nt': |
|
290 # Jython's .bat sys.executable can't handle a command line |
|
291 # argument with newlines |
|
292 fd, ez_setup = tempfile.mkstemp('.py') |
|
293 os.write(fd, bootstrap_script) |
|
294 os.close(fd) |
|
295 cmd = [py_executable, ez_setup] |
|
296 else: |
|
297 cmd = [py_executable, '-c', bootstrap_script] |
|
298 if unzip: |
|
299 cmd.append('--always-unzip') |
|
300 env = {} |
|
301 if logger.stdout_level_matches(logger.DEBUG): |
|
302 cmd.append('-v') |
|
303 |
|
304 old_chdir = os.getcwd() |
|
305 if setup_fn is not None and os.path.exists(setup_fn): |
|
306 logger.info('Using existing %s egg: %s' % (project_name, setup_fn)) |
|
307 cmd.append(setup_fn) |
|
308 if os.environ.get('PYTHONPATH'): |
|
309 env['PYTHONPATH'] = setup_fn + os.path.pathsep + os.environ['PYTHONPATH'] |
|
310 else: |
|
311 env['PYTHONPATH'] = setup_fn |
|
312 else: |
|
313 # the source is found, let's chdir |
|
314 if source is not None and os.path.exists(source): |
|
315 os.chdir(os.path.dirname(source)) |
|
316 else: |
|
317 logger.info('No %s egg found; downloading' % project_name) |
|
318 cmd.extend(['--always-copy', '-U', project_name]) |
|
319 logger.start_progress('Installing %s...' % project_name) |
|
320 logger.indent += 2 |
|
321 cwd = None |
|
322 if project_name == 'distribute': |
|
323 env['DONT_PATCH_SETUPTOOLS'] = 'true' |
|
324 |
|
325 def _filter_ez_setup(line): |
|
326 return filter_ez_setup(line, project_name) |
|
327 |
|
328 if not os.access(os.getcwd(), os.W_OK): |
|
329 cwd = tempfile.mkdtemp() |
|
330 if source is not None and os.path.exists(source): |
|
331 # the current working dir is hostile, let's copy the |
|
332 # tarball to a temp dir |
|
333 target = os.path.join(cwd, os.path.split(source)[-1]) |
|
334 shutil.copy(source, target) |
|
335 try: |
|
336 call_subprocess(cmd, show_stdout=False, |
|
337 filter_stdout=_filter_ez_setup, |
|
338 extra_env=env, |
|
339 cwd=cwd) |
|
340 finally: |
|
341 logger.indent -= 2 |
|
342 logger.end_progress() |
|
343 if os.getcwd() != old_chdir: |
|
344 os.chdir(old_chdir) |
|
345 if is_jython and os._name == 'nt': |
|
346 os.remove(ez_setup) |
|
347 |
|
348 def file_search_dirs(): |
|
349 here = os.path.dirname(os.path.abspath(__file__)) |
|
350 dirs = ['.', here, |
|
351 join(here, 'virtualenv_support')] |
|
352 if os.path.splitext(os.path.dirname(__file__))[0] != 'virtualenv': |
|
353 # Probably some boot script; just in case virtualenv is installed... |
|
354 try: |
|
355 import virtualenv |
|
356 except ImportError: |
|
357 pass |
|
358 else: |
|
359 dirs.append(os.path.join(os.path.dirname(virtualenv.__file__), 'virtualenv_support')) |
|
360 return [d for d in dirs if os.path.isdir(d)] |
|
361 |
|
362 def install_setuptools(py_executable, unzip=False): |
|
363 _install_req(py_executable, unzip) |
|
364 |
|
365 def install_distribute(py_executable, unzip=False): |
|
366 _install_req(py_executable, unzip, distribute=True) |
|
367 |
|
368 _pip_re = re.compile(r'^pip-.*(zip|tar.gz|tar.bz2|tgz|tbz)$', re.I) |
|
369 def install_pip(py_executable): |
|
370 filenames = [] |
|
371 for dir in file_search_dirs(): |
|
372 filenames.extend([join(dir, fn) for fn in os.listdir(dir) |
|
373 if _pip_re.search(fn)]) |
|
374 filenames = [(os.path.basename(filename).lower(), i, filename) for i, filename in enumerate(filenames)] |
|
375 filenames.sort() |
|
376 filenames = [filename for basename, i, filename in filenames] |
|
377 if not filenames: |
|
378 filename = 'pip' |
|
379 else: |
|
380 filename = filenames[-1] |
|
381 easy_install_script = 'easy_install' |
|
382 if sys.platform == 'win32': |
|
383 easy_install_script = 'easy_install-script.py' |
|
384 cmd = [py_executable, join(os.path.dirname(py_executable), easy_install_script), filename] |
|
385 if filename == 'pip': |
|
386 logger.info('Installing pip from network...') |
|
387 else: |
|
388 logger.info('Installing %s' % os.path.basename(filename)) |
|
389 logger.indent += 2 |
|
390 def _filter_setup(line): |
|
391 return filter_ez_setup(line, 'pip') |
|
392 try: |
|
393 call_subprocess(cmd, show_stdout=False, |
|
394 filter_stdout=_filter_setup) |
|
395 finally: |
|
396 logger.indent -= 2 |
|
397 |
|
398 def filter_ez_setup(line, project_name='setuptools'): |
|
399 if not line.strip(): |
|
400 return Logger.DEBUG |
|
401 if project_name == 'distribute': |
|
402 for prefix in ('Extracting', 'Now working', 'Installing', 'Before', |
|
403 'Scanning', 'Setuptools', 'Egg', 'Already', |
|
404 'running', 'writing', 'reading', 'installing', |
|
405 'creating', 'copying', 'byte-compiling', 'removing', |
|
406 'Processing'): |
|
407 if line.startswith(prefix): |
|
408 return Logger.DEBUG |
|
409 return Logger.DEBUG |
|
410 for prefix in ['Reading ', 'Best match', 'Processing setuptools', |
|
411 'Copying setuptools', 'Adding setuptools', |
|
412 'Installing ', 'Installed ']: |
|
413 if line.startswith(prefix): |
|
414 return Logger.DEBUG |
|
415 return Logger.INFO |
|
416 |
|
417 def main(): |
|
418 parser = optparse.OptionParser( |
|
419 version=virtualenv_version, |
|
420 usage="%prog [OPTIONS] DEST_DIR") |
|
421 |
|
422 parser.add_option( |
|
423 '-v', '--verbose', |
|
424 action='count', |
|
425 dest='verbose', |
|
426 default=0, |
|
427 help="Increase verbosity") |
|
428 |
|
429 parser.add_option( |
|
430 '-q', '--quiet', |
|
431 action='count', |
|
432 dest='quiet', |
|
433 default=0, |
|
434 help='Decrease verbosity') |
|
435 |
|
436 parser.add_option( |
|
437 '-p', '--python', |
|
438 dest='python', |
|
439 metavar='PYTHON_EXE', |
|
440 help='The Python interpreter to use, e.g., --python=python2.5 will use the python2.5 ' |
|
441 'interpreter to create the new environment. The default is the interpreter that ' |
|
442 'virtualenv was installed with (%s)' % sys.executable) |
|
443 |
|
444 parser.add_option( |
|
445 '--clear', |
|
446 dest='clear', |
|
447 action='store_true', |
|
448 help="Clear out the non-root install and start from scratch") |
|
449 |
|
450 parser.add_option( |
|
451 '--no-site-packages', |
|
452 dest='no_site_packages', |
|
453 action='store_true', |
|
454 help="Don't give access to the global site-packages dir to the " |
|
455 "virtual environment") |
|
456 |
|
457 parser.add_option( |
|
458 '--unzip-setuptools', |
|
459 dest='unzip_setuptools', |
|
460 action='store_true', |
|
461 help="Unzip Setuptools or Distribute when installing it") |
|
462 |
|
463 parser.add_option( |
|
464 '--relocatable', |
|
465 dest='relocatable', |
|
466 action='store_true', |
|
467 help='Make an EXISTING virtualenv environment relocatable. ' |
|
468 'This fixes up scripts and makes all .pth files relative') |
|
469 |
|
470 parser.add_option( |
|
471 '--distribute', |
|
472 dest='use_distribute', |
|
473 action='store_true', |
|
474 help='Use Distribute instead of Setuptools. Set environ variable ' |
|
475 'VIRTUALENV_USE_DISTRIBUTE to make it the default ') |
|
476 |
|
477 parser.add_option( |
|
478 '--prompt=', |
|
479 dest='prompt', |
|
480 help='Provides an alternative prompt prefix for this environment') |
|
481 |
|
482 if 'extend_parser' in globals(): |
|
483 extend_parser(parser) |
|
484 |
|
485 options, args = parser.parse_args() |
|
486 |
|
487 global logger |
|
488 |
|
489 if 'adjust_options' in globals(): |
|
490 adjust_options(options, args) |
|
491 |
|
492 verbosity = options.verbose - options.quiet |
|
493 logger = Logger([(Logger.level_for_integer(2-verbosity), sys.stdout)]) |
|
494 |
|
495 if options.python and not os.environ.get('VIRTUALENV_INTERPRETER_RUNNING'): |
|
496 env = os.environ.copy() |
|
497 interpreter = resolve_interpreter(options.python) |
|
498 if interpreter == sys.executable: |
|
499 logger.warn('Already using interpreter %s' % interpreter) |
|
500 else: |
|
501 logger.notify('Running virtualenv with interpreter %s' % interpreter) |
|
502 env['VIRTUALENV_INTERPRETER_RUNNING'] = 'true' |
|
503 file = __file__ |
|
504 if file.endswith('.pyc'): |
|
505 file = file[:-1] |
|
506 popen = subprocess.Popen([interpreter, file] + sys.argv[1:], env=env) |
|
507 raise SystemExit(popen.wait()) |
|
508 |
|
509 if not args: |
|
510 print 'You must provide a DEST_DIR' |
|
511 parser.print_help() |
|
512 sys.exit(2) |
|
513 if len(args) > 1: |
|
514 print 'There must be only one argument: DEST_DIR (you gave %s)' % ( |
|
515 ' '.join(args)) |
|
516 parser.print_help() |
|
517 sys.exit(2) |
|
518 |
|
519 home_dir = args[0] |
|
520 |
|
521 if os.environ.get('WORKING_ENV'): |
|
522 logger.fatal('ERROR: you cannot run virtualenv while in a workingenv') |
|
523 logger.fatal('Please deactivate your workingenv, then re-run this script') |
|
524 sys.exit(3) |
|
525 |
|
526 if 'PYTHONHOME' in os.environ: |
|
527 logger.warn('PYTHONHOME is set. You *must* activate the virtualenv before using it') |
|
528 del os.environ['PYTHONHOME'] |
|
529 |
|
530 if options.relocatable: |
|
531 make_environment_relocatable(home_dir) |
|
532 return |
|
533 |
|
534 create_environment(home_dir, site_packages=not options.no_site_packages, clear=options.clear, |
|
535 unzip_setuptools=options.unzip_setuptools, |
|
536 use_distribute=options.use_distribute, |
|
537 prompt=options.prompt) |
|
538 if 'after_install' in globals(): |
|
539 after_install(options, home_dir) |
|
540 |
|
541 def call_subprocess(cmd, show_stdout=True, |
|
542 filter_stdout=None, cwd=None, |
|
543 raise_on_returncode=True, extra_env=None): |
|
544 cmd_parts = [] |
|
545 for part in cmd: |
|
546 if len(part) > 40: |
|
547 part = part[:30]+"..."+part[-5:] |
|
548 if ' ' in part or '\n' in part or '"' in part or "'" in part: |
|
549 part = '"%s"' % part.replace('"', '\\"') |
|
550 cmd_parts.append(part) |
|
551 cmd_desc = ' '.join(cmd_parts) |
|
552 if show_stdout: |
|
553 stdout = None |
|
554 else: |
|
555 stdout = subprocess.PIPE |
|
556 logger.debug("Running command %s" % cmd_desc) |
|
557 if extra_env: |
|
558 env = os.environ.copy() |
|
559 env.update(extra_env) |
|
560 else: |
|
561 env = None |
|
562 try: |
|
563 proc = subprocess.Popen( |
|
564 cmd, stderr=subprocess.STDOUT, stdin=None, stdout=stdout, |
|
565 cwd=cwd, env=env) |
|
566 except Exception, e: |
|
567 logger.fatal( |
|
568 "Error %s while executing command %s" % (e, cmd_desc)) |
|
569 raise |
|
570 all_output = [] |
|
571 if stdout is not None: |
|
572 stdout = proc.stdout |
|
573 while 1: |
|
574 line = stdout.readline() |
|
575 if not line: |
|
576 break |
|
577 line = line.rstrip() |
|
578 all_output.append(line) |
|
579 if filter_stdout: |
|
580 level = filter_stdout(line) |
|
581 if isinstance(level, tuple): |
|
582 level, line = level |
|
583 logger.log(level, line) |
|
584 if not logger.stdout_level_matches(level): |
|
585 logger.show_progress() |
|
586 else: |
|
587 logger.info(line) |
|
588 else: |
|
589 proc.communicate() |
|
590 proc.wait() |
|
591 if proc.returncode: |
|
592 if raise_on_returncode: |
|
593 if all_output: |
|
594 logger.notify('Complete output from command %s:' % cmd_desc) |
|
595 logger.notify('\n'.join(all_output) + '\n----------------------------------------') |
|
596 raise OSError( |
|
597 "Command %s failed with error code %s" |
|
598 % (cmd_desc, proc.returncode)) |
|
599 else: |
|
600 logger.warn( |
|
601 "Command %s had error code %s" |
|
602 % (cmd_desc, proc.returncode)) |
|
603 |
|
604 |
|
605 def create_environment(home_dir, site_packages=True, clear=False, |
|
606 unzip_setuptools=False, use_distribute=False, |
|
607 prompt=None): |
|
608 """ |
|
609 Creates a new environment in ``home_dir``. |
|
610 |
|
611 If ``site_packages`` is true (the default) then the global |
|
612 ``site-packages/`` directory will be on the path. |
|
613 |
|
614 If ``clear`` is true (default False) then the environment will |
|
615 first be cleared. |
|
616 """ |
|
617 home_dir, lib_dir, inc_dir, bin_dir = path_locations(home_dir) |
|
618 |
|
619 py_executable = os.path.abspath(install_python( |
|
620 home_dir, lib_dir, inc_dir, bin_dir, |
|
621 site_packages=site_packages, clear=clear)) |
|
622 |
|
623 install_distutils(lib_dir, home_dir) |
|
624 |
|
625 if use_distribute or os.environ.get('VIRTUALENV_USE_DISTRIBUTE'): |
|
626 install_distribute(py_executable, unzip=unzip_setuptools) |
|
627 else: |
|
628 install_setuptools(py_executable, unzip=unzip_setuptools) |
|
629 |
|
630 install_pip(py_executable) |
|
631 |
|
632 install_activate(home_dir, bin_dir, prompt) |
|
633 |
|
634 def path_locations(home_dir): |
|
635 """Return the path locations for the environment (where libraries are, |
|
636 where scripts go, etc)""" |
|
637 # XXX: We'd use distutils.sysconfig.get_python_inc/lib but its |
|
638 # prefix arg is broken: http://bugs.python.org/issue3386 |
|
639 if sys.platform == 'win32': |
|
640 # Windows has lots of problems with executables with spaces in |
|
641 # the name; this function will remove them (using the ~1 |
|
642 # format): |
|
643 mkdir(home_dir) |
|
644 if ' ' in home_dir: |
|
645 try: |
|
646 import win32api |
|
647 except ImportError: |
|
648 print 'Error: the path "%s" has a space in it' % home_dir |
|
649 print 'To handle these kinds of paths, the win32api module must be installed:' |
|
650 print ' http://sourceforge.net/projects/pywin32/' |
|
651 sys.exit(3) |
|
652 home_dir = win32api.GetShortPathName(home_dir) |
|
653 lib_dir = join(home_dir, 'Lib') |
|
654 inc_dir = join(home_dir, 'Include') |
|
655 bin_dir = join(home_dir, 'Scripts') |
|
656 elif is_jython: |
|
657 lib_dir = join(home_dir, 'Lib') |
|
658 inc_dir = join(home_dir, 'Include') |
|
659 bin_dir = join(home_dir, 'bin') |
|
660 else: |
|
661 lib_dir = join(home_dir, 'lib', py_version) |
|
662 inc_dir = join(home_dir, 'include', py_version) |
|
663 bin_dir = join(home_dir, 'bin') |
|
664 return home_dir, lib_dir, inc_dir, bin_dir |
|
665 |
|
666 def install_python(home_dir, lib_dir, inc_dir, bin_dir, site_packages, clear): |
|
667 """Install just the base environment, no distutils patches etc""" |
|
668 if sys.executable.startswith(bin_dir): |
|
669 print 'Please use the *system* python to run this script' |
|
670 return |
|
671 |
|
672 if clear: |
|
673 rmtree(lib_dir) |
|
674 ## FIXME: why not delete it? |
|
675 ## Maybe it should delete everything with #!/path/to/venv/python in it |
|
676 logger.notify('Not deleting %s', bin_dir) |
|
677 |
|
678 if hasattr(sys, 'real_prefix'): |
|
679 logger.notify('Using real prefix %r' % sys.real_prefix) |
|
680 prefix = sys.real_prefix |
|
681 else: |
|
682 prefix = sys.prefix |
|
683 mkdir(lib_dir) |
|
684 fix_lib64(lib_dir) |
|
685 stdlib_dirs = [os.path.dirname(os.__file__)] |
|
686 if sys.platform == 'win32': |
|
687 stdlib_dirs.append(join(os.path.dirname(stdlib_dirs[0]), 'DLLs')) |
|
688 elif sys.platform == 'darwin': |
|
689 stdlib_dirs.append(join(stdlib_dirs[0], 'site-packages')) |
|
690 for stdlib_dir in stdlib_dirs: |
|
691 if not os.path.isdir(stdlib_dir): |
|
692 continue |
|
693 if hasattr(os, 'symlink'): |
|
694 logger.info('Symlinking Python bootstrap modules') |
|
695 else: |
|
696 logger.info('Copying Python bootstrap modules') |
|
697 logger.indent += 2 |
|
698 try: |
|
699 for fn in os.listdir(stdlib_dir): |
|
700 if fn != 'site-packages' and os.path.splitext(fn)[0] in REQUIRED_MODULES: |
|
701 copyfile(join(stdlib_dir, fn), join(lib_dir, fn)) |
|
702 finally: |
|
703 logger.indent -= 2 |
|
704 mkdir(join(lib_dir, 'site-packages')) |
|
705 writefile(join(lib_dir, 'site.py'), SITE_PY) |
|
706 writefile(join(lib_dir, 'orig-prefix.txt'), prefix) |
|
707 site_packages_filename = join(lib_dir, 'no-global-site-packages.txt') |
|
708 if not site_packages: |
|
709 writefile(site_packages_filename, '') |
|
710 else: |
|
711 if os.path.exists(site_packages_filename): |
|
712 logger.info('Deleting %s' % site_packages_filename) |
|
713 os.unlink(site_packages_filename) |
|
714 |
|
715 stdinc_dir = join(prefix, 'include', py_version) |
|
716 if os.path.exists(stdinc_dir): |
|
717 copyfile(stdinc_dir, inc_dir) |
|
718 else: |
|
719 logger.debug('No include dir %s' % stdinc_dir) |
|
720 |
|
721 if sys.exec_prefix != prefix: |
|
722 if sys.platform == 'win32': |
|
723 exec_dir = join(sys.exec_prefix, 'lib') |
|
724 elif is_jython: |
|
725 exec_dir = join(sys.exec_prefix, 'Lib') |
|
726 else: |
|
727 exec_dir = join(sys.exec_prefix, 'lib', py_version) |
|
728 for fn in os.listdir(exec_dir): |
|
729 copyfile(join(exec_dir, fn), join(lib_dir, fn)) |
|
730 |
|
731 if is_jython: |
|
732 # Jython has either jython-dev.jar and javalib/ dir, or just |
|
733 # jython.jar |
|
734 for name in 'jython-dev.jar', 'javalib', 'jython.jar': |
|
735 src = join(prefix, name) |
|
736 if os.path.exists(src): |
|
737 copyfile(src, join(home_dir, name)) |
|
738 # XXX: registry should always exist after Jython 2.5rc1 |
|
739 src = join(prefix, 'registry') |
|
740 if os.path.exists(src): |
|
741 copyfile(src, join(home_dir, 'registry'), symlink=False) |
|
742 copyfile(join(prefix, 'cachedir'), join(home_dir, 'cachedir'), |
|
743 symlink=False) |
|
744 |
|
745 mkdir(bin_dir) |
|
746 py_executable = join(bin_dir, os.path.basename(sys.executable)) |
|
747 if 'Python.framework' in prefix: |
|
748 if re.search(r'/Python(?:-32|-64)*$', py_executable): |
|
749 # The name of the python executable is not quite what |
|
750 # we want, rename it. |
|
751 py_executable = os.path.join( |
|
752 os.path.dirname(py_executable), 'python') |
|
753 |
|
754 logger.notify('New %s executable in %s', expected_exe, py_executable) |
|
755 if sys.executable != py_executable: |
|
756 ## FIXME: could I just hard link? |
|
757 executable = sys.executable |
|
758 if sys.platform == 'cygwin' and os.path.exists(executable + '.exe'): |
|
759 # Cygwin misreports sys.executable sometimes |
|
760 executable += '.exe' |
|
761 py_executable += '.exe' |
|
762 logger.info('Executable actually exists in %s' % executable) |
|
763 shutil.copyfile(executable, py_executable) |
|
764 make_exe(py_executable) |
|
765 if sys.platform == 'win32' or sys.platform == 'cygwin': |
|
766 pythonw = os.path.join(os.path.dirname(sys.executable), 'pythonw.exe') |
|
767 if os.path.exists(pythonw): |
|
768 logger.info('Also created pythonw.exe') |
|
769 shutil.copyfile(pythonw, os.path.join(os.path.dirname(py_executable), 'pythonw.exe')) |
|
770 |
|
771 if os.path.splitext(os.path.basename(py_executable))[0] != expected_exe: |
|
772 secondary_exe = os.path.join(os.path.dirname(py_executable), |
|
773 expected_exe) |
|
774 py_executable_ext = os.path.splitext(py_executable)[1] |
|
775 if py_executable_ext == '.exe': |
|
776 # python2.4 gives an extension of '.4' :P |
|
777 secondary_exe += py_executable_ext |
|
778 if os.path.exists(secondary_exe): |
|
779 logger.warn('Not overwriting existing %s script %s (you must use %s)' |
|
780 % (expected_exe, secondary_exe, py_executable)) |
|
781 else: |
|
782 logger.notify('Also creating executable in %s' % secondary_exe) |
|
783 shutil.copyfile(sys.executable, secondary_exe) |
|
784 make_exe(secondary_exe) |
|
785 |
|
786 if 'Python.framework' in prefix: |
|
787 logger.debug('MacOSX Python framework detected') |
|
788 |
|
789 # Make sure we use the the embedded interpreter inside |
|
790 # the framework, even if sys.executable points to |
|
791 # the stub executable in ${sys.prefix}/bin |
|
792 # See http://groups.google.com/group/python-virtualenv/ |
|
793 # browse_thread/thread/17cab2f85da75951 |
|
794 original_python = os.path.join( |
|
795 prefix, 'Resources/Python.app/Contents/MacOS/Python') |
|
796 shutil.copy(original_python, py_executable) |
|
797 |
|
798 # Copy the framework's dylib into the virtual |
|
799 # environment |
|
800 virtual_lib = os.path.join(home_dir, '.Python') |
|
801 |
|
802 if os.path.exists(virtual_lib): |
|
803 os.unlink(virtual_lib) |
|
804 copyfile( |
|
805 os.path.join(prefix, 'Python'), |
|
806 virtual_lib) |
|
807 |
|
808 # And then change the install_name of the copied python executable |
|
809 try: |
|
810 call_subprocess( |
|
811 ["install_name_tool", "-change", |
|
812 os.path.join(prefix, 'Python'), |
|
813 '@executable_path/../.Python', |
|
814 py_executable]) |
|
815 except: |
|
816 logger.fatal( |
|
817 "Could not call install_name_tool -- you must have Apple's development tools installed") |
|
818 raise |
|
819 |
|
820 # Some tools depend on pythonX.Y being present |
|
821 py_executable_version = '%s.%s' % ( |
|
822 sys.version_info[0], sys.version_info[1]) |
|
823 if not py_executable.endswith(py_executable_version): |
|
824 # symlinking pythonX.Y > python |
|
825 pth = py_executable + '%s.%s' % ( |
|
826 sys.version_info[0], sys.version_info[1]) |
|
827 if os.path.exists(pth): |
|
828 os.unlink(pth) |
|
829 os.symlink('python', pth) |
|
830 else: |
|
831 # reverse symlinking python -> pythonX.Y (with --python) |
|
832 pth = join(bin_dir, 'python') |
|
833 if os.path.exists(pth): |
|
834 os.unlink(pth) |
|
835 os.symlink(os.path.basename(py_executable), pth) |
|
836 |
|
837 if sys.platform == 'win32' and ' ' in py_executable: |
|
838 # There's a bug with subprocess on Windows when using a first |
|
839 # argument that has a space in it. Instead we have to quote |
|
840 # the value: |
|
841 py_executable = '"%s"' % py_executable |
|
842 cmd = [py_executable, '-c', 'import sys; print sys.prefix'] |
|
843 logger.info('Testing executable with %s %s "%s"' % tuple(cmd)) |
|
844 proc = subprocess.Popen(cmd, |
|
845 stdout=subprocess.PIPE) |
|
846 proc_stdout, proc_stderr = proc.communicate() |
|
847 proc_stdout = os.path.normcase(os.path.abspath(proc_stdout.strip())) |
|
848 if proc_stdout != os.path.normcase(os.path.abspath(home_dir)): |
|
849 logger.fatal( |
|
850 'ERROR: The executable %s is not functioning' % py_executable) |
|
851 logger.fatal( |
|
852 'ERROR: It thinks sys.prefix is %r (should be %r)' |
|
853 % (proc_stdout, os.path.normcase(os.path.abspath(home_dir)))) |
|
854 logger.fatal( |
|
855 'ERROR: virtualenv is not compatible with this system or executable') |
|
856 if sys.platform == 'win32': |
|
857 logger.fatal( |
|
858 'Note: some Windows users have reported this error when they installed Python for "Only this user". The problem may be resolvable if you install Python "For all users". (See https://bugs.launchpad.net/virtualenv/+bug/352844)') |
|
859 sys.exit(100) |
|
860 else: |
|
861 logger.info('Got sys.prefix result: %r' % proc_stdout) |
|
862 |
|
863 pydistutils = os.path.expanduser('~/.pydistutils.cfg') |
|
864 if os.path.exists(pydistutils): |
|
865 logger.notify('Please make sure you remove any previous custom paths from ' |
|
866 'your %s file.' % pydistutils) |
|
867 ## FIXME: really this should be calculated earlier |
|
868 return py_executable |
|
869 |
|
870 def install_activate(home_dir, bin_dir, prompt=None): |
|
871 if sys.platform == 'win32' or is_jython and os._name == 'nt': |
|
872 files = {'activate.bat': ACTIVATE_BAT, |
|
873 'deactivate.bat': DEACTIVATE_BAT} |
|
874 if os.environ.get('OS') == 'Windows_NT' and os.environ.get('OSTYPE') == 'cygwin': |
|
875 files['activate'] = ACTIVATE_SH |
|
876 else: |
|
877 files = {'activate': ACTIVATE_SH} |
|
878 files['activate_this.py'] = ACTIVATE_THIS |
|
879 vname = os.path.basename(os.path.abspath(home_dir)) |
|
880 for name, content in files.items(): |
|
881 content = content.replace('__VIRTUAL_PROMPT__', prompt or '') |
|
882 content = content.replace('__VIRTUAL_WINPROMPT__', prompt or '(%s)' % vname) |
|
883 content = content.replace('__VIRTUAL_ENV__', os.path.abspath(home_dir)) |
|
884 content = content.replace('__VIRTUAL_NAME__', vname) |
|
885 content = content.replace('__BIN_NAME__', os.path.basename(bin_dir)) |
|
886 writefile(os.path.join(bin_dir, name), content) |
|
887 |
|
888 def install_distutils(lib_dir, home_dir): |
|
889 distutils_path = os.path.join(lib_dir, 'distutils') |
|
890 mkdir(distutils_path) |
|
891 ## FIXME: maybe this prefix setting should only be put in place if |
|
892 ## there's a local distutils.cfg with a prefix setting? |
|
893 home_dir = os.path.abspath(home_dir) |
|
894 ## FIXME: this is breaking things, removing for now: |
|
895 #distutils_cfg = DISTUTILS_CFG + "\n[install]\nprefix=%s\n" % home_dir |
|
896 writefile(os.path.join(distutils_path, '__init__.py'), DISTUTILS_INIT) |
|
897 writefile(os.path.join(distutils_path, 'distutils.cfg'), DISTUTILS_CFG, overwrite=False) |
|
898 |
|
899 def fix_lib64(lib_dir): |
|
900 """ |
|
901 Some platforms (particularly Gentoo on x64) put things in lib64/pythonX.Y |
|
902 instead of lib/pythonX.Y. If this is such a platform we'll just create a |
|
903 symlink so lib64 points to lib |
|
904 """ |
|
905 if [p for p in distutils.sysconfig.get_config_vars().values() |
|
906 if isinstance(p, basestring) and 'lib64' in p]: |
|
907 logger.debug('This system uses lib64; symlinking lib64 to lib') |
|
908 assert os.path.basename(lib_dir) == 'python%s' % sys.version[:3], ( |
|
909 "Unexpected python lib dir: %r" % lib_dir) |
|
910 lib_parent = os.path.dirname(lib_dir) |
|
911 assert os.path.basename(lib_parent) == 'lib', ( |
|
912 "Unexpected parent dir: %r" % lib_parent) |
|
913 copyfile(lib_parent, os.path.join(os.path.dirname(lib_parent), 'lib64')) |
|
914 |
|
915 def resolve_interpreter(exe): |
|
916 """ |
|
917 If the executable given isn't an absolute path, search $PATH for the interpreter |
|
918 """ |
|
919 if os.path.abspath(exe) != exe: |
|
920 paths = os.environ.get('PATH', '').split(os.pathsep) |
|
921 for path in paths: |
|
922 if os.path.exists(os.path.join(path, exe)): |
|
923 exe = os.path.join(path, exe) |
|
924 break |
|
925 if not os.path.exists(exe): |
|
926 logger.fatal('The executable %s (from --python=%s) does not exist' % (exe, exe)) |
|
927 sys.exit(3) |
|
928 return exe |
|
929 |
|
930 ############################################################ |
|
931 ## Relocating the environment: |
|
932 |
|
933 def make_environment_relocatable(home_dir): |
|
934 """ |
|
935 Makes the already-existing environment use relative paths, and takes out |
|
936 the #!-based environment selection in scripts. |
|
937 """ |
|
938 home_dir, lib_dir, inc_dir, bin_dir = path_locations(home_dir) |
|
939 activate_this = os.path.join(bin_dir, 'activate_this.py') |
|
940 if not os.path.exists(activate_this): |
|
941 logger.fatal( |
|
942 'The environment doesn\'t have a file %s -- please re-run virtualenv ' |
|
943 'on this environment to update it' % activate_this) |
|
944 fixup_scripts(home_dir) |
|
945 fixup_pth_and_egg_link(home_dir) |
|
946 ## FIXME: need to fix up distutils.cfg |
|
947 |
|
948 OK_ABS_SCRIPTS = ['python', 'python%s' % sys.version[:3], |
|
949 'activate', 'activate.bat', 'activate_this.py'] |
|
950 |
|
951 def fixup_scripts(home_dir): |
|
952 # This is what we expect at the top of scripts: |
|
953 shebang = '#!%s/bin/python' % os.path.normcase(os.path.abspath(home_dir)) |
|
954 # This is what we'll put: |
|
955 new_shebang = '#!/usr/bin/env python%s' % sys.version[:3] |
|
956 activate = "import os; activate_this=os.path.join(os.path.dirname(__file__), 'activate_this.py'); execfile(activate_this, dict(__file__=activate_this)); del os, activate_this" |
|
957 bin_dir = os.path.join(home_dir, 'bin') |
|
958 home_dir, lib_dir, inc_dir, bin_dir = path_locations(home_dir) |
|
959 for filename in os.listdir(bin_dir): |
|
960 filename = os.path.join(bin_dir, filename) |
|
961 if not os.path.isfile(filename): |
|
962 # ignore subdirs, e.g. .svn ones. |
|
963 continue |
|
964 f = open(filename, 'rb') |
|
965 lines = f.readlines() |
|
966 f.close() |
|
967 if not lines: |
|
968 logger.warn('Script %s is an empty file' % filename) |
|
969 continue |
|
970 if not lines[0].strip().startswith(shebang): |
|
971 if os.path.basename(filename) in OK_ABS_SCRIPTS: |
|
972 logger.debug('Cannot make script %s relative' % filename) |
|
973 elif lines[0].strip() == new_shebang: |
|
974 logger.info('Script %s has already been made relative' % filename) |
|
975 else: |
|
976 logger.warn('Script %s cannot be made relative (it\'s not a normal script that starts with %s)' |
|
977 % (filename, shebang)) |
|
978 continue |
|
979 logger.notify('Making script %s relative' % filename) |
|
980 lines = [new_shebang+'\n', activate+'\n'] + lines[1:] |
|
981 f = open(filename, 'wb') |
|
982 f.writelines(lines) |
|
983 f.close() |
|
984 |
|
985 def fixup_pth_and_egg_link(home_dir, sys_path=None): |
|
986 """Makes .pth and .egg-link files use relative paths""" |
|
987 home_dir = os.path.normcase(os.path.abspath(home_dir)) |
|
988 if sys_path is None: |
|
989 sys_path = sys.path |
|
990 for path in sys_path: |
|
991 if not path: |
|
992 path = '.' |
|
993 if not os.path.isdir(path): |
|
994 continue |
|
995 path = os.path.normcase(os.path.abspath(path)) |
|
996 if not path.startswith(home_dir): |
|
997 logger.debug('Skipping system (non-environment) directory %s' % path) |
|
998 continue |
|
999 for filename in os.listdir(path): |
|
1000 filename = os.path.join(path, filename) |
|
1001 if filename.endswith('.pth'): |
|
1002 if not os.access(filename, os.W_OK): |
|
1003 logger.warn('Cannot write .pth file %s, skipping' % filename) |
|
1004 else: |
|
1005 fixup_pth_file(filename) |
|
1006 if filename.endswith('.egg-link'): |
|
1007 if not os.access(filename, os.W_OK): |
|
1008 logger.warn('Cannot write .egg-link file %s, skipping' % filename) |
|
1009 else: |
|
1010 fixup_egg_link(filename) |
|
1011 |
|
1012 def fixup_pth_file(filename): |
|
1013 lines = [] |
|
1014 prev_lines = [] |
|
1015 f = open(filename) |
|
1016 prev_lines = f.readlines() |
|
1017 f.close() |
|
1018 for line in prev_lines: |
|
1019 line = line.strip() |
|
1020 if (not line or line.startswith('#') or line.startswith('import ') |
|
1021 or os.path.abspath(line) != line): |
|
1022 lines.append(line) |
|
1023 else: |
|
1024 new_value = make_relative_path(filename, line) |
|
1025 if line != new_value: |
|
1026 logger.debug('Rewriting path %s as %s (in %s)' % (line, new_value, filename)) |
|
1027 lines.append(new_value) |
|
1028 if lines == prev_lines: |
|
1029 logger.info('No changes to .pth file %s' % filename) |
|
1030 return |
|
1031 logger.notify('Making paths in .pth file %s relative' % filename) |
|
1032 f = open(filename, 'w') |
|
1033 f.write('\n'.join(lines) + '\n') |
|
1034 f.close() |
|
1035 |
|
1036 def fixup_egg_link(filename): |
|
1037 f = open(filename) |
|
1038 link = f.read().strip() |
|
1039 f.close() |
|
1040 if os.path.abspath(link) != link: |
|
1041 logger.debug('Link in %s already relative' % filename) |
|
1042 return |
|
1043 new_link = make_relative_path(filename, link) |
|
1044 logger.notify('Rewriting link %s in %s as %s' % (link, filename, new_link)) |
|
1045 f = open(filename, 'w') |
|
1046 f.write(new_link) |
|
1047 f.close() |
|
1048 |
|
1049 def make_relative_path(source, dest, dest_is_directory=True): |
|
1050 """ |
|
1051 Make a filename relative, where the filename is dest, and it is |
|
1052 being referred to from the filename source. |
|
1053 |
|
1054 >>> make_relative_path('/usr/share/something/a-file.pth', |
|
1055 ... '/usr/share/another-place/src/Directory') |
|
1056 '../another-place/src/Directory' |
|
1057 >>> make_relative_path('/usr/share/something/a-file.pth', |
|
1058 ... '/home/user/src/Directory') |
|
1059 '../../../home/user/src/Directory' |
|
1060 >>> make_relative_path('/usr/share/a-file.pth', '/usr/share/') |
|
1061 './' |
|
1062 """ |
|
1063 source = os.path.dirname(source) |
|
1064 if not dest_is_directory: |
|
1065 dest_filename = os.path.basename(dest) |
|
1066 dest = os.path.dirname(dest) |
|
1067 dest = os.path.normpath(os.path.abspath(dest)) |
|
1068 source = os.path.normpath(os.path.abspath(source)) |
|
1069 dest_parts = dest.strip(os.path.sep).split(os.path.sep) |
|
1070 source_parts = source.strip(os.path.sep).split(os.path.sep) |
|
1071 while dest_parts and source_parts and dest_parts[0] == source_parts[0]: |
|
1072 dest_parts.pop(0) |
|
1073 source_parts.pop(0) |
|
1074 full_parts = ['..']*len(source_parts) + dest_parts |
|
1075 if not dest_is_directory: |
|
1076 full_parts.append(dest_filename) |
|
1077 if not full_parts: |
|
1078 # Special case for the current directory (otherwise it'd be '') |
|
1079 return './' |
|
1080 return os.path.sep.join(full_parts) |
|
1081 |
|
1082 |
|
1083 |
|
1084 ############################################################ |
|
1085 ## Bootstrap script creation: |
|
1086 |
|
1087 def create_bootstrap_script(extra_text, python_version=''): |
|
1088 """ |
|
1089 Creates a bootstrap script, which is like this script but with |
|
1090 extend_parser, adjust_options, and after_install hooks. |
|
1091 |
|
1092 This returns a string that (written to disk of course) can be used |
|
1093 as a bootstrap script with your own customizations. The script |
|
1094 will be the standard virtualenv.py script, with your extra text |
|
1095 added (your extra text should be Python code). |
|
1096 |
|
1097 If you include these functions, they will be called: |
|
1098 |
|
1099 ``extend_parser(optparse_parser)``: |
|
1100 You can add or remove options from the parser here. |
|
1101 |
|
1102 ``adjust_options(options, args)``: |
|
1103 You can change options here, or change the args (if you accept |
|
1104 different kinds of arguments, be sure you modify ``args`` so it is |
|
1105 only ``[DEST_DIR]``). |
|
1106 |
|
1107 ``after_install(options, home_dir)``: |
|
1108 |
|
1109 After everything is installed, this function is called. This |
|
1110 is probably the function you are most likely to use. An |
|
1111 example would be:: |
|
1112 |
|
1113 def after_install(options, home_dir): |
|
1114 subprocess.call([join(home_dir, 'bin', 'easy_install'), |
|
1115 'MyPackage']) |
|
1116 subprocess.call([join(home_dir, 'bin', 'my-package-script'), |
|
1117 'setup', home_dir]) |
|
1118 |
|
1119 This example immediately installs a package, and runs a setup |
|
1120 script from that package. |
|
1121 |
|
1122 If you provide something like ``python_version='2.4'`` then the |
|
1123 script will start with ``#!/usr/bin/env python2.4`` instead of |
|
1124 ``#!/usr/bin/env python``. You can use this when the script must |
|
1125 be run with a particular Python version. |
|
1126 """ |
|
1127 filename = __file__ |
|
1128 if filename.endswith('.pyc'): |
|
1129 filename = filename[:-1] |
|
1130 f = open(filename, 'rb') |
|
1131 content = f.read() |
|
1132 f.close() |
|
1133 py_exe = 'python%s' % python_version |
|
1134 content = (('#!/usr/bin/env %s\n' % py_exe) |
|
1135 + '## WARNING: This file is generated\n' |
|
1136 + content) |
|
1137 return content.replace('##EXT' 'END##', extra_text) |
|
1138 |
|
1139 import sys |
|
1140 sys.path.append('/Users/ymh/dev/workspace/platform/virtualenv/res/lib') |
|
1141 sys.path.append('/Users/ymh/dev/workspace/platform/virtualenv/setup/res') |
|
1142 from res_create_env import generate_install_methods |
|
1143 adjust_options, extend_parser, after_install = generate_install_methods(path_locations, '/Users/ymh/dev/workspace/platform/virtualenv/res/src', Logger, call_subprocess) |
|
1144 |
|
1145 |
|
1146 ##file site.py |
|
1147 SITE_PY = """ |
|
1148 eJzVPGtz2ziS3/krsHSlKGVkOo/ZqS1nPFdO4sx4z5N4J5na3HpSWkqCJI4pkkOQlrVXd7/9+gGA |
|
1149 AEn5sbP74VSpWCKARqPRbzQYhuFpWcp8ITbFosmkUDKp5mtRJvVaiWVRiXqdVovDMqnqHTydXycr |
|
1150 qURdCLVTMfaKg+Dp7/wET8WndaoMCvAtaepik9TpPMmynUg3ZVHVciEWTZXmK5HmaZ0mWfoP6FHk |
|
1151 sXj6+zEIznMBK89SWYkbWSmAq0SxFJe7el3kYtSUuObn8R+Tl+OJUPMqLWvoUGmcgSLrpA5yKReA |
|
1152 JvRsFJAyreWhKuU8XaZz23FbNNlClFkyl+Lvf+elUdcoClSxkdu1rKTIARmAKQFWiXjA17QS82Ih |
|
1153 YyFey3mCE/DzllgBQ5vgnikkY16IrMhXsKZczqVSSbUTo1lTEyBCWSwKwCkFDOo0y4JtUV2rMWwp |
|
1154 7ccWHomE2cNfDLMHrBPn73MO4PghD37O09sJwwbuQXD1mtmmksv0ViQIFn7KWzmf6mejdCkW6XIJ |
|
1155 NMjrMXYJGAElsnR2VNJ2fKt36LsjwspyZQJzSESZO3MjjYiD81okmQK2bUqkkSLM38pZmuRAjfwG |
|
1156 pgOIQNJgaJ5Fqmo7D61OFACgwn2sQUo2Sow2SZoDs/6YzAntv6b5otiqMVEAdkuJXxtVu+sfDRAA |
|
1157 ejsEmAS4WWY3mzxLr2W2GwMCnwD7Sqomq1EgFmkl53VRpVIRAEBtJ+QtID0RSSU1CZkzjdxOiP5E |
|
1158 kzTHjUUBQ4HHRiTJMl01FUmYWKbAucAV7z78JN6evT4/fa95zABjmV1tAGeAQhvt4AQTiKNGVUdZ |
|
1159 AQIdBxf4RySLBQrZCucHvNoOR/fudDCCtZdxd4yz4UB2vbl6GlhjDcqE5gpo3H/DkIlaA33+5579 |
|
1160 DoLTfVShhfO37boAmcyTjRTrhPkLOSP4VsP5Li7r9SvgBoVwaiCVws1BBFOEByRxaTYqcilKYLEs |
|
1161 zeU4AArNqK+/i8AK74v8kPa6wwkAoQpyaHSejWnGXMJC+7Beob4wnXe0Mt0lsPu8KSpSHMD/+Zx0 |
|
1162 UZbk14SjIobibzO5SvMcEUJeCKKDiCZW1ylw4iIWF9SL9ILpJCLWXtwTRaIBXkKmA56Ut8mmzOSE |
|
1163 xRd1691qhCaTtTB7nTHHQc+a1CvtWrvUQd57EX/ucB2hWa8rCcCbmSd0y6KYiBnobMKmTDYsXvW2 |
|
1164 IM4JBuSJBiFPUE8Yi9+BoqdKNRtpG5FXQLMQQwXLIsuKLZDsOAiEOMBOxij7zAmt0Ab/A1z8P5P1 |
|
1165 fB0EzkwWsAaFyO8DhUDAJMhcc7VGwuM2zcpdJZPmrCmKaiErmuphxD5ixB/YGdcavC9qbdR4ubjL |
|
1166 xSatUSXNtMlM2eLlUc368RWvG5YBllsRzUzXlk4bXF5WrpOZNC7JTC5REvQmvbLbDnMGA3OSLa7F |
|
1167 hq0MtAFZZMoWZFixoNJZ1pKcAIDBwpfkadlk1Ekhg4kEJtqUBH+ToEkvtLME7M1mOUCFxOZ7DvYH |
|
1168 cPsHiNF2nQJ95gABNAxqKdi+WVpX6CC0+ijwjb4Zz/MDp54vtW3iKZdJmmkrn+TBOT08qyoS37ks |
|
1169 cdREE0PBCvMaXbtVDnREMQ/DMAiMO7RT5mthv02nsyZFezedBnW1OwbuECjkAUMX72GhNB23LKti |
|
1170 g80WvY+gD0Av44jgQFySopDs43rM9Aop4Grl0nRF8+twpEBVElz+dPbu/PPZR3EirlqtNOmqpC8w |
|
1171 51meAGeSUge+6EzbqiPoiborRfUl3oGFpn0Fk0SjSQJlUjfAfoD6p6qhZljG3GsMzt6fvr44m/78 |
|
1172 8eyn6cfzT2eAIJgKGRzQktHCNeDzqRj4GxhroWJtIoPeCHrw+vSjfRBMUzX9lV3jExZ27QddHX/9 |
|
1173 RZyciOjX5CaJAvBF2q68Lz8SW37alRKG1vBnVKhxECzkElj4WiKjj56SfznmAUAX6Floe/drkeam |
|
1174 nZq9KUgORzQCcJhO51miFHaeTiOgFg0Y+MCAmJ1U5N4RDCx37tCxRgU/lQTq5jhkgv8NoJjMaByi |
|
1175 wSi6Q0wnYPvNPFGSe9HyYdx0irI/nY70hCAUxLbguLA4R8J0QdmvUvAPaftRF8xUkeFPhI/SRFKA |
|
1176 IQpqG9wkHYLEN0nWSDVyFgVEHI06ZESFlSpiCjD1I7Bo7daNx11qgsuDCGE3IF9WgDaqOpTDzwH4 |
|
1177 DSD2JhjCgIljGKYZYvpn9tgJB3DdIlSbSnWgsJYRl2eX4uWzF4foFkDstrDU8bqjpUvzRtqHS9it |
|
1178 lawdhHlUNCH+Hrt0WaK+wqfHd8PcxHZn+qyw1FtcyU1xIxeALTKws8viJ2qBCBfWMU9gF0E/kl1l |
|
1179 PWb8rwTjOV49SAvaYKDehqCY/Tdbf8BBtcwVaAMOUInUOnpmk1JWxU2KRnu2041gc0BjoeUxDkLg |
|
1180 bJzHZGhawA6BN5kjpbYyAp1UNez4Ed4IErX2otVuMYG7QHX5hb5e58U2n3JEeYKabzS2rIuCpZkX |
|
1181 O7RbcCDegS0AJAsIkFqiMRRwnQXK1iEgD8uH5QJlyUcHQGAwFYU9DiwTMtESOfrCaRHG+JUg4a0k |
|
1182 2t0bMwWFLIYYDiRqje0DoyUQEizOKjirGjSToayZbjCxQxKf6y5iDuV8AB0qxmC7RhoadzL0uzoG |
|
1183 5SwuXKXkjEOz+PnzZ2YbtaY8BSI2w0WjKV6SxYrLHVi3FHSC8Ww460FssAUnEcA0SrOmOPwoipK9 |
|
1184 GtjPSy3bYIwhSqrr8vjoaLvdxjpKL6rVkVoe/fFP33zzp2esExcL4h9YjiMtOmUVH1Ebeobxt8YC |
|
1185 fWd2rsOPae5zI8EaSfJuyKVD/L5v0kUhjg/HVn8iF7e2Ev83/gQokKmZlKkMtA1bjJ6owyfxSxWK |
|
1186 J2Lk9h2N2TnQwaa1YkaDQhuoJBhRF2COwXmYF01eR44iVeIrsG4Q6S7krFlFdnLPRpofsFSU05Hl |
|
1187 gcPnXxADnzMMXxlTPEUtQWyR5svCIf1PzDYJuShaQyB50UT1otDdsBYzxF08XN6tw+cIjVlhqpA7 |
|
1188 UCL8Lg8WQNu5Lzn40f4l2j3HvzQfzxAYSx8Y5tXe3QgFh3DBvZi4UudwNbqdIE1bVs2gYFzVCAoa |
|
1189 PLUZU1uDIxsZIUj0bkzQzBurewCdOhk4E2ebXYAe7jw9a9dlBccTQh44Ec/piQQ/9bjX9oy3tsky |
|
1190 Sox0eNSjCgP2NhrtdAF8OTIAJiKsfg65p96W8w+dTeE9GABWcC4FGWzZYyZscX3A8CAcYKee1d83 |
|
1191 mmk8BAI3ifo/DDhhfMITVAqEqRz5jLuPwy1tOX/UQXi/wSGeMrtEEq32yFZXdwzK1J12aZnmqHqd |
|
1192 PYrnWQFOsVWKxEdtu+8rUCyCj4dsmRZATYaWHE6nE3L2PPmLdD/MQq0ajNfddAZitEkVGTck0xr+ |
|
1193 A6+C0gSU0wFaEjQL5qFC5i/sXyBydr36yx72sIRGhnC77vNCegZDwzHtBwLJqJMaIAQ5kLAvi+Q5 |
|
1194 sjbIgMOcDfJkG5rlXuEmGLECMXMMCGkZwJ0avfgGn8R4kEACipBvayVL8ZUIYfu6kvow1f0v5VKT |
|
1195 CBg5HchT0BmEEze74GQWTjqZBp+h/RwDHTmUBXDwDDweN1/usrlhWpv4AF/d19sWKVDIlAsJxy6q |
|
1196 Xwxh3JzsH06cHi2xzCSGobyJvJMRM9M4sNutQcOGGzDennfn0o/dhAWOHUWFeiE3txD+RVWq5oWK |
|
1197 ML7tpS7cj+aKPm0sthfpLIQ/3gaE4y8eJJl10cG8xSKptmkekYrRKzzxiddDxy7Ws0JHHyneOQJU |
|
1198 MLV39K4CFqYzviNgeJRVCJtlpLRf3gd750pDC5eHh55fe3X88kt/+ZN9KRj7GSbm2W1dJQrpmTFZ |
|
1199 mW2Rnn0Li2oRFpfkO31Kp09x0Y+vCgVhnvjw8bNAQnACc5vsHrf0liURm3vX5H0M6qB57iVXZ3XE |
|
1200 LoAI6i1klKPo8Yz5cGQfu7g7FvYIII9imDs2xUDSfPLPwLlro2COw8Uux0RXV6jxA83ffD0dSF26 |
|
1201 SH7zdXjPLB1iDIn9qOOr2Znp9FwMLtsMqWSSkTfgDKK0X97yju1TjlnlUoCmmezLgFuIH9NulHoL |
|
1202 v9e9F9mZzwHRA+LgYvYrRJNKJ6BukjSjRDigcXiIes4EwhzbD+PjQbobZUwagU/xbDIYq6irZ7Ax |
|
1203 EUfe4/5ytOdyapKzAxGj+ZSJ6qNyoM+t22MX7yzaPXLbL/uDtvTfpLMeCchbTThAwAeuwRwJ/v9f |
|
1204 CSsrhqaV1bij9ZW8W88bYA9Qh3sckTvckP7UfIK0NM4Ey50ST1FAn4otnQNTsg2PDgDKgv2MATi4 |
|
1205 jfo08U1TVXwmSHJeyuoQD8kmAktgjKdBlTV9MEfvZY2Y2G5zSl46BRPFkOqMdDrSriRqPclhkV0X |
|
1206 Jokh85u0grGgVUbRDx9+PIv6DKCnwUHD4Nx9NFzycDuFcB/BtJEmTvSYMUyhxwz556Uq8ji0q1zN |
|
1207 Oa1JEWqy9QnbywyayHJ4D+7JEXgneHz4iTHbfC3n11NJB7rIpjjUyZK+wWbExJ7z+oU1KllSdRCs |
|
1208 ZJ41SCt29LCsa9nkc0qY1xLsua7BxJoMOqblhNAyS1ZiRIMXmIzQ3Ej5ipuk0t5OWRVY9SeadHG0 |
|
1209 ShdC/tYkGQZ6crkEXPA0QzfFPD3lJMRbPmnmajAl502V1jsgQaIKfRhEh9JOx9mOFzrykOS8PxMQ |
|
1210 j6mPxUdcNrYz4RaGXCZc9FPguEiMxHCAOa1D7qLn0J4XU5x1SsWTE0aqf1BLj4PuDAUACAEorD8c |
|
1211 61yO3yKpyT1xoj13iYpa0iOlG3sW5HEglNEYY1/+TT99RnR5aw+Wq/1Yru7GctXFcjWI5crHcnU3 |
|
1212 lq5I4MbaNIaRhKFURjfPPVgF4WYheJqzZL7mflhUh8VzAFGUJqAzMsW1pV6ugw98CAipbecEkh62 |
|
1213 VQ0pV+tVBSdFNUjkfjzV0MGjqQp2BlONhB7MSzE+277KDn/sURxTDc6MhrO8LZI6iT25WGXFDMTW |
|
1214 ojtpAUxEt8iDs2f5zXTG+b6OpQov/+vTDx/eY3cEFZrzbhqGm4iGBZcyeppUK9WXpjbYKIEdqadf |
|
1215 mUHDNMCDB+ZaeJYD/u8tHfkj44gtHVkXogQPgGptbDe3IiWKOs916Yp+zkzOpw8nIszrsF3UHiKd |
|
1216 Xl6+Pf10GlISKPzf0BUYQ1tfOlx8TA/boe+/ud0txXEMCLXOpbTGz12TR+uWI+63sQZsx+199qXz |
|
1217 4MVDDPZgWOqv8t9KKdgSIFSs04GPIdSDg5/fFSb06GMYsVeS5Z61sLNi2xzZc1wUR/SHEtHdCfzT |
|
1218 L4wxpkAA7UKNTGTQBlMdpW/N6x0UdYA+0Nf73SFYN/TqRjI+Re0iBhxAh7K22373z8vcs9FTsn59 |
|
1219 9v35+4vz15enn35wXEB05T58PHohzn78LKhgAA0Y+0QJnpXXWJoChsW9QSIWBfxrML2xaGpOSsKo |
|
1220 txcXOne/wTsEWFSKNieG51zXYqFxjoaznvahLkhBjDIdIDmXNah+gy5zYLy04YsCqtCFp3QHZIbO |
|
1221 aqNDL30Jx1zWoYPOGKQPOrukYBBccwRNVB5cm6iw4jMhfYFlAClto22lQEY5qN75sXMiYvLtXmKO |
|
1222 BsOTdrBW9FeRi2v0JVZllkIk9yqysqSHYb1Eyzj6oT3yZLyGNKAzHGbWHXnVe7FAq/Uq4rXp8eOW |
|
1223 0X5rAMOWwd7CunNJ9QJUGIvVTiLCTnxyEMlb+Gq3Xu+Bgg3Do58aN9EwXQqrTyC4FusUAgjgyTVY |
|
1224 X4wTAEJnJ/wE9LGTHZAFHtdHbzaLw79EmiB+719+GeheV9nh30QJUZDg2pJogJhu57cQ+MQyFmcf |
|
1225 3o0jRo5qNcVfGqy7BoeEsnyOtFNBC5+pTkdKZktdcODrA2zQfgI1d4ZXsqz08GHXOEIJeKJG5DU8 |
|
1226 UYZ+Edb/WNgTXMq4AxpLyi1meDXLPZg2nwPxcS2zTFchn7+9OAPfEavcUYL4nOcMpuN8CR6q6mos |
|
1227 vjrWAYVHrtBcIRtX6MLSsfsi9roNZmZR5Gi0d1Jv94myn/1RvVRnlaTKRXuEy2ZYTp13jNwM22F2 |
|
1228 lrm73w3p7HYjuqPkMGNMLyuqa/Q5AzianiYcGEHEhJX0JtnMp4tpXptCtiydgzYFxQtqdQKigiTG |
|
1229 62LEf0XO6d6iUuaWCTwsd1W6WteYUofBMVW4Y/cfTz9fnL+nkvEXL1vfe4BFJxQPTLi44AQrxzDn |
|
1230 AV/cajDkrel0iHN1E8JAHQR/uk1ctXDCE/TGcXoR/3Sb+JrPiRMP8gpATTVlV0gwDHCGDUlPKxGM |
|
1231 q42G8eNWhrWY+WAoI4m3CnQBgLu+Pj/anh2DQtkf0/iIs4plqWk4MoPdSqXuR69xWeLhymI03Ala |
|
1232 hyTMfGYw9LrXsq8myv30ZBFvHAJG/d7+HKZqqNdVL8dhtn3cQsGttrS/5E7G1Ok3z1GUgYgjd/DY |
|
1233 ZbJhVay7Mwd61bU9YOJbja6RxEGFHv6Sh9rP8DCxxO5FK2Yg3W4gU4D5DKnvZTTgSaFdAAVCRaEj |
|
1234 R3In46cvvDU6NuH+NWrdBRbyB1CEukSTSv+LCjgRvvzG7iM3EVqoSo9F5PgrucwLWz+En+0afcvn |
|
1235 /hoHZYBSmSh2VZKv5IhhTQzMr3xi70nEkrb1OOYq7VRLaO4GD/V2D4P3xWL49MRg1uGDXr9ruetq |
|
1236 I5862GHwgoAPoUq2oN3Lph7xXu09LMDu+gh2FGGS5LdoD73uQU/DQr/rt4EzHPwwsYx7ae1V5/JJ |
|
1237 ZBu0XzmvIGCqFR2WOFbYeIiuYW5t4ElrhUP7VFeM2N8DN3qcOlQXLqPgQvVWGOoOnVA/5LslfF0u |
|
1238 pdrl9uqDblvIG5kV4BZBxIWl6b/a0vRxPJjquAevFhUk6C/aHU/ya/IQ3/z1fCLevP8J/n8tP0BM |
|
1239 gdexJuJvgIB4U1QQW/GVQLqrjWXtNQdNRaPwzhZBozQ9X2tHZ+XSWwceCeh6e7/Q3uoHgTWG1Ybf |
|
1240 pQAo8hrpmmxrHU0VOfw211z6bphxkYZ2JdSNSIb9xf9YMH+ke8brepOhonSSBO12XoUX52/O3n88 |
|
1241 i+tb5CPzM3SSCH79C65IH5FWeBw0EfbJvMEnXxyP8QeZlQMOo465zEUCjLlEBG55aeMsvqqfWN86 |
|
1242 qTBwFuVuUcxj7AlcxXeX6i14kGMnvLrXwnnmBWGNxvoQqXVj8TFQQ/zSlfgQOtIYvSYaSQglM7xE |
|
1243 w4/jcNgGTQRlduHP0+vtwk0M69sQtMAupu2qR/5wq3TWTGcNz2UmQu3E7oS5I5elidrM5u7dqQ+5 |
|
1244 0C9bAHVCmX65TJqsFjKHqILCXLr1DlrVve7EcsLcwrqc7gBRoiLbJjvl1JokSoQ4a0gXd/FIgnJm |
|
1245 EIX+mFyz7sV7WKLhO5oAnRCl2KFwhqpmvmY55nBAq7ve0fs2zV++iHpE5kk5Rpy3ThysE10mxmgl |
|
1246 a71+fjAaXz1vzSjlZefeZcd5CRbG5ZQDUJ/l06dPQ/Ef91t+RiXOiuIaXBKAPRQQigtq3mOz9eLs |
|
1247 bvW9WtMSA0vO1/IKHnyh/LF93uSUnLtjKG2ItH8NjAj3JrL8aPp3bCCnrSo+auUefGSjbcfPeUqv |
|
1248 VMHkikSVq99Mg4kXI1DEkqAbokTN0zTiQB32Y1c0eE8JE22aX+QtcHyKYCbYimdEHGau0buikkXL |
|
1249 PRadExES4JBKiHg2uuhJN3UAz+nlTqM5Pc/Tuq2xf+YeH+o7yrV9U4rmK5FsUTLMOjrEcK68eaza |
|
1250 epfFnSzqeevF/MpNuXVWyc334Q6sDZJWLJcGU3hoNmleyGpujCruWDpPaweM6YdweDC9IIYMUBwM |
|
1251 oBSChifDsLASbVv/YPfFxfQDnaQempl0AU1tX7rD6ZEk79SRxXE7PyViLCEt35ovY5jlPSV2tT/g |
|
1252 zSX+oNOKWGDtvRvAverV5PrOP1cwtC8CADj0nhmrIC07ejrCebmRhc9Mqx359hUBTj04hqeE201a |
|
1253 1U2STfW99Cm6bFN7tKzxtFeE7rz8Zn0WcKgLcDUPdbE0+A6mzgTpibWOplwd4nMdnsfutRv/hkpZ |
|
1254 oK/3wtPjmPR9xpfgHQ2OPb8yFzceovLN9YFe5b2L5YSqeqJxt1ax1wtPECJd80Vp2SEP+1FTGliu |
|
1255 K/xQABkAgD/s+EVfdU6BnNI0rhvdl/rvAf3m67vAukpmsGiW8u2+4tEXl9wq1jbhz7JsfL41uJUo |
|
1256 GQtz1VQLHt/KQylhlW9vEptah+6FCGh++JLvWPADTtMinOzwiYq0m2048i5aWfzuIlXbKfinqKRH |
|
1257 DdMK3TwsM1wn3ILi2pTHNhgybxLAFO3ILT7BT309WJad4MtqkKCH9XV01/J5/F1r1z0Cu3Jz9tJb |
|
1258 u3/9wqWBHrufX4ZowC6oJsSDKjotRtN/jehO9LHgcHpDf5b2tXmc5SAe1KhNNEtukrn7HQ+nD/mt |
|
1259 e219oHM5wt31zpr2Xhs27Nzn5D4380EcPrf33+h0daHZiw0WvYNlyvU6U7laqWmCr/CZkpdDZ8s9 |
|
1260 82Xs5jt6fYtM1M6YO7xRDyAMq+gqILfQD3YdPCl+lSAfzTpXpwVNTQVMTkWUShccvWrbCuBijlpp |
|
1261 vEmKcElTmEnMN6imKitwR0L9wjk+Mxwqs2qBmghqk6hrg7oZMdHvH8Mp+KDaXL/hWJldHI86QAiu |
|
1262 ynfe28E1gtOpbQN+edZeBEwnliFk3mwgPq7bO/D+2UQqvnNmoEtXuMFOjNSKXYdTXMRSyx8OUhil |
|
1263 2O9fafPveTd33P4bW5X2cLaiETr8fszFQkfKDTent/YdOO67Fxb0HkOKiPjdCcJ2a7nP3vuHrTAv |
|
1264 dCFFqIMWbtUvmeAXinFWBSuyHD4CuXevPPiVcVZnscNg0XCeuYqh/1YBvDVHhnboZUE9Lui/Fshn |
|
1265 hnZ+X29YZullovd0tlQ84R6Diqedbdy68ljEco8r7xcqPtKV9+A/0JXXr3YCa6Lx0fpgsHTxHp+f |
|
1266 1YT7nqSWEWDMFIiEyfbOW3aMPRy5hYDgkKe3oX17IOtM53aBMRPIkf0XaBAIfh+ScqumvPeVmHmH |
|
1267 fG1fuujx9xcfXp9eEC2ml6dv/vP0ezoixrxVx2Y9ONbJi0Om9qFXkubGPfpYb2jyFtuBd4lxXbWG |
|
1268 0GvvHYkMQBiuoR/a0K4ic5v3DejVIvcHAeJ3L7sDdZ/KHoTcc7503at7mNepHQv0Uy70Mb+ccxnz |
|
1269 yGRNWRzalKhpb7NYWkZ7Qf6+jXNKbvrqRDul+lVVexIQY1v4RTuAySvkL5u7MlW8NkPCjkr3nc5U |
|
1270 rYY3IMw9b5DCuXReN0RvGmJQtf/y6AqUXYI5eHYYJ/ZFjNSP83TKvmEU8/BzGRuCeFcQwv76XGFf |
|
1271 yGwPFYKAFZ5+mQ4jYvSfzmzb06AnSlwd0mWnQ1Q2X+wv3DPt5P41xTOf2r6VQpnjUsx3Q+dlk7nn |
|
1272 OHZMbwA5f5QWLJZOdS1oviOgcyueCtgbfSZWiLOdiCBK1IcVWLBDdNRvlHGQR7vpYG9o9Uwc7rsK |
|
1273 414FEeL5/o6Lzm0TPeIFj1D3jFCNuXDgWGCsGdl3x0V8R5A5ryzoNRSe84HnGfrlh/D15ur5sU1K |
|
1274 Ir9js/uSA6R96Bj2q7aq/M4XHzmjiVeqCdUOYKHKuAv+S+iw5lLsD3B6NbJ7giBz4MSQQq99+Fzd |
|
1275 jPBeshp2EbV8dwwLEqMnakyLcqqKNe72ybi32FZl9WFwgfT9MHraD0AhlGHfBD/8rg1Qz890PDhr |
|
1276 6G1x1uHEa4WOPNAhuc8LPMJ4fS123eF0relBw6lc3BaZc4cu7+n9BrFmr4F7eYmO/bagu/KWB/bY |
|
1277 fr4gNjz++QPG98sp7PAXdznUttfLwUsJ7MRiAQ4ez3YoZB7HYF1AYY5ITWPtppFwvPjdktHhpnZp |
|
1278 yBXo8FFND74JkgILcmKn2vJbYxD8H2/QG9E= |
|
1279 """.decode("base64").decode("zlib") |
|
1280 |
|
1281 ##file ez_setup.py |
|
1282 EZ_SETUP_PY = """ |
|
1283 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 |
|
1349 178BYnMUkw== |
|
1350 """.decode("base64").decode("zlib") |
|
1351 |
|
1352 ##file distribute_setup.py |
|
1353 DISTRIBUTE_SETUP_PY = """ |
|
1354 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 |
|
1433 """.decode("base64").decode("zlib") |
|
1434 |
|
1435 ##file activate.sh |
|
1436 ACTIVATE_SH = """ |
|
1437 eJytVU1v4jAQPW9+xTT0ANVS1GsrDlRFAqmFqmG72m0rY5IJsRRslDiktNr/vuMQ8tFQpNU2B4I9 |
|
1438 H36eeW/SglkgYvBFiLBKYg0LhCRGD1KhA7BjlUQuwkLIHne12HCNNpz5kVrBgsfBmdWCrUrA5VIq |
|
1439 DVEiQWjwRISuDreW5eE+CtodeLeAnhZEGKMGFXqAciMiJVcoNWx4JPgixDjzEj48QVeCfcqmtzfs |
|
1440 cfww+zG4ZfeD2ciGF7gCHaDMPM1jtvuHXAsPfF2rSGeOxV4iDY5GUGb3xVEYv2aj6WQ0vRseAlMY |
|
1441 G5DKsAawwnQUXt2LQOYlzZoYByqhonqoqfxZf4BLD97i4DukgXADCPgGgdOLTK5arYxZB1xnrc9T |
|
1442 EQFcHoZEAa1gSQioo/TPV5FZrDlxJA+NzwF+Ek1UonOzFnKZp6k5mgLBqSkuuAGXS4whJb5xz/xs |
|
1443 wXCHjiVerAk5eh9Kfz1wqOldtVv9dkbscfjgjKeTA8XPrtaNauX5rInOxaHuOReNtpFjo1/OxdFG |
|
1444 5eY9hJ3L3jqcPJbATggXAemDLZX0MNZRYjSDH7C1wMHQh73DyYfTu8a0F9v+6D8W6XNnF1GEIXW/ |
|
1445 JrSKPOtnW1YFat9mrLJkzLbyIlTvYzV0RGXcaTBfVLx7jF2PJ2wyuBsydpm7VSVa4C4Zb6pFO2TR |
|
1446 huypCEPwuQjNftUrNl6GsYZzuFrrLdC9iJjQ3omAPBbcI2lsU77tUD43kw1NPZhTrnZWzuQKLomx |
|
1447 Rd4OXM1ByExVVkmoTwfBJ7Lt10Iq1Kgo23Bmd8Ib1KrGbsbO4Pp2yO4fpnf3s6MnZiwuiJuls1/L |
|
1448 Pu4yUCvhpA+vZaJvWWDTr0yFYYyVnHMqCEq+QniuYX225xmnzRENjbXACF3wkCYNVZ1mBwxoR9Iw |
|
1449 WAo3/36oSOTfgjwEEQKt15e9Xpqm52+oaXxszmnE9GLl65RH2OMmS6+u5acKxDmlPgj2eT5/gQOX |
|
1450 LLK0j1y0Uwbmn438VZkVpqlfNKa/YET/53j+99G8H8tUhr9ZSXs2 |
|
1451 """.decode("base64").decode("zlib") |
|
1452 |
|
1453 ##file activate.bat |
|
1454 ACTIVATE_BAT = """ |
|
1455 eJyFUkEKgzAQvAfyhz0YaL9QEWpRqlSjWGspFPZQTevFHOr/adQaU1GaUzI7Mzu7ZF89XhKkEJS8 |
|
1456 qxaKMMsvboQ+LxxE44VICSW1gEa2UFaibqoS0iyJ0xw2lIA6nX5AHCu1jpRsv5KRjknkac9VLVug |
|
1457 sX9mtzxIeJDE/mg4OGp47qoLo3NHX2jsMB3AiDht5hryAUOEifoTdCXbSh7V0My2NMq/Xbh5MEjU |
|
1458 ZT63gpgNT9lKOJ/CtHsvT99re3pX303kydn4HeyOeAg5cjf2EW1D6HOPkg9NGKhu |
|
1459 """.decode("base64").decode("zlib") |
|
1460 |
|
1461 ##file deactivate.bat |
|
1462 DEACTIVATE_BAT = """ |
|
1463 eJxzSE3OyFfIT0vj4spMU0hJTcvMS01RiPf3cYkP8wwKCXX0iQ8I8vcNCFHQ4FIAguLUEgWIgK0q |
|
1464 FlWqXJpcICVYpGzx2BAZ4uHv5+Hv6wq1BWINXBTdKriEKkI1DhW2QAfhttcxxANiFZCBbglQSJUL |
|
1465 i2dASrm4rFz9XLgAwJNbyQ== |
|
1466 """.decode("base64").decode("zlib") |
|
1467 |
|
1468 ##file distutils-init.py |
|
1469 DISTUTILS_INIT = """ |
|
1470 eJytVl2L6zYQffevGBKK7XavKe3bhVBo78uFSyml0IdlEVpbTtR1JCMpm6S/vjOSY0v+uO1DDbs4 |
|
1471 0tF8nJk5sjz32jjQNpPhzd7H1ys3SqqjhcfCL1q18vgbN1YY2Kc/pQWlHXB4l8ZdeCfUO5x1c+nE |
|
1472 E1gNVwE1V3CxAqQDp6GVqgF3EmBd08nXLGukUfws4IDBVD13p2pYoS3rLk52ltF6hPhLS1XM4EUc |
|
1473 VsVYKzvBWPkE+WgmLzPZjkaUNmd6KVI3JRwWoRSLM6P98mMG+Dw4q+il8Ev07P7ATCNmRlfQ8/qN |
|
1474 HwVwB99Y4H0vMHAi6BWZUoEhoqXTNXdSK+A2LN6tE+fJ0E+7MhOdFSEM5lNgrJIKWXDF908wy87D |
|
1475 xE3UoHsxkegZTaHIHGNSSYfm+ntelpURvCnK7NEWBI/ap/b8Z1m232N2rj7B60V2DRM3B5NpaLSw |
|
1476 KnfwpvQVTviHOR+F88lhQyBAGlE7be6DoRNg9ldsG3218IHa6MRNU+tGBEYIggwafRk6yzsXDcVU |
|
1477 9Ua08kYxt+F3x12LRaQi52j0xx/ywFxrdMRqVevzmaummlIYEp0WsCAaX8cFb6buuLUTqEgQQ6/Q |
|
1478 04iWRoF38m/BdE8VtlBY0bURiB6KG1crpMZwc2fIjqWh+1UrkSLpWUIP8PySwLKv4qPGSVqDuMPy |
|
1479 dywQ+gS7L1irXVkm5pJsq3l+Ib1lMOvUrxI+/mBBY4KB+WpUtcO06RtzckNvQ6vYj1lGoZM2sdDG |
|
1480 fryJPYJVn/Cfka8XSqNaoLKhmOlqXMzW9+YBVp1EtIThZtOwzCRvMaARa+0xD0b2kcaJGwJsMbc7 |
|
1481 hLUfY4vKvsCOBdvDnyfuRbzmXRdGTZgPF7oGQkJACWVD22IMQdhx0npt5S2f+pXO+OwH6d+hwiS5 |
|
1482 7IJOjcK2emj1zBy1aONHByfAMoraw6WlrSIFTbGghqASoRCjVncYROFpXM4uYSqhGnuVeGvks4jz |
|
1483 cjnCoR5GnPW7KOh4maVbdFeoplgJ3wh3MSrAsv/QuMjOspnTKRl1fTYqqNisv7uTVnhF1GhoBFbp |
|
1484 lh+OcXN2riA5ZrYXtWxlfcDuC8U5kLoN3CCJYXGpesO6dx6rU0zGMtjU6cNlmW0Fid8Sja4ZG+Z3 |
|
1485 fTPbyj+mZnZ2wSQK8RaT9Km0ySRuLpm0DkUUL0ra3WQ2BgGJ7v9I9SKqNKZ/IR4R28RHm+vEz5ic |
|
1486 nZ2IH7bfub8pU1PR3gr10W7xLTfHh6Z6bgZ7K14G7Mj/1z5J6MFo6V5e07H0Ou78dTyeI+mxKOpI |
|
1487 eC2KMSj6HKxd6Uudf/n886fPv+f++x1lbASlmjQuPz8OvGA0j7j2eCu/4bcW6SFeCuNJ0W1GQHI5 |
|
1488 iwC9Ey0bjtHd9P4dPA++XxLnZDVuxvFEtlm3lf5a2c02u2LRYXHH/AOs8pIa |
|
1489 """.decode("base64").decode("zlib") |
|
1490 |
|
1491 ##file distutils.cfg |
|
1492 DISTUTILS_CFG = """ |
|
1493 eJxNj00KwkAMhfc9xYNuxe4Ft57AjYiUtDO1wXSmNJnK3N5pdSEEAu8nH6lxHVlRhtDHMPATA4uH |
|
1494 xJ4EFmGbvfJiicSHFRzUSISMY6hq3GLCRLnIvSTnEefN0FIjw5tF0Hkk9Q5dRunBsVoyFi24aaLg |
|
1495 9FDOlL0FPGluf4QjcInLlxd6f6rqkgPu/5nHLg0cXCscXoozRrP51DRT3j9QNl99AP53T2Q= |
|
1496 """.decode("base64").decode("zlib") |
|
1497 |
|
1498 ##file activate_this.py |
|
1499 ACTIVATE_THIS = """ |
|
1500 eJyNUlGL2zAMfvevEBlHEujSsXsL9GGDvW1jD3sZpQQ3Ua7aJXawnbT595Ocpe0dO5ghseVP+vRJ |
|
1501 VpIkn2cYPZknwAvWLXWYhRP5Sk4baKgOWRWNqtpdgTyH2Y5wpq5Tug406YAgKEzkwqg7NBPwR86a |
|
1502 Hk0olPopaK0NHJHzYQPnE5rI0o8+yBUwiBfyQcT8mMPJGiAT0A0O+b8BY4MKJ7zPcSSzHaKrSpJE |
|
1503 qeDmUgGvVbPCS41DgO+6xy/OWbfAThMn/OQ9ukDWRCSLiKzk1yrLjWapq6NnvHUoHXQ4bYPdrsVX |
|
1504 4lQMc/q6ZW975nmSK+oH6wL42a9H65U6aha342Mh0UVDzrD87C1bH73s16R5zsStkBZDp0NrXQ+7 |
|
1505 HaRnMo8f06UBnljKoOtn/YT+LtdvSyaT/BtIv9KR60nF9f3qmuYKO4//T9ItJMsjPfgUHqKwCZ3n |
|
1506 xu/Lx8M/UvCLTxW7VULHxB1PRRbrYfvWNY5S8it008jOjcleaMqVBDnUXcWULV2YK9JEQ92OfC96 |
|
1507 1Tv4ZicZZZ7GpuEpZbbeQ7DxquVx5hdqoyFSSmXwfC90f1Dc7hjFs/tK99I0fpkI8zSLy4tSy+sI |
|
1508 3vMWehjQNJmE5VePlZbL61nzX3S93ZcfDqznnkb9AZ3GWJU= |
|
1509 """.decode("base64").decode("zlib") |
|
1510 |
|
1511 if __name__ == '__main__': |
|
1512 main() |
|
1513 |
|
1514 ## TODO: |
|
1515 ## Copy python.exe.manifest |
|
1516 ## Monkeypatch distutils.sysconfig |