install.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. import os
  2. import sys
  3. import tempfile
  4. import shutil
  5. from pip.req import InstallRequirement, RequirementSet, parse_requirements
  6. from pip.log import logger
  7. from pip.locations import (src_prefix, virtualenv_no_global, distutils_scheme,
  8. build_prefix)
  9. from pip.basecommand import Command
  10. from pip.index import PackageFinder
  11. from pip.exceptions import InstallationError, CommandError, PreviousBuildDirError
  12. from pip import cmdoptions
  13. class InstallCommand(Command):
  14. """
  15. Install packages from:
  16. - PyPI (and other indexes) using requirement specifiers.
  17. - VCS project urls.
  18. - Local project directories.
  19. - Local or remote source archives.
  20. pip also supports installing from "requirements files", which provide
  21. an easy way to specify a whole environment to be installed.
  22. """
  23. name = 'install'
  24. usage = """
  25. %prog [options] <requirement specifier> ...
  26. %prog [options] -r <requirements file> ...
  27. %prog [options] [-e] <vcs project url> ...
  28. %prog [options] [-e] <local project path> ...
  29. %prog [options] <archive url/path> ..."""
  30. summary = 'Install packages.'
  31. bundle = False
  32. def __init__(self, *args, **kw):
  33. super(InstallCommand, self).__init__(*args, **kw)
  34. cmd_opts = self.cmd_opts
  35. cmd_opts.add_option(
  36. '-e', '--editable',
  37. dest='editables',
  38. action='append',
  39. default=[],
  40. metavar='path/url',
  41. help='Install a project in editable mode (i.e. setuptools "develop mode") from a local project path or a VCS url.')
  42. cmd_opts.add_option(cmdoptions.requirements.make())
  43. cmd_opts.add_option(cmdoptions.build_dir.make())
  44. cmd_opts.add_option(
  45. '-t', '--target',
  46. dest='target_dir',
  47. metavar='dir',
  48. default=None,
  49. help='Install packages into <dir>.')
  50. cmd_opts.add_option(
  51. '-d', '--download', '--download-dir', '--download-directory',
  52. dest='download_dir',
  53. metavar='dir',
  54. default=None,
  55. help="Download packages into <dir> instead of installing them, regardless of what's already installed.")
  56. cmd_opts.add_option(cmdoptions.download_cache.make())
  57. cmd_opts.add_option(
  58. '--src', '--source', '--source-dir', '--source-directory',
  59. dest='src_dir',
  60. metavar='dir',
  61. default=src_prefix,
  62. help='Directory to check out editable projects into. '
  63. 'The default in a virtualenv is "<venv path>/src". '
  64. 'The default for global installs is "<current dir>/src".')
  65. cmd_opts.add_option(
  66. '-U', '--upgrade',
  67. dest='upgrade',
  68. action='store_true',
  69. help='Upgrade all packages to the newest available version. '
  70. 'This process is recursive regardless of whether a dependency is already satisfied.')
  71. cmd_opts.add_option(
  72. '--force-reinstall',
  73. dest='force_reinstall',
  74. action='store_true',
  75. help='When upgrading, reinstall all packages even if they are '
  76. 'already up-to-date.')
  77. cmd_opts.add_option(
  78. '-I', '--ignore-installed',
  79. dest='ignore_installed',
  80. action='store_true',
  81. help='Ignore the installed packages (reinstalling instead).')
  82. cmd_opts.add_option(cmdoptions.no_deps.make())
  83. cmd_opts.add_option(
  84. '--no-install',
  85. dest='no_install',
  86. action='store_true',
  87. help="DEPRECATED. Download and unpack all packages, but don't actually install them.")
  88. cmd_opts.add_option(
  89. '--no-download',
  90. dest='no_download',
  91. action="store_true",
  92. help="DEPRECATED. Don't download any packages, just install the ones already downloaded "
  93. "(completes an install run with --no-install).")
  94. cmd_opts.add_option(cmdoptions.install_options.make())
  95. cmd_opts.add_option(cmdoptions.global_options.make())
  96. cmd_opts.add_option(
  97. '--user',
  98. dest='use_user_site',
  99. action='store_true',
  100. help='Install using the user scheme.')
  101. cmd_opts.add_option(
  102. '--egg',
  103. dest='as_egg',
  104. action='store_true',
  105. help="Install packages as eggs, not 'flat', like pip normally does. This option is not about installing *from* eggs. (WARNING: Because this option overrides pip's normal install logic, requirements files may not behave as expected.)")
  106. cmd_opts.add_option(
  107. '--root',
  108. dest='root_path',
  109. metavar='dir',
  110. default=None,
  111. help="Install everything relative to this alternate root directory.")
  112. cmd_opts.add_option(
  113. "--compile",
  114. action="store_true",
  115. dest="compile",
  116. default=True,
  117. help="Compile py files to pyc",
  118. )
  119. cmd_opts.add_option(
  120. "--no-compile",
  121. action="store_false",
  122. dest="compile",
  123. help="Do not compile py files to pyc",
  124. )
  125. cmd_opts.add_option(cmdoptions.use_wheel.make())
  126. cmd_opts.add_option(cmdoptions.no_use_wheel.make())
  127. cmd_opts.add_option(
  128. '--pre',
  129. action='store_true',
  130. default=False,
  131. help="Include pre-release and development versions. By default, pip only finds stable versions.")
  132. cmd_opts.add_option(cmdoptions.no_clean.make())
  133. index_opts = cmdoptions.make_option_group(cmdoptions.index_group, self.parser)
  134. self.parser.insert_option_group(0, index_opts)
  135. self.parser.insert_option_group(0, cmd_opts)
  136. def _build_package_finder(self, options, index_urls, session):
  137. """
  138. Create a package finder appropriate to this install command.
  139. This method is meant to be overridden by subclasses, not
  140. called directly.
  141. """
  142. return PackageFinder(find_links=options.find_links,
  143. index_urls=index_urls,
  144. use_wheel=options.use_wheel,
  145. allow_external=options.allow_external,
  146. allow_unverified=options.allow_unverified,
  147. allow_all_external=options.allow_all_external,
  148. allow_all_prereleases=options.pre,
  149. process_dependency_links=
  150. options.process_dependency_links,
  151. session=session,
  152. )
  153. def run(self, options, args):
  154. if (
  155. options.no_install or
  156. options.no_download or
  157. (options.build_dir != build_prefix) or
  158. options.no_clean
  159. ):
  160. logger.deprecated('1.7', 'DEPRECATION: --no-install, --no-download, --build, '
  161. 'and --no-clean are deprecated. See https://github.com/pypa/pip/issues/906.')
  162. if options.download_dir:
  163. options.no_install = True
  164. options.ignore_installed = True
  165. options.build_dir = os.path.abspath(options.build_dir)
  166. options.src_dir = os.path.abspath(options.src_dir)
  167. install_options = options.install_options or []
  168. if options.use_user_site:
  169. if virtualenv_no_global():
  170. raise InstallationError("Can not perform a '--user' install. User site-packages are not visible in this virtualenv.")
  171. install_options.append('--user')
  172. temp_target_dir = None
  173. if options.target_dir:
  174. options.ignore_installed = True
  175. temp_target_dir = tempfile.mkdtemp()
  176. options.target_dir = os.path.abspath(options.target_dir)
  177. if os.path.exists(options.target_dir) and not os.path.isdir(options.target_dir):
  178. raise CommandError("Target path exists but is not a directory, will not continue.")
  179. install_options.append('--home=' + temp_target_dir)
  180. global_options = options.global_options or []
  181. index_urls = [options.index_url] + options.extra_index_urls
  182. if options.no_index:
  183. logger.notify('Ignoring indexes: %s' % ','.join(index_urls))
  184. index_urls = []
  185. if options.use_mirrors:
  186. logger.deprecated("1.7",
  187. "--use-mirrors has been deprecated and will be removed"
  188. " in the future. Explicit uses of --index-url and/or "
  189. "--extra-index-url is suggested.")
  190. if options.mirrors:
  191. logger.deprecated("1.7",
  192. "--mirrors has been deprecated and will be removed in "
  193. " the future. Explicit uses of --index-url and/or "
  194. "--extra-index-url is suggested.")
  195. index_urls += options.mirrors
  196. session = self._build_session(options)
  197. finder = self._build_package_finder(options, index_urls, session)
  198. requirement_set = RequirementSet(
  199. build_dir=options.build_dir,
  200. src_dir=options.src_dir,
  201. download_dir=options.download_dir,
  202. download_cache=options.download_cache,
  203. upgrade=options.upgrade,
  204. as_egg=options.as_egg,
  205. ignore_installed=options.ignore_installed,
  206. ignore_dependencies=options.ignore_dependencies,
  207. force_reinstall=options.force_reinstall,
  208. use_user_site=options.use_user_site,
  209. target_dir=temp_target_dir,
  210. session=session,
  211. pycompile=options.compile,
  212. )
  213. for name in args:
  214. requirement_set.add_requirement(
  215. InstallRequirement.from_line(name, None))
  216. for name in options.editables:
  217. requirement_set.add_requirement(
  218. InstallRequirement.from_editable(name, default_vcs=options.default_vcs))
  219. for filename in options.requirements:
  220. for req in parse_requirements(filename, finder=finder, options=options, session=session):
  221. requirement_set.add_requirement(req)
  222. if not requirement_set.has_requirements:
  223. opts = {'name': self.name}
  224. if options.find_links:
  225. msg = ('You must give at least one requirement to %(name)s '
  226. '(maybe you meant "pip %(name)s %(links)s"?)' %
  227. dict(opts, links=' '.join(options.find_links)))
  228. else:
  229. msg = ('You must give at least one requirement '
  230. 'to %(name)s (see "pip help %(name)s")' % opts)
  231. logger.warn(msg)
  232. return
  233. try:
  234. if not options.no_download:
  235. requirement_set.prepare_files(finder, force_root_egg_info=self.bundle, bundle=self.bundle)
  236. else:
  237. requirement_set.locate_files()
  238. if not options.no_install and not self.bundle:
  239. requirement_set.install(install_options, global_options, root=options.root_path)
  240. installed = ' '.join([req.name for req in
  241. requirement_set.successfully_installed])
  242. if installed:
  243. logger.notify('Successfully installed %s' % installed)
  244. elif not self.bundle:
  245. downloaded = ' '.join([req.name for req in
  246. requirement_set.successfully_downloaded])
  247. if downloaded:
  248. logger.notify('Successfully downloaded %s' % downloaded)
  249. elif self.bundle:
  250. requirement_set.create_bundle(self.bundle_filename)
  251. logger.notify('Created bundle in %s' % self.bundle_filename)
  252. except PreviousBuildDirError:
  253. options.no_clean = True
  254. raise
  255. finally:
  256. # Clean up
  257. if (not options.no_clean) and ((not options.no_install) or options.download_dir):
  258. requirement_set.cleanup_files(bundle=self.bundle)
  259. if options.target_dir:
  260. if not os.path.exists(options.target_dir):
  261. os.makedirs(options.target_dir)
  262. lib_dir = distutils_scheme('', home=temp_target_dir)['purelib']
  263. for item in os.listdir(lib_dir):
  264. shutil.move(
  265. os.path.join(lib_dir, item),
  266. os.path.join(options.target_dir, item)
  267. )
  268. shutil.rmtree(temp_target_dir)
  269. return requirement_set