install_egg_info.py 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. """
  2. distutils.command.install_egg_info
  3. Implements the Distutils 'install_egg_info' command, for installing
  4. a package's PKG-INFO metadata.
  5. """
  6. import os
  7. import re
  8. import sys
  9. from typing import ClassVar
  10. from .. import dir_util
  11. from .._log import log
  12. from ..cmd import Command
  13. class install_egg_info(Command):
  14. """Install an .egg-info file for the package"""
  15. description = "Install package's PKG-INFO metadata as an .egg-info file"
  16. user_options: ClassVar[list[tuple[str, str, str]]] = [
  17. ('install-dir=', 'd', "directory to install to"),
  18. ]
  19. def initialize_options(self):
  20. self.install_dir = None
  21. @property
  22. def basename(self):
  23. """
  24. Allow basename to be overridden by child class.
  25. Ref pypa/distutils#2.
  26. """
  27. name = to_filename(safe_name(self.distribution.get_name()))
  28. version = to_filename(safe_version(self.distribution.get_version()))
  29. return f"{name}-{version}-py{sys.version_info.major}.{sys.version_info.minor}.egg-info"
  30. def finalize_options(self):
  31. self.set_undefined_options('install_lib', ('install_dir', 'install_dir'))
  32. self.target = os.path.join(self.install_dir, self.basename)
  33. self.outputs = [self.target]
  34. def run(self):
  35. target = self.target
  36. if os.path.isdir(target) and not os.path.islink(target):
  37. dir_util.remove_tree(target)
  38. elif os.path.exists(target):
  39. self.execute(os.unlink, (self.target,), "Removing " + target)
  40. elif not os.path.isdir(self.install_dir):
  41. self.execute(
  42. os.makedirs, (self.install_dir,), "Creating " + self.install_dir
  43. )
  44. log.info("Writing %s", target)
  45. with open(target, 'w', encoding='UTF-8') as f:
  46. self.distribution.metadata.write_pkg_file(f)
  47. def get_outputs(self):
  48. return self.outputs
  49. # The following routines are taken from setuptools' pkg_resources module and
  50. # can be replaced by importing them from pkg_resources once it is included
  51. # in the stdlib.
  52. def safe_name(name):
  53. """Convert an arbitrary string to a standard distribution name
  54. Any runs of non-alphanumeric/. characters are replaced with a single '-'.
  55. """
  56. return re.sub('[^A-Za-z0-9.]+', '-', name)
  57. def safe_version(version):
  58. """Convert an arbitrary string to a standard version string
  59. Spaces become dots, and all other non-alphanumeric characters become
  60. dashes, with runs of multiple dashes condensed to a single dash.
  61. """
  62. version = version.replace(' ', '.')
  63. return re.sub('[^A-Za-z0-9.]+', '-', version)
  64. def to_filename(name):
  65. """Convert a project or version name to its filename-escaped form
  66. Any '-' characters are currently replaced with '_'.
  67. """
  68. return name.replace('-', '_')