wheel_legacy.py 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. import logging
  2. import os.path
  3. from typing import List, Optional
  4. from pip._internal.cli.spinners import open_spinner
  5. from pip._internal.utils.setuptools_build import make_setuptools_bdist_wheel_args
  6. from pip._internal.utils.subprocess import (
  7. LOG_DIVIDER,
  8. call_subprocess,
  9. format_command_args,
  10. )
  11. logger = logging.getLogger(__name__)
  12. def format_command_result(
  13. command_args, # type: List[str]
  14. command_output, # type: str
  15. ):
  16. # type: (...) -> str
  17. """Format command information for logging."""
  18. command_desc = format_command_args(command_args)
  19. text = f'Command arguments: {command_desc}\n'
  20. if not command_output:
  21. text += 'Command output: None'
  22. elif logger.getEffectiveLevel() > logging.DEBUG:
  23. text += 'Command output: [use --verbose to show]'
  24. else:
  25. if not command_output.endswith('\n'):
  26. command_output += '\n'
  27. text += f'Command output:\n{command_output}{LOG_DIVIDER}'
  28. return text
  29. def get_legacy_build_wheel_path(
  30. names, # type: List[str]
  31. temp_dir, # type: str
  32. name, # type: str
  33. command_args, # type: List[str]
  34. command_output, # type: str
  35. ):
  36. # type: (...) -> Optional[str]
  37. """Return the path to the wheel in the temporary build directory."""
  38. # Sort for determinism.
  39. names = sorted(names)
  40. if not names:
  41. msg = (
  42. 'Legacy build of wheel for {!r} created no files.\n'
  43. ).format(name)
  44. msg += format_command_result(command_args, command_output)
  45. logger.warning(msg)
  46. return None
  47. if len(names) > 1:
  48. msg = (
  49. 'Legacy build of wheel for {!r} created more than one file.\n'
  50. 'Filenames (choosing first): {}\n'
  51. ).format(name, names)
  52. msg += format_command_result(command_args, command_output)
  53. logger.warning(msg)
  54. return os.path.join(temp_dir, names[0])
  55. def build_wheel_legacy(
  56. name, # type: str
  57. setup_py_path, # type: str
  58. source_dir, # type: str
  59. global_options, # type: List[str]
  60. build_options, # type: List[str]
  61. tempd, # type: str
  62. ):
  63. # type: (...) -> Optional[str]
  64. """Build one unpacked package using the "legacy" build process.
  65. Returns path to wheel if successfully built. Otherwise, returns None.
  66. """
  67. wheel_args = make_setuptools_bdist_wheel_args(
  68. setup_py_path,
  69. global_options=global_options,
  70. build_options=build_options,
  71. destination_dir=tempd,
  72. )
  73. spin_message = f'Building wheel for {name} (setup.py)'
  74. with open_spinner(spin_message) as spinner:
  75. logger.debug('Destination directory: %s', tempd)
  76. try:
  77. output = call_subprocess(
  78. wheel_args,
  79. cwd=source_dir,
  80. spinner=spinner,
  81. )
  82. except Exception:
  83. spinner.finish("error")
  84. logger.error('Failed building wheel for %s', name)
  85. return None
  86. names = os.listdir(tempd)
  87. wheel_path = get_legacy_build_wheel_path(
  88. names=names,
  89. temp_dir=tempd,
  90. name=name,
  91. command_args=wheel_args,
  92. command_output=output,
  93. )
  94. return wheel_path