Commit 0ca8b7e9 by George Waters Committed by GitHub

Calculate and store hash for url dependencies (#7121)

parent f594246c
......@@ -15,7 +15,6 @@ from typing import TYPE_CHECKING
from typing import Any
from cleo.io.null_io import NullIO
from poetry.core.packages.file_dependency import FileDependency
from poetry.core.packages.utils.link import Link
from poetry.core.pyproject.toml import PyProjectTOML
......@@ -28,6 +27,7 @@ from poetry.utils._compat import decode
from poetry.utils.authenticator import Authenticator
from poetry.utils.env import EnvCommandError
from poetry.utils.helpers import atomic_open
from poetry.utils.helpers import get_file_hash
from poetry.utils.helpers import pluralize
from poetry.utils.helpers import remove_directory
from poetry.utils.pip import pip_install
......@@ -666,8 +666,7 @@ class Executor:
@staticmethod
def _validate_archive_hash(archive: Path, package: Package) -> str:
file_dep = FileDependency(package.name, archive)
archive_hash: str = "sha256:" + file_dep.hash()
archive_hash: str = "sha256:" + get_file_hash(archive)
known_hashes = {f["hash"] for f in package.files}
if archive_hash not in known_hashes:
......
......@@ -33,6 +33,7 @@ from poetry.packages.package_collection import PackageCollection
from poetry.puzzle.exceptions import OverrideNeeded
from poetry.repositories.exceptions import PackageNotFound
from poetry.utils.helpers import download_file
from poetry.utils.helpers import get_file_hash
from poetry.vcs.git import Git
......@@ -396,7 +397,10 @@ class Provider:
package.root_dir = dependency.base
package.files = [
{"file": dependency.path.name, "hash": "sha256:" + dependency.hash()}
{
"file": dependency.path.name,
"hash": "sha256:" + get_file_hash(dependency.full_path),
}
]
return package
......@@ -453,6 +457,10 @@ class Provider:
download_file(url, dest)
package = cls.get_package_from_file(dest)
package.files = [
{"file": file_name, "hash": "sha256:" + get_file_hash(dest)}
]
package._source_type = "url"
package._source_url = url
......
from __future__ import annotations
import hashlib
import io
import os
import shutil
import stat
......@@ -252,3 +254,12 @@ def get_real_windows_path(path: str | Path) -> Path:
path = path.resolve()
return path
def get_file_hash(path: Path, hash_name: str = "sha256") -> str:
h = hashlib.new(hash_name)
with path.open("rb") as fp:
for content in iter(lambda: fp.read(io.DEFAULT_BUFFER_SIZE), b""):
h.update(content)
return h.hexdigest()
......@@ -5,7 +5,9 @@ description = ""
category = "main"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
files = []
files = [
{file = "demo-0.1.0-py2.py3-none-any.whl", hash = "sha256:70e704135718fffbcbf61ed1fc45933cfd86951a744b681000eaaa75da31f17a"}
]
[package.source]
type = "url"
......@@ -25,8 +27,9 @@ description = ""
category = "main"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
files = []
files = [
{file = "demo-0.1.0.tar.gz", hash = "sha256:72e8531e49038c5f9c4a837b088bfcb8011f4a9f76335c8f0654df6ac539b3d6"}
]
[package.source]
type = "url"
url = "https://python-poetry.org/distributions/demo-0.1.0.tar.gz"
......
......@@ -5,7 +5,9 @@ description = ""
category = "main"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
files = []
files = [
{file = "demo-0.1.0-py2.py3-none-any.whl", hash = "sha256:70e704135718fffbcbf61ed1fc45933cfd86951a744b681000eaaa75da31f17a"}
]
[package.source]
type = "url"
......
from __future__ import annotations
from pathlib import Path
from typing import TYPE_CHECKING
import pytest
from poetry.core.utils.helpers import parse_requires
from poetry.utils.helpers import get_file_hash
if TYPE_CHECKING:
from tests.types import FixtureDirGetter
def test_parse_requires():
requires = """\
......@@ -57,3 +68,68 @@ isort@ git+git://github.com/timothycrosley/isort.git@e63ae06ec7d70b06df9e5283576
]
# fmt: on
assert result == expected
def test_default_hash(fixture_dir: FixtureDirGetter) -> None:
root_dir = Path(__file__).parent.parent.parent
file_path = root_dir / fixture_dir("distributions/demo-0.1.0.tar.gz")
sha_256 = "72e8531e49038c5f9c4a837b088bfcb8011f4a9f76335c8f0654df6ac539b3d6"
assert get_file_hash(file_path) == sha_256
try:
from hashlib import algorithms_guaranteed
except ImportError:
algorithms_guaranteed = {"md5", "sha1", "sha224", "sha256", "sha384", "sha512"}
@pytest.mark.parametrize(
"hash_name,expected",
[
(hash_name, value)
for hash_name, value in [
("sha224", "972d02f36539a98599aed0566bc8aaf3e6701f4e895dd797d8f5248e"),
(
"sha3_512",
"c04ee109ae52d6440445e24dbd6d244a1d0f0289ef79cb7ba9bc3c139c0237169af9a8f61cd1cf4fc17f853ddf84f97c475ac5bb6c91a4aff0b825b884d4896c", # noqa: E501
),
(
"blake2s",
"c336ecbc9d867c9d860accfba4c3723c51c4b5c47a1e0a955e1c8df499e36741",
),
(
"sha3_384",
"d4abb2459941369aabf8880c5287b7eeb80678e14f13c71b9ecf64c772029dc3f93939590bea9ecdb51a1d1a74fefc5a", # noqa: E501
),
(
"blake2b",
"48e70abac547ab38e2330e6e6743a0c0f6274dcaa6df2c98135a78a9dd5b04a072d551fc3851b34da03eb0bf50dd71c7f32a8c36956e99fd6c66491bc7844800", # noqa: E501
),
(
"sha256",
"72e8531e49038c5f9c4a837b088bfcb8011f4a9f76335c8f0654df6ac539b3d6",
),
(
"sha512",
"e08a00a4b86358e49a318e7e3ba7a3d2fabdd17a2fef95559a0af681ea07ab1296b0b8e11e645297da296290661dc07ae3c8f74eab66bd18a80dce0c0ccb355b", # noqa: E501
),
(
"sha384",
"aa3144e28c6700a83247e8ec8711af5d3f5f75997990d48ec41e66bd275b3d0e19ee6f2fe525a358f874aa717afd06a9", # noqa: E501
),
("sha3_224", "64bfc6e4125b4c6d67fd88ad1c7d1b5c4dc11a1970e433cd576c91d4"),
("sha1", "4c057579005ac3e68e951a11ffdc4b27c6ae16af"),
(
"sha3_256",
"ba3d2a964b0680b6dc9565a03952e29c294c785d5a2307d3e2d785d73b75ed7e",
),
]
if hash_name in algorithms_guaranteed
],
)
def test_guaranteed_hash(
hash_name: str, expected: str, fixture_dir: FixtureDirGetter
) -> None:
root_dir = Path(__file__).parent.parent.parent
file_path = root_dir / fixture_dir("distributions/demo-0.1.0.tar.gz")
assert get_file_hash(file_path, hash_name) == expected
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment