direct_url_helpers.py 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. from typing import Optional
  2. from pip._internal.models.direct_url import ArchiveInfo, DirectUrl, DirInfo, VcsInfo
  3. from pip._internal.models.link import Link
  4. from pip._internal.utils.urls import path_to_url
  5. from pip._internal.vcs import vcs
  6. def direct_url_as_pep440_direct_reference(direct_url: DirectUrl, name: str) -> str:
  7. """Convert a DirectUrl to a pip requirement string."""
  8. direct_url.validate() # if invalid, this is a pip bug
  9. requirement = name + " @ "
  10. fragments = []
  11. if isinstance(direct_url.info, VcsInfo):
  12. requirement += "{}+{}@{}".format(
  13. direct_url.info.vcs, direct_url.url, direct_url.info.commit_id
  14. )
  15. elif isinstance(direct_url.info, ArchiveInfo):
  16. requirement += direct_url.url
  17. if direct_url.info.hash:
  18. fragments.append(direct_url.info.hash)
  19. else:
  20. assert isinstance(direct_url.info, DirInfo)
  21. requirement += direct_url.url
  22. if direct_url.subdirectory:
  23. fragments.append("subdirectory=" + direct_url.subdirectory)
  24. if fragments:
  25. requirement += "#" + "&".join(fragments)
  26. return requirement
  27. def direct_url_for_editable(source_dir: str) -> DirectUrl:
  28. return DirectUrl(
  29. url=path_to_url(source_dir),
  30. info=DirInfo(editable=True),
  31. )
  32. def direct_url_from_link(
  33. link: Link, source_dir: Optional[str] = None, link_is_in_wheel_cache: bool = False
  34. ) -> DirectUrl:
  35. if link.is_vcs:
  36. vcs_backend = vcs.get_backend_for_scheme(link.scheme)
  37. assert vcs_backend
  38. url, requested_revision, _ = vcs_backend.get_url_rev_and_auth(
  39. link.url_without_fragment
  40. )
  41. # For VCS links, we need to find out and add commit_id.
  42. if link_is_in_wheel_cache:
  43. # If the requested VCS link corresponds to a cached
  44. # wheel, it means the requested revision was an
  45. # immutable commit hash, otherwise it would not have
  46. # been cached. In that case we don't have a source_dir
  47. # with the VCS checkout.
  48. assert requested_revision
  49. commit_id = requested_revision
  50. else:
  51. # If the wheel was not in cache, it means we have
  52. # had to checkout from VCS to build and we have a source_dir
  53. # which we can inspect to find out the commit id.
  54. assert source_dir
  55. commit_id = vcs_backend.get_revision(source_dir)
  56. return DirectUrl(
  57. url=url,
  58. info=VcsInfo(
  59. vcs=vcs_backend.name,
  60. commit_id=commit_id,
  61. requested_revision=requested_revision,
  62. ),
  63. subdirectory=link.subdirectory_fragment,
  64. )
  65. elif link.is_existing_dir():
  66. return DirectUrl(
  67. url=link.url_without_fragment,
  68. info=DirInfo(),
  69. subdirectory=link.subdirectory_fragment,
  70. )
  71. else:
  72. hash = None
  73. hash_name = link.hash_name
  74. if hash_name:
  75. hash = f"{hash_name}={link.hash}"
  76. return DirectUrl(
  77. url=link.url_without_fragment,
  78. info=ArchiveInfo(hash=hash),
  79. subdirectory=link.subdirectory_fragment,
  80. )