wheel_legacy.py 3.0 KB

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