Skip to content

Commit

Permalink
feat: generate provenance_url.json when installing packages(PEP 710)
Browse files Browse the repository at this point in the history
Signed-off-by: Frost Ming <[email protected]>
  • Loading branch information
frostming committed Jul 15, 2024
1 parent 0e5f028 commit 5ad7ef1
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 8 deletions.
8 changes: 3 additions & 5 deletions src/pdm/installers/installers.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from __future__ import annotations

import json
import os
import stat
from functools import cached_property
Expand Down Expand Up @@ -151,7 +150,7 @@ def _get_link_method(cache_method: str) -> LinkMethod:
def install_wheel(
wheel: Path,
environment: BaseEnvironment,
direct_url: dict[str, Any] | None = None,
additional_metadata: dict[str, bytes] | None = None,
install_links: bool = False,
rename_pth: bool = False,
) -> str:
Expand All @@ -169,9 +168,8 @@ def install_wheel(
else:
link_method = _get_link_method(cache_method)

additional_metadata: dict[str, bytes] = {}
if direct_url is not None:
additional_metadata["direct_url.json"] = json.dumps(direct_url, indent=2).encode()
if additional_metadata is None:
additional_metadata = {}

destination = InstallDestination(
scheme_dict=environment.get_paths(dist_name),
Expand Down
11 changes: 9 additions & 2 deletions src/pdm/installers/manager.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from __future__ import annotations

import json
from typing import TYPE_CHECKING

from pdm import termui
Expand Down Expand Up @@ -29,10 +30,16 @@ def __init__(
def install(self, candidate: Candidate) -> Distribution:
"""Install a candidate into the environment, return the distribution"""
prepared = candidate.prepare(self.environment)
wheel = prepared.build()
additional_metadata: dict[str, bytes] = {}
if direct_url := prepared.direct_url():
additional_metadata["direct_url.json"] = json.dumps(direct_url, indent=2).encode("utf-8")
elif provenance_url := prepared.provenance_url():
additional_metadata["provenance_url.json"] = json.dumps(provenance_url, indent=2).encode("utf-8")
dist_info = install_wheel(
prepared.build(),
wheel,
self.environment,
direct_url=prepared.direct_url(),
additional_metadata=additional_metadata,
install_links=self.use_install_cache and not candidate.req.editable,
rename_pth=self.rename_pth,
)
Expand Down
32 changes: 31 additions & 1 deletion src/pdm/models/candidates.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import dataclasses
import hashlib
import os
import posixpath
import re
import warnings
from functools import cached_property
Expand All @@ -21,6 +22,7 @@
from pdm.models.reporter import BaseReporter
from pdm.models.requirements import (
FileRequirement,
NamedRequirement,
Requirement,
VcsRequirement,
_egg_info_re,
Expand All @@ -47,6 +49,9 @@
from pdm.environments import BaseEnvironment


ALLOWED_HASHES = hashlib.algorithms_guaranteed - {"shake_128", "shake_256", "sha1", "md5"}


def _dist_info_files(whl_zip: ZipFile) -> list[str]:
"""Identify the .dist-info folder inside a wheel ZipFile."""
res = []
Expand Down Expand Up @@ -335,7 +340,9 @@ def revision(self) -> str:
)

def direct_url(self) -> dict[str, Any] | None:
"""PEP 610 direct_url.json data"""
"""PEP 610 direct_url.json data
https://peps.python.org/pep-0610/
"""
req = self.req
if isinstance(req, VcsRequirement):
if req.editable:
Expand Down Expand Up @@ -383,6 +390,29 @@ def direct_url(self) -> dict[str, Any] | None:
else:
return None

def provenance_url(self) -> dict[str, Any] | None:
"""PEP 710 provenance_url.json data
https://peps.python.org/pep-0710/
"""
req = self.req
if not isinstance(req, NamedRequirement):
return None

Check warning on line 399 in src/pdm/models/candidates.py

View check run for this annotation

Codecov / codecov/patch

src/pdm/models/candidates.py#L399

Added line #L399 was not covered by tests
assert self.link is not None
comes_from = self.link.comes_from # e.g. https://pypi.org/simple/requests/
if comes_from is None: # can't determine the index_url
return None
# FIXME: what about find-links source?
index_url = posixpath.dirname(comes_from.rstrip("/")) + "/"
return {
"url": self.link.url_without_fragment,
"index_url": index_url,
"archive_info": {
"hashes": {
name: hashes[0] for name, hashes in (self.link.hash_option or {}).items() if name in ALLOWED_HASHES
},
},
}

def build(self) -> Path:
"""Call PEP 517 build hook to build the candidate into a wheel"""
self._obtain(allow_all=False)
Expand Down

0 comments on commit 5ad7ef1

Please sign in to comment.