From abfc6d8b5f19c101729095dab03e17c91be484e1 Mon Sep 17 00:00:00 2001 From: ralbertazzi Date: Mon, 20 Mar 2023 18:18:56 +0100 Subject: [PATCH] feat: use ArtifactCache in get_package_from_url --- src/poetry/console/commands/init.py | 9 ++++++ src/poetry/puzzle/provider.py | 33 +++++++++++++++----- src/poetry/utils/dependency_specification.py | 16 +++++++--- 3 files changed, 47 insertions(+), 11 deletions(-) diff --git a/src/poetry/console/commands/init.py b/src/poetry/console/commands/init.py index fdf48832ce7..68be83b2f19 100644 --- a/src/poetry/console/commands/init.py +++ b/src/poetry/console/commands/init.py @@ -13,6 +13,7 @@ from poetry.console.commands.command import Command from poetry.console.commands.env_command import EnvCommand +from poetry.utils.cache import ArtifactCache from poetry.utils.dependency_specification import parse_dependency_specification @@ -440,11 +441,19 @@ def _parse_requirements(self, requirements: list[str]) -> list[dict[str, Any]]: except (PyProjectException, RuntimeError): cwd = Path.cwd() + try: + artifact_cache = ArtifactCache( + cache_dir=self.poetry.config.artifacts_cache_directory + ) + except PyProjectException: + artifact_cache = None + return [ parse_dependency_specification( requirement=requirement, env=self.env if isinstance(self, EnvCommand) else None, cwd=cwd, + artifact_cache=artifact_cache, ) for requirement in requirements ] diff --git a/src/poetry/puzzle/provider.py b/src/poetry/puzzle/provider.py index cd63bc99d6d..00827e78f70 100644 --- a/src/poetry/puzzle/provider.py +++ b/src/poetry/puzzle/provider.py @@ -18,6 +18,7 @@ from cleo.ui.progress_indicator import ProgressIndicator from poetry.core.constraints.version import EmptyConstraint from poetry.core.constraints.version import Version +from poetry.core.packages.utils.link import Link from poetry.core.packages.utils.utils import get_python_constraint_from_marker from poetry.core.version.markers import AnyMarker from poetry.core.version.markers import EmptyMarker @@ -442,7 +443,7 @@ def get_package_from_directory(cls, directory: Path) -> Package: return PackageInfo.from_directory(path=directory).to_package(root_dir=directory) def _search_for_url(self, dependency: URLDependency) -> Package: - package = self.get_package_from_url(dependency.url) + package = self.get_package_from_url(dependency.url, self._artifact_cache) self.validate_package_for_dependency(dependency=dependency, package=package) @@ -457,15 +458,33 @@ def _search_for_url(self, dependency: URLDependency) -> Package: return package @classmethod - def get_package_from_url(cls, url: str) -> Package: + def get_package_from_url( + cls, url: str, artifact_cache: ArtifactCache | None = None + ) -> Package: file_name = os.path.basename(urllib.parse.urlparse(url).path) - with tempfile.TemporaryDirectory() as temp_dir: - dest = Path(temp_dir) / file_name - download_file(url, dest) - package = cls.get_package_from_file(dest) + link = Link(url) + artifact = ( + artifact_cache.get_cached_archive_for_link(Link(url), strict=True) + if artifact_cache + else None + ) + + with tempfile.TemporaryDirectory() as tmp_dir: + if not artifact: + if artifact_cache: + artifact = ( + artifact_cache.get_cache_directory_for_link(link) / file_name + ) + artifact.parent.mkdir(parents=True, exist_ok=True) + else: + artifact = Path(tmp_dir) / file_name + + download_file(url, artifact) + + package = cls.get_package_from_file(artifact) package.files = [ - {"file": file_name, "hash": "sha256:" + get_file_hash(dest)} + {"file": file_name, "hash": "sha256:" + get_file_hash(artifact)} ] package._source_type = "url" diff --git a/src/poetry/utils/dependency_specification.py b/src/poetry/utils/dependency_specification.py index adcfd3d55ab..2219660d0ed 100644 --- a/src/poetry/utils/dependency_specification.py +++ b/src/poetry/utils/dependency_specification.py @@ -22,6 +22,7 @@ if TYPE_CHECKING: from poetry.core.packages.vcs_dependency import VCSDependency + from poetry.utils.cache import ArtifactCache from poetry.utils.env import Env @@ -58,7 +59,9 @@ def _parse_dependency_specification_git_url( def _parse_dependency_specification_url( - requirement: str, env: Env | None = None + requirement: str, + env: Env | None = None, + artifact_cache: ArtifactCache | None = None, ) -> DependencySpec | None: url_parsed = urllib.parse.urlparse(requirement) if not (url_parsed.scheme and url_parsed.netloc): @@ -68,7 +71,7 @@ def _parse_dependency_specification_url( return _parse_dependency_specification_git_url(requirement, env) if url_parsed.scheme in ["http", "https"]: - package = Provider.get_package_from_url(requirement) + package = Provider.get_package_from_url(requirement, artifact_cache) assert package.source_url is not None return {"name": package.name, "url": package.source_url} @@ -196,7 +199,10 @@ def pep508_to_dependency_specification(requirement: str) -> DependencySpec | Non def parse_dependency_specification( - requirement: str, env: Env | None = None, cwd: Path | None = None + requirement: str, + env: Env | None = None, + cwd: Path | None = None, + artifact_cache: ArtifactCache | None = None, ) -> DependencySpec: requirement = requirement.strip() cwd = cwd or Path.cwd() @@ -213,7 +219,9 @@ def parse_dependency_specification( requirement, _ = requirement.split("[") specification = ( - _parse_dependency_specification_url(requirement, env=env) + _parse_dependency_specification_url( + requirement, env=env, artifact_cache=artifact_cache + ) or _parse_dependency_specification_path(requirement, cwd=cwd) or _parse_dependency_specification_simple(requirement) )