You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

204 lines
7.3 KiB

  1. # -*- coding: utf-8 -*-
  2. from __future__ import absolute_import
  3. import logging
  4. import os
  5. import warnings
  6. from pip.basecommand import RequirementCommand
  7. from pip.index import PackageFinder
  8. from pip.exceptions import CommandError, PreviousBuildDirError
  9. from pip.req import RequirementSet
  10. from pip.utils import import_or_raise, normalize_path
  11. from pip.utils.build import BuildDirectory
  12. from pip.utils.deprecation import RemovedInPip8Warning
  13. from pip.wheel import WheelCache, WheelBuilder
  14. from pip import cmdoptions
  15. DEFAULT_WHEEL_DIR = os.path.join(normalize_path(os.curdir), 'wheelhouse')
  16. logger = logging.getLogger(__name__)
  17. class WheelCommand(RequirementCommand):
  18. """
  19. Build Wheel archives for your requirements and dependencies.
  20. Wheel is a built-package format, and offers the advantage of not
  21. recompiling your software during every install. For more details, see the
  22. wheel docs: http://wheel.readthedocs.org/en/latest.
  23. Requirements: setuptools>=0.8, and wheel.
  24. 'pip wheel' uses the bdist_wheel setuptools extension from the wheel
  25. package to build individual wheels.
  26. """
  27. name = 'wheel'
  28. usage = """
  29. %prog [options] <requirement specifier> ...
  30. %prog [options] -r <requirements file> ...
  31. %prog [options] [-e] <vcs project url> ...
  32. %prog [options] [-e] <local project path> ...
  33. %prog [options] <archive url/path> ..."""
  34. summary = 'Build wheels from your requirements.'
  35. def __init__(self, *args, **kw):
  36. super(WheelCommand, self).__init__(*args, **kw)
  37. cmd_opts = self.cmd_opts
  38. cmd_opts.add_option(
  39. '-w', '--wheel-dir',
  40. dest='wheel_dir',
  41. metavar='dir',
  42. default=DEFAULT_WHEEL_DIR,
  43. help=("Build wheels into <dir>, where the default is "
  44. "'<cwd>/wheelhouse'."),
  45. )
  46. cmd_opts.add_option(cmdoptions.use_wheel())
  47. cmd_opts.add_option(cmdoptions.no_use_wheel())
  48. cmd_opts.add_option(cmdoptions.no_binary())
  49. cmd_opts.add_option(cmdoptions.only_binary())
  50. cmd_opts.add_option(
  51. '--build-option',
  52. dest='build_options',
  53. metavar='options',
  54. action='append',
  55. help="Extra arguments to be supplied to 'setup.py bdist_wheel'.")
  56. cmd_opts.add_option(cmdoptions.constraints())
  57. cmd_opts.add_option(cmdoptions.editable())
  58. cmd_opts.add_option(cmdoptions.requirements())
  59. cmd_opts.add_option(cmdoptions.download_cache())
  60. cmd_opts.add_option(cmdoptions.src())
  61. cmd_opts.add_option(cmdoptions.no_deps())
  62. cmd_opts.add_option(cmdoptions.build_dir())
  63. cmd_opts.add_option(
  64. '--global-option',
  65. dest='global_options',
  66. action='append',
  67. metavar='options',
  68. help="Extra global options to be supplied to the setup.py "
  69. "call before the 'bdist_wheel' command.")
  70. cmd_opts.add_option(
  71. '--pre',
  72. action='store_true',
  73. default=False,
  74. help=("Include pre-release and development versions. By default, "
  75. "pip only finds stable versions."),
  76. )
  77. cmd_opts.add_option(cmdoptions.no_clean())
  78. index_opts = cmdoptions.make_option_group(
  79. cmdoptions.index_group,
  80. self.parser,
  81. )
  82. self.parser.insert_option_group(0, index_opts)
  83. self.parser.insert_option_group(0, cmd_opts)
  84. def check_required_packages(self):
  85. import_or_raise(
  86. 'wheel.bdist_wheel',
  87. CommandError,
  88. "'pip wheel' requires the 'wheel' package. To fix this, run: "
  89. "pip install wheel"
  90. )
  91. pkg_resources = import_or_raise(
  92. 'pkg_resources',
  93. CommandError,
  94. "'pip wheel' requires setuptools >= 0.8 for dist-info support."
  95. " To fix this, run: pip install --upgrade setuptools"
  96. )
  97. if not hasattr(pkg_resources, 'DistInfoDistribution'):
  98. raise CommandError(
  99. "'pip wheel' requires setuptools >= 0.8 for dist-info "
  100. "support. To fix this, run: pip install --upgrade "
  101. "setuptools"
  102. )
  103. def run(self, options, args):
  104. self.check_required_packages()
  105. cmdoptions.resolve_wheel_no_use_binary(options)
  106. cmdoptions.check_install_build_global(options)
  107. index_urls = [options.index_url] + options.extra_index_urls
  108. if options.no_index:
  109. logger.info('Ignoring indexes: %s', ','.join(index_urls))
  110. index_urls = []
  111. if options.download_cache:
  112. warnings.warn(
  113. "--download-cache has been deprecated and will be removed in "
  114. "the future. Pip now automatically uses and configures its "
  115. "cache.",
  116. RemovedInPip8Warning,
  117. )
  118. if options.build_dir:
  119. options.build_dir = os.path.abspath(options.build_dir)
  120. with self._build_session(options) as session:
  121. finder = PackageFinder(
  122. find_links=options.find_links,
  123. format_control=options.format_control,
  124. index_urls=index_urls,
  125. allow_external=options.allow_external,
  126. allow_unverified=options.allow_unverified,
  127. allow_all_external=options.allow_all_external,
  128. allow_all_prereleases=options.pre,
  129. trusted_hosts=options.trusted_hosts,
  130. process_dependency_links=options.process_dependency_links,
  131. session=session,
  132. )
  133. build_delete = (not (options.no_clean or options.build_dir))
  134. wheel_cache = WheelCache(options.cache_dir, options.format_control)
  135. with BuildDirectory(options.build_dir,
  136. delete=build_delete) as build_dir:
  137. requirement_set = RequirementSet(
  138. build_dir=build_dir,
  139. src_dir=options.src_dir,
  140. download_dir=None,
  141. ignore_dependencies=options.ignore_dependencies,
  142. ignore_installed=True,
  143. isolated=options.isolated_mode,
  144. session=session,
  145. wheel_cache=wheel_cache,
  146. wheel_download_dir=options.wheel_dir
  147. )
  148. self.populate_requirement_set(
  149. requirement_set, args, options, finder, session, self.name,
  150. wheel_cache
  151. )
  152. if not requirement_set.has_requirements:
  153. return
  154. try:
  155. # build wheels
  156. wb = WheelBuilder(
  157. requirement_set,
  158. finder,
  159. build_options=options.build_options or [],
  160. global_options=options.global_options or [],
  161. )
  162. if not wb.build():
  163. raise CommandError(
  164. "Failed to build one or more wheels"
  165. )
  166. except PreviousBuildDirError:
  167. options.no_clean = True
  168. raise
  169. finally:
  170. if not options.no_clean:
  171. requirement_set.cleanup_files()