virtual-bootstrap.py 91 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397
  1. #!/usr/bin/env python
  2. """Create a "virtual" Python installation"""
  3. import os
  4. import sys
  5. # If we are running in a new interpreter to create a virtualenv,
  6. # we do NOT want paths from our existing location interfering with anything,
  7. # So we remove this file's directory from sys.path - most likely to be
  8. # the previous interpreter's site-packages. Solves #705, #763, #779
  9. if os.environ.get('VIRTUALENV_INTERPRETER_RUNNING'):
  10. for path in sys.path[:]:
  11. if os.path.realpath(os.path.dirname(__file__)) == os.path.realpath(path):
  12. sys.path.remove(path)
  13. import base64
  14. import codecs
  15. import optparse
  16. import re
  17. import shutil
  18. import logging
  19. import zlib
  20. import errno
  21. import glob
  22. import distutils.sysconfig
  23. import struct
  24. import subprocess
  25. import pkgutil
  26. import tempfile
  27. import textwrap
  28. from distutils.util import strtobool
  29. from os.path import join
  30. try:
  31. import ConfigParser
  32. except ImportError:
  33. import configparser as ConfigParser
  34. __version__ = "15.1.0"
  35. virtualenv_version = __version__ # legacy
  36. if sys.version_info < (2, 6):
  37. print('ERROR: %s' % sys.exc_info()[1])
  38. print('ERROR: this script requires Python 2.6 or greater.')
  39. sys.exit(101)
  40. try:
  41. basestring
  42. except NameError:
  43. basestring = str
  44. py_version = 'python%s.%s' % (sys.version_info[0], sys.version_info[1])
  45. is_jython = sys.platform.startswith('java')
  46. is_pypy = hasattr(sys, 'pypy_version_info')
  47. is_win = (sys.platform == 'win32')
  48. is_cygwin = (sys.platform == 'cygwin')
  49. is_darwin = (sys.platform == 'darwin')
  50. abiflags = getattr(sys, 'abiflags', '')
  51. user_dir = os.path.expanduser('~')
  52. if is_win:
  53. default_storage_dir = os.path.join(user_dir, 'virtualenv')
  54. else:
  55. default_storage_dir = os.path.join(user_dir, '.virtualenv')
  56. default_config_file = os.path.join(default_storage_dir, 'virtualenv.ini')
  57. if is_pypy:
  58. expected_exe = 'pypy'
  59. elif is_jython:
  60. expected_exe = 'jython'
  61. else:
  62. expected_exe = 'python'
  63. # Return a mapping of version -> Python executable
  64. # Only provided for Windows, where the information in the registry is used
  65. if not is_win:
  66. def get_installed_pythons():
  67. return {}
  68. else:
  69. try:
  70. import winreg
  71. except ImportError:
  72. import _winreg as winreg
  73. def get_installed_pythons():
  74. try:
  75. python_core = winreg.CreateKey(winreg.HKEY_LOCAL_MACHINE,
  76. "Software\\Python\\PythonCore")
  77. except WindowsError:
  78. # No registered Python installations
  79. return {}
  80. i = 0
  81. versions = []
  82. while True:
  83. try:
  84. versions.append(winreg.EnumKey(python_core, i))
  85. i = i + 1
  86. except WindowsError:
  87. break
  88. exes = dict()
  89. for ver in versions:
  90. try:
  91. path = winreg.QueryValue(python_core, "%s\\InstallPath" % ver)
  92. except WindowsError:
  93. continue
  94. exes[ver] = join(path, "python.exe")
  95. winreg.CloseKey(python_core)
  96. # Add the major versions
  97. # Sort the keys, then repeatedly update the major version entry
  98. # Last executable (i.e., highest version) wins with this approach
  99. for ver in sorted(exes):
  100. exes[ver[0]] = exes[ver]
  101. return exes
  102. REQUIRED_MODULES = ['os', 'posix', 'posixpath', 'nt', 'ntpath', 'genericpath',
  103. 'fnmatch', 'locale', 'encodings', 'codecs',
  104. 'stat', 'UserDict', 'readline', 'copy_reg', 'types',
  105. 're', 'sre', 'sre_parse', 'sre_constants', 'sre_compile',
  106. 'zlib']
  107. REQUIRED_FILES = ['lib-dynload', 'config']
  108. majver, minver = sys.version_info[:2]
  109. if majver == 2:
  110. if minver >= 6:
  111. REQUIRED_MODULES.extend(['warnings', 'linecache', '_abcoll', 'abc'])
  112. if minver >= 7:
  113. REQUIRED_MODULES.extend(['_weakrefset'])
  114. elif majver == 3:
  115. # Some extra modules are needed for Python 3, but different ones
  116. # for different versions.
  117. REQUIRED_MODULES.extend([
  118. '_abcoll', 'warnings', 'linecache', 'abc', 'io', '_weakrefset',
  119. 'copyreg', 'tempfile', 'random', '__future__', 'collections',
  120. 'keyword', 'tarfile', 'shutil', 'struct', 'copy', 'tokenize',
  121. 'token', 'functools', 'heapq', 'bisect', 'weakref', 'reprlib'
  122. ])
  123. if minver >= 2:
  124. REQUIRED_FILES[-1] = 'config-%s' % majver
  125. if minver >= 3:
  126. import sysconfig
  127. platdir = sysconfig.get_config_var('PLATDIR')
  128. REQUIRED_FILES.append(platdir)
  129. REQUIRED_MODULES.extend([
  130. 'base64', '_dummy_thread', 'hashlib', 'hmac',
  131. 'imp', 'importlib', 'rlcompleter'
  132. ])
  133. if minver >= 4:
  134. REQUIRED_MODULES.extend([
  135. 'operator',
  136. '_collections_abc',
  137. '_bootlocale',
  138. ])
  139. if minver >= 6:
  140. REQUIRED_MODULES.extend(['enum'])
  141. if is_pypy:
  142. # these are needed to correctly display the exceptions that may happen
  143. # during the bootstrap
  144. REQUIRED_MODULES.extend(['traceback', 'linecache'])
  145. if majver == 3:
  146. # _functools is needed to import locale during stdio initialization and
  147. # needs to be copied on PyPy because it's not built in
  148. REQUIRED_MODULES.append('_functools')
  149. class Logger(object):
  150. """
  151. Logging object for use in command-line script. Allows ranges of
  152. levels, to avoid some redundancy of displayed information.
  153. """
  154. DEBUG = logging.DEBUG
  155. INFO = logging.INFO
  156. NOTIFY = (logging.INFO + logging.WARN) / 2
  157. WARN = WARNING = logging.WARN
  158. ERROR = logging.ERROR
  159. FATAL = logging.FATAL
  160. LEVELS = [DEBUG, INFO, NOTIFY, WARN, ERROR, FATAL]
  161. def __init__(self, consumers):
  162. self.consumers = consumers
  163. self.indent = 0
  164. self.in_progress = None
  165. self.in_progress_hanging = False
  166. def debug(self, msg, *args, **kw):
  167. self.log(self.DEBUG, msg, *args, **kw)
  168. def info(self, msg, *args, **kw):
  169. self.log(self.INFO, msg, *args, **kw)
  170. def notify(self, msg, *args, **kw):
  171. self.log(self.NOTIFY, msg, *args, **kw)
  172. def warn(self, msg, *args, **kw):
  173. self.log(self.WARN, msg, *args, **kw)
  174. def error(self, msg, *args, **kw):
  175. self.log(self.ERROR, msg, *args, **kw)
  176. def fatal(self, msg, *args, **kw):
  177. self.log(self.FATAL, msg, *args, **kw)
  178. def log(self, level, msg, *args, **kw):
  179. if args:
  180. if kw:
  181. raise TypeError(
  182. "You may give positional or keyword arguments, not both")
  183. args = args or kw
  184. rendered = None
  185. for consumer_level, consumer in self.consumers:
  186. if self.level_matches(level, consumer_level):
  187. if (self.in_progress_hanging
  188. and consumer in (sys.stdout, sys.stderr)):
  189. self.in_progress_hanging = False
  190. sys.stdout.write('\n')
  191. sys.stdout.flush()
  192. if rendered is None:
  193. if args:
  194. rendered = msg % args
  195. else:
  196. rendered = msg
  197. rendered = ' ' * self.indent + rendered
  198. if hasattr(consumer, 'write'):
  199. consumer.write(rendered + '\n')
  200. else:
  201. consumer(rendered)
  202. def start_progress(self, msg):
  203. assert not self.in_progress, (
  204. "Tried to start_progress(%r) while in_progress %r"
  205. % (msg, self.in_progress))
  206. if self.level_matches(self.NOTIFY, self._stdout_level()):
  207. sys.stdout.write(msg)
  208. sys.stdout.flush()
  209. self.in_progress_hanging = True
  210. else:
  211. self.in_progress_hanging = False
  212. self.in_progress = msg
  213. def end_progress(self, msg='done.'):
  214. assert self.in_progress, (
  215. "Tried to end_progress without start_progress")
  216. if self.stdout_level_matches(self.NOTIFY):
  217. if not self.in_progress_hanging:
  218. # Some message has been printed out since start_progress
  219. sys.stdout.write('...' + self.in_progress + msg + '\n')
  220. sys.stdout.flush()
  221. else:
  222. sys.stdout.write(msg + '\n')
  223. sys.stdout.flush()
  224. self.in_progress = None
  225. self.in_progress_hanging = False
  226. def show_progress(self):
  227. """If we are in a progress scope, and no log messages have been
  228. shown, write out another '.'"""
  229. if self.in_progress_hanging:
  230. sys.stdout.write('.')
  231. sys.stdout.flush()
  232. def stdout_level_matches(self, level):
  233. """Returns true if a message at this level will go to stdout"""
  234. return self.level_matches(level, self._stdout_level())
  235. def _stdout_level(self):
  236. """Returns the level that stdout runs at"""
  237. for level, consumer in self.consumers:
  238. if consumer is sys.stdout:
  239. return level
  240. return self.FATAL
  241. def level_matches(self, level, consumer_level):
  242. """
  243. >>> l = Logger([])
  244. >>> l.level_matches(3, 4)
  245. False
  246. >>> l.level_matches(3, 2)
  247. True
  248. >>> l.level_matches(slice(None, 3), 3)
  249. False
  250. >>> l.level_matches(slice(None, 3), 2)
  251. True
  252. >>> l.level_matches(slice(1, 3), 1)
  253. True
  254. >>> l.level_matches(slice(2, 3), 1)
  255. False
  256. """
  257. if isinstance(level, slice):
  258. start, stop = level.start, level.stop
  259. if start is not None and start > consumer_level:
  260. return False
  261. if stop is not None and stop <= consumer_level:
  262. return False
  263. return True
  264. else:
  265. return level >= consumer_level
  266. @classmethod
  267. def level_for_integer(cls, level):
  268. levels = cls.LEVELS
  269. if level < 0:
  270. return levels[0]
  271. if level >= len(levels):
  272. return levels[-1]
  273. return levels[level]
  274. # create a silent logger just to prevent this from being undefined
  275. # will be overridden with requested verbosity main() is called.
  276. logger = Logger([(Logger.LEVELS[-1], sys.stdout)])
  277. def mkdir(path):
  278. if not os.path.exists(path):
  279. logger.info('Creating %s', path)
  280. os.makedirs(path)
  281. else:
  282. logger.info('Directory %s already exists', path)
  283. def copyfileordir(src, dest, symlink=True):
  284. if os.path.isdir(src):
  285. shutil.copytree(src, dest, symlink)
  286. else:
  287. shutil.copy2(src, dest)
  288. def copyfile(src, dest, symlink=True):
  289. if not os.path.exists(src):
  290. # Some bad symlink in the src
  291. logger.warn('Cannot find file %s (bad symlink)', src)
  292. return
  293. if os.path.exists(dest):
  294. logger.debug('File %s already exists', dest)
  295. return
  296. if not os.path.exists(os.path.dirname(dest)):
  297. logger.info('Creating parent directories for %s', os.path.dirname(dest))
  298. os.makedirs(os.path.dirname(dest))
  299. if not os.path.islink(src):
  300. srcpath = os.path.abspath(src)
  301. else:
  302. srcpath = os.readlink(src)
  303. if symlink and hasattr(os, 'symlink') and not is_win:
  304. logger.info('Symlinking %s', dest)
  305. try:
  306. os.symlink(srcpath, dest)
  307. except (OSError, NotImplementedError):
  308. logger.info('Symlinking failed, copying to %s', dest)
  309. copyfileordir(src, dest, symlink)
  310. else:
  311. logger.info('Copying to %s', dest)
  312. copyfileordir(src, dest, symlink)
  313. def writefile(dest, content, overwrite=True):
  314. if not os.path.exists(dest):
  315. logger.info('Writing %s', dest)
  316. with open(dest, 'wb') as f:
  317. f.write(content.encode('utf-8'))
  318. return
  319. else:
  320. with open(dest, 'rb') as f:
  321. c = f.read()
  322. if c != content.encode("utf-8"):
  323. if not overwrite:
  324. logger.notify('File %s exists with different content; not overwriting', dest)
  325. return
  326. logger.notify('Overwriting %s with new content', dest)
  327. with open(dest, 'wb') as f:
  328. f.write(content.encode('utf-8'))
  329. else:
  330. logger.info('Content %s already in place', dest)
  331. def rmtree(dir):
  332. if os.path.exists(dir):
  333. logger.notify('Deleting tree %s', dir)
  334. shutil.rmtree(dir)
  335. else:
  336. logger.info('Do not need to delete %s; already gone', dir)
  337. def make_exe(fn):
  338. if hasattr(os, 'chmod'):
  339. oldmode = os.stat(fn).st_mode & 0xFFF # 0o7777
  340. newmode = (oldmode | 0x16D) & 0xFFF # 0o555, 0o7777
  341. os.chmod(fn, newmode)
  342. logger.info('Changed mode of %s to %s', fn, oct(newmode))
  343. def _find_file(filename, dirs):
  344. for dir in reversed(dirs):
  345. files = glob.glob(os.path.join(dir, filename))
  346. if files and os.path.isfile(files[0]):
  347. return True, files[0]
  348. return False, filename
  349. def file_search_dirs():
  350. here = os.path.dirname(os.path.abspath(__file__))
  351. dirs = [here, 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(
  360. os.path.dirname(virtualenv.__file__), 'virtualenv_support'))
  361. return [d for d in dirs if os.path.isdir(d)]
  362. class UpdatingDefaultsHelpFormatter(optparse.IndentedHelpFormatter):
  363. """
  364. Custom help formatter for use in ConfigOptionParser that updates
  365. the defaults before expanding them, allowing them to show up correctly
  366. in the help listing
  367. """
  368. def expand_default(self, option):
  369. if self.parser is not None:
  370. self.parser.update_defaults(self.parser.defaults)
  371. return optparse.IndentedHelpFormatter.expand_default(self, option)
  372. class ConfigOptionParser(optparse.OptionParser):
  373. """
  374. Custom option parser which updates its defaults by checking the
  375. configuration files and environmental variables
  376. """
  377. def __init__(self, *args, **kwargs):
  378. self.config = ConfigParser.RawConfigParser()
  379. self.files = self.get_config_files()
  380. self.config.read(self.files)
  381. optparse.OptionParser.__init__(self, *args, **kwargs)
  382. def get_config_files(self):
  383. config_file = os.environ.get('VIRTUALENV_CONFIG_FILE', False)
  384. if config_file and os.path.exists(config_file):
  385. return [config_file]
  386. return [default_config_file]
  387. def update_defaults(self, defaults):
  388. """
  389. Updates the given defaults with values from the config files and
  390. the environ. Does a little special handling for certain types of
  391. options (lists).
  392. """
  393. # Then go and look for the other sources of configuration:
  394. config = {}
  395. # 1. config files
  396. config.update(dict(self.get_config_section('virtualenv')))
  397. # 2. environmental variables
  398. config.update(dict(self.get_environ_vars()))
  399. # Then set the options with those values
  400. for key, val in config.items():
  401. key = key.replace('_', '-')
  402. if not key.startswith('--'):
  403. key = '--%s' % key # only prefer long opts
  404. option = self.get_option(key)
  405. if option is not None:
  406. # ignore empty values
  407. if not val:
  408. continue
  409. # handle multiline configs
  410. if option.action == 'append':
  411. val = val.split()
  412. else:
  413. option.nargs = 1
  414. if option.action == 'store_false':
  415. val = not strtobool(val)
  416. elif option.action in ('store_true', 'count'):
  417. val = strtobool(val)
  418. try:
  419. val = option.convert_value(key, val)
  420. except optparse.OptionValueError:
  421. e = sys.exc_info()[1]
  422. print("An error occurred during configuration: %s" % e)
  423. sys.exit(3)
  424. defaults[option.dest] = val
  425. return defaults
  426. def get_config_section(self, name):
  427. """
  428. Get a section of a configuration
  429. """
  430. if self.config.has_section(name):
  431. return self.config.items(name)
  432. return []
  433. def get_environ_vars(self, prefix='VIRTUALENV_'):
  434. """
  435. Returns a generator with all environmental vars with prefix VIRTUALENV
  436. """
  437. for key, val in os.environ.items():
  438. if key.startswith(prefix):
  439. yield (key.replace(prefix, '').lower(), val)
  440. def get_default_values(self):
  441. """
  442. Overridding to make updating the defaults after instantiation of
  443. the option parser possible, update_defaults() does the dirty work.
  444. """
  445. if not self.process_default_values:
  446. # Old, pre-Optik 1.5 behaviour.
  447. return optparse.Values(self.defaults)
  448. defaults = self.update_defaults(self.defaults.copy()) # ours
  449. for option in self._get_all_options():
  450. default = defaults.get(option.dest)
  451. if isinstance(default, basestring):
  452. opt_str = option.get_opt_string()
  453. defaults[option.dest] = option.check_value(opt_str, default)
  454. return optparse.Values(defaults)
  455. def main():
  456. parser = ConfigOptionParser(
  457. version=virtualenv_version,
  458. usage="%prog [OPTIONS] DEST_DIR",
  459. formatter=UpdatingDefaultsHelpFormatter())
  460. parser.add_option(
  461. '-v', '--verbose',
  462. action='count',
  463. dest='verbose',
  464. default=0,
  465. help="Increase verbosity.")
  466. parser.add_option(
  467. '-q', '--quiet',
  468. action='count',
  469. dest='quiet',
  470. default=0,
  471. help='Decrease verbosity.')
  472. parser.add_option(
  473. '-p', '--python',
  474. dest='python',
  475. metavar='PYTHON_EXE',
  476. help='The Python interpreter to use, e.g., --python=python2.5 will use the python2.5 '
  477. 'interpreter to create the new environment. The default is the interpreter that '
  478. 'virtualenv was installed with (%s)' % sys.executable)
  479. parser.add_option(
  480. '--clear',
  481. dest='clear',
  482. action='store_true',
  483. help="Clear out the non-root install and start from scratch.")
  484. parser.set_defaults(system_site_packages=False)
  485. parser.add_option(
  486. '--no-site-packages',
  487. dest='system_site_packages',
  488. action='store_false',
  489. help="DEPRECATED. Retained only for backward compatibility. "
  490. "Not having access to global site-packages is now the default behavior.")
  491. parser.add_option(
  492. '--system-site-packages',
  493. dest='system_site_packages',
  494. action='store_true',
  495. help="Give the virtual environment access to the global site-packages.")
  496. parser.add_option(
  497. '--always-copy',
  498. dest='symlink',
  499. action='store_false',
  500. default=True,
  501. help="Always copy files rather than symlinking.")
  502. parser.add_option(
  503. '--unzip-setuptools',
  504. dest='unzip_setuptools',
  505. action='store_true',
  506. help="Unzip Setuptools when installing it.")
  507. parser.add_option(
  508. '--relocatable',
  509. dest='relocatable',
  510. action='store_true',
  511. help='Make an EXISTING virtualenv environment relocatable. '
  512. 'This fixes up scripts and makes all .pth files relative.')
  513. parser.add_option(
  514. '--relocatable_pth',
  515. dest='relocatable_pth',
  516. action='store_true',
  517. help='Make an EXISTING virtualenv environment relocatable. '
  518. 'This fixes up scripts and makes all .pth files relative.')
  519. parser.add_option(
  520. '--no-setuptools',
  521. dest='no_setuptools',
  522. action='store_true',
  523. help='Do not install setuptools in the new virtualenv.')
  524. parser.add_option(
  525. '--no-pip',
  526. dest='no_pip',
  527. action='store_true',
  528. help='Do not install pip in the new virtualenv.')
  529. parser.add_option(
  530. '--no-wheel',
  531. dest='no_wheel',
  532. action='store_true',
  533. help='Do not install wheel in the new virtualenv.')
  534. default_search_dirs = file_search_dirs()
  535. parser.add_option(
  536. '--extra-search-dir',
  537. dest="search_dirs",
  538. action="append",
  539. metavar='DIR',
  540. default=default_search_dirs,
  541. help="Directory to look for setuptools/pip distributions in. "
  542. "This option can be used multiple times.")
  543. parser.add_option(
  544. "--download",
  545. dest="download",
  546. default=True,
  547. action="store_true",
  548. help="Download preinstalled packages from PyPI.",
  549. )
  550. parser.add_option(
  551. "--no-download",
  552. '--never-download',
  553. dest="download",
  554. action="store_false",
  555. help="Do not download preinstalled packages from PyPI.",
  556. )
  557. parser.add_option(
  558. '--prompt',
  559. dest='prompt',
  560. help='Provides an alternative prompt prefix for this environment.')
  561. parser.add_option(
  562. '--setuptools',
  563. dest='setuptools',
  564. action='store_true',
  565. help="DEPRECATED. Retained only for backward compatibility. This option has no effect.")
  566. parser.add_option(
  567. '--distribute',
  568. dest='distribute',
  569. action='store_true',
  570. help="DEPRECATED. Retained only for backward compatibility. This option has no effect.")
  571. if 'extend_parser' in globals():
  572. extend_parser(parser)
  573. options, args = parser.parse_args()
  574. global logger
  575. if 'adjust_options' in globals():
  576. adjust_options(options, args)
  577. verbosity = options.verbose - options.quiet
  578. logger = Logger([(Logger.level_for_integer(2 - verbosity), sys.stdout)])
  579. if options.python and not os.environ.get('VIRTUALENV_INTERPRETER_RUNNING'):
  580. env = os.environ.copy()
  581. interpreter = resolve_interpreter(options.python)
  582. if interpreter == sys.executable:
  583. logger.warn('Already using interpreter %s' % interpreter)
  584. else:
  585. logger.notify('Running virtualenv with interpreter %s' % interpreter)
  586. env['VIRTUALENV_INTERPRETER_RUNNING'] = 'true'
  587. file = __file__
  588. if file.endswith('.pyc'):
  589. file = file[:-1]
  590. popen = subprocess.Popen([interpreter, file] + sys.argv[1:], env=env)
  591. raise SystemExit(popen.wait())
  592. if not args:
  593. print('You must provide a DEST_DIR')
  594. parser.print_help()
  595. sys.exit(2)
  596. if len(args) > 1:
  597. print('There must be only one argument: DEST_DIR (you gave %s)' % (
  598. ' '.join(args)))
  599. parser.print_help()
  600. sys.exit(2)
  601. home_dir = args[0]
  602. if os.path.exists(home_dir) and os.path.isfile(home_dir):
  603. logger.fatal('ERROR: File already exists and is not a directory.')
  604. logger.fatal('Please provide a different path or delete the file.')
  605. sys.exit(3)
  606. if os.environ.get('WORKING_ENV'):
  607. logger.fatal('ERROR: you cannot run virtualenv while in a workingenv')
  608. logger.fatal('Please deactivate your workingenv, then re-run this script')
  609. sys.exit(3)
  610. if 'PYTHONHOME' in os.environ:
  611. logger.warn('PYTHONHOME is set. You *must* activate the virtualenv before using it')
  612. del os.environ['PYTHONHOME']
  613. if options.relocatable:
  614. make_environment_relocatable(home_dir)
  615. return
  616. if options.relocatable_pth:
  617. make_pth_relocatable(home_dir)
  618. return
  619. create_environment(home_dir,
  620. site_packages=options.system_site_packages,
  621. clear=options.clear,
  622. unzip_setuptools=options.unzip_setuptools,
  623. prompt=options.prompt,
  624. search_dirs=options.search_dirs,
  625. download=options.download,
  626. no_setuptools=options.no_setuptools,
  627. no_pip=options.no_pip,
  628. no_wheel=options.no_wheel,
  629. symlink=options.symlink)
  630. if 'after_install' in globals():
  631. after_install(options, home_dir)
  632. def call_subprocess(cmd, show_stdout=True,
  633. filter_stdout=None, cwd=None,
  634. raise_on_returncode=True, extra_env=None,
  635. remove_from_env=None, stdin=None):
  636. cmd_parts = []
  637. for part in cmd:
  638. if len(part) > 45:
  639. part = part[:20] + "..." + part[-20:]
  640. if ' ' in part or '\n' in part or '"' in part or "'" in part:
  641. part = '"%s"' % part.replace('"', '\\"')
  642. if hasattr(part, 'decode'):
  643. try:
  644. part = part.decode(sys.getdefaultencoding())
  645. except UnicodeDecodeError:
  646. part = part.decode(sys.getfilesystemencoding())
  647. cmd_parts.append(part)
  648. cmd_desc = ' '.join(cmd_parts)
  649. if show_stdout:
  650. stdout = None
  651. else:
  652. stdout = subprocess.PIPE
  653. logger.debug("Running command %s" % cmd_desc)
  654. if extra_env or remove_from_env:
  655. env = os.environ.copy()
  656. if extra_env:
  657. env.update(extra_env)
  658. if remove_from_env:
  659. for varname in remove_from_env:
  660. env.pop(varname, None)
  661. else:
  662. env = None
  663. try:
  664. proc = subprocess.Popen(
  665. cmd, stderr=subprocess.STDOUT,
  666. stdin=None if stdin is None else subprocess.PIPE,
  667. stdout=stdout,
  668. cwd=cwd, env=env)
  669. except Exception:
  670. e = sys.exc_info()[1]
  671. logger.fatal(
  672. "Error %s while executing command %s" % (e, cmd_desc))
  673. raise
  674. all_output = []
  675. if stdout is not None:
  676. if stdin is not None:
  677. proc.stdin.write(stdin)
  678. proc.stdin.close()
  679. stdout = proc.stdout
  680. encoding = sys.getdefaultencoding()
  681. fs_encoding = sys.getfilesystemencoding()
  682. while 1:
  683. line = stdout.readline()
  684. try:
  685. line = line.decode(encoding)
  686. except UnicodeDecodeError:
  687. line = line.decode(fs_encoding)
  688. if not line:
  689. break
  690. line = line.rstrip()
  691. all_output.append(line)
  692. if filter_stdout:
  693. level = filter_stdout(line)
  694. if isinstance(level, tuple):
  695. level, line = level
  696. logger.log(level, line)
  697. if not logger.stdout_level_matches(level):
  698. logger.show_progress()
  699. else:
  700. logger.info(line)
  701. else:
  702. proc.communicate(stdin)
  703. proc.wait()
  704. if proc.returncode:
  705. if raise_on_returncode:
  706. if all_output:
  707. logger.notify('Complete output from command %s:' % cmd_desc)
  708. logger.notify('\n'.join(all_output) + '\n----------------------------------------')
  709. raise OSError(
  710. "Command %s failed with error code %s"
  711. % (cmd_desc, proc.returncode))
  712. else:
  713. logger.warn(
  714. "Command %s had error code %s"
  715. % (cmd_desc, proc.returncode))
  716. def filter_install_output(line):
  717. if line.strip().startswith('running'):
  718. return Logger.INFO
  719. return Logger.DEBUG
  720. def find_wheels(projects, search_dirs):
  721. """Find wheels from which we can import PROJECTS.
  722. Scan through SEARCH_DIRS for a wheel for each PROJECT in turn. Return
  723. a list of the first wheel found for each PROJECT
  724. """
  725. wheels = []
  726. # Look through SEARCH_DIRS for the first suitable wheel. Don't bother
  727. # about version checking here, as this is simply to get something we can
  728. # then use to install the correct version.
  729. for project in projects:
  730. for dirname in search_dirs:
  731. # This relies on only having "universal" wheels available.
  732. # The pattern could be tightened to require -py2.py3-none-any.whl.
  733. files = glob.glob(os.path.join(dirname, project + '-*.whl'))
  734. if files:
  735. wheels.append(os.path.abspath(files[0]))
  736. break
  737. else:
  738. # We're out of luck, so quit with a suitable error
  739. logger.fatal('Cannot find a wheel for %s' % (project,))
  740. return wheels
  741. def install_wheel(project_names, py_executable, search_dirs=None,
  742. download=False):
  743. if search_dirs is None:
  744. search_dirs = file_search_dirs()
  745. wheels = find_wheels(['setuptools', 'pip'], search_dirs)
  746. pythonpath = os.pathsep.join(wheels)
  747. # PIP_FIND_LINKS uses space as the path separator and thus cannot have paths
  748. # with spaces in them. Convert any of those to local file:// URL form.
  749. try:
  750. from urlparse import urljoin
  751. from urllib import pathname2url
  752. except ImportError:
  753. from urllib.parse import urljoin
  754. from urllib.request import pathname2url
  755. def space_path2url(p):
  756. if ' ' not in p:
  757. return p
  758. return urljoin('file:', pathname2url(os.path.abspath(p)))
  759. findlinks = ' '.join(space_path2url(d) for d in search_dirs)
  760. SCRIPT = textwrap.dedent("""
  761. import sys
  762. import pkgutil
  763. import tempfile
  764. import os
  765. import pip
  766. cert_data = pkgutil.get_data("pip._vendor.requests", "cacert.pem")
  767. if cert_data is not None:
  768. cert_file = tempfile.NamedTemporaryFile(delete=False)
  769. cert_file.write(cert_data)
  770. cert_file.close()
  771. else:
  772. cert_file = None
  773. try:
  774. args = ["install", "--ignore-installed"]
  775. if cert_file is not None:
  776. args += ["--cert", cert_file.name]
  777. args += sys.argv[1:]
  778. sys.exit(pip.main(args))
  779. finally:
  780. if cert_file is not None:
  781. os.remove(cert_file.name)
  782. """).encode("utf8")
  783. cmd = [py_executable, '-'] + project_names
  784. logger.start_progress('Installing %s...' % (', '.join(project_names)))
  785. logger.indent += 2
  786. env = {
  787. "PYTHONPATH": pythonpath,
  788. "JYTHONPATH": pythonpath, # for Jython < 3.x
  789. "PIP_FIND_LINKS": findlinks,
  790. "PIP_USE_WHEEL": "1",
  791. "PIP_ONLY_BINARY": ":all:",
  792. "PIP_USER": "0",
  793. }
  794. if not download:
  795. env["PIP_NO_INDEX"] = "1"
  796. try:
  797. call_subprocess(cmd, show_stdout=False, extra_env=env, stdin=SCRIPT)
  798. finally:
  799. logger.indent -= 2
  800. logger.end_progress()
  801. def create_environment(home_dir, site_packages=False, clear=False,
  802. unzip_setuptools=False,
  803. prompt=None, search_dirs=None, download=False,
  804. no_setuptools=False, no_pip=False, no_wheel=False,
  805. symlink=True):
  806. """
  807. Creates a new environment in ``home_dir``.
  808. If ``site_packages`` is true, then the global ``site-packages/``
  809. directory will be on the path.
  810. If ``clear`` is true (default False) then the environment will
  811. first be cleared.
  812. """
  813. home_dir, lib_dir, inc_dir, bin_dir = path_locations(home_dir)
  814. py_executable = os.path.abspath(install_python(
  815. home_dir, lib_dir, inc_dir, bin_dir,
  816. site_packages=site_packages, clear=clear, symlink=symlink))
  817. install_distutils(home_dir)
  818. to_install = []
  819. if not no_setuptools:
  820. to_install.append('setuptools')
  821. if not no_pip:
  822. to_install.append('pip')
  823. if not no_wheel:
  824. to_install.append('wheel')
  825. if to_install:
  826. install_wheel(
  827. to_install,
  828. py_executable,
  829. search_dirs,
  830. download=download,
  831. )
  832. install_activate(home_dir, bin_dir, prompt)
  833. install_python_config(home_dir, bin_dir, prompt)
  834. def is_executable_file(fpath):
  835. return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
  836. def path_locations(home_dir):
  837. """Return the path locations for the environment (where libraries are,
  838. where scripts go, etc)"""
  839. home_dir = os.path.abspath(home_dir)
  840. # XXX: We'd use distutils.sysconfig.get_python_inc/lib but its
  841. # prefix arg is broken: http://bugs.python.org/issue3386
  842. if is_win:
  843. # Windows has lots of problems with executables with spaces in
  844. # the name; this function will remove them (using the ~1
  845. # format):
  846. mkdir(home_dir)
  847. if ' ' in home_dir:
  848. import ctypes
  849. GetShortPathName = ctypes.windll.kernel32.GetShortPathNameW
  850. size = max(len(home_dir) + 1, 256)
  851. buf = ctypes.create_unicode_buffer(size)
  852. try:
  853. u = unicode
  854. except NameError:
  855. u = str
  856. ret = GetShortPathName(u(home_dir), buf, size)
  857. if not ret:
  858. print('Error: the path "%s" has a space in it' % home_dir)
  859. print('We could not determine the short pathname for it.')
  860. print('Exiting.')
  861. sys.exit(3)
  862. home_dir = str(buf.value)
  863. lib_dir = join(home_dir, 'Lib')
  864. inc_dir = join(home_dir, 'Include')
  865. bin_dir = join(home_dir, 'Scripts')
  866. if is_jython:
  867. lib_dir = join(home_dir, 'Lib')
  868. inc_dir = join(home_dir, 'Include')
  869. bin_dir = join(home_dir, 'bin')
  870. elif is_pypy:
  871. lib_dir = home_dir
  872. inc_dir = join(home_dir, 'include')
  873. bin_dir = join(home_dir, 'bin')
  874. elif not is_win:
  875. lib_dir = join(home_dir, 'lib', py_version)
  876. inc_dir = join(home_dir, 'include', py_version + abiflags)
  877. bin_dir = join(home_dir, 'bin')
  878. return home_dir, lib_dir, inc_dir, bin_dir
  879. def change_prefix(filename, dst_prefix):
  880. prefixes = [sys.prefix]
  881. if is_darwin:
  882. prefixes.extend((
  883. os.path.join("/Library/Python", sys.version[:3], "site-packages"),
  884. os.path.join(sys.prefix, "Extras", "lib", "python"),
  885. os.path.join("~", "Library", "Python", sys.version[:3], "site-packages"),
  886. # Python 2.6 no-frameworks
  887. os.path.join("~", ".local", "lib", "python", sys.version[:3], "site-packages"),
  888. # System Python 2.7 on OSX Mountain Lion
  889. os.path.join("~", "Library", "Python", sys.version[:3], "lib", "python", "site-packages")))
  890. if hasattr(sys, 'real_prefix'):
  891. prefixes.append(sys.real_prefix)
  892. if hasattr(sys, 'base_prefix'):
  893. prefixes.append(sys.base_prefix)
  894. prefixes = list(map(os.path.expanduser, prefixes))
  895. prefixes = list(map(os.path.abspath, prefixes))
  896. # Check longer prefixes first so we don't split in the middle of a filename
  897. prefixes = sorted(prefixes, key=len, reverse=True)
  898. filename = os.path.abspath(filename)
  899. # On Windows, make sure drive letter is uppercase
  900. if is_win and filename[0] in 'abcdefghijklmnopqrstuvwxyz':
  901. filename = filename[0].upper() + filename[1:]
  902. for i, prefix in enumerate(prefixes):
  903. if is_win and prefix[0] in 'abcdefghijklmnopqrstuvwxyz':
  904. prefixes[i] = prefix[0].upper() + prefix[1:]
  905. for src_prefix in prefixes:
  906. if filename.startswith(src_prefix):
  907. _, relpath = filename.split(src_prefix, 1)
  908. if src_prefix != os.sep: # sys.prefix == "/"
  909. assert relpath[0] == os.sep
  910. relpath = relpath[1:]
  911. return join(dst_prefix, relpath)
  912. assert False, "Filename %s does not start with any of these prefixes: %s" % \
  913. (filename, prefixes)
  914. def copy_required_modules(dst_prefix, symlink):
  915. import imp
  916. for modname in REQUIRED_MODULES:
  917. if modname in sys.builtin_module_names:
  918. logger.info("Ignoring built-in bootstrap module: %s" % modname)
  919. continue
  920. try:
  921. f, filename, _ = imp.find_module(modname)
  922. except ImportError:
  923. logger.info("Cannot import bootstrap module: %s" % modname)
  924. else:
  925. if f is not None:
  926. f.close()
  927. # special-case custom readline.so on OS X, but not for pypy:
  928. if modname == 'readline' and sys.platform == 'darwin' and not (
  929. is_pypy or filename.endswith(join('lib-dynload', 'readline.so'))):
  930. dst_filename = join(dst_prefix, 'lib', 'python%s' % sys.version[:3], 'readline.so')
  931. elif modname == 'readline' and sys.platform == 'win32':
  932. # special-case for Windows, where readline is not a
  933. # standard module, though it may have been installed in
  934. # site-packages by a third-party package
  935. pass
  936. else:
  937. dst_filename = change_prefix(filename, dst_prefix)
  938. copyfile(filename, dst_filename, symlink)
  939. if filename.endswith('.pyc'):
  940. pyfile = filename[:-1]
  941. if os.path.exists(pyfile):
  942. copyfile(pyfile, dst_filename[:-1], symlink)
  943. def copy_tcltk(src, dest, symlink):
  944. """ copy tcl/tk libraries on Windows (issue #93) """
  945. for libversion in '8.5', '8.6':
  946. for libname in 'tcl', 'tk':
  947. srcdir = join(src, 'tcl', libname + libversion)
  948. destdir = join(dest, 'tcl', libname + libversion)
  949. # Only copy the dirs from the above combinations that exist
  950. if os.path.exists(srcdir) and not os.path.exists(destdir):
  951. copyfileordir(srcdir, destdir, symlink)
  952. def subst_path(prefix_path, prefix, home_dir):
  953. prefix_path = os.path.normpath(prefix_path)
  954. prefix = os.path.normpath(prefix)
  955. home_dir = os.path.normpath(home_dir)
  956. if not prefix_path.startswith(prefix):
  957. logger.warn('Path not in prefix %r %r', prefix_path, prefix)
  958. return
  959. return prefix_path.replace(prefix, home_dir, 1)
  960. def install_python(home_dir, lib_dir, inc_dir, bin_dir, site_packages, clear, symlink=True):
  961. """Install just the base environment, no distutils patches etc"""
  962. if sys.executable.startswith(bin_dir):
  963. print('Please use the *system* python to run this script')
  964. return
  965. if clear:
  966. rmtree(lib_dir)
  967. ## FIXME: why not delete it?
  968. ## Maybe it should delete everything with #!/path/to/venv/python in it
  969. logger.notify('Not deleting %s', bin_dir)
  970. if hasattr(sys, 'real_prefix'):
  971. logger.notify('Using real prefix %r' % sys.real_prefix)
  972. prefix = sys.real_prefix
  973. elif hasattr(sys, 'base_prefix'):
  974. logger.notify('Using base prefix %r' % sys.base_prefix)
  975. prefix = sys.base_prefix
  976. else:
  977. prefix = sys.prefix
  978. mkdir(lib_dir)
  979. fix_lib64(lib_dir, symlink)
  980. stdlib_dirs = [os.path.dirname(os.__file__)]
  981. if is_win:
  982. stdlib_dirs.append(join(os.path.dirname(stdlib_dirs[0]), 'DLLs'))
  983. elif is_darwin:
  984. stdlib_dirs.append(join(stdlib_dirs[0], 'site-packages'))
  985. if hasattr(os, 'symlink'):
  986. logger.info('Symlinking Python bootstrap modules')
  987. else:
  988. logger.info('Copying Python bootstrap modules')
  989. logger.indent += 2
  990. try:
  991. # copy required files...
  992. for stdlib_dir in stdlib_dirs:
  993. if not os.path.isdir(stdlib_dir):
  994. continue
  995. for fn in os.listdir(stdlib_dir):
  996. bn = os.path.splitext(fn)[0]
  997. if fn != 'site-packages' and bn in REQUIRED_FILES:
  998. copyfile(join(stdlib_dir, fn), join(lib_dir, fn), symlink)
  999. # ...and modules
  1000. copy_required_modules(home_dir, symlink)
  1001. finally:
  1002. logger.indent -= 2
  1003. # ...copy tcl/tk
  1004. if is_win:
  1005. copy_tcltk(prefix, home_dir, symlink)
  1006. mkdir(join(lib_dir, 'site-packages'))
  1007. import site
  1008. site_filename = site.__file__
  1009. if site_filename.endswith('.pyc') or site_filename.endswith('.pyo'):
  1010. site_filename = site_filename[:-1]
  1011. elif site_filename.endswith('$py.class'):
  1012. site_filename = site_filename.replace('$py.class', '.py')
  1013. site_filename_dst = change_prefix(site_filename, home_dir)
  1014. site_dir = os.path.dirname(site_filename_dst)
  1015. writefile(site_filename_dst, SITE_PY)
  1016. writefile(join(site_dir, 'orig-prefix.txt'), prefix)
  1017. site_packages_filename = join(site_dir, 'no-global-site-packages.txt')
  1018. if not site_packages:
  1019. writefile(site_packages_filename, '')
  1020. if is_pypy or is_win:
  1021. stdinc_dir = join(prefix, 'include')
  1022. else:
  1023. stdinc_dir = join(prefix, 'include', py_version + abiflags)
  1024. if os.path.exists(stdinc_dir):
  1025. copyfile(stdinc_dir, inc_dir, symlink)
  1026. else:
  1027. logger.debug('No include dir %s' % stdinc_dir)
  1028. platinc_dir = distutils.sysconfig.get_python_inc(plat_specific=1)
  1029. if platinc_dir != stdinc_dir:
  1030. platinc_dest = distutils.sysconfig.get_python_inc(
  1031. plat_specific=1, prefix=home_dir)
  1032. if platinc_dir == platinc_dest:
  1033. # Do platinc_dest manually due to a CPython bug;
  1034. # not http://bugs.python.org/issue3386 but a close cousin
  1035. platinc_dest = subst_path(platinc_dir, prefix, home_dir)
  1036. if platinc_dest:
  1037. # PyPy's stdinc_dir and prefix are relative to the original binary
  1038. # (traversing virtualenvs), whereas the platinc_dir is relative to
  1039. # the inner virtualenv and ignores the prefix argument.
  1040. # This seems more evolved than designed.
  1041. copyfile(platinc_dir, platinc_dest, symlink)
  1042. # pypy never uses exec_prefix, just ignore it
  1043. if sys.exec_prefix != prefix and not is_pypy:
  1044. if is_win:
  1045. exec_dir = join(sys.exec_prefix, 'lib')
  1046. elif is_jython:
  1047. exec_dir = join(sys.exec_prefix, 'Lib')
  1048. else:
  1049. exec_dir = join(sys.exec_prefix, 'lib', py_version)
  1050. for fn in os.listdir(exec_dir):
  1051. copyfile(join(exec_dir, fn), join(lib_dir, fn), symlink)
  1052. if is_jython:
  1053. # Jython has either jython-dev.jar and javalib/ dir, or just
  1054. # jython.jar
  1055. for name in 'jython-dev.jar', 'javalib', 'jython.jar':
  1056. src = join(prefix, name)
  1057. if os.path.exists(src):
  1058. copyfile(src, join(home_dir, name), symlink)
  1059. # XXX: registry should always exist after Jython 2.5rc1
  1060. src = join(prefix, 'registry')
  1061. if os.path.exists(src):
  1062. copyfile(src, join(home_dir, 'registry'), symlink=False)
  1063. copyfile(join(prefix, 'cachedir'), join(home_dir, 'cachedir'),
  1064. symlink=False)
  1065. mkdir(bin_dir)
  1066. py_executable = join(bin_dir, os.path.basename(sys.executable))
  1067. if 'Python.framework' in prefix:
  1068. # OS X framework builds cause validation to break
  1069. # https://github.com/pypa/virtualenv/issues/322
  1070. if os.environ.get('__PYVENV_LAUNCHER__'):
  1071. del os.environ["__PYVENV_LAUNCHER__"]
  1072. if re.search(r'/Python(?:-32|-64)*$', py_executable):
  1073. # The name of the python executable is not quite what
  1074. # we want, rename it.
  1075. py_executable = os.path.join(
  1076. os.path.dirname(py_executable), 'python')
  1077. logger.notify('New %s executable in %s', expected_exe, py_executable)
  1078. pcbuild_dir = os.path.dirname(sys.executable)
  1079. pyd_pth = os.path.join(lib_dir, 'site-packages', 'virtualenv_builddir_pyd.pth')
  1080. if is_win and os.path.exists(os.path.join(pcbuild_dir, 'build.bat')):
  1081. logger.notify('Detected python running from build directory %s', pcbuild_dir)
  1082. logger.notify('Writing .pth file linking to build directory for *.pyd files')
  1083. writefile(pyd_pth, pcbuild_dir)
  1084. else:
  1085. pcbuild_dir = None
  1086. if os.path.exists(pyd_pth):
  1087. logger.info('Deleting %s (not Windows env or not build directory python)' % pyd_pth)
  1088. os.unlink(pyd_pth)
  1089. if sys.executable != py_executable:
  1090. ## FIXME: could I just hard link?
  1091. executable = sys.executable
  1092. shutil.copyfile(executable, py_executable)
  1093. make_exe(py_executable)
  1094. if is_win or is_cygwin:
  1095. pythonw = os.path.join(os.path.dirname(sys.executable), 'pythonw.exe')
  1096. if os.path.exists(pythonw):
  1097. logger.info('Also created pythonw.exe')
  1098. shutil.copyfile(pythonw, os.path.join(os.path.dirname(py_executable), 'pythonw.exe'))
  1099. python_d = os.path.join(os.path.dirname(sys.executable), 'python_d.exe')
  1100. python_d_dest = os.path.join(os.path.dirname(py_executable), 'python_d.exe')
  1101. if os.path.exists(python_d):
  1102. logger.info('Also created python_d.exe')
  1103. shutil.copyfile(python_d, python_d_dest)
  1104. elif os.path.exists(python_d_dest):
  1105. logger.info('Removed python_d.exe as it is no longer at the source')
  1106. os.unlink(python_d_dest)
  1107. # we need to copy the DLL to enforce that windows will load the correct one.
  1108. # may not exist if we are cygwin.
  1109. py_executable_dll = 'python%s%s.dll' % (
  1110. sys.version_info[0], sys.version_info[1])
  1111. py_executable_dll_d = 'python%s%s_d.dll' % (
  1112. sys.version_info[0], sys.version_info[1])
  1113. pythondll = os.path.join(os.path.dirname(sys.executable), py_executable_dll)
  1114. pythondll_d = os.path.join(os.path.dirname(sys.executable), py_executable_dll_d)
  1115. pythondll_d_dest = os.path.join(os.path.dirname(py_executable), py_executable_dll_d)
  1116. if os.path.exists(pythondll):
  1117. logger.info('Also created %s' % py_executable_dll)
  1118. shutil.copyfile(pythondll, os.path.join(os.path.dirname(py_executable), py_executable_dll))
  1119. if os.path.exists(pythondll_d):
  1120. logger.info('Also created %s' % py_executable_dll_d)
  1121. shutil.copyfile(pythondll_d, pythondll_d_dest)
  1122. elif os.path.exists(pythondll_d_dest):
  1123. logger.info('Removed %s as the source does not exist' % pythondll_d_dest)
  1124. os.unlink(pythondll_d_dest)
  1125. if is_pypy:
  1126. # make a symlink python --> pypy-c
  1127. python_executable = os.path.join(os.path.dirname(py_executable), 'python')
  1128. if sys.platform in ('win32', 'cygwin'):
  1129. python_executable += '.exe'
  1130. logger.info('Also created executable %s' % python_executable)
  1131. copyfile(py_executable, python_executable, symlink)
  1132. if is_win:
  1133. for name in ['libexpat.dll', 'libpypy.dll', 'libpypy-c.dll',
  1134. 'libeay32.dll', 'ssleay32.dll', 'sqlite3.dll',
  1135. 'tcl85.dll', 'tk85.dll']:
  1136. src = join(prefix, name)
  1137. if os.path.exists(src):
  1138. copyfile(src, join(bin_dir, name), symlink)
  1139. for d in sys.path:
  1140. if d.endswith('lib_pypy'):
  1141. break
  1142. else:
  1143. logger.fatal('Could not find lib_pypy in sys.path')
  1144. raise SystemExit(3)
  1145. logger.info('Copying lib_pypy')
  1146. copyfile(d, os.path.join(home_dir, 'lib_pypy'), symlink)
  1147. if os.path.splitext(os.path.basename(py_executable))[0] != expected_exe:
  1148. secondary_exe = os.path.join(os.path.dirname(py_executable),
  1149. expected_exe)
  1150. py_executable_ext = os.path.splitext(py_executable)[1]
  1151. if py_executable_ext.lower() == '.exe':
  1152. # python2.4 gives an extension of '.4' :P
  1153. secondary_exe += py_executable_ext
  1154. if os.path.exists(secondary_exe):
  1155. logger.warn('Not overwriting existing %s script %s (you must use %s)'
  1156. % (expected_exe, secondary_exe, py_executable))
  1157. else:
  1158. logger.notify('Also creating executable in %s' % secondary_exe)
  1159. shutil.copyfile(sys.executable, secondary_exe)
  1160. make_exe(secondary_exe)
  1161. if '.framework' in prefix:
  1162. if 'Python.framework' in prefix:
  1163. logger.debug('MacOSX Python framework detected')
  1164. # Make sure we use the embedded interpreter inside
  1165. # the framework, even if sys.executable points to
  1166. # the stub executable in ${sys.prefix}/bin
  1167. # See http://groups.google.com/group/python-virtualenv/
  1168. # browse_thread/thread/17cab2f85da75951
  1169. original_python = os.path.join(
  1170. prefix, 'Resources/Python.app/Contents/MacOS/Python')
  1171. if 'EPD' in prefix:
  1172. logger.debug('EPD framework detected')
  1173. original_python = os.path.join(prefix, 'bin/python')
  1174. shutil.copy(original_python, py_executable)
  1175. # Copy the framework's dylib into the virtual
  1176. # environment
  1177. virtual_lib = os.path.join(home_dir, '.Python')
  1178. if os.path.exists(virtual_lib):
  1179. os.unlink(virtual_lib)
  1180. copyfile(
  1181. os.path.join(prefix, 'Python'),
  1182. virtual_lib,
  1183. symlink)
  1184. # And then change the install_name of the copied python executable
  1185. try:
  1186. mach_o_change(py_executable,
  1187. os.path.join(prefix, 'Python'),
  1188. '@executable_path/../.Python')
  1189. except:
  1190. e = sys.exc_info()[1]
  1191. logger.warn("Could not call mach_o_change: %s. "
  1192. "Trying to call install_name_tool instead." % e)
  1193. try:
  1194. call_subprocess(
  1195. ["install_name_tool", "-change",
  1196. os.path.join(prefix, 'Python'),
  1197. '@executable_path/../.Python',
  1198. py_executable])
  1199. except:
  1200. logger.fatal("Could not call install_name_tool -- you must "
  1201. "have Apple's development tools installed")
  1202. raise
  1203. if not is_win:
  1204. # Ensure that 'python', 'pythonX' and 'pythonX.Y' all exist
  1205. py_exe_version_major = 'python%s' % sys.version_info[0]
  1206. py_exe_version_major_minor = 'python%s.%s' % (
  1207. sys.version_info[0], sys.version_info[1])
  1208. py_exe_no_version = 'python'
  1209. required_symlinks = [py_exe_no_version, py_exe_version_major,
  1210. py_exe_version_major_minor]
  1211. py_executable_base = os.path.basename(py_executable)
  1212. if py_executable_base in required_symlinks:
  1213. # Don't try to symlink to yourself.
  1214. required_symlinks.remove(py_executable_base)
  1215. for pth in required_symlinks:
  1216. full_pth = join(bin_dir, pth)
  1217. if os.path.exists(full_pth):
  1218. os.unlink(full_pth)
  1219. if symlink:
  1220. os.symlink(py_executable_base, full_pth)
  1221. else:
  1222. copyfile(py_executable, full_pth, symlink)
  1223. cmd = [py_executable, '-c', 'import sys;out=sys.stdout;'
  1224. 'getattr(out, "buffer", out).write(sys.prefix.encode("utf-8"))']
  1225. logger.info('Testing executable with %s %s "%s"' % tuple(cmd))
  1226. try:
  1227. proc = subprocess.Popen(cmd,
  1228. stdout=subprocess.PIPE)
  1229. proc_stdout, proc_stderr = proc.communicate()
  1230. except OSError:
  1231. e = sys.exc_info()[1]
  1232. if e.errno == errno.EACCES:
  1233. logger.fatal('ERROR: The executable %s could not be run: %s' % (py_executable, e))
  1234. sys.exit(100)
  1235. else:
  1236. raise e
  1237. proc_stdout = proc_stdout.strip().decode("utf-8")
  1238. proc_stdout = os.path.normcase(os.path.abspath(proc_stdout))
  1239. norm_home_dir = os.path.normcase(os.path.abspath(home_dir))
  1240. if hasattr(norm_home_dir, 'decode'):
  1241. norm_home_dir = norm_home_dir.decode(sys.getfilesystemencoding())
  1242. if proc_stdout != norm_home_dir:
  1243. logger.fatal(
  1244. 'ERROR: The executable %s is not functioning' % py_executable)
  1245. logger.fatal(
  1246. 'ERROR: It thinks sys.prefix is %r (should be %r)'
  1247. % (proc_stdout, norm_home_dir))
  1248. logger.fatal(
  1249. 'ERROR: virtualenv is not compatible with this system or executable')
  1250. if is_win:
  1251. logger.fatal(
  1252. 'Note: some Windows users have reported this error when they '
  1253. 'installed Python for "Only this user" or have multiple '
  1254. 'versions of Python installed. Copying the appropriate '
  1255. 'PythonXX.dll to the virtualenv Scripts/ directory may fix '
  1256. 'this problem.')
  1257. sys.exit(100)
  1258. else:
  1259. logger.info('Got sys.prefix result: %r' % proc_stdout)
  1260. pydistutils = os.path.expanduser('~/.pydistutils.cfg')
  1261. if os.path.exists(pydistutils):
  1262. logger.notify('Please make sure you remove any previous custom paths from '
  1263. 'your %s file.' % pydistutils)
  1264. ## FIXME: really this should be calculated earlier
  1265. fix_local_scheme(home_dir, symlink)
  1266. if site_packages:
  1267. if os.path.exists(site_packages_filename):
  1268. logger.info('Deleting %s' % site_packages_filename)
  1269. os.unlink(site_packages_filename)
  1270. return py_executable
  1271. def install_activate(home_dir, bin_dir, prompt=None):
  1272. if is_win or is_jython and os._name == 'nt':
  1273. files = {
  1274. 'activate.bat': ACTIVATE_BAT,
  1275. 'deactivate.bat': DEACTIVATE_BAT,
  1276. 'activate.ps1': ACTIVATE_PS,
  1277. }
  1278. # MSYS needs paths of the form /c/path/to/file
  1279. drive, tail = os.path.splitdrive(home_dir.replace(os.sep, '/'))
  1280. home_dir_msys = (drive and "/%s%s" or "%s%s") % (drive[:1], tail)
  1281. # Run-time conditional enables (basic) Cygwin compatibility
  1282. home_dir_sh = ("""$(if [ "$OSTYPE" "==" "cygwin" ]; then cygpath -u '%s'; else echo '%s'; fi;)""" %
  1283. (home_dir, home_dir_msys))
  1284. files['activate'] = ACTIVATE_SH.replace('__VIRTUAL_ENV__', home_dir_sh)
  1285. else:
  1286. files = {'activate': ACTIVATE_SH}
  1287. # suppling activate.fish in addition to, not instead of, the
  1288. # bash script support.
  1289. files['activate.fish'] = ACTIVATE_FISH
  1290. # same for csh/tcsh support...
  1291. files['activate.csh'] = ACTIVATE_CSH
  1292. files['activate_this.py'] = ACTIVATE_THIS
  1293. install_files(home_dir, bin_dir, prompt, files)
  1294. def install_files(home_dir, bin_dir, prompt, files):
  1295. if hasattr(home_dir, 'decode'):
  1296. home_dir = home_dir.decode(sys.getfilesystemencoding())
  1297. vname = os.path.basename(home_dir)
  1298. for name, content in files.items():
  1299. content = content.replace('__VIRTUAL_PROMPT__', prompt or '')
  1300. content = content.replace('__VIRTUAL_WINPROMPT__', prompt or '(%s)' % vname)
  1301. content = content.replace('__VIRTUAL_ENV__', home_dir)
  1302. content = content.replace('__VIRTUAL_NAME__', vname)
  1303. content = content.replace('__BIN_NAME__', os.path.basename(bin_dir))
  1304. writefile(os.path.join(bin_dir, name), content)
  1305. def install_python_config(home_dir, bin_dir, prompt=None):
  1306. if sys.platform == 'win32' or is_jython and os._name == 'nt':
  1307. files = {}
  1308. else:
  1309. files = {'python-config': PYTHON_CONFIG}
  1310. install_files(home_dir, bin_dir, prompt, files)
  1311. for name, content in files.items():
  1312. make_exe(os.path.join(bin_dir, name))
  1313. def install_distutils(home_dir):
  1314. distutils_path = change_prefix(distutils.__path__[0], home_dir)
  1315. mkdir(distutils_path)
  1316. ## FIXME: maybe this prefix setting should only be put in place if
  1317. ## there's a local distutils.cfg with a prefix setting?
  1318. home_dir = os.path.abspath(home_dir)
  1319. ## FIXME: this is breaking things, removing for now:
  1320. # distutils_cfg = DISTUTILS_CFG + "\n[install]\nprefix=%s\n" % home_dir
  1321. writefile(os.path.join(distutils_path, '__init__.py'), DISTUTILS_INIT)
  1322. writefile(os.path.join(distutils_path, 'distutils.cfg'), DISTUTILS_CFG, overwrite=False)
  1323. def fix_local_scheme(home_dir, symlink=True):
  1324. """
  1325. Platforms that use the "posix_local" install scheme (like Ubuntu with
  1326. Python 2.7) need to be given an additional "local" location, sigh.
  1327. """
  1328. try:
  1329. import sysconfig
  1330. except ImportError:
  1331. pass
  1332. else:
  1333. if sysconfig._get_default_scheme() == 'posix_local':
  1334. local_path = os.path.join(home_dir, 'local')
  1335. if not os.path.exists(local_path):
  1336. os.mkdir(local_path)
  1337. for subdir_name in os.listdir(home_dir):
  1338. if subdir_name == 'local':
  1339. continue
  1340. copyfile(os.path.abspath(os.path.join(home_dir, subdir_name)), \
  1341. os.path.join(local_path, subdir_name), symlink)
  1342. def fix_lib64(lib_dir, symlink=True):
  1343. """
  1344. Some platforms (particularly Gentoo on x64) put things in lib64/pythonX.Y
  1345. instead of lib/pythonX.Y. If this is such a platform we'll just create a
  1346. symlink so lib64 points to lib
  1347. """
  1348. # PyPy's library path scheme is not affected by this.
  1349. # Return early or we will die on the following assert.
  1350. if is_pypy:
  1351. logger.debug('PyPy detected, skipping lib64 symlinking')
  1352. return
  1353. # Check we have a lib64 library path
  1354. if not [p for p in distutils.sysconfig.get_config_vars().values()
  1355. if isinstance(p, basestring) and 'lib64' in p]:
  1356. return
  1357. logger.debug('This system uses lib64; symlinking lib64 to lib')
  1358. assert os.path.basename(lib_dir) == 'python%s' % sys.version[:3], (
  1359. "Unexpected python lib dir: %r" % lib_dir)
  1360. lib_parent = os.path.dirname(lib_dir)
  1361. top_level = os.path.dirname(lib_parent)
  1362. lib_dir = os.path.join(top_level, 'lib')
  1363. lib64_link = os.path.join(top_level, 'lib64')
  1364. assert os.path.basename(lib_parent) == 'lib', (
  1365. "Unexpected parent dir: %r" % lib_parent)
  1366. if os.path.lexists(lib64_link):
  1367. return
  1368. if symlink:
  1369. os.symlink('lib', lib64_link)
  1370. else:
  1371. copyfile('lib', lib64_link)
  1372. def resolve_interpreter(exe):
  1373. """
  1374. If the executable given isn't an absolute path, search $PATH for the interpreter
  1375. """
  1376. # If the "executable" is a version number, get the installed executable for
  1377. # that version
  1378. orig_exe = exe
  1379. python_versions = get_installed_pythons()
  1380. if exe in python_versions:
  1381. exe = python_versions[exe]
  1382. if os.path.abspath(exe) != exe:
  1383. paths = os.environ.get('PATH', '').split(os.pathsep)
  1384. for path in paths:
  1385. if os.path.exists(join(path, exe)):
  1386. exe = join(path, exe)
  1387. break
  1388. if not os.path.exists(exe):
  1389. logger.fatal('The path %s (from --python=%s) does not exist' % (exe, orig_exe))
  1390. raise SystemExit(3)
  1391. if not is_executable(exe):
  1392. logger.fatal('The path %s (from --python=%s) is not an executable file' % (exe, orig_exe))
  1393. raise SystemExit(3)
  1394. return exe
  1395. def is_executable(exe):
  1396. """Checks a file is executable"""
  1397. return os.path.isfile(exe) and os.access(exe, os.X_OK)
  1398. ############################################################
  1399. ## Relocating the environment:
  1400. def make_environment_relocatable(home_dir):
  1401. """
  1402. Makes the already-existing environment use relative paths, and takes out
  1403. the #!-based environment selection in scripts.
  1404. """
  1405. home_dir, lib_dir, inc_dir, bin_dir = path_locations(home_dir)
  1406. activate_this = os.path.join(bin_dir, 'activate_this.py')
  1407. if not os.path.exists(activate_this):
  1408. logger.fatal(
  1409. 'The environment doesn\'t have a file %s -- please re-run virtualenv '
  1410. 'on this environment to update it' % activate_this)
  1411. fixup_scripts(home_dir, bin_dir)
  1412. fixup_pth_and_egg_link(home_dir)
  1413. ## FIXME: need to fix up distutils.cfg
  1414. def make_pth_relocatable(home_dir):
  1415. """
  1416. Makes the already-existing environment use relative paths, and takes out
  1417. the #!-based environment selection in scripts.
  1418. """
  1419. home_dir, lib_dir, inc_dir, bin_dir = path_locations(home_dir)
  1420. fixup_pth_and_egg_link(home_dir)
  1421. OK_ABS_SCRIPTS = ['python', 'python%s' % sys.version[:3],
  1422. 'activate', 'activate.bat', 'activate_this.py',
  1423. 'activate.fish', 'activate.csh']
  1424. def fixup_scripts(home_dir, bin_dir):
  1425. if is_win:
  1426. new_shebang_args = (
  1427. '%s /c' % os.path.normcase(os.environ.get('COMSPEC', 'cmd.exe')),
  1428. '', '.exe')
  1429. else:
  1430. new_shebang_args = ('/usr/bin/env', sys.version[:3], '')
  1431. # This is what we expect at the top of scripts:
  1432. shebang = '#!%s' % os.path.normcase(os.path.join(
  1433. os.path.abspath(bin_dir), 'python%s' % new_shebang_args[2]))
  1434. # This is what we'll put:
  1435. new_shebang = '#!%s python%s%s' % new_shebang_args
  1436. for filename in os.listdir(bin_dir):
  1437. filename = os.path.join(bin_dir, filename)
  1438. if not os.path.isfile(filename):
  1439. # ignore subdirs, e.g. .svn ones.
  1440. continue
  1441. lines = None
  1442. with open(filename, 'rb') as f:
  1443. try:
  1444. lines = f.read().decode('utf-8').splitlines()
  1445. except UnicodeDecodeError:
  1446. # This is probably a binary program instead
  1447. # of a script, so just ignore it.
  1448. continue
  1449. if not lines:
  1450. logger.warn('Script %s is an empty file' % filename)
  1451. continue
  1452. old_shebang = lines[0].strip()
  1453. old_shebang = old_shebang[0:2] + os.path.normcase(old_shebang[2:])
  1454. if not old_shebang.startswith(shebang):
  1455. if os.path.basename(filename) in OK_ABS_SCRIPTS:
  1456. logger.debug('Cannot make script %s relative' % filename)
  1457. elif lines[0].strip() == new_shebang:
  1458. logger.info('Script %s has already been made relative' % filename)
  1459. else:
  1460. logger.warn('Script %s cannot be made relative (it\'s not a normal script that starts with %s)'
  1461. % (filename, shebang))
  1462. continue
  1463. logger.notify('Making script %s relative' % filename)
  1464. script = relative_script([new_shebang] + lines[1:])
  1465. with open(filename, 'wb') as f:
  1466. f.write('\n'.join(script).encode('utf-8'))
  1467. def relative_script(lines):
  1468. "Return a script that'll work in a relocatable environment."
  1469. activate = "import os; activate_this=os.path.join(os.path.dirname(os.path.realpath(__file__)), 'activate_this.py'); "
  1470. activate += "exec(compile(open(activate_this).read(), activate_this, 'exec'), dict(__file__=activate_this)); del os, activate_this"
  1471. # Find the last future statement in the script. If we insert the activation
  1472. # line before a future statement, Python will raise a SyntaxError.
  1473. activate_at = None
  1474. for idx, line in reversed(list(enumerate(lines))):
  1475. if line.split()[:3] == ['from', '__future__', 'import']:
  1476. activate_at = idx + 1
  1477. break
  1478. if activate_at is None:
  1479. # Activate after the shebang.
  1480. activate_at = 1
  1481. return lines[:activate_at] + ['', activate, ''] + lines[activate_at:]
  1482. def fixup_pth_and_egg_link(home_dir, sys_path=None):
  1483. """Makes .pth and .egg-link files use relative paths"""
  1484. home_dir = os.path.normcase(os.path.abspath(home_dir))
  1485. if sys_path is None:
  1486. sys_path = sys.path
  1487. for path in sys_path:
  1488. if not path:
  1489. path = '.'
  1490. if not os.path.isdir(path):
  1491. continue
  1492. path = os.path.normcase(os.path.abspath(path))
  1493. if not path.startswith(home_dir):
  1494. logger.debug('Skipping system (non-environment) directory %s' % path)
  1495. continue
  1496. for filename in os.listdir(path):
  1497. filename = os.path.join(path, filename)
  1498. if filename.endswith('.pth'):
  1499. if not os.access(filename, os.W_OK):
  1500. logger.warn('Cannot write .pth file %s, skipping' % filename)
  1501. else:
  1502. fixup_pth_file(filename)
  1503. if filename.endswith('.egg-link'):
  1504. if not os.access(filename, os.W_OK):
  1505. logger.warn('Cannot write .egg-link file %s, skipping' % filename)
  1506. else:
  1507. fixup_egg_link(filename)
  1508. def fixup_pth_file(filename):
  1509. lines = []
  1510. prev_lines = []
  1511. with open(filename) as f:
  1512. prev_lines = f.readlines()
  1513. for line in prev_lines:
  1514. line = line.strip()
  1515. if (not line or line.startswith('#') or line.startswith('import ')
  1516. or os.path.abspath(line) != line):
  1517. lines.append(line)
  1518. else:
  1519. new_value = make_relative_path(filename, line)
  1520. if line != new_value:
  1521. logger.debug('Rewriting path %s as %s (in %s)' % (line, new_value, filename))
  1522. lines.append(new_value)
  1523. if lines == prev_lines:
  1524. logger.info('No changes to .pth file %s' % filename)
  1525. return
  1526. logger.notify('Making paths in .pth file %s relative' % filename)
  1527. with open(filename, 'w') as f:
  1528. f.write('\n'.join(lines) + '\n')
  1529. def fixup_egg_link(filename):
  1530. with open(filename) as f:
  1531. link = f.readline().strip()
  1532. if os.path.abspath(link) != link:
  1533. logger.debug('Link in %s already relative' % filename)
  1534. return
  1535. # filename = /container.ubuntu1604/output/cdh/hue/hue-3.9.0+cdh6.x+0/build/env/local/lib/python2.7/site-packages/liboozie.egg-link
  1536. # link = /container.ubuntu1604/output/cdh/hue/hue-3.9.0+cdh6.x+0/desktop/libs/liboozie/src
  1537. # new_link = ../../../../../../desktop/libs/liboozie/src
  1538. new_link = make_relative_path(filename, link)
  1539. logger.notify('Rewriting link %s in %s as %s' % (link, filename, new_link))
  1540. with open(filename, 'w') as f:
  1541. f.write(new_link)
  1542. def make_relative_path(source, dest, dest_is_directory=True):
  1543. """
  1544. Make a filename relative, where the filename is dest, and it is
  1545. being referred to from the filename source.
  1546. >>> make_relative_path('/usr/share/something/a-file.pth',
  1547. ... '/usr/share/another-place/src/Directory')
  1548. '../another-place/src/Directory'
  1549. >>> make_relative_path('/usr/share/something/a-file.pth',
  1550. ... '/home/user/src/Directory')
  1551. '../../../home/user/src/Directory'
  1552. >>> make_relative_path('/usr/share/a-file.pth', '/usr/share/')
  1553. './'
  1554. """
  1555. source = os.path.dirname(source)
  1556. if not dest_is_directory:
  1557. dest_filename = os.path.basename(dest)
  1558. dest = os.path.dirname(dest)
  1559. dest = os.path.normpath(os.path.abspath(dest))
  1560. source = os.path.normpath(os.path.abspath(source))
  1561. dest_parts = dest.strip(os.path.sep).split(os.path.sep)
  1562. source_parts = source.strip(os.path.sep).split(os.path.sep)
  1563. while dest_parts and source_parts and dest_parts[0] == source_parts[0]:
  1564. dest_parts.pop(0)
  1565. source_parts.pop(0)
  1566. full_parts = ""
  1567. if '/local/' in source:
  1568. full_parts = ['..'] * (len(source_parts) - 1) + dest_parts
  1569. else:
  1570. full_parts = ['..'] * len(source_parts) + dest_parts
  1571. if not dest_is_directory:
  1572. full_parts.append(dest_filename)
  1573. if not full_parts:
  1574. # Special case for the current directory (otherwise it'd be '')
  1575. return './'
  1576. return os.path.sep.join(full_parts)
  1577. ############################################################
  1578. ## Bootstrap script creation:
  1579. def create_bootstrap_script(extra_text, python_version=''):
  1580. """
  1581. Creates a bootstrap script, which is like this script but with
  1582. extend_parser, adjust_options, and after_install hooks.
  1583. This returns a string that (written to disk of course) can be used
  1584. as a bootstrap script with your own customizations. The script
  1585. will be the standard virtualenv.py script, with your extra text
  1586. added (your extra text should be Python code).
  1587. If you include these functions, they will be called:
  1588. ``extend_parser(optparse_parser)``:
  1589. You can add or remove options from the parser here.
  1590. ``adjust_options(options, args)``:
  1591. You can change options here, or change the args (if you accept
  1592. different kinds of arguments, be sure you modify ``args`` so it is
  1593. only ``[DEST_DIR]``).
  1594. ``after_install(options, home_dir)``:
  1595. After everything is installed, this function is called. This
  1596. is probably the function you are most likely to use. An
  1597. example would be::
  1598. def after_install(options, home_dir):
  1599. subprocess.call([join(home_dir, 'bin', 'easy_install'),
  1600. 'MyPackage'])
  1601. subprocess.call([join(home_dir, 'bin', 'my-package-script'),
  1602. 'setup', home_dir])
  1603. This example immediately installs a package, and runs a setup
  1604. script from that package.
  1605. If you provide something like ``python_version='2.5'`` then the
  1606. script will start with ``#!/usr/bin/env python2.5`` instead of
  1607. ``#!/usr/bin/env python``. You can use this when the script must
  1608. be run with a particular Python version.
  1609. """
  1610. filename = __file__
  1611. if filename.endswith('.pyc'):
  1612. filename = filename[:-1]
  1613. with codecs.open(filename, 'r', encoding='utf-8') as f:
  1614. content = f.read()
  1615. py_exe = 'python%s' % python_version
  1616. content = (('#!/usr/bin/env %s\n' % py_exe)
  1617. + '## WARNING: This file is generated\n'
  1618. + content)
  1619. return content.replace('##EXT' 'END##', extra_text)
  1620. ##EXTEND##
  1621. def convert(s):
  1622. b = base64.b64decode(s.encode('ascii'))
  1623. return zlib.decompress(b).decode('utf-8')
  1624. ##file site.py
  1625. SITE_PY = convert("""
  1626. eJzFPf1z2zaWv/OvwMqToZTKdOJ0e3tO3RsncVrfuYm3yc7m1vXoKAmyWFMkS5C2tTd3f/u9DwAE
  1627. +CHb2+6cphNLJPDw8PC+8PAeOhqNTopCZkuxyZd1KoWScblYiyKu1kqs8lJU66Rc7hdxWW3h6eIm
  1628. vpZKVLlQWxVhqygInv/GT/BcfF4nyqAA3+K6yjdxlSziNN2KZFPkZSWXYlmXSXYtkiypkjhN/g4t
  1629. 8iwSz387BsFZJmDmaSJLcStLBXCVyFfiYlut80yM6wLn/DL6Y/xqMhVqUSZFBQ1KjTNQZB1XQSbl
  1630. EtCElrUCUiaV3FeFXCSrZGEb3uV1uhRFGi+k+K//4qlR0zAMVL6Rd2tZSpEBMgBTAqwC8YCvSSkW
  1631. +VJGQryRixgH4OcNsQKGNsU1U0jGLBdpnl3DnDK5kErF5VaM53VFgAhlscwBpwQwqJI0De7y8kZN
  1632. YElpPe7gkYiZPfzJMHvAPHH8LucAjh+z4C9Zcj9l2MA9CK5aM9uUcpXcixjBwk95Lxcz/WycrMQy
  1633. Wa2ABlk1wSYBI6BEmswPClqOb/UKfXdAWFmujGEMiShzY35JPaLgrBJxqoBt6wJppAjzd3KexBlQ
  1634. I7uF4QAikDToG2eZqMqOQ7MTOQAocR0rkJKNEuNNnGTArD/GC0L7r0m2zO/UhCgAq6XEL7Wq3PmP
  1635. ewgArR0CTANcLLOadZYmNzLdTgCBz4B9KVWdVigQy6SUiyovE6kIAKC2FfIekJ6KuJSahMyZRm6n
  1636. RH+iSZLhwqKAocDjSyTJKrmuS5IwsUqAc4Er3n/8Sbw7fXN28kHzmAHGMnu9AZwBCi20gxMMIA5q
  1637. VR6kOQh0FJzjHxEvlyhk1zg+4NU0OHhwpYMxzL2I2n2cBQey68XVw8AcK1AmNFZA/f4bukzVGujz
  1638. Pw+sdxCcDFGFJs7f7tY5yGQWb6RYx8xfyBnBtxrOd1FRrV8DNyiEUwGpFC4OIpggPCCJS7NxnklR
  1639. AIulSSYnAVBoTm39VQRW+JBn+7TWLU4ACGWQwUvn2YRGzCRMtAvrNeoL03hLM9NNArvOm7wkxQH8
  1640. ny1IF6VxdkM4KmIo/jaX10mWIULIC0G4F9LA6iYBTlxG4pxakV4wjUTI2otbokjUwEvIdMCT8j7e
  1641. FKmcsviibt2tRmgwWQmz1ilzHLSsSL3SqjVT7eW9w+hLi+sIzWpdSgBezz2hW+X5VMxBZxM2Rbxh
  1642. 8arucuKcoEeeqBPyBLWEvvgdKHqiVL2R9iXyCmgWYqhgladpfgckOwoCIfawkTHKPnPCW3gH/wJc
  1643. /DeV1WIdBM5IFrAGhcgPgUIgYBJkprlaI+Fxm2bltpJJMtYUebmUJQ31OGIfMOKPbIxzDT7klTZq
  1644. PF1c5XyTVKiS5tpkJmzxsrBi/fia5w3TAMutiGamaUOnDU4vLdbxXBqXZC5XKAl6kV7bZYcxg54x
  1645. yRZXYsNWBt4BWWTCFqRfsaDSWVWSnACAwcIXZ0lRp9RIIYOJGAbaFAR/E6NJz7WzBOzNZjlAhcTm
  1646. ewH2B3D7O4jR3ToB+iwAAmgY1FKwfPOkKtFBaPRR4Bt905/HB049W2nbxEOu4iTVVj7OgjN6eFqW
  1647. JL4LWWCvqSaGghlmFbp21xnQEcV8NBoFgXGHtsp8zVVQldsjYAVhxpnN5nWChm82Q1Ovf6iARxHO
  1648. wF43287CAw1hOn0AKjldVmW+wdd2bp9AmcBY2CPYExekZSQ7yB4nvkbyuSq9ME3RdjvsLFAPBRc/
  1649. nb4/+3L6SRyLy0alTdv67ArGPM1iYGuyCMBUrWEbXQYtUfElqPvEezDvxBRgz6g3ia+Mqxp4F1D/
  1650. XNb0Gqax8F4Gpx9O3pyfzv7y6fSn2aezz6eAINgZGezRlNE81uAwqgiEA7hyqSJtX4NOD3rw5uST
  1651. fRDMEjX75mtgN3gyvpYVMHE5hhlPRbiJ7xUwaDilphPEsdMALHg4mYjvxOHz568OCVqxLbYADMyu
  1652. 0xQfzrRFnyXZKg8n1PgXdumPWUlp/+3y6OsrcXwswl/i2zgMwIdqmjJL/Eji9HlbSOhawZ9xriZB
  1653. sJQrEL0biQI6fk5+8YQ7wJJAy1zb6V/yJDPvmSvdIUh/jKkH4DCbLdJYKWw8m4VABOrQ84EOETvX
  1654. KHVj6Fhs3a4TjQp+SgkLm2GXKf7Tg2I8p36IBqPodjGNQFw3i1hJbkXTh36zGeqs2WysBwRhJokB
  1655. h4vVUChME9RZZQJ+LXEe6rC5ylP8ifBRC5AA4tYKtSQukt46RbdxWks1diYFRByPW2RERZso4kdw
  1656. UcZgiZulm0za1DQ8A82AfGkOWrRsUQ4/e+DvgLoymzjc6PHei2mGmP477zQIB3A5Q1T3SrWgsHYU
  1657. F6cX4tWLw310Z2DPubTU8ZqjhU6yWtqHK1gtIw+MMPcy8uLSZYV6Fp8e7Ya5iezKdFlhpZe4lJv8
  1658. Vi4BW2RgZ5XFT/QGduYwj0UMqwh6nfwBVqHGb4xxH8qzB2lB3wGotyEoZv3N0u9xMEBmChQRb6yJ
  1659. 1HrXz6awKPPbBJ2N+Va/BFsJyhItpnFsAmfhPCZDkwgaArzgDCl1J0NQh2XNDivhjSDRXiwbxRoR
  1660. uHPU1Ff09SbL77IZ74SPUemOJ5Z1UbA082KDZgn2xHuwQoBkDhu7hmgMBVx+gbK1D8jD9GG6QFna
  1661. WwAgMPSKtmsOLLPVoynyrhGHRRiT14KEt5ToL9yaIWirZYjhQKK3kX1gtARCgslZBWdVg2YylDXT
  1662. DAZ2SOJz3XnEW1AfQIuKEZjNsYbGjQz9Lo9AOYtzVyk5/dAif/nyhdlGrSm+gojNcdLoQqzIWEbF
  1663. FgxrAjrBeGQcrSE2uAPnFsDUSrOm2P8k8oK9MVjPCy3b4AfA7q6qiqODg7u7u0hHF/Ly+kCtDv74
  1664. p2+++dML1onLJfEPTMeRFh1qiw7oHXq00bfGAn1nVq7Fj0nmcyPBGkvyysgVRfy+r5NlLo72J1Z/
  1665. Ihc3Zhr/Na4MKJCZGZSpDLQdNRg9U/vPoldqJJ6RdbZtxxP2S7RJtVbMt7rQo8rBEwC/ZZHXaKob
  1666. TlDiK7BusENfynl9HdrBPRtpfsBUUU7Hlgf2X14hBj5nGL4ypniGWoLYAi2+Q/qfmG1i8o60hkDy
  1667. oonq7J63/VrMEHf5eHm3vqYjNGaGiULuQInwmzxaAG3jruTgR7u2aPcc19Z8PENgLH1gmFc7lmMU
  1668. HMIF12LqSp3D1ejxgjTdsWoGBeOqRlDQ4CTOmdoaHNnIEEGid2M2+7ywugXQqRU5NPEBswrQwh2n
  1669. Y+3arOB4QsgDx+IlPZHgIh913r3gpa3TlAI6LR71qMKAvYVGO50DX44NgKkYlX8ZcUuzTfnYWhRe
  1670. gx5gOceAkMFWHWbCN64PONob9bBTx+oP9WYa94HARRpzLOpR0AnlYx6hVCBNxdjvOcTilrjdwXZa
  1671. HGIqs0wk0mpAuNrKo1eodhqmVZKh7nUWKVqkOXjFVisSIzXvfWeB9kH4uM+YaQnUZGjI4TQ6Jm/P
  1672. E8BQt8Pw2XWNgQY3DoMYbRJF1g3JtIZ/wK2g+AYFo4CWBM2CeayU+RP7HWTOzld/GWAPS2hkCLfp
  1673. kBvSsRgajnm/J5CMOhoDUpABCbvCSK4jq4MUOMxZIE+44bUclG6CESmQM8eCkJoB3Omlt8HBJxGe
  1674. gJCEIuT7SslCfCVGsHxtUX2c7v5dudQEIcZOA3IVdPTi2I1sOFGN41aUw2doP75BZyVFDhw8B5fH
  1675. DfS7bG6Y1gZdwFn3FbdFCjQyxWFGExfVK0MYN5j8h2OnRUMsM4hhKG8g70jHjDQJ7HJr0LDgBoy3
  1676. 5u2x9GM3YoF9x2GuDuXmHvZ/YZmoRa5Cipm0YxfuR3NFlzYW2/NkPoI/3gKMJlceJJnq+AVGWf6B
  1677. QUIPetgH3ZsshkWWcXmXZCEpME2/Y39pOnhYUnpG7uATbacOYKIY8Tx4X4KA0NHnAYgTagLYlctQ
  1678. abe/C3bnFEcWLncfeW7z5dGrqy5xp0MRHvvpX6rT+6qMFa5WyovGQoGr1TXgqHRhcnG21YeX+nAb
  1679. twllrmAXKT5++iKQEBzXvYu3T5t6w/CIzYNz8j4GddBrD5KrNTtiF0AEtSIyykH4dI58PLJPndyO
  1680. iT0ByJMYZseiGEiaT/4ROLsWCsbYX24zjKO1VQZ+4PU3X896IqMukt98PXpglBYx+sR+3PIE7cic
  1681. VLBrtqWMU3I1nD4UVMwa1rFtignrc9r+aR676vE5NVo29t3fAj8GCobUJfgIL6YN2bpTxY/vTg3C
  1682. 03ZqB7DObtV89mgRYG+fz3+BHbLSQbXbOEnpXAEmv7+PytVs7jle0a89PEg7FYxDgr79l7p8AdwQ
  1683. cjRh0p2OdsZOTMC5ZxdsPkWsuqjs6RyC5gjMywtwjz+HFU6ve+B7Bge/r7p8IiBvTqMeMmpbbIZ4
  1684. wQclhz1K9gnzfvqMf9dZP27mw4L1/zHLF/+cST5hKgaaNh4+rH5iuXbXAHuEeRpwO3e4hd2h+axy
  1685. ZZw7VklKPEfd9VzcUboCxVbxpAigLNnv64GDUqoPvd/WZclH16QCC1nu43HsVGCmlvH8ek3Mnjj4
  1686. ICvExDZbUKzayevJ+4Qv1NFnO5Ow2Tf0c+c6NzErmd0mJfQFhTsOf/j442nYb0IwjgudHm9FHu83
  1687. INwnMG6oiRM+pQ9T6Cld/nH10d66+AQ1GQEmIqzJ1iVsJxBs4gj9a/BARMg7sOVjdtyhL9ZycTOT
  1688. lDqAbIpdnaD4W3yNmNiMAj//S8UrSmKDmSzSGmnFjjdmH67qbEHnI5UE/0qnCmPqECUEcPhvlcbX
  1689. Ykydlxh60txI0anbuNTeZ1HmmJwq6mR5cJ0shfy1jlPc1svVCnDBwyv9KuLhKQIl3nFOAyctKrmo
  1690. y6TaAglileuzP0p/cBrOtzzRsYckH/MwATEh4kh8wmnjeybc0pDLBAf8Ew+cJO67sYOTrBDRc3if
  1691. 5TMcdUY5vlNGqnsuT4+D9gg5ABgBUJj/aKIjd/4bSa/cA0Zac5eoqCU9UrqRhpycMYQynmCkg3/T
  1692. T58RXd4awPJ6GMvr3Vhet7G87sXy2sfyejeWrkjgwtqglZGEvsBV+1ijN9/GjTnxMKfxYs3tMPcT
  1693. czwBoijMBtvIFKdAe5EtPt8jIKS2nQNnetjkzyScVFrmHALXIJH78RBLb+ZN8rrTmbJxdGeeinFn
  1694. h3KI/L4HUUSpYnPqzvK2jKs48uTiOs3nILYW3WkDYCra6UQcK81uZ3OO7rYs1ejiPz//8PEDNkdQ
  1695. I5PeQN1wEdGw4FTGz+PyWnWlqdn8FcCO1NJPxKFuGuDeIyNrPMoe//OOMjyQccQdZSjkogAPgLK6
  1696. bDM39ykMW891kpR+zkzOh03HYpRVo2ZSA0Q6ubh4d/L5ZEQhv9H/jlyBMbT1pcPFx7SwDbr+m9vc
  1697. Uhz7gFDr2FZj/Nw5ebRuOOJhG2vAdjzf1oPDxxjs3jCBP8t/KqVgSYBQkQ7+PoVQj945/Kb9UIc+
  1698. hhE7yX/uyRo7K/adI3uOi+KIft+xQ3sA/7AT9xgzIIB2ocZmZ9DslVtK35rXHRR1gD7S1/vNe832
  1699. 1qu9k/EpaifR4wA6lLXNht0/75yGjZ6S1ZvT788+nJ+9uTj5/IPjAqIr9/HTwaE4/fGLoPwQNGDs
  1700. E8WYGlFhJhIYFrfQSSxz+K/GyM+yrjhIDL3enZ/rk5oNlrpg7jPanAiecxqThcZBM45C24c6/wgx
  1701. SvUGyakponQdqjnC/dKG61lUrvOjqVRpjs5qrbdeulbM1JTRuXYE0geNXVIwCE4xg1eUxV6ZXWHJ
  1702. J4C6zqoHKW2jbWJISkHBTrqAc/5lTle8QCl1hidNZ63oL0MX1/AqUkWawE7udWhlSXfD9JiGcfRD
  1703. e8DNePVpQKc7jKwb8qwHsUCr9Trkuen+k4bRfq0Bw4bB3sG8M0npIZSBjcltIsRGfJITynv4apde
  1704. r4GCBcODvgoX0TBdArOPYXMt1glsIIAn12B9cZ8AEFor4R8IHDnRAZljdkb4drPc/3OoCeK3/vnn
  1705. nuZVme7/TRSwCxKcShT2ENNt/A42PpGMxOnH95OQkaPUXPHnGssDwCGhAKgj7ZS/xCfos7GS6Urn
  1706. l/j6AF9oP4Fet7qXsih1937XOEQJeKbG5DU8U4Z+IaZ7WdhTnMqkBRorHyxmWEHopiGYz574tJZp
  1707. qvPdz96dn4LviMUYKEF87nYKw3G8BI/QdfIdVzi2QOEBO7wukY1LdGEpyWIZec16g9YoctTby8uw
  1708. 60SB4W6vThS4jBPloj3GaTMsU04QISvDWphlZdZutUEKu22I4igzzBKzi5ISWH2eAF6mpzFviWCv
  1709. hKUeJgLPp8hJVpmMxTRZgB4FlQsKdQpCgsTFekbivDzjGHheKlMGBQ+LbZlcrys83YDOEZVgYPMf
  1710. T76cn32gsoTDV43X3cOcU9oJTDmJ5BhTBDHaAV/ctD/kqtmsj2f1K4SB2gf+tF9xdsoxD9Dpx4FF
  1711. /NN+xXVox85OkGcACqou2uKBGwCnW5/cNLLAuNp9MH7cFMAGMx8MxSKx7EUnerjz63KibdkyJRT3
  1712. MS+fcICzKmxKmu7spqS1P3qOqwLPuZbj/kbwtk+2zGcOXW86b4aS39xPRwqxJBYw6rb2xzDZYZ2m
  1713. ejoOsw1xC21rtY39OXNipU67RYaiDEQcu50nLpP1K2HdnDnQS6PuABPfanSNJPaq8tHP2Uh7GB4m
  1714. ltidfYrpSGUsZAQwkiF17U8NPhRaBFAglP07diR3Onl+6M3RsQYPz1HrLrCNP4Ai1Lm4VOORl8CJ
  1715. 8OVXdhz5FaGFevRIhI6nkskst3li+Llbo1f50p9jrwxQEBPFroyzazlmWFMD8yuf2AMhWNK2Hqkv
  1716. k6s+wyLOwDm9H+Dwrlz0H5wY1FqM0Gl3I7dtdeSTBxv0loLsJJgPvozvQPcXdTXmlRw4h+6tpRuG
  1717. +jBEzD6Epvr0fRxiOObXcGB9GsC91NCw0MP7deDsktfGOLLWPraqmkL7QnuwixK2ZpWiYxmnONH4
  1718. otYLaAzucWPyR/apThSyv3vqxJyYkAXKg7sgvbmNdINWOGHE5UpcOZpQOnxTTaPfLeWtTMFogJEd
  1719. Y7XDL7baYRLZcEpvHthvxu5ie7Htx43eNJgdmXIMRIAKMXoDPbsQanDAFf5Z70Ti7Iac47d/PZuK
  1720. tx9+gn/fyI9gQbHmcSr+BqOLt3kJ20ou2qXbFLCAo+L9Yl4rLIwkaHRCwRdPoLd24ZEXT0N0ZYlf
  1721. UmIVpMBk2nLDt50AijxBKmRv3ANTLwG/TUFXywk1DmLfWoz0S6TBcI0L1oUc6JbRutqkaCac4Eiz
  1722. iJej87O3px8+nUbVPTK2+Tlygid+HhZORx8Nl3gMNhX2yaLGJ1eOv/yDTIsed1nvNU29DO41RQjb
  1723. kcLuL/kmjdjuKeISAwai2C7zRYQtgdO5RK+6A/954mwrH7TvnnFFWOOJPjxrnHh8DNQQP7f1zwga
  1724. Uh89J+pJCMVzrBXjx9Go3wJPBUW04c/zm7ulGxDXRT80wTamzazHfnerAtdMZw3PchLhdWyXwdSB
  1725. pkmsNvOFWx/4MRP6IhRQbnS8IVdxnVZCZrCVor093UgBCt4t6WMJYVZhK0Z1bhSdSe/irXJyj2Il
  1726. RjjqiIrq8RyGAoWw9f4xvmEzgLWGouYSaIBOiNK2KXe6qnqxZgnmnRBRryff4C7JXrnJL5rCPChv
  1727. jBeN/wrzRG+RMbqWlZ4/PxhPLl82CQ4UjF54Bb2LAoydyyZ7oDGL58+fj8S/Pez0MCpRmuc34I0B
  1728. 7F5n5ZxeDxhsPTm7Wl2H3ryJgB8Xa3kJD64oaG6f1xlFJHd0pQWR9q+BEeLahJYZTfuWOeZYXcnn
  1729. y9yCz6m0wfhLltB1RxhRkqhs9a1RGG0y0kQsCYohjNUiSUKOTsB6bPMaa/Ewuqj5Rd4DxycIZopv
  1730. 8WCMd9hrdCwpb9Zyj0XnWIwI8IhSyng0KmamajTAc3ax1WjOzrKkaspIXrhnpvoKgMreYqT5SsR3
  1731. KBlmHi1iOGWdHqs2jnW+k0W9jUq+uHTjjK1Z8uuHcAfWBknLVyuDKTw0i7TIZbkw5hRXLFkklQPG
  1732. tEM43JkubyLrEwU9KI1AvZNVWFqJtm//YNfFxfQjHR/vm5F01lBlL8TimFCctfIKo6gZn6JPlpCW
  1733. b82XCYzygaLZ2hPwxhJ/0LFUrCHw7u1wyxnrTN/HwWkbzSUdAIfugLIK0rKjpyOci8csfGbagVs0
  1734. 8EM7c8LtNimrOk5n+tqHGfppM3uervG0ZXA7CzyttwK+fQ6O777O2AfHwSTXID0x49ZUZByLlY5M
  1735. RG5lmV+EVeTo5R2yrwQ+BVJmOTP10CZ2dGnZ1Raa6gRHR8UjqK9M8dKAQ26qZjoFJy7mU0pvMuUO
  1736. A86zn29JV1eI78T41VQctnY+i2KLNzkBss+Woe+KUTeYihMMMHNs34shvjsW45dT8ccd0KOBAY4O
  1737. 3RHa+9gWhEEgr66eTMY0mRPZwr4U9of76hxG0PSM4+SqTf4umb4lKv1ri0pcIagTlV+2E5VbYw/u
  1738. WzsfH8lwA4pjlcjl/jOFJNRIN7p5mMEJPyyg37M5Wrp2vKmoocK5OWxG7ho96GhE4zbbQUxRulZf
  1739. XL+LuoYNp71zwKTJtFIV7S1zmMao0WsRFQDM+o7S8Bve7QLvNSlc/2zwiFUXAViwPREEXenJB2ZN
  1740. w0ZQH3QEn6QBHmAUEeJhaqMoXMl6goiEdA8OMdFXrUNsh+N/d+bhEoOho9AOlt98vQtPVzB7izp6
  1741. FnR3pYUnsra8ollu8+kPzHmM0tf1NwmMA6URHXBWzVWV5GYeYfYy30GT2yzmDV4GSSfTaBJT6bpN
  1742. vJXmW7/Qj6HYASWTwVqAJ1Wv8CD5lu62PFGU9IZX1Hx9+HJqKoMZkJ7Aq+jVV/oKSOpmLj/wfeyp
  1743. 3rvBS93vMPoXB1hS+b3tq85uhqZ13LoLyh8spOjZJJpZOjSG6eE6kGbNYoF3JjbEZN/aXgDyHryd
  1744. Ofg55vLTHBw22JBGfei6GqOR3iHVNiDAD5uMIcl5VNdGkSLSu4RtSHnuUpxPFgXdq9+CYAgBOX8d
  1745. 8xt0BeviyIbYjE3Bk8+xm82Jn+qmt+6M7Qka2+om3DV97r9r7rpFYGdukhk6c/frS10a6L7DVrSP
  1746. Bhze0IR4VIlEo/H7jYlrB6Y6h6Y/Qq8/SH63E850wKw8BMZk7GC8n9hTY2/M/iZeuN8xIWyfL2R2
  1747. y4l7nY3WtDs2o83xj/EUOPkFn9sbBiijaak5kPdLdMPejHNkZ/L6Ws1ivN1xRptsyufq7J7Mtu09
  1748. Xc4nY7U1uy28tAhAGG7Smbducj0wBuhKvmWa06Gc22kEDU1Jw04WskqWbBL01g7ARRwxpf4mEM9p
  1749. xKNUYqBb1WVRwm54pO8i5jydvtTmBqgJ4G1idWNQNz2m+mpaUqyUHGZKkDlO20ryASKwEe+YhtnM
  1750. vgNeedFcs5BMLTPIrN7IMq6aK4b8jIAENl3NCFR0jovrhOcaqWxxiYtYYnnDQQoDZPb7V7Cx9DbV
  1751. O+5VmFht93h2oh465PuUKxscY2S4OLm31wu611ot6Wpr1zu0zRqus1cqwTKYu/JIR+pYGb/V93fx
  1752. HbMcyUf/0uEfkHe38tLPQrfqjL1bi4bzzFUI3Qub8MYAMs599zB2OKB742JrA2zH9/WFZZSOhznQ
  1753. 2FJR++S9CqcZbdJEkDBh9IEIkl8U8MQIkgf/kREkfWsmGBqNj9YDvWUCD4SaWD24V1A2jAB9ZkAk
  1754. PMBuXWBoTOXYTbovcpXcj+yF0qwrnUo+Yx6QI7t3kxEIvmpSuRnK3lVwuyJIvnTR4+/PP745OSda
  1755. zC5O3v7HyfeUlIXHJS1b9egQW5bvM7X3vfRvN9ymE2n6Bm+w7bkhlmuYNITO+04OQg+E/nq1vgVt
  1756. KzL39VCHTt1PtxMgvnvaLahDKrsXcscv0zUmbvpMK0870E85qdb8cjITzCNzUsfi0JzEmffN4YmW
  1757. 0U5seWjhnPTWrjrR/qq+BXQg7j2xSda0Anhmgvxlj0xMxYwNzLOD0v7ffFBmOFYbmht0QAoX0rnJ
  1758. kS5xZFCV//8TKUHZxbi3Y0dxau/mpnZ8PKTspfN49ruQkSGIV+436s7PFfalTAeoEASs8PQ9hYyI
  1759. 0X/6QNWmHzxT4nKfCov3Udlc2V+4Ztq5/WuCSQaVve9LcYISH7NC41WduokDtk+nAzl9dBqVr5xK
  1760. FtB8B0DnRjwVsDf6S6wQ51sRwsZRu2SYHEt01Jf1Ocij3XSwN7R6IfaHyk7dskshXg43XLYqO3WP
  1761. Q+6hHuihalPc51hgzNIcqicV3xFkPs4UdMGX53zgGbre9sPX28uXR/ZwAfkdXzuKhLLJRo5hv3Sy
  1762. MXdeKul0J2Ypp5Suh3s1JySsW1w5UNknGNrbdEpSBvY/Js+BIY289/0hM9PDu3p/1MbUst4RTEmM
  1763. n6kJTcsp4tG42yeT7nQbtdUFwgVJjwDSUYEAC8F0dKOTILrlLO/xC70bnNd0Ha97whQ6UkHJYj5H
  1764. cA/j+zX4tbtTIfGjujOKpj83aHOgXnIQbvYduNXEC4UMm4T21Bs+GHABuCa7v//LR/TvpjHa7oe7
  1765. /Grb6lVvHSD7spj5iplBLRKZxxEYGdCbY9LWWC5hBB2voWno6DJUMzfkC3T8KJsWL9umDQY5szPt
  1766. AVijEPwfucjncQ==
  1767. """)
  1768. ##file activate.sh
  1769. ACTIVATE_SH = convert("""
  1770. eJytVd9v2kAMfs9fYQLq2m4MscdNVKMqEkgtVIQxbeuUHolpTgsXdHehpT/+9/mSEBJS2MOaB0ji
  1771. z77P9menDpOAK5jzEGERKw0zhFihD/dcB2CrKJYewoyLFvM0XzGNNpzOZbSAGVPBqVWHdRSDx4SI
  1772. NMhYANfgc4meDteW5ePGC45P4MkCumKhUENzDsu1H3lw1vJx1RJxGMKns6O2lWDqINGgotAHFCsu
  1773. I7FAoWHFJGezEFWGqsEvaD5C42naHb93X+A3+elYCgVaxgh8DmQAys9HL2SS0mIaWBgm7mTN/O3G
  1774. kzu6vHCng/HkW/fSve5O+hTOpnhfQAcoEry5jKVjNypoO0fgwzKSOgHm79KUK06Jfc7/RebHpD8a
  1775. 9kdXvT2UcnuFWG6p0stNB0mWUUQ1q3uiGRVEMfXHR03dTuQATPjwqIIPcB9wL4CArRAY/ZHJixYL
  1776. Y9YBtcAoLQtFevOoI9QaHcEdMSAB0d08kuZhyUiSmav6CPCdVBnFOjNrLu6yMCWgKRA0TInBC5i4
  1777. QwX3JG/mm581GKnSsSSxJTFHf9MAKr8w5T/vOv1mUurn5/zlT6fvTntjZzAaNl9rQ5JkU5KIc0GX
  1778. inagwU57T2eddqWlTrvaS6d9sImZeUMkhWysveF0m37NcGub9Dpgi0j4qGiOzATjDr06OBjOYQOo
  1779. 7RBoGtNm9Denv1i0LVI7lxJDXLHSSBeWRflsyyqw7diuW3h0XdvK6lBMyaoMG1UyHdTsoYBuue75
  1780. YOgOu1c91/2cwYpznPPeDoQpGL2xSm09NKp7BsvQ2hnT3aMs07lUnskpxewvBk73/LLnXo9HV9eT
  1781. ijB3hWBO2ygoiWg/bKuZxqCCQq0DD3vkWIVvI2KosIw+vqW1gIItEG5KJb+xb09g65ktwYKgTc51
  1782. uGJ/EFQs0ayEWLCQM5V9N4g+1+8UbXOJzF8bqhKtIqIwicWvzNFROZJlpfD8A7Vc044R0FxkcezG
  1783. VzsV75usvTdYef+57v5n1b225qhXfwEmxHEs
  1784. """)
  1785. ##file activate.fish
  1786. ACTIVATE_FISH = convert("""
  1787. eJyFVVFv2zYQftevuMoOnBS1gr0WGIZ08RADSRw4boBhGGhGOsUcKFIjKbUu9uN7lC2JsrXWDzZM
  1788. fnf38e6+uwlsdsJCLiRCUVkHrwiVxYy+hHqDbQKvQl3z1ImaO0xyYXdbeP9FuJ1QwMFUSnmcP4dL
  1789. 2DlXfry+9v/sDqVMUl3AFVi0Vmj1PokmcKtBaecNQTjIhMHUyX0SRXmlKIpWkGEbDuYZzBZfCVcL
  1790. 4youUdVQ6AyBqwwMusoocBrcDsmpKbgEQgijVYHKJbMI6DMhoEUHWmbhLdTcCP4q0TYokYNDev5c
  1791. QTxlq/tb9rJcbz7f3LOnm81d3GD8x3uav30FfwrnwCEOYRyAKot+FvXPzd3q8W71sBiJ3d2dMugu
  1792. fsxjCPsBmz+Wz3fsab16eNqw1ctivV7eBnwm8EzeuQIsSrcHqVMqwHbqq8/aarKSO+oYKhKXUn9p
  1793. SmWw0DVBdQ7bBlwaTR62bc+1tpaYb5PhUyScu48CRgvDLQbtMrMnMQ6dY5022JDRRrwJxWUfJwwP
  1794. ge0YIAVGfcUC1M8s8MxitFZjmR9W64hui7p4fBlWMZ5y81b/9cvfMbz7FWZKq4yOTeW1hbNBEWU+
  1795. b+/ejXMu95lOx696uXb8Go4T+Kw8R2EMSqx5KLkkCkQ+ZBZFbZsHL4OYseAvY3EPO5MYTBuhDZQa
  1796. TwPza8Y+LR/Z483Dgjwd4R3f7bTXx9Znkw6T6PAL83/hRD3jNAKFjuEx9NJkq5t+fabLvdvRwbw4
  1797. nEFTzwO6U+q34cvY7fL55tP94tg58XEA/q7LfdPsaUXFoEIMJdHF5iSW0+48CnDQ82G7n3XzAD6q
  1798. Bmo5XuOA0NQ67ir7AXJtQhtLKO7XhC0l39PGOBsHPvzBuHUSjoOnA0ldozGC9gZ5rek3+y3ALHO/
  1799. kT7AP379lQZLSnFDLtwWihfYxw4nZd+ZR7myfkI2ZTRCuRxmF/bCzkbhcElvYamW9PbDGrvqPKC0
  1800. +D/uLi/sFcxGjOHylYagZzzsjjhw206RQwrWIwOxS2dnk+40xOjX8bTPegz/gdWVSXuaowNuOLda
  1801. wYyNuRPSTcd/B48Ppeg=
  1802. """)
  1803. ##file activate.csh
  1804. ACTIVATE_CSH = convert("""
  1805. eJx1U2FP2zAQ/e5f8TAV3Soo+0zXbYUiDQkKQgVp2ibjJNfFUuIg22nVf885SVFLO3+I7Lt3fr6X
  1806. d8eY58ZjYQpCWfuAhFB7yrAyIYf0Ve1SQmLsuU6DWepAw9TnEoOFq0rwdjAUx/hV1Ui1tVWAqy1M
  1807. QGYcpaFYx+yVI67LkKwx1UuTEaYGl4X2Bl+zJpAlP/6V2hTDtCq/DYXQhdEeGW040Q/Eb+t9V/e3
  1808. U/V88zh/mtyqh8n8J47G+IKTE3gKZJdoYrK3h5MRU1tGYS83gqNc+3yEgyyP93cP820evHLvr2H8
  1809. kaYB/peoyY7aVHzpJnE9e+6I5Z+ji4GMTNJWNuOQq6MA1N25p8pW9HWdVWlfsNpPDbdxjgpaahuw
  1810. 1M7opCA/FFu1uwxC7L8KUqmto1KyQe3rx0I0Eovdf7BVe67U5c1MzSZ310pddGheZoFPWyytRkzU
  1811. aCA/I+RkBXhFXr5aWV0SxjhUI6jwdAj8kmhPzX7nTfJFkM3MImp2VdVFFq1vLHSU5szYQK4Ri+Jd
  1812. xlW2JBtOGcyYVW7SnB3v6RS91g3gKapZ0oWxbHVteYIIq3iv7QeuSrUj6KSqQ+yqsxDj1ivNQxKF
  1813. YON10Q+NH/ARS95i5Tuqq2Vxfvc23f/FO6zrtXXmJr+ZtMY9/A15ZXFWtmch2rEQ4g1ryVHH
  1814. """)
  1815. ##file activate.bat
  1816. ACTIVATE_BAT = convert("""
  1817. eJx9Ul9LhEAQfxf8DoOclI/dYyFkaCmcq4gZQTBUrincuZFbff12T133TM+nnd35/Zvxlr7XDFhV
  1818. mUZHOVhFlOWP3g4DUriIWoVomYZpNBWUtGpaWgImO191pFkSpzlcmgaI70jVX7n2Qp8tuByg+46O
  1819. CMHbMq64T+nmlJt082D1T44muCDk2prgEHF4mdI9RaS/QwSt3zSyIAaftRccvqVTBziD1x/WlPD5
  1820. xd729NDBb8Nr4DU9QNMKsJeH9pkhPedhQsIkDuCDCa6A+NF9IevVFAohkqizdHetg/tkWvPoftWJ
  1821. MCqnOxv7/x7Np6yv9P2Ker5dmX8yNyCkkWnbZy3N5LarczlqL8htx2EM9rQ/2H5BvIsIEi8OEG8U
  1822. +g8CsNTr
  1823. """)
  1824. ##file deactivate.bat
  1825. DEACTIVATE_BAT = convert("""
  1826. eJyFkN0KgkAUhO8F32EQpHqFQEjQUPAPMaErqVxzId3IrV6/XST/UDx3c86c4WMO5FYysKJQFVVp
  1827. CEfqxsnJ9DI7SA25i20fFqs3HO+GYLsDZ7h8GM3xfLHrg1QNvpSX4CWpQGvokZk4uqrQAjXjyElB
  1828. a5IjCz0r+2dHcehHCe5MZNmB5R7TdqMqECMptHZh6DN/utb7Zs6Cej8OXYE5J04YOKFvD4GkHuJ0
  1829. pilSd1jG6n87tDZ+BUwUOepI6CGSkFMYWf0ihvT33Qj1A+tCkSI=
  1830. """)
  1831. ##file activate.ps1
  1832. ACTIVATE_PS = convert("""
  1833. eJylWdmO41hyfW+g/0FTU7C7IXeJIqmtB/3AnZRIStxF2kaBm7gv4ipyMF/mB3+Sf8GXVGVl1tLT
  1834. 43ECSqR4b5wbETeWE8z/+a///vNCDaN6cYtSf5G1dbNw/IVXNIu6aCvX9xa3qsgWl0IJ/7IYinbh
  1835. 2nkOVqs2X0TNjz/8eeFFle826fBhQRaLBkD9uviw+LCy3Sbq7Mb/UNbrH3+YNtLcVaB+Xbipb+eL
  1836. tly0eVsD/M6u6g8//vC+dquobH5VWU75eMFUdvHb4n02RHlXuHYTFfmHbHCLLLNz70NpN+GrBI4p
  1837. 1EeSk4FAXaZR88u0vPip8usi7fznt3fvP+OuPnx49/Pil4td+XnzigIAPoqYQH2J8v4z+C+8b98m
  1838. Q25t7k76LIK0cOz0V89/MXXx0+Lf6z5q3PA/F+/FIif9uqnaadFf/PzXSXYBfqIb2NeApecJwPzI
  1839. dlL/149nnvyoc7KqYfzTAT8v/voUmX7e+3n364tffl/oVaDyswKY/7J18e6bve8Wv9RuUfqfLHmK
  1840. /u139Hwx+9ePRep97KKqae30YwmCo2y+0vTz1k+rv7159B3pb1SOGj97Pe8/flfkC1Vn/7xYR4n6
  1841. lypNEGDDV5f7lcjil3S+4++p881Wv6qKyn5GQg1yJwcp4BZ5E+Wt/z1P/umbiHir4J8Xip/eFt6n
  1842. 9T/9gU9eY+7zUX97Jlmb136ziKrKT/3OzpvP8VX/+MObSP0lL3LvVZlJ9v1b8357jXyw8rXxYPXN
  1843. 11n4UzJ8G8S/vUbuJ6RPj999DbtS5kys//JusXwrNLnvT99cFlBNwXCe+niRz8JF/ezNr9Pze+H6
  1844. 18W7d5PPvozW7+387Zto/v4pL8BvbxTzvIW9KCv/Fj0WzVQb/YXbVlPZWTz3/9vCaRtQbPN/Bb+j
  1845. 2rUrDxTVD68gfQXu/ZewAFX53U/vf/rD2P3558W7+W79Po1y/xXoX/6RFHyNIoVjgAG4H0RTcAe5
  1846. 3bSVv3DSwk2mZYHjFB8zj6fC4sLOFTHJJQrwzFYJgso0ApOoBzFiRzzQKjIQCCbQMIFJGCKqGUyS
  1847. 8AkjiF2wTwmMEbcEUvq8Nj+X0f4YcCQmYRiOY7eRbAJDqzm1chOoNstbJ8oTBhZQ2NcfgaB6QjLp
  1848. U4+SWFjQGCZpyqby8V4JkPGs9eH1BscXIrTG24QxXLIgCLYNsIlxSYLA6SjAeg7HAg4/kpiIB8k9
  1849. TCLm0EM4gKIxEj8IUj2dQeqSxEwYVH88qiRlCLjEYGuNIkJB1BA5dHOZdGAoUFk54WOqEojkuf4Q
  1850. Ig3WY+96TDlKLicMC04h0+gDCdYHj0kz2xBDj9ECDU5zJ0tba6RKgXBneewhBG/xJ5m5FX+WSzsn
  1851. wnHvKhcOciw9NunZ0BUF0n0IJAcJMdcLqgQb0zP19dl8t9PzmMBjkuIF7KkvHgqEovUPOsY0PBB1
  1852. HCtUUhch83qEJPjQcNQDsgj0cRqx2ZbnnlrlUjE1EX2wFJyyDa/0GLrmKDEFepdWlsbmVU45Wiwt
  1853. eFM6mfs4kxg8yc4YmKDy67dniLV5FUeO5AKNPZaOQQ++gh+dXE7dbJ1aTDr7S4WPd8sQoQkDyODg
  1854. XnEu/voeKRAXZxB/e2xaJ4LTFLPYEJ15Ltb87I45l+P6OGFA5F5Ix8A4ORV6M1NH1uMuZMnmFtLi
  1855. VpYed+gSq9JDBoHc05J4OhKetrk1p0LYiKipxLMe3tYS7c5V7O1KcPU8BJGdLfcswhoFCSGQqJ8f
  1856. ThyQKy5EWFtHVuNhvTnkeTc8JMpN5li3buURh0+3ZGuzdwM55kon+8urbintjdQJf9U1D0ah+hNh
  1857. i1XNu4fSKbTC5AikGEaj0CYM1dpuli7EoqUt7929f1plxGGNZnixFSFP2qzhlZMonu2bB9OWSqYx
  1858. VuHKWNGJI8kqUhMTRtk0vJ5ycZ60JlodlmN3D9XiEj/cG2lSt+WV3OtMgt1Tf4/Z+1BaCus740kx
  1859. Nvj78+jMd9tq537Xz/mNFyiHb0HdwHytJ3uQUzKkYhK7wjGtx3oKX43YeYoJVtqDSrCnQFzMemCS
  1860. 2bPSvP+M4yZFi/iZhAjL4UOeMfa7Ex8HKBqw4umOCPh+imOP6yVTwG2MplB+wtg97olEtykNZ6wg
  1861. FJBNXSTJ3g0CCTEEMdUjjcaBDjhJ9fyINXgQVHhA0bjk9lhhhhOGzcqQSxYdj3iIN2xGEOODx4qj
  1862. Q2xikJudC1ujCVOtiRwhga5nPdhe1gSa649bLJ0wCuLMcEYIeSy25YcDQHJb95nfowv3rQnin0fE
  1863. zIXFkM/EwSGxvCCMgEPNcDp/wph1gMEa8Xd1qAWOwWZ/KhjlqzgisBpDDDXz9Cmov46GYBKHC4zZ
  1864. 84HJnXoTxyWNBbXV4LK/r+OEwSN45zBp7Cub3gIYIvYlxon5BzDgtPUYfXAMPbENGrI+YVGSeTQ5
  1865. i8NMB5UCcC+YRGIBhgs0xhAGwSgYwywpbu4vpCSTdEKrsy8osXMUnHQYenQHbOBofLCNNTg3CRRj
  1866. A1nXY2MZcjnXI+oQ2Zk+561H4CqoW61tbPKv65Y7fqc3TDUF9CA3F3gM0e0JQ0TPADJFJXVzphpr
  1867. 2FzwAY8apGCju1QGOiUVO5KV6/hKbtgVN6hRVwpRYtu+/OC6w2bCcGzZQ8NCc4WejNEjFxOIgR3o
  1868. QqR1ZK0IaUxZ9nbL7GWJIjxBARUhAMnYrq/S0tVOjzlOSYRqeIZxaSaOBX5HSR3MFekOXVdUPbjX
  1869. nru61fDwI8HRYPUS7a6Inzq9JLjokU6P6OzT4UCH+Nha+JrU4VqEo4rRHQJhVuulAnvFhYz5NWFT
  1870. aS/bKxW6J3e46y4PLagGrCDKcq5B9EmP+s1QMCaxHNeM7deGEV3WPn3CeKjndlygdPyoIcNaL3dd
  1871. bdqPs47frcZ3aNWQ2Tk+rjFR01Ul4XnQQB6CSKA+cZusD0CP3F2Ph0e78baybgioepG12luSpFXi
  1872. bHbI6rGLDsGEodMObDG7uyxfCeU+1OiyXYk8fnGu0SpbpRoEuWdSUlNi5bd9nBxYqZGrq7Qa7zV+
  1873. VLazLcelzzP9+n6+xUtWx9OVJZW3gk92XGGkstTJ/LreFVFF2feLpXGGuQqq6/1QbWPyhJXIXIMs
  1874. 7ySVlzMYqoPmnmrobbeauMIxrCr3sM+qs5HpwmmFt7SM3aRNQWpCrmeAXY28EJ9uc966urGKBL9H
  1875. 18MtDE5OX97GDOHxam11y5LCAzcwtkUu8wqWI1dWgHyxGZdY8mC3lXzbzncLZ2bIUxTD2yW7l9eY
  1876. gBUo7uj02ZI3ydUViL7oAVFag37JsjYG8o4Csc5R7SeONGF8yZP+7xxi9scnHvHPcogJ44VH/LMc
  1877. Yu6Vn3jEzCFw9Eqq1ENQAW8aqbUwSiAqi+nZ+OkZJKpBL66Bj8z+ATqb/8qDIJUeNRTwrI0YrVmb
  1878. 9FArKVEbCWUNSi8ipfVv+STgkpSsUhcBg541eeKLoBpLGaiHTNoK0r4nn3tZqrcIULtq20Df+FVQ
  1879. Sa0MnWxTugMuzD410sQygF4qdntbswiJMqjs014Irz/tm+pd5oygJ0fcdNbMg165Pqi7EkYGAXcB
  1880. dwxioCDA3+BY9+JjuOmJu/xyX2GJtaKSQcOZxyqFzTaa6/ot21sez0BtKjirROKRm2zuai02L0N+
  1881. ULaX8H5P6VwsGPbYOY7sAy5FHBROMrMzFVPYhFHZ7M3ZCZa2hsT4jGow6TGtG8Nje9405uMUjdF4
  1882. PtKQjw6yZOmPUmO8LjFWS4aPCfE011N+l3EdYq09O3iQJ9a01B3KXiMF1WmtZ+l1gmyJ/ibAHZil
  1883. vQzdOl6g9PoSJ4TM4ghTnTndEVMOmsSSu+SCVlGCOLQRaw9oLzamSWP62VuxPZ77mZYdfTRGuNBi
  1884. KyhZL32S2YckO/tU7y4Bf+QKKibQSKCTDWPUwWaE8yCBeL5FjpbQuAlb53mGX1jptLeRotREbx96
  1885. gnicYz0496dYauCjpTCA4VA0cdLJewzRmZeTwuXWD0talJsSF9J1Pe72nkaHSpULgNeK1+o+9yi0
  1886. YpYwXZyvaZatK2eL0U0ZY6ekZkFPdC8JTF4Yo1ytawNfepqUKEhwznp6HO6+2l7L2R9Q3N49JMIe
  1887. Z+ax1mVaWussz98QbNTRPo1xu4W33LJpd9H14dd66ype7UktfEDi3oUTccJ4nODjwBKFxS7lYWiq
  1888. XoHu/b7ZVcK5TbRD0F/2GShg2ywwUl07k4LLqhofKxFBNd1grWY+Zt/cPtacBpV9ys2z1moMLrT3
  1889. W0Elrjtt5y/dvDQYtObYS97pqj0eqmwvD3jCPRqamGthLiF0XkgB6IdHLBBwDGPiIDh7oPaRmTrN
  1890. tYA/yQKFxRiok+jM6ciJq/ZgiOi5+W4DEmufPEubeSuYJaM3/JHEevM08yJAXUQwb9LS2+8FOfds
  1891. FfOe3Bel6EDSjIEIKs4o9tyt67L1ylQlzhe0Q+7ue/bJnWMcD3q6wDSIQi8ThnRM65aqLWesi/ZM
  1892. xhHmQvfKBbWcC194IPjbBLYR9JTPITbzwRcu+OSFHDHNSYCLt29sAHO6Gf0h/2UO9Xwvhrjhczyx
  1893. Ygz6CqP4IwxQj5694Q1Pe2IR+KF/yy+5PvCL/vgwv5mPp9n4kx7fnY/nmV++410qF/ZVCMyv5nAP
  1894. pkeOSce53yJ6ahF4aMJi52by1HcCj9mDT5i+7TF6RoPaLL+cN1hXem2DmX/mdIbeeqwQOLD5lKO/
  1895. 6FM4x77w6D5wMx3g0IAfa2D/pgY9a7bFQbinLDPz5dZi9ATIrd0cB5xfC0BfCCZO7TKP0jQ2Meih
  1896. nRXhkA3smTAnDN9IW2vA++lsgNuZ2QP0UhqyjUPrDmgfWP2bWWiKA+YiEK7xou8cY0+d3/bk0oHR
  1897. QLrq4KzDYF/ljQDmNhBHtkVNuoDey6TTeaD3SHO/Bf4d3IwGdqQp6FuhmwFbmbQBssDXVKDBYOpk
  1898. Jy7wxOaSRwr0rDmGbsFdCM+7XU/84JPu3D/gW7QXgzlvbjixn99/8CpWFUQWHFEz/RyXvzNXTTOd
  1899. OXLNNFc957Jn/YikNzEpUdRNxXcC6b76ccTwMGoKj5X7c7TvHFgc3Tf4892+5A+iR+D8OaaE6ACe
  1900. gdgHcyCoPm/xiDCWP+OZRjpzfj5/2u0i4qQfmIEOsTV9Hw6jZ3Agnh6hiwjDtGYxWvt5TiWEuabN
  1901. 77YCyRXwO8P8wdzG/8489KwfFBZWI6Vvx76gmlOc03JI1HEfXYZEL4sNFQ3+bqf7e2hdSWQknwKF
  1902. ICJjGyDs3fdmnnxubKXebpQYLjPgEt9GTzKkUgTvOoQa1J7N3nv4sR6uvYFLhkXZ+pbCoU3K9bfq
  1903. gF7W82tNutRRZExad+k4GYYsCfmEbvizS4jsRr3fdzqjEthpEwm7pmN7OgVzRbrktjrFw1lc0vM8
  1904. V7dyTJ71qlsd7v3KhmHzeJB35pqEOk2pEe5uPeCToNkmedmxcKbIj+MZzjFSsvCmimaMQB1uJJKa
  1905. +hoWUi7aEFLvIxKxJavqpggXBIk2hr0608dIgnfG5ZEprqmH0b0YSy6jVXTCuIB+WER4d5BPVy9Q
  1906. M4taX0RIlDYxQ2CjBuq78AAcHQf5qoKP8BXHnDnd/+ed5fS+csL4g3eWqECaL+8suy9r8hx7c+4L
  1907. EegEWdqAWN1w1NezP34xsxLkvRRI0DRzKOg0U+BKfQY128YlYsbwSczEg2LqKxRmcgiwHdhc9MQJ
  1908. IwKQHlgBejWeMGDYYxTOQUiJOmIjJbzIzHH6lAMP+y/fR0v1g4wx4St8fcqTt3gz5wc+xXFZZ3qI
  1909. JpXI5iJk7xmNL2tYsDpcqu0375Snd5EKsIvg8u5szTOyZ4v06Ny2TZXRpHUSinh4IFp8Eoi7GINJ
  1910. 02lPJnS/9jSxolJwp2slPMIEbjleWw3eec4XaetyEnSSqTPRZ9fVA0cPXMqzrPYQQyrRux3LaAh1
  1911. wujbgcObg1nt4iiJ5IMbc/WNPc280I2T4nTkdwG8H6iS5xO2WfsFsruBwf2QkgZlb6w7om2G65Lr
  1912. r2Gl4dk63F8rCEHoUJ3fW+pU2Srjlmcbp+JXY3DMifEI22HcHAvT7zzXiMTr7VbUR5a2lZtJkk4k
  1913. 1heZZFdru8ucCWMTr3Z4eNnjLm7LW7rcN7QjMpxrsCzjxndeyFUX7deIs3PQkgyH8k6luI0uUyLr
  1914. va47TBjM4JmNHFzGPcP6BV6cYgQy8VQYZe5GmzZHMxyBYhGiUdekZQ/qwyxC3WGylQGdUpSf9ZCP
  1915. a7qPdJd31fPRC0TOgzupO7nLuBGr2A02yuUQwt2KQG31sW8Gd9tQiHq+hPDt4OzJuY4pS8XRsepY
  1916. tsd7dVEfJFmc15IYqwHverrpWyS1rFZibDPW1hUUb+85CGUzSBSTK8hpvee/ZxonW51TUXekMy3L
  1917. uy25tMTg4mqbSLQQJ+skiQu2toIfBFYrOWql+EQipgfT15P1aq6FDK3xgSjIGWde0BPftYchDTdM
  1918. i4QdudHFkN0u6fSKiT09QLv2mtSblt5nNzBR6UReePNs+khE4rHcXuoK21igUKHl1c3MXMgPu7y8
  1919. rKQDxR6N/rffXv+lROXet/9Q+l9I4D1U
  1920. """)
  1921. ##file distutils-init.py
  1922. DISTUTILS_INIT = convert("""
  1923. eJytV1uL4zYUfvevOE0ottuMW9q3gVDa3aUMXXbLMlDKMBiNrSTqOJKRlMxkf33PkXyRbGe7Dw2E
  1924. UXTu37lpxLFV2oIyifAncxmOL0xLIfcG+gv80x9VW6maw7o/CANSWWBwFtqeWMPlGY6qPjV8A0bB
  1925. C4eKSTgZ5LRgFeyErMEeOBhbN+Ipgeizhjtnhkn7DdyjuNLPoCS0l/ayQTG0djwZC08cLXozeMss
  1926. aG5EzQ0IScpnWtHSTXuxByV/QCmxE7y+eS0uxWeoheaVVfqSJHiU7Mhhi6gULbOHorshkrEnKxpT
  1927. 0n3A8Y8SMpuwZx6aoix3ouFlmW8gHRSkeSJ2g7hU+kiHLDaQw3bmRDaTGfTnty7gPm0FHbIBg9U9
  1928. oh1kZzAFLaue2R6htPCtAda2nGlDSUJ4PZBgCJBGVcwKTAMz/vJiLD+Oin5Z5QlvDPdulC6EsiyE
  1929. NFzb7McNTKJzbJqzphx92VKRFY1idenzmq3K0emRcbWBD0ryqc4NZGmKOOOX9Pz5x+/l27tP797c
  1930. f/z0d+4NruGNai8uAM0bfsYaw8itFk8ny41jsfpyO+BWlpqfhcG4yxLdi/0tQqoT4a8Vby382mt8
  1931. p7XSo7aWGdPBc+b6utaBmCQ7rQKQoWtAuthQCiold2KfJIPTT8xwg9blPumc+YDZC/wYGdAyHpJk
  1932. vUbHbHWAp5No6pK/WhhLEWrFjUwtPEv1Agf8YmnsuXUQYkeZoHm8ogP16gt2uHoxcEMdf2C6pmbw
  1933. hUMsWGhanboh4IzzmsIpWs134jVPqD/c74bZHdY69UKKSn/+KfVhxLgUlToemayLMYQOqfEC61bh
  1934. cbhwaqoGUzIyZRFHPmau5juaWqwRn3mpWmoEA5nhzS5gog/5jbcFQqOZvmBasZtwYlG93k5GEiyw
  1935. buHhMWLjDarEGpMGB2LFs5nIJkhp/nUmZneFaRth++lieJtHepIvKgx6PJqIlD9X2j6pG1i9x3pZ
  1936. 5bHuCPFiirGHeO7McvoXkz786GaKVzC9DSpnOxJdc4xm6NSVq7lNEnKdVlnpu9BNYoKX2Iq3wvgh
  1937. gGEUM66kK6j4NiyoneuPLSwaCWDxczgaolEWpiMyDVDb7dNuLAbriL8ig8mmeju31oNvQdpnvEPC
  1938. 1vAXbWacGRVrGt/uXN/gU0CDDwgooKRrHfTBb1/s9lYZ8ZqOBU0yLvpuP6+K9hLFsvIjeNhBi0KL
  1939. MlOuWRn3FRwx5oHXjl0YImUx0+gLzjGchrgzca026ETmYJzPD+IpuKzNi8AFn048Thd63OdD86M6
  1940. 84zE8yQm0VqXdbbgvub2pKVnS76icBGdeTHHXTKspUmr4NYo/furFLKiMdQzFjHJNcdAnMhltBJK
  1941. 0/IKX3DVFqvPJ2dLE7bDBkH0l/PJ29074+F0CsGYOxsb7U3myTUncYfXqnLLfa6sJybX4g+hmcjO
  1942. kMRBfA1JellfRRKJcyRpxdS4rIl6FdmQCWjo/o9Qz7yKffoP4JHjOvABcRn4CZIT2RH4jnxmfpVG
  1943. qgLaAvQBNfuO6X0/Ux02nb4FKx3vgP+XnkX0QW9pLy/NsXgdN24dD3LxO2Nwil7Zlc1dqtP3d7/h
  1944. kzp1/+7hGBuY4pk0XD/0Ao/oTe/XGrfyM773aB7iUhgkpy+dwAMalxMP0DrBcsVw/6p25+/hobP9
  1945. GBknrWExDhLJ1bwt1NcCNblaFbMKCyvmX0PeRaQ=
  1946. """)
  1947. ##file distutils.cfg
  1948. DISTUTILS_CFG = convert("""
  1949. eJxNj00KwkAMhfc9xYNuxe4Ft57AjYiUtDO1wXSmNJnK3N5pdSEEAu8nH6lxHVlRhtDHMPATA4uH
  1950. xJ4EFmGbvfJiicSHFRzUSISMY6hq3GLCRLnIvSTnEefN0FIjw5tF0Hkk9Q5dRunBsVoyFi24aaLg
  1951. 9FDOlL0FPGluf4QjcInLlxd6f6rqkgPu/5nHLg0cXCscXoozRrP51DRT3j9QNl99AP53T2Q=
  1952. """)
  1953. ##file activate_this.py
  1954. ACTIVATE_THIS = convert("""
  1955. eJyNU01v2zAMvetXEB4K21jnDOstQA4dMGCHbeihlyEIDMWmE62yJEiKE//7kXKdpEWLzYBt8evx
  1956. kRSzLPs6wiEoswM8YdMpjUXcq1Dz6RZa1cSiTkJdr86GsoTRHuCotBayiWqQEYGtMCgfD1KjGYBe
  1957. 5a3p0cRKiEe2NtLAFikftnDco0ko/SFEVgEZ8aRCZDIPY9xbA8pE9M4jfW/B2CjiHq9zbJVZuOQq
  1958. siwTIvpxKYCembPAU4Muwi/Z4zfvrZ/MXipKeB8C+qisSZYiWfjJfs+0/MFMdWn1hJcO5U7G/SLa
  1959. xVx8zU6VG/PXLXvfsyyzUqjeWR8hjGE+2iCE1W1tQ82hsCJN9dzKaoexyB/uH79TnjwvxcW0ntSb
  1960. yZ8jq1Z5Q1UXsyy3gf9nbjTEj7NzQMfCJa/YSmrQ+2D/BqfiOi6sclrGzvoeVivIj8rcfcmnIQRF
  1961. 7XCyeZI7DFe5/lhlCs5PRf5QW66VXT/NrlQ46oD/D6InkOmi3IQcbhKxAX2g4a+Xd5s3UtCtG2py
  1962. m8eg6WYWqR6SL5OjKMGfSrYt/6kxxQtOpeAgj1LXBNmpE2ElmCSIy5H0zFd8gJ924HWijWhb2hRC
  1963. 6wNEm1QdDZtuSZcEprIUBo/XRNcbQe1OUbQ/r3hPTaPJJDNtFLu8KHV5XoNr3Eo6h6YtOKw8e8yw
  1964. VF5PnJ+ts3a9/Mz38RpG/AUSzYUW
  1965. """)
  1966. ##file python-config
  1967. PYTHON_CONFIG = convert("""
  1968. eJyNVV1P2zAUfc+v8ODBiSABxlulTipbO6p1LWqBgVhlhcZpPYUkctzSivHfd6+dpGloGH2Ja/ue
  1969. e+65Hz78xNhtf3x90xmw7vCWsRPGLvpDNuz87MKfdKMWSWxZ4ilNpCLZJiuWc66SVFUOZkkcirll
  1970. rfxIBAzOMtImDzSVPBRrekwoX/OZu/0r4lm0DHiG60g86u8sjPw5rCyy86NRkB8QuuBRSqfAKESn
  1971. 3orLTCQxE3GYkC9tYp8fk89OSwNsmXgizrhUtnumeSgeo5GbLUMk49Rv+2nK48Cm/qMwfp333J2/
  1972. dVcAGE0CIQHBsgIeEr4Wij0LtWDLzJ9ze5YEvH2WI6CHTAVcSu9ZCsXtgxu81CIvp6/k4eXsdfo7
  1973. PvDCRD75yi41QitfzlcPp1OI7i/1/iQitqnr0iMgQ+A6wa+IKwwdxyk9IiXNAzgquTFU8NIxAVjM
  1974. osm1Zz526e+shQ4hKRVci69nPC3Kw4NQEmkQ65E7OodxorSvxjvpBjQHDmWFIQ1mlmzlS5vedseT
  1975. /mgIEsMJ7Lxz2bLAF9M5xeLEhdbHxpWOw0GdkJApMVBRF1y+a0z3c9WZPAXGFcFrJgCIB+024uad
  1976. 0CrzmEoRa3Ub4swNIHPGf7QDV+2uj2OiFWsChgCwjKqN6rp5izpbH6Wc1O1TclQTP/XVwi6anTr1
  1977. 1sbubjZLI1+VptPSdCfwnFBrB1jvebrTA9uUhU2/9gad7xPqeFkaQcnnLbCViZK8d7R1kxzFrIJV
  1978. 8EaLYmKYpvGVkig+3C5HCXbM1jGCGekiM2pRCVPyRyXYdPf6kcbWEQ36F5V4Gq9N7icNNw+JHwRE
  1979. LTgxRXACpvnQv/PuT0xCCAywY/K4hE6Now2qDwaSE5FB+1agsoUveYDepS83qFcF1NufvULD3fTl
  1980. g6Hgf7WBt6lzMeiyyWVn3P1WVbwaczHmTzE9A5SyItTVgFYyvs/L/fXlaNgbw8v3azT+0eikVlWD
  1981. /vBHbzQumP23uBCjsYdrL9OWARwxs/nuLOzeXbPJTa/Xv6sUmQir5pC1YRLz3eA+CD8Z0XpcW8v9
  1982. MZWF36ryyXXf3yBIz6nzqz8Muyz0m5Qj7OexfYo/Ph3LqvkHUg7AuA==
  1983. """)
  1984. MH_MAGIC = 0xfeedface
  1985. MH_CIGAM = 0xcefaedfe
  1986. MH_MAGIC_64 = 0xfeedfacf
  1987. MH_CIGAM_64 = 0xcffaedfe
  1988. FAT_MAGIC = 0xcafebabe
  1989. BIG_ENDIAN = '>'
  1990. LITTLE_ENDIAN = '<'
  1991. LC_LOAD_DYLIB = 0xc
  1992. maxint = majver == 3 and getattr(sys, 'maxsize') or getattr(sys, 'maxint')
  1993. class fileview(object):
  1994. """
  1995. A proxy for file-like objects that exposes a given view of a file.
  1996. Modified from macholib.
  1997. """
  1998. def __init__(self, fileobj, start=0, size=maxint):
  1999. if isinstance(fileobj, fileview):
  2000. self._fileobj = fileobj._fileobj
  2001. else:
  2002. self._fileobj = fileobj
  2003. self._start = start
  2004. self._end = start + size
  2005. self._pos = 0
  2006. def __repr__(self):
  2007. return '<fileview [%d, %d] %r>' % (
  2008. self._start, self._end, self._fileobj)
  2009. def tell(self):
  2010. return self._pos
  2011. def _checkwindow(self, seekto, op):
  2012. if not (self._start <= seekto <= self._end):
  2013. raise IOError("%s to offset %d is outside window [%d, %d]" % (
  2014. op, seekto, self._start, self._end))
  2015. def seek(self, offset, whence=0):
  2016. seekto = offset
  2017. if whence == os.SEEK_SET:
  2018. seekto += self._start
  2019. elif whence == os.SEEK_CUR:
  2020. seekto += self._start + self._pos
  2021. elif whence == os.SEEK_END:
  2022. seekto += self._end
  2023. else:
  2024. raise IOError("Invalid whence argument to seek: %r" % (whence,))
  2025. self._checkwindow(seekto, 'seek')
  2026. self._fileobj.seek(seekto)
  2027. self._pos = seekto - self._start
  2028. def write(self, bytes):
  2029. here = self._start + self._pos
  2030. self._checkwindow(here, 'write')
  2031. self._checkwindow(here + len(bytes), 'write')
  2032. self._fileobj.seek(here, os.SEEK_SET)
  2033. self._fileobj.write(bytes)
  2034. self._pos += len(bytes)
  2035. def read(self, size=maxint):
  2036. assert size >= 0
  2037. here = self._start + self._pos
  2038. self._checkwindow(here, 'read')
  2039. size = min(size, self._end - here)
  2040. self._fileobj.seek(here, os.SEEK_SET)
  2041. bytes = self._fileobj.read(size)
  2042. self._pos += len(bytes)
  2043. return bytes
  2044. def read_data(file, endian, num=1):
  2045. """
  2046. Read a given number of 32-bits unsigned integers from the given file
  2047. with the given endianness.
  2048. """
  2049. res = struct.unpack(endian + 'L' * num, file.read(num * 4))
  2050. if len(res) == 1:
  2051. return res[0]
  2052. return res
  2053. def mach_o_change(path, what, value):
  2054. """
  2055. Replace a given name (what) in any LC_LOAD_DYLIB command found in
  2056. the given binary with a new name (value), provided it's shorter.
  2057. """
  2058. def do_macho(file, bits, endian):
  2059. # Read Mach-O header (the magic number is assumed read by the caller)
  2060. cputype, cpusubtype, filetype, ncmds, sizeofcmds, flags = read_data(file, endian, 6)
  2061. # 64-bits header has one more field.
  2062. if bits == 64:
  2063. read_data(file, endian)
  2064. # The header is followed by ncmds commands
  2065. for n in range(ncmds):
  2066. where = file.tell()
  2067. # Read command header
  2068. cmd, cmdsize = read_data(file, endian, 2)
  2069. if cmd == LC_LOAD_DYLIB:
  2070. # The first data field in LC_LOAD_DYLIB commands is the
  2071. # offset of the name, starting from the beginning of the
  2072. # command.
  2073. name_offset = read_data(file, endian)
  2074. file.seek(where + name_offset, os.SEEK_SET)
  2075. # Read the NUL terminated string
  2076. load = file.read(cmdsize - name_offset).decode()
  2077. load = load[:load.index('\0')]
  2078. # If the string is what is being replaced, overwrite it.
  2079. if load == what:
  2080. file.seek(where + name_offset, os.SEEK_SET)
  2081. file.write(value.encode() + '\0'.encode())
  2082. # Seek to the next command
  2083. file.seek(where + cmdsize, os.SEEK_SET)
  2084. def do_file(file, offset=0, size=maxint):
  2085. file = fileview(file, offset, size)
  2086. # Read magic number
  2087. magic = read_data(file, BIG_ENDIAN)
  2088. if magic == FAT_MAGIC:
  2089. # Fat binaries contain nfat_arch Mach-O binaries
  2090. nfat_arch = read_data(file, BIG_ENDIAN)
  2091. for n in range(nfat_arch):
  2092. # Read arch header
  2093. cputype, cpusubtype, offset, size, align = read_data(file, BIG_ENDIAN, 5)
  2094. do_file(file, offset, size)
  2095. elif magic == MH_MAGIC:
  2096. do_macho(file, 32, BIG_ENDIAN)
  2097. elif magic == MH_CIGAM:
  2098. do_macho(file, 32, LITTLE_ENDIAN)
  2099. elif magic == MH_MAGIC_64:
  2100. do_macho(file, 64, BIG_ENDIAN)
  2101. elif magic == MH_CIGAM_64:
  2102. do_macho(file, 64, LITTLE_ENDIAN)
  2103. assert (len(what) >= len(value))
  2104. with open(path, 'r+b') as f:
  2105. do_file(f)
  2106. if __name__ == '__main__':
  2107. main()
  2108. # TODO:
  2109. # Copy python.exe.manifest
  2110. # Monkeypatch distutils.sysconfig