Skip to content

Commit

Permalink
feat: make lockfile contain urls instead of filenames (#1203)
Browse files Browse the repository at this point in the history
* feat: make lockfile contain urls instead of filenames

* add release note

Co-authored-by: Frost Ming <mianghong@gmail.com>
  • Loading branch information
betaboon and frostming authored Jul 7, 2022
1 parent 204f96c commit d463726
Show file tree
Hide file tree
Showing 10 changed files with 219 additions and 148 deletions.
1 change: 1 addition & 0 deletions news/1203.break.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Store file URLs instead of filenames in the lock file, bump lock version to `4.0`.
7 changes: 5 additions & 2 deletions pdm/cli/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,7 @@ def format_lockfile(
"""Format lock file from a dict of resolved candidates, a mapping of dependencies
and a collection of package summaries.
"""

packages = tomlkit.aot()
file_hashes = tomlkit.table()
for k, v in sorted(mapping.items()):
Expand All @@ -463,8 +464,10 @@ def format_lockfile(
if key in file_hashes:
continue
array = tomlkit.array().multiline(True)
for filename, hash_value in sorted(v.hashes.items()):
inline = make_inline_table({"file": filename, "hash": hash_value})
for link, hash_value in sorted(
v.hashes.items(), key=lambda l: l[0].filename
):
inline = make_inline_table({"url": link.url, "hash": hash_value})
array.append(inline) # type: ignore
if array:
file_hashes.add(key, array)
Expand Down
2 changes: 1 addition & 1 deletion pdm/formats/requirements.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ def export(
)
)
if options.hashes and getattr(candidate, "hashes", None):
for item in candidate.hashes.values(): # type: ignore
for item in sorted(set(candidate.hashes.values())): # type: ignore
lines.append(f" \\\n --hash={item}")
lines.append("\n")
sources = project.tool_settings.get("source", [])
Expand Down
2 changes: 1 addition & 1 deletion pdm/models/candidates.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ def __init__(
link = req.as_file_link() # type: ignore
self.link = link
self.summary = ""
self.hashes: dict[str, str] | None = None
self.hashes: dict[Link, str] | None = None

self._requires_python: str | None = None
self._prepared: PreparedCandidate | None = None
Expand Down
6 changes: 4 additions & 2 deletions pdm/models/repositories.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
from functools import lru_cache, wraps
from typing import TYPE_CHECKING, Any, Callable, Iterable, Mapping, TypeVar, cast

from unearth import Link

from pdm import termui
from pdm.exceptions import CandidateInfoNotFound, CandidateNotFound
from pdm.models.candidates import Candidate
Expand Down Expand Up @@ -211,7 +213,7 @@ def get_hashes(self, candidate: Candidate) -> dict[str, str] | None:
link = c.prepare(self.environment).link
if not link or link.is_vcs:
continue
result[link.filename] = self._hash_cache.get_hash(link, finder.session)
result[link] = self._hash_cache.get_hash(link, finder.session)
return result or None

def dependency_generators(self) -> Iterable[Callable[[Candidate], CandidateInfo]]:
Expand Down Expand Up @@ -362,7 +364,7 @@ def _read_lockfile(self, lockfile: Mapping[str, Any]) -> None:

for key, hashes in lockfile.get("metadata", {}).get("files", {}).items():
self.file_hashes[tuple(key.split(None, 1))] = { # type: ignore
item["file"]: item["hash"] for item in hashes
Link(item["url"]): item["hash"] for item in hashes
}

def _identify_candidate(self, candidate: Candidate) -> tuple:
Expand Down
2 changes: 1 addition & 1 deletion pdm/project/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ class Project:

PYPROJECT_FILENAME = "pyproject.toml"
DEPENDENCIES_RE = re.compile(r"(?:(.+?)-)?dependencies")
LOCKFILE_VERSION = "3.1"
LOCKFILE_VERSION = "4.0"

def __init__(
self,
Expand Down
12 changes: 9 additions & 3 deletions tests/cli/test_lock.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from unittest.mock import ANY

import pytest
from unearth import Link

from pdm.cli import actions
from pdm.models.requirements import parse_requirement
Expand Down Expand Up @@ -30,16 +31,21 @@ def test_lock_refresh(invoke, project, repository):
assert not project.lockfile["metadata"]["files"].get("requests 2.19.1")
project.add_dependencies({"requests": parse_requirement("requests>=2.0")})
repository.get_hashes = (
lambda c: {"requests-2.19.1-py3-none-any.whl": "sha256:abcdef123456"}
lambda c: {
Link(
"http://example.com/requests-2.19.1-py3-none-any.whl"
): "sha256:abcdef123456"
}
if c.identify() == "requests"
else {}
)
print(project.lockfile)
assert not project.is_lockfile_hash_match()
result = invoke(["lock", "--refresh"], obj=project)
result = invoke(["lock", "--refresh", "-v"], obj=project)
assert result.exit_code == 0
assert project.is_lockfile_hash_match()
assert project.lockfile["metadata"]["files"]["requests 2.19.1"][0] == {
"file": "requests-2.19.1-py3-none-any.whl",
"url": "http://example.com/requests-2.19.1-py3-none-any.whl",
"hash": "sha256:abcdef123456",
}

Expand Down
24 changes: 12 additions & 12 deletions tests/fixtures/projects/demo-package-has-dep-with-extras/pdm.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit d463726

Please sign in to comment.