virtual-bootstrap.py 97 KB

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