From 4f3c1caf4fb640b5a59a435d208405f6dc279715 Mon Sep 17 00:00:00 2001 From: Felix Schwarz Date: Tue, 24 Oct 2023 18:14:41 +0200 Subject: [PATCH] support also "file://" urls for private pip repositories --- conda_lock/_vendor/requests_file.py | 2 + conda_lock/interfaces/vendored_poetry.py | 7 +++ .../interfaces/vendored_requests_file.py | 6 +++ conda_lock/pypi_solver.py | 45 +++++++++++++++---- 4 files changed, 52 insertions(+), 8 deletions(-) create mode 100644 conda_lock/interfaces/vendored_requests_file.py diff --git a/conda_lock/_vendor/requests_file.py b/conda_lock/_vendor/requests_file.py index d9bf5b862..e850ed0c8 100644 --- a/conda_lock/_vendor/requests_file.py +++ b/conda_lock/_vendor/requests_file.py @@ -82,6 +82,8 @@ def send(self, request, **kwargs): if path_drive and not os.path.splitdrive(path): path = os.sep + os.path.join(path_drive, *path_parts) + if os.path.isdir(path): + path = os.path.join(path, "index.html") # Use io.open since we need to add a release_conn method, and # methods can't be added to file objects in python 2. resp.raw = io.open(path, "rb") diff --git a/conda_lock/interfaces/vendored_poetry.py b/conda_lock/interfaces/vendored_poetry.py index ac04c220e..e8e9bd253 100644 --- a/conda_lock/interfaces/vendored_poetry.py +++ b/conda_lock/interfaces/vendored_poetry.py @@ -1,3 +1,4 @@ +from conda_lock._vendor.poetry.config.config import Config from conda_lock._vendor.poetry.core.packages import Dependency as PoetryDependency from conda_lock._vendor.poetry.core.packages import Package as PoetryPackage from conda_lock._vendor.poetry.core.packages import ( @@ -9,16 +10,22 @@ from conda_lock._vendor.poetry.installation.chooser import Chooser from conda_lock._vendor.poetry.installation.operations.uninstall import Uninstall from conda_lock._vendor.poetry.puzzle import Solver as PoetrySolver +from conda_lock._vendor.poetry.repositories.legacy_repository import LegacyRepository from conda_lock._vendor.poetry.repositories.pool import Pool from conda_lock._vendor.poetry.repositories.pypi_repository import PyPiRepository from conda_lock._vendor.poetry.repositories.repository import Repository from conda_lock._vendor.poetry.utils.env import Env +from conda_lock._vendor.poetry.utils.helpers import get_cert, get_client_cert __all__ = [ + "get_cert", + "get_client_cert", "Chooser", + "Config", "Env", "Factory", + "LegacyRepository", "PoetryDependency", "PoetryPackage", "PoetryProjectPackage", diff --git a/conda_lock/interfaces/vendored_requests_file.py b/conda_lock/interfaces/vendored_requests_file.py new file mode 100644 index 000000000..9e0cbdb48 --- /dev/null +++ b/conda_lock/interfaces/vendored_requests_file.py @@ -0,0 +1,6 @@ +from conda_lock._vendor.requests_file import FileAdapter + + +__all__ = [ + "FileAdapter", +] diff --git a/conda_lock/pypi_solver.py b/conda_lock/pypi_solver.py index 9fe7f742e..a432b6e38 100644 --- a/conda_lock/pypi_solver.py +++ b/conda_lock/pypi_solver.py @@ -4,7 +4,9 @@ from pathlib import Path from posixpath import expandvars from typing import TYPE_CHECKING, Dict, List, Optional -from urllib.parse import urldefrag, urlparse, urlsplit, urlunsplit +from urllib.parse import urldefrag, urlsplit, urlunsplit + +import requests from clikit.api.io.flags import VERY_VERBOSE from clikit.io import ConsoleIO, NullIO @@ -12,8 +14,10 @@ from conda_lock.interfaces.vendored_poetry import ( Chooser, + Config, Env, Factory, + LegacyRepository, PoetryDependency, PoetryPackage, PoetryProjectPackage, @@ -24,7 +28,10 @@ PyPiRepository, Repository, Uninstall, + get_cert, + get_client_cert, ) +from conda_lock.interfaces.vendored_requests_file import FileAdapter from conda_lock.lockfile import apply_categories from conda_lock.lockfile.v2prelim.models import ( DependencySource, @@ -384,6 +391,28 @@ def solve_pypi( return {dep.name: dep for dep in requirements} +class CondaLockLegacyRepository(LegacyRepository): + @property + def session(self) -> requests.Session: + _session = super().session + _session.mount("file://", FileAdapter()) + return _session + + +def create_legacy_repository( + source: Dict[str, str], auth_config: Config +) -> LegacyRepository: + name = source["name"] + url = source["url"] + return CondaLockLegacyRepository( + name, + url, + config=auth_config, + cert=get_cert(auth_config, name), + client_cert=get_client_cert(auth_config, name), + ) + + def _prepare_repositories_pool( allow_pypi_requests: bool, pip_repositories: Optional[List[PipRepository]] = None ) -> Pool: @@ -397,13 +426,13 @@ def _prepare_repositories_pool( """ factory = Factory() config = factory.create_config() - repos = [ - factory.create_legacy_repository( - {"name": pip_repository.name, "url": expandvars(pip_repository.url)}, - config, - ) - for pip_repository in pip_repositories or [] - ] + [ + + legacy_repos = [] + for pip_repository in pip_repositories or []: + repo_cfg = {"name": pip_repository.name, "url": expandvars(pip_repository.url)} + legacy_repo = create_legacy_repository(repo_cfg, config) + legacy_repos.append(legacy_repo) + repos = legacy_repos + [ factory.create_legacy_repository( {"name": source[0], "url": source[1]["url"]}, config )