From f6f120da104a1579255f9e3f54750a8e8f5d8746 Mon Sep 17 00:00:00 2001 From: macro128 <29261232+macro128@users.noreply.github.com> Date: Sun, 19 May 2024 21:15:14 -0300 Subject: [PATCH 01/18] only modify pdm settings if plugin is active --- src/pdm_conda/models/config.py | 51 +++++++++++++++++++++++++++++----- 1 file changed, 44 insertions(+), 7 deletions(-) diff --git a/src/pdm_conda/models/config.py b/src/pdm_conda/models/config.py index 468d1f1..2d5a790 100644 --- a/src/pdm_conda/models/config.py +++ b/src/pdm_conda/models/config.py @@ -280,15 +280,52 @@ def is_initialized(self): @is_initialized.setter def is_initialized(self, value): - if value: - config = self._project.project_config - config["python.use_venv"] = True - config["python.use_pyenv"] = False - config["venv.backend"] = self.runner - config.setdefault("venv.in_project", False) - os.environ.pop("PDM_IGNORE_ACTIVE_VENV", None) self._initialized = value + @staticmethod + def check_active(func): + """Decorator that checks if the plugin is active and temporarily updates the project config.""" + + @wraps(func) + def decorator(*args, **kwargs): + from pdm_conda.project import CondaProject + + project = None + for arg in args: + if isinstance(arg, CondaProject): + project = arg + break + + if project is None: + return func(*args, **kwargs) + + config = project.conda_config + if not config.is_initialized: + return func(*args, **kwargs) + + project_config = project.project_config + old_configs = { + name: getattr(project_config, name, None) + for name in ("python.use_venv", "python.use_pyenv", "venv.backend", "venv.in_project") + } + active_venv = os.environ.pop("CONDA_DEFAULT_ENV", None) + try: + for name, value in zip(old_configs, (True, False, config.runner, False), strict=False): + if old_configs[name] != value: + setattr(project_config, name, value) + return func(*args, **kwargs) + finally: + for name, value in old_configs.items(): + if value is not None: + if project_config[name] != value: + project_config[name] = value + elif name in project_config: + del project_config[name] + if active_venv is not None: + os.environ["CONDA_DEFAULT_ENV"] = active_venv + + return decorator + @contextmanager def with_conda_venv_location(self): """Context manager that ensures the PDM venv location is set to the detected Conda environment if was the From 58a53b237e1e8f0b63c7d9ec39cbb8d704a63398 Mon Sep 17 00:00:00 2001 From: macro128 <29261232+macro128@users.noreply.github.com> Date: Sun, 19 May 2024 21:28:13 -0300 Subject: [PATCH 02/18] only use plugin behaviour if is active --- src/pdm_conda/cli/commands/add.py | 2 + src/pdm_conda/cli/commands/init.py | 2 +- src/pdm_conda/cli/commands/install.py | 2 + src/pdm_conda/cli/commands/list.py | 2 + src/pdm_conda/cli/commands/lock.py | 2 + src/pdm_conda/cli/commands/remove.py | 2 + src/pdm_conda/cli/commands/update.py | 2 + src/pdm_conda/cli/commands/use.py | 2 + src/pdm_conda/cli/commands/venv/backends.py | 10 ++- src/pdm_conda/cli/commands/venv/create.py | 2 +- src/pdm_conda/cli/commands/venv/list.py | 2 + src/pdm_conda/cli/commands/venv/utils.py | 4 +- src/pdm_conda/conda.py | 11 ++- src/pdm_conda/environments/conda.py | 4 +- src/pdm_conda/installers/manager.py | 4 +- src/pdm_conda/installers/synchronizers.py | 3 +- src/pdm_conda/models/repositories.py | 13 +++- src/pdm_conda/project/core.py | 74 +++++++++++++-------- src/pdm_conda/project/project_file.py | 1 + src/pdm_conda/resolvers.py | 4 +- 20 files changed, 106 insertions(+), 42 deletions(-) diff --git a/src/pdm_conda/cli/commands/add.py b/src/pdm_conda/cli/commands/add.py index d083ee7..2c53895 100644 --- a/src/pdm_conda/cli/commands/add.py +++ b/src/pdm_conda/cli/commands/add.py @@ -7,6 +7,7 @@ from pdm.exceptions import RequirementError from pdm_conda.cli.utils import remove_quotes +from pdm_conda.models.config import PluginConfig from pdm_conda.models.requirements import CondaRequirement, is_conda_managed, parse_requirement from pdm_conda.project import CondaProject @@ -64,6 +65,7 @@ def add_arguments(self, parser: argparse.ArgumentParser) -> None: ) conda_group.add_to_parser(parser) + @PluginConfig.check_active def handle(self, project: Project, options: argparse.Namespace) -> None: project = cast(CondaProject, project) config = project.conda_config diff --git a/src/pdm_conda/cli/commands/init.py b/src/pdm_conda/cli/commands/init.py index 9572a92..b8e013b 100644 --- a/src/pdm_conda/cli/commands/init.py +++ b/src/pdm_conda/cli/commands/init.py @@ -54,7 +54,7 @@ def handle(self, project: Project, options: argparse.Namespace) -> None: config.channels.append(channel) overridden_configs["channels"] = config.channels - super().handle(project, options) + config.check_active(super().handle)(project, options) with config.write_project_config(): for key, value in overridden_configs.items(): setattr(config, key, value) diff --git a/src/pdm_conda/cli/commands/install.py b/src/pdm_conda/cli/commands/install.py index 3e051a9..64c0a75 100644 --- a/src/pdm_conda/cli/commands/install.py +++ b/src/pdm_conda/cli/commands/install.py @@ -4,6 +4,7 @@ from pdm.cli.commands.install import Command as BaseCommand +from pdm_conda.models.config import PluginConfig from pdm_conda.project import CondaProject if TYPE_CHECKING: @@ -16,6 +17,7 @@ class Command(BaseCommand): description = BaseCommand.__doc__ name = "install" + @PluginConfig.check_active def handle(self, project: Project, options: argparse.Namespace) -> None: project = cast(CondaProject, project) if options.groups and ":all" in options.groups: diff --git a/src/pdm_conda/cli/commands/list.py b/src/pdm_conda/cli/commands/list.py index 8bf8152..d570b1a 100644 --- a/src/pdm_conda/cli/commands/list.py +++ b/src/pdm_conda/cli/commands/list.py @@ -5,6 +5,7 @@ from pdm.cli.commands.list import Command as BaseCommand from pdm_conda.cli.utils import ensure_logger +from pdm_conda.models.config import PluginConfig if TYPE_CHECKING: import argparse @@ -16,6 +17,7 @@ class Command(BaseCommand): description = BaseCommand.__doc__ name = "list" + @PluginConfig.check_active def handle(self, project: Project, options: argparse.Namespace) -> None: with ensure_logger(project, "list"): super().handle(project, options) diff --git a/src/pdm_conda/cli/commands/lock.py b/src/pdm_conda/cli/commands/lock.py index f4363b4..a93ecd1 100644 --- a/src/pdm_conda/cli/commands/lock.py +++ b/src/pdm_conda/cli/commands/lock.py @@ -5,6 +5,7 @@ from pdm.cli.commands.lock import Command as BaseCommand from pdm.project.lockfile import FLAG_CROSS_PLATFORM +from pdm_conda.models.config import PluginConfig from pdm_conda.project import CondaProject if TYPE_CHECKING: @@ -17,6 +18,7 @@ class Command(BaseCommand): description = BaseCommand.__doc__ name = "lock" + @PluginConfig.check_active def handle(self, project: Project, options: argparse.Namespace) -> None: project = cast(CondaProject, project) if project.conda_config.is_initialized: diff --git a/src/pdm_conda/cli/commands/remove.py b/src/pdm_conda/cli/commands/remove.py index a7bc5cb..c6c0d9a 100644 --- a/src/pdm_conda/cli/commands/remove.py +++ b/src/pdm_conda/cli/commands/remove.py @@ -5,6 +5,7 @@ from pdm.cli.commands.remove import Command as BaseCommand from pdm_conda.cli.utils import remove_quotes +from pdm_conda.models.config import PluginConfig from pdm_conda.models.requirements import parse_requirement from pdm_conda.project import CondaProject @@ -18,6 +19,7 @@ class Command(BaseCommand): description = BaseCommand.__doc__ name = "remove" + @PluginConfig.check_active def handle(self, project: Project, options: argparse.Namespace) -> None: if options.group is None: options.group = "dev" if options.dev else "default" diff --git a/src/pdm_conda/cli/commands/update.py b/src/pdm_conda/cli/commands/update.py index 9f77875..92e1cad 100644 --- a/src/pdm_conda/cli/commands/update.py +++ b/src/pdm_conda/cli/commands/update.py @@ -5,6 +5,7 @@ from pdm.cli.commands.update import Command as BaseCommand from pdm.models.specifiers import get_specifier +from pdm_conda.models.config import PluginConfig from pdm_conda.models.requirements import CondaRequirement from pdm_conda.project import CondaProject @@ -18,6 +19,7 @@ class Command(BaseCommand): description = BaseCommand.__doc__ name = "update" + @PluginConfig.check_active def handle(self, project: Project, options: argparse.Namespace) -> None: super().handle(project=project, options=options) project = cast(CondaProject, project) diff --git a/src/pdm_conda/cli/commands/use.py b/src/pdm_conda/cli/commands/use.py index cd88797..f4aacd7 100644 --- a/src/pdm_conda/cli/commands/use.py +++ b/src/pdm_conda/cli/commands/use.py @@ -7,6 +7,7 @@ from pdm.utils import is_conda_base from pdm_conda.cli.utils import ensure_logger +from pdm_conda.models.config import PluginConfig from pdm_conda.project import CondaProject if TYPE_CHECKING: @@ -19,6 +20,7 @@ class Command(BaseCommand): description = BaseCommand.__doc__ name = "use" + @PluginConfig.check_active def handle(self, project: Project, options: argparse.Namespace) -> None: project = cast(CondaProject, project) conda_base = is_conda_base() diff --git a/src/pdm_conda/cli/commands/venv/backends.py b/src/pdm_conda/cli/commands/venv/backends.py index 7100076..ee2f49c 100644 --- a/src/pdm_conda/cli/commands/venv/backends.py +++ b/src/pdm_conda/cli/commands/venv/backends.py @@ -6,7 +6,7 @@ from pdm_conda.cli.utils import ensure_logger from pdm_conda.conda import conda_create, conda_env_remove -from pdm_conda.models.config import CondaRunner +from pdm_conda.models.config import CondaRunner, PluginConfig from pdm_conda.models.requirements import parse_requirement from pdm_conda.project import CondaProject @@ -20,6 +20,7 @@ def __init__(self, project: Project, python: str | None) -> None: super().__init__(project, python) self.project = cast(CondaProject, project) + @PluginConfig.check_active def create( self, name: str | None = None, @@ -32,6 +33,7 @@ def create( with ensure_logger(self.project, "conda_create"): return super().create(name, args, force, in_project, prompt, with_pip) + @PluginConfig.check_active def get_location(self, name: str | None) -> Path: with self.project.conda_config.with_conda_venv_location() as (venv_location, _): if conda_name := (name is not None and name.startswith("conda:")): @@ -42,12 +44,16 @@ def get_location(self, name: str | None) -> Path: location = super().get_location(name) return location + @PluginConfig.check_active def _ensure_clean(self, location: Path, force: bool = False) -> None: - if location.is_dir() and force: + if self.project.conda_config.is_initialized and location.is_dir() and force: conda_env_remove(self.project, prefix=location) super()._ensure_clean(location, force) + @PluginConfig.check_active def perform_create(self, location: Path, args: tuple[str, ...], prompt: str | None = None) -> None: + if not self.project.conda_config.is_initialized: + return super().perform_create(location, args, prompt) if self.python: python_ver = self.python else: diff --git a/src/pdm_conda/cli/commands/venv/create.py b/src/pdm_conda/cli/commands/venv/create.py index f5f82fe..21005bf 100644 --- a/src/pdm_conda/cli/commands/venv/create.py +++ b/src/pdm_conda/cli/commands/venv/create.py @@ -58,7 +58,7 @@ def handle(self, project: Project, options: argparse.Namespace) -> None: conda_config.channels.append(channel) overridden_configs["channels"] = conda_config.channels - super().handle(project, options) + conda_config.check_active(super().handle)(project, options) # if inside a project ensure saving conda runner if conda_project and project.pyproject.exists(): diff --git a/src/pdm_conda/cli/commands/venv/list.py b/src/pdm_conda/cli/commands/venv/list.py index d3b3188..65d052c 100644 --- a/src/pdm_conda/cli/commands/venv/list.py +++ b/src/pdm_conda/cli/commands/venv/list.py @@ -5,6 +5,7 @@ from pdm.cli.commands.venv.list import ListCommand as BaseCommand from pdm_conda.cli.utils import ensure_logger +from pdm_conda.models.config import PluginConfig if TYPE_CHECKING: import argparse @@ -14,6 +15,7 @@ class ListCommand(BaseCommand): description = BaseCommand.__doc__ + @PluginConfig.check_active def handle(self, project: Project, options: argparse.Namespace) -> None: from pdm_conda.project import CondaProject diff --git a/src/pdm_conda/cli/commands/venv/utils.py b/src/pdm_conda/cli/commands/venv/utils.py index 0ea40a2..76d8fc3 100644 --- a/src/pdm_conda/cli/commands/venv/utils.py +++ b/src/pdm_conda/cli/commands/venv/utils.py @@ -1,6 +1,5 @@ from __future__ import annotations -import functools import sys from typing import TYPE_CHECKING @@ -9,6 +8,7 @@ from pdm.models.venv import VirtualEnv from pdm_conda.conda import conda_env_list +from pdm_conda.models.config import PluginConfig from pdm_conda.utils import get_python_dir if TYPE_CHECKING: @@ -49,7 +49,7 @@ def find_pythons(self) -> Iterable[PythonVersion]: def wrap_iter_venvs(func): - @functools.wraps(func) + @PluginConfig.check_active def wrapper(project): yield from func(project) if project.conda_config.is_initialized: diff --git a/src/pdm_conda/conda.py b/src/pdm_conda/conda.py index c7ec7d7..dddf62e 100644 --- a/src/pdm_conda/conda.py +++ b/src/pdm_conda/conda.py @@ -20,7 +20,7 @@ from pdm_conda import logger from pdm_conda.models.candidates import CondaCandidate, parse_channel from pdm_conda.models.conda import ChannelSorter -from pdm_conda.models.config import CondaRunner +from pdm_conda.models.config import CondaRunner, PluginConfig from pdm_conda.models.requirements import CondaRequirement, parse_conda_version, parse_requirement from pdm_conda.models.setup import CondaSetupDistribution from pdm_conda.utils import fix_path, normalize_name @@ -280,6 +280,7 @@ def _conda_search(project: CondaProject, requirement: str, channels: tuple[str], return packages +@PluginConfig.check_active def conda_search( project: CondaProject, requirement: CondaRequirement | str, @@ -311,6 +312,7 @@ def conda_search( return _parse_candidates(project, packages, requirement) +@PluginConfig.check_active def conda_create( project: CondaProject, requirements: Iterable[CondaRequirement], @@ -418,6 +420,7 @@ def conda_create( raise +@PluginConfig.check_active def conda_env_remove(project: CondaProject, prefix: Path | str | None = None, name: str = "", dry_run: bool = False): """Removes environment using conda. @@ -444,6 +447,7 @@ def conda_env_remove(project: CondaProject, prefix: Path | str | None = None, na run_conda(command, exception_cls=VirtualenvCreateError, exception_msg="Error removing environment") +@PluginConfig.check_active def conda_env_list(project: CondaProject) -> list[Path]: """List Conda environments. @@ -480,6 +484,7 @@ def _conda_install( run_conda(command + ["--json"], exception_cls=exception_cls, exception_msg="", **kwargs) +@PluginConfig.check_active def conda_install( project: CondaProject, packages: str | list[str], @@ -509,6 +514,7 @@ def conda_install( _conda_install(command, packages, dry_run=dry_run, explicit=True) +@PluginConfig.check_active def conda_uninstall( project: CondaProject, packages: str | list[str], @@ -539,6 +545,7 @@ def not_initialized_warning(project): ) +@PluginConfig.check_active def conda_info(project: CondaProject) -> dict: """Get conda info containing virtual packages, default channels and packages. @@ -563,6 +570,7 @@ def conda_info(project: CondaProject) -> dict: return res +@PluginConfig.check_active def conda_base_path(project: CondaProject) -> Path: """Get conda base environment path :param project: PDM project :return: Conda base environment path.""" config = project.conda_config @@ -581,6 +589,7 @@ def conda_base_path(project: CondaProject) -> Path: return res +@PluginConfig.check_active def conda_list(project: CondaProject) -> dict[str, CondaSetupDistribution]: """List conda installed packages. diff --git a/src/pdm_conda/environments/conda.py b/src/pdm_conda/environments/conda.py index 542fce1..fc105be 100644 --- a/src/pdm_conda/environments/conda.py +++ b/src/pdm_conda/environments/conda.py @@ -25,7 +25,6 @@ class CondaEnvironment(PythonEnvironment): def __init__(self, project: Project) -> None: super().__init__(project) - self._env_dependencies: dict[str, Requirement] | None = None if self.project.conda_config.is_initialized: self.python_requires &= PySpecSet(f"=={self.interpreter.version}") self.prefix = str(get_python_dir(fix_path(self.interpreter.path))) @@ -33,6 +32,7 @@ def __init__(self, project: Project) -> None: self._platform: str | None = None self._default_channels: list[str] | None = None self._base_env: Path | None = None + self._env_dependencies: dict[str, Requirement] | None = None @property def virtual_packages(self) -> set[CondaRequirement]: @@ -97,4 +97,4 @@ def env_dependencies(self) -> dict[str, Requirement]: dry_run=True, ) - return self._env_dependencies + return self._env_dependencies # type: ignore diff --git a/src/pdm_conda/installers/manager.py b/src/pdm_conda/installers/manager.py index 9129c8c..1fac3e3 100644 --- a/src/pdm_conda/installers/manager.py +++ b/src/pdm_conda/installers/manager.py @@ -1,11 +1,10 @@ from __future__ import annotations -from typing import TYPE_CHECKING, cast +from typing import TYPE_CHECKING from pdm.installers import InstallManager from pdm_conda.conda import conda_install, conda_uninstall -from pdm_conda.environments import CondaEnvironment from pdm_conda.models.candidates import CondaCandidate from pdm_conda.models.setup import CondaSetupDistribution @@ -25,7 +24,6 @@ def __init__( rename_pth: bool = False, ) -> None: super().__init__(environment, use_install_cache=use_install_cache, rename_pth=rename_pth) - self.environment = cast(CondaEnvironment, environment) self._num_install = 0 self._num_remove = 0 self._batch_install: list[str] = [] diff --git a/src/pdm_conda/installers/synchronizers.py b/src/pdm_conda/installers/synchronizers.py index 6dfaa86..8af4a23 100644 --- a/src/pdm_conda/installers/synchronizers.py +++ b/src/pdm_conda/installers/synchronizers.py @@ -1,7 +1,7 @@ from __future__ import annotations from functools import cached_property -from typing import TYPE_CHECKING, cast +from typing import TYPE_CHECKING from pdm.installers import Synchronizer @@ -45,7 +45,6 @@ def __init__( fail_fast, use_install_cache, ) - self.environment = cast(CondaEnvironment, environment) self.parallel = bool(self.parallel) # type: ignore @cached_property diff --git a/src/pdm_conda/models/repositories.py b/src/pdm_conda/models/repositories.py index 20a14b5..4a1ee4c 100644 --- a/src/pdm_conda/models/repositories.py +++ b/src/pdm_conda/models/repositories.py @@ -55,7 +55,10 @@ def is_conda_managed(self, requirement: Requirement, excluded_identifiers: set[s :param requirement: requirement to evaluate :param excluded_identifiers: identifiers to exclude """ - if not isinstance(self.environment, CondaEnvironment): + if ( + not isinstance(self.environment, CondaEnvironment) + or not self.environment.project.conda_config.is_initialized + ): return False from pdm_conda.models.requirements import is_conda_managed as _is_conda_managed @@ -249,6 +252,14 @@ def _read_lockfile(self, lockfile: Mapping[str, Any]) -> None: pypi_packages.append(package) super()._read_lockfile({"package": pypi_packages, **{k: v for k, v in lockfile.items() if k != "package"}}) + if conda_packages and ( + isinstance(self.environment, CondaEnvironment) and not self.environment.project.conda_config.is_initialized + ): + raise CondaResolutionError( + "Conda packages found in lock file but Conda is not initialized, " + "you should delete the lock file or initialize pdm-conda.", + ) + for package in conda_packages: can = CondaCandidate.from_lock_package(package) can_id = self._identify_candidate(can) diff --git a/src/pdm_conda/project/core.py b/src/pdm_conda/project/core.py index 9141b91..a1f8884 100644 --- a/src/pdm_conda/project/core.py +++ b/src/pdm_conda/project/core.py @@ -3,7 +3,7 @@ from functools import cached_property from typing import TYPE_CHECKING, cast -from pdm.exceptions import ProjectError +from pdm.exceptions import PdmUsageError, ProjectError from pdm.models.python import PythonInfo from pdm.project import Project from pdm.project.lockfile import Lockfile @@ -34,7 +34,6 @@ def __init__( is_global: bool = False, global_config: str | Path | None = None, ) -> None: - from pdm_conda.environments import CondaEnvironment from pdm_conda.installers.manager import CondaInstallManager from pdm_conda.installers.synchronizers import CondaSynchronizer from pdm_conda.models.repositories import LockedCondaRepository, PyPICondaRepository @@ -46,7 +45,6 @@ def __init__( self.core.synchronizer_class = CondaSynchronizer self.core.resolver_class = CondaResolver self.locked_repository_class = LockedCondaRepository - self.environment_class = CondaEnvironment self._conda_mapping: dict[str, str] = {} self._pypi_mapping: dict[str, str] = {} self.conda_config = PluginConfig.load_config(self) @@ -95,7 +93,12 @@ def locked_repository(self) -> LockedRepository: return self.locked_repository_class(lockfile=lockfile, sources=self.sources, environment=self.environment) # type: ignore @Project.python.setter + @PluginConfig.check_active def python(self, value: PythonInfo) -> None: + if not self.conda_config.is_initialized: + Project.python.fset(self, value) + return + self._python = value self._saved_python = value.path.as_posix() self.environment = None @@ -150,12 +153,17 @@ def iter_groups(self, dev: bool = True) -> Iterable[str]: return groups def get_dependencies(self, group: str | None = None) -> dict[str, Requirement]: - result = super().get_dependencies(group) if group in super().iter_groups() else {} - config = self.conda_config - group = group or "default" + if not config.is_initialized: + return super().get_dependencies(group) + group = group or "default" dev = group not in config.optional_dependencies + try: + result = super().get_dependencies(group) + except PdmUsageError: + result = {} + if group in config.optional_dependencies and group in config.dev_dependencies: self.core.ui.echo( f"The {group} group exists in both [optional-dependencies] " @@ -200,36 +208,46 @@ def add_dependencies( requirements = {n: r for n, r in requirements.items() if n not in conda_requirements} | { n: r.as_named_requirement() for n, r in conda_requirements.items() if r.is_python_package } - if self.conda_config.as_default_manager: - conda_requirements = { - n: r for n, r in conda_requirements.items() if not r.is_python_package or r.channel or r.build_string - } - if conda_requirements: - deps = self.get_conda_pyproject_dependencies(to_group, dev, set_defaults=True) - python_deps, _ = self.use_pyproject_dependencies(to_group, dev) - cast(Array, deps).multiline(True) - for name, dep in conda_requirements.items(): - matched_index = next((i for i, r in enumerate(deps) if dep.matches(f"conda:{r}")), None) - req = dep.as_line(with_channel=True) - if matched_index is None: - deps.append(req) - else: - deps[matched_index] = req - if name not in requirements: - matched_index = next((i for i, r in enumerate(python_deps) if dep.matches(r)), None) - if matched_index is not None: - python_deps.pop(matched_index) + if self.conda_config.is_initialized: + if self.conda_config.as_default_manager: + conda_requirements = { + n: r + for n, r in conda_requirements.items() + if not r.is_python_package or r.channel or r.build_string + } + if conda_requirements: + deps = self.get_conda_pyproject_dependencies(to_group, dev, set_defaults=True) + python_deps, _ = self.use_pyproject_dependencies(to_group, dev) + cast(Array, deps).multiline(True) + for name, dep in conda_requirements.items(): + matched_index = next((i for i, r in enumerate(deps) if dep.matches(f"conda:{r}")), None) + req = dep.as_line(with_channel=True) + if matched_index is None: + deps.append(req) + else: + deps[matched_index] = req + if name not in requirements: + matched_index = next((i for i, r in enumerate(python_deps) if dep.matches(r)), None) + if matched_index is not None: + python_deps.pop(matched_index) + else: + assert not conda_requirements, "Conda is not initialized but conda requirements are present." + super().add_dependencies(requirements, to_group, dev, show_message, write=write) + @PluginConfig.check_active def get_environment(self) -> BaseEnvironment: if not self.conda_config.is_initialized: return super().get_environment() + if not get_venv_like_prefix(self.python.executable)[1]: logger.debug("Conda environment not detected.") return super().get_environment() if not self.config["python.use_venv"]: raise ProjectError("python.use_venv is required to use Conda.") - return self.environment_class(self) + from pdm_conda.environments import CondaEnvironment + + return CondaEnvironment(self) def get_provider( self, @@ -239,6 +257,9 @@ def get_provider( ignore_compatibility: bool = True, direct_minimal_versions: bool = False, ) -> BaseProvider: + if not self.conda_config.is_initialized: + return super().get_provider(strategy, tracked_names, for_install, ignore_compatibility) + from pdm_conda.resolver.providers import BaseProvider, CondaBaseProvider kwargs = {"direct_minimal_versions": direct_minimal_versions} @@ -258,6 +279,7 @@ def is_distribution(self) -> bool: def is_distribution(self, value: bool | None): self._is_distribution = value + @PluginConfig.check_active def find_interpreters( self, python_spec: str | None = None, diff --git a/src/pdm_conda/project/project_file.py b/src/pdm_conda/project/project_file.py index b82ea98..de7d53a 100644 --- a/src/pdm_conda/project/project_file.py +++ b/src/pdm_conda/project/project_file.py @@ -34,6 +34,7 @@ def content_hash(self, algo: str = "sha256") -> str: "dependencies", "dev-dependencies", "optional-dependencies", + "active", ): if hash_config in pdm_conda_data: pdm_conda_dump_data[hash_config] = pdm_conda_data[hash_config] diff --git a/src/pdm_conda/resolvers.py b/src/pdm_conda/resolvers.py index 6a72064..aca9c5c 100644 --- a/src/pdm_conda/resolvers.py +++ b/src/pdm_conda/resolvers.py @@ -225,7 +225,9 @@ def resolve(self, requirements, max_rounds=100): if conda_config.custom_behavior: project.is_distribution = True else: - assert not any(isinstance(r, CondaRequirement) for r in requirements) + for r in requirements: + if isinstance(r, CondaRequirement): + raise CondaResolutionError(f"Conda requirement {r} detected but pdm-plugin is not initialized.") try: state = resolution.resolve(requirements, max_rounds=max_rounds) From 6a499ba10480b1034e3d6265e9048342b75b70ec Mon Sep 17 00:00:00 2001 From: macro128 <29261232+macro128@users.noreply.github.com> Date: Sun, 19 May 2024 23:23:26 -0300 Subject: [PATCH 03/18] fix batch ops --- src/pdm_conda/installers/manager.py | 60 +++++++++++++---------- src/pdm_conda/installers/synchronizers.py | 37 +++++++------- src/pdm_conda/models/config.py | 4 +- 3 files changed, 56 insertions(+), 45 deletions(-) diff --git a/src/pdm_conda/installers/manager.py b/src/pdm_conda/installers/manager.py index 1fac3e3..7533a66 100644 --- a/src/pdm_conda/installers/manager.py +++ b/src/pdm_conda/installers/manager.py @@ -24,29 +24,31 @@ def __init__( rename_pth: bool = False, ) -> None: super().__init__(environment, use_install_cache=use_install_cache, rename_pth=rename_pth) - self._num_install = 0 - self._num_remove = 0 - self._batch_install: list[str] = [] - self._batch_remove: list[str] = [] - - def prepare_batch_operations(self, num_install: int, num_remove: int): - self._num_install = num_install - self._num_remove = num_remove - - def _run_with_conda(self, conda_func, new_requirement: str, requirements: list[str], min_requirements: int): - requirements.append(new_requirement) - if len(requirements) >= min_requirements: - try: - conda_func( - self.environment.project, - list(requirements), - no_deps=True, - ) - requirements.clear() - except: - if min_requirements == 0: - requirements.clear() - raise + self._batch_install_queue: dict[str, str] = {} + self._batch_install_expected: set[str] = set() + self._batch_uninstall_queue: dict[str, str] = {} + self._batch_uninstall_expected: set[str] = set() + + def prepare_batch_operations(self, to_install: set[str], to_uninstall: set[str]): + self._batch_install_expected = to_install + self._batch_uninstall_expected = to_uninstall + + def _run_with_conda( + self, + conda_func, + new_requirement: str, + queue: dict[str, str], + expected: set[str], + op_name: str = "", + ): + if should_run := (new_requirement not in expected): + queue = {new_requirement: op_name or new_requirement} + else: + queue[new_requirement] = op_name or new_requirement + should_run = set(queue) == expected + + if should_run: + conda_func(self.environment.project, list(queue.values()), no_deps=True) def install(self, candidate: Candidate) -> Distribution: """Install candidate, use conda if conda package else default installer. @@ -56,9 +58,10 @@ def install(self, candidate: Candidate) -> Distribution: if isinstance(candidate, CondaCandidate): self._run_with_conda( conda_install, + candidate.name, + self._batch_install_queue, + self._batch_install_expected, f"{candidate.link.url_without_fragment}#{candidate.link.hash}", - self._batch_install, - self._num_install, ) return candidate.distribution @@ -70,7 +73,12 @@ def uninstall(self, dist: Distribution) -> None: :param dist: distribution to uninstall """ if isinstance(dist, CondaSetupDistribution): - self._run_with_conda(conda_uninstall, dist.name, self._batch_remove, self._num_remove) + self._run_with_conda( + conda_uninstall, + dist.name, + self._batch_uninstall_queue, + self._batch_uninstall_expected, + ) else: super().uninstall(dist) diff --git a/src/pdm_conda/installers/synchronizers.py b/src/pdm_conda/installers/synchronizers.py index 8af4a23..f47d81c 100644 --- a/src/pdm_conda/installers/synchronizers.py +++ b/src/pdm_conda/installers/synchronizers.py @@ -6,6 +6,7 @@ from pdm.installers import Synchronizer from pdm_conda.environments import CondaEnvironment +from pdm_conda.installers.manager import CondaInstallManager from pdm_conda.models.candidates import CondaCandidate from pdm_conda.models.requirements import strip_extras from pdm_conda.models.setup import CondaSetupDistribution @@ -63,29 +64,31 @@ def compare_with_working_set(self) -> tuple[list[str], list[str], list[str]]: to_add, to_update, to_remove = super().compare_with_working_set() if not isinstance(self.environment, CondaEnvironment): return to_add, to_update, to_remove - - # deactivate parallel execution if uninstall - self.parallel = self.environment.project.config["install.parallel"] if to_remove: to_remove = [p for p in to_remove if p not in self.environment.env_dependencies] - num_install = 0 + if ( + not isinstance(self.manager, CondaInstallManager) + or not self.environment.project.conda_config.batched_commands + ): + return to_add, to_update, to_remove + + to_batch_install = set() + to_batch_remove = set() + + def extract_conda(pkgs, candidates, cls): + conda_pkgs = [] + for pkg in pkgs: + if isinstance(candidates[pkg], cls): + conda_pkgs.append(pkg) + return conda_pkgs + for pkgs in (to_add, to_update): - num_install += len([p for p in pkgs if isinstance(self.candidates[p], CondaCandidate)]) + to_batch_install.update(extract_conda(pkgs, self.candidates, CondaCandidate)) - num_remove = 0 for pkgs in (to_remove, to_update): - num_remove += len([p for p in pkgs if isinstance(self.working_set[p], CondaSetupDistribution)]) - - if self.parallel and num_remove > 0: - if not self.dry_run: - self.environment.project.core.ui.echo("Deactivating parallel uninstall.") - self.parallel = False + to_batch_remove.update(extract_conda(pkgs, self.working_set, CondaSetupDistribution)) - batched_commands = self.environment.project.conda_config.batched_commands - self.manager.prepare_batch_operations( - num_install=num_install if batched_commands else 0, - num_remove=num_remove if batched_commands else 0, - ) + self.manager.prepare_batch_operations(to_batch_install, to_batch_remove) return to_add, to_update, to_remove diff --git a/src/pdm_conda/models/config.py b/src/pdm_conda/models/config.py index 2d5a790..9aa2727 100644 --- a/src/pdm_conda/models/config.py +++ b/src/pdm_conda/models/config.py @@ -311,8 +311,8 @@ def decorator(*args, **kwargs): active_venv = os.environ.pop("CONDA_DEFAULT_ENV", None) try: for name, value in zip(old_configs, (True, False, config.runner, False), strict=False): - if old_configs[name] != value: - setattr(project_config, name, value) + if getattr(old_configs, name, None) != value: + project_config[name] = value return func(*args, **kwargs) finally: for name, value in old_configs.items(): From 1203a3b02cf6c89f38ed02520c76eaabdd6189cd Mon Sep 17 00:00:00 2001 From: macro128 <29261232+macro128@users.noreply.github.com> Date: Mon, 20 May 2024 00:18:19 -0300 Subject: [PATCH 04/18] add active config --- src/pdm_conda/models/config.py | 12 ++++++-- src/pdm_conda/project/core.py | 2 ++ tests/test_lock.py | 54 ++++++++++++++++++++++++++++++++++ tests/test_plugin_config.py | 13 +++++++- 4 files changed, 78 insertions(+), 3 deletions(-) diff --git a/src/pdm_conda/models/config.py b/src/pdm_conda/models/config.py index 9aa2727..ec44c77 100644 --- a/src/pdm_conda/models/config.py +++ b/src/pdm_conda/models/config.py @@ -36,6 +36,7 @@ class CondaSolver(str, Enum): CONFIGS = [ + ("active", ConfigItem("Use pdm-conda plugin", True, env_var="PDM_CONDA_ACTIVE")), ("runner", ConfigItem("Conda runner executable", CondaRunner.CONDA.value, env_var="PDM_CONDA_RUNNER")), ("solver", ConfigItem("Solver to use for Conda resolution", CondaSolver.CONDA.value, env_var="PDM_CONDA_SOLVER")), ("channels", ConfigItem("Conda channels to use", [])), @@ -120,6 +121,7 @@ class PluginConfig: channels: list[str] = field(default_factory=list) runner: str = CondaRunner.CONDA solver: str = CondaSolver.CONDA + active: bool = True as_default_manager: bool = False custom_behavior: bool = False auto_excludes: bool = False @@ -276,7 +278,7 @@ def excludes(self, value): @property def is_initialized(self): - return self._initialized + return self._initialized and self.active @is_initialized.setter def is_initialized(self, value): @@ -381,7 +383,13 @@ def flatten_config(config, allowed_levels, parent_key="", result=None) -> dict: value = project.config[n] if prop_name == "mapping_download_dir": value = Path(value) - elif prop_name in ("as_default_manager", "batched_commands", "custom_behavior", "auto_excludes"): + elif prop_name in ( + "as_default_manager", + "batched_commands", + "custom_behavior", + "auto_excludes", + "active", + ): value = str(value).lower() in ("true", "1") config[prop_name] = value config |= kwargs diff --git a/src/pdm_conda/project/core.py b/src/pdm_conda/project/core.py index a1f8884..42d24c2 100644 --- a/src/pdm_conda/project/core.py +++ b/src/pdm_conda/project/core.py @@ -144,6 +144,8 @@ def _getter(conf, name, default, set_defaults=False): def iter_groups(self, dev: bool = True) -> Iterable[str]: groups = set(super().iter_groups()) config = self.conda_config + if not config.is_initialized: + return groups for is_dev, deps in ((False, config.optional_dependencies), (True, config.dev_dependencies)): if deps and (dev or not is_dev): groups.update(deps.keys()) diff --git a/tests/test_lock.py b/tests/test_lock.py index 020f394..2b4feb6 100644 --- a/tests/test_lock.py +++ b/tests/test_lock.py @@ -270,6 +270,60 @@ def test_lock_refresh( ) assert old_lockfile == lockfile + def test_lock_inactive( + self, + pdm, + project, + conda, + conda_info, + runner, + solver, + pypi, + group, + conda_mapping, + mock_conda_mapping, + ): + """Test lock command work as expected.""" + + python_dependencies = {c["name"] for c in PYTHON_REQUIREMENTS} + conda_packages = [c for c in conda_info if c["name"] not in python_dependencies] + config = project.conda_config + config.runner = runner + config.solver = solver + assert config.is_initialized + config.active = False + assert not config.is_initialized + + from pdm_conda.mapping import conda_to_pypi + + name = conda_packages[-1]["name"] + packages = {group: [name]} + if group != "default": + if group != "dev": + config.optional_dependencies = packages + else: + config.dev_dependencies = packages + else: + config.dependencies = packages[group] + + pkg = copy(conda_packages[1]) + name = conda_to_pypi(pkg["name"]) + project.pyproject._data.update( + { + "project": { + "dependencies": [name], + "requires-python": project.pyproject.metadata["requires-python"], + }, + }, + ) + config.excludes = [name] + # this will assert that this package is searched on pypi + pypi([pkg], with_dependencies=True) + + cmd = ["lock", "-vv", "-G", ":all"] + pdm(cmd, obj=project, strict=True) + conda.assert_not_called() + class TestGroupsLock: def test_lock_prod_dev( diff --git a/tests/test_plugin_config.py b/tests/test_plugin_config.py index bf8f850..e29f561 100644 --- a/tests/test_plugin_config.py +++ b/tests/test_plugin_config.py @@ -14,6 +14,8 @@ class TestPluginConfig: ["channels", ["other"]], ["excludes", ["another-dep-pip"]], ["batched-commands", True], + ["active", False], + ["active", True], ["custom-behavior", True], ["batched-commands", False], ["dependencies", ["package"]], @@ -69,6 +71,8 @@ def test_set_configs(self, project, mocker, set_before, config_name, config_valu _config = _config[k] assert config_value == _config + if config_name == "active" and not config_value: + assert not config.is_initialized @pytest.mark.parametrize( "config_name,config_value", @@ -78,19 +82,26 @@ def test_set_configs(self, project, mocker, set_before, config_name, config_valu ["excludes", ["another-dep-pip"]], ["batched-commands", True], ["batched-commands", False], + ["active", False], ["dependencies", ["package"]], ], ) - def test_with_config(self, project, mocker, config_name, config_value): + @pytest.mark.parametrize("is_initialized", [True, False]) + def test_with_config(self, project, mocker, config_name, config_value, is_initialized): config = project.conda_config subscribed = mocker.spy(project.pyproject._data, "update") conda_config_name = config_name.replace("-", "_") old_value = getattr(config, conda_config_name) project.pyproject.write(False) + config.is_initialized = is_initialized assert not config._dry_run with config.with_config(**{conda_config_name: config_value}): assert config._dry_run assert getattr(config, conda_config_name) == config_value + if config_name == "active" and not config_value: + assert not config.is_initialized + elif old_value != config_value: + assert config.is_initialized == is_initialized assert getattr(config, conda_config_name) == old_value assert subscribed.call_count == 0 From 1a2b61b0c511f8939937c0277cc509fc26bbcfb2 Mon Sep 17 00:00:00 2001 From: macro128 <29261232+macro128@users.noreply.github.com> Date: Tue, 21 May 2024 16:08:31 -0300 Subject: [PATCH 05/18] ensure active config cannot be set with PluginConfig --- src/pdm_conda/models/config.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pdm_conda/models/config.py b/src/pdm_conda/models/config.py index ec44c77..534335f 100644 --- a/src/pdm_conda/models/config.py +++ b/src/pdm_conda/models/config.py @@ -159,6 +159,7 @@ def __setattr__(self, name: str, value: Any) -> None: # if plugin config is set then maybe update pyproject settings if ( ((not name.startswith("_")) or name == "_excludes") + and name != "active" and not isinstance(getattr(type(self), name, None), property) and not callable(getattr(self, name)) ): From 7493f8c16c3c278cd58ef5caf588495e37997ab5 Mon Sep 17 00:00:00 2001 From: macro128 <29261232+macro128@users.noreply.github.com> Date: Tue, 21 May 2024 16:08:47 -0300 Subject: [PATCH 06/18] add inactive tests --- tests/data/pyproject_2.toml | 24 ++++++++++++++++++++++++ tests/test_integration.py | 21 +++++++++++++++++++-- tests/test_lock.py | 3 ++- tests/test_plugin_config.py | 21 ++++++++++++++++++++- 4 files changed, 65 insertions(+), 4 deletions(-) create mode 100644 tests/data/pyproject_2.toml diff --git a/tests/data/pyproject_2.toml b/tests/data/pyproject_2.toml new file mode 100644 index 0000000..65853f8 --- /dev/null +++ b/tests/data/pyproject_2.toml @@ -0,0 +1,24 @@ +[tool.pdm.conda] +runner = "micromamba" +solver = "libmamba" +channels = ["conda-forge"] +as-default-manager = true +custom-behavior = true +auto-excludes = true +batched-commands = true +active = false + +[project] +name = "test-project" +version = "0.0.0" +description = "" +authors = [] +dependencies = [ "r" ] +requires-python = ">=3.10.14" + +[project.license] +text = "MIT" + +[build-system] +requires = ["pdm-backend"] +build-backend = "pdm.backend" diff --git a/tests/test_integration.py b/tests/test_integration.py index c7c1995..9d2be63 100644 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -3,6 +3,7 @@ from pathlib import Path import pytest +from pdm.exceptions import PdmException from tests.conftest import PYTHON_VERSION @@ -69,8 +70,8 @@ def test_case_01(self, pdm, project, build_env, env_name, runner): config.batched_commands = True from pdm_conda.project.core import PyProject - # python_version = "3.11" - python_version = PYTHON_VERSION + python_version = "3.11" + # python_version = PYTHON_VERSION print("list environments:") pdm(["venv", "list"], obj=project, strict=True, cleanup=True).print() @@ -228,3 +229,19 @@ def test_case_05(self, pdm, project, build_env, env_name): assert len(interpreters) == 2 for i in interpreters: assert res.stdout.count(f"({i.executable.parent}") == 1 + + def test_case_06(self, pdm, project, build_env, env_name, runner): + from pdm_conda.project.core import PyProject + + project.pyproject.set_data( + PyProject(Path(__file__).parent / "data" / "pyproject_2.toml", ui=project.core.ui)._data, + ) + project.pyproject.write() + project.conda_config.runner = runner + assert not project.conda_config.active + assert not project.conda_config.is_initialized + assert project.config["venv.backend"] != runner + + print("lock:") + with pytest.raises(PdmException): + pdm(["lock", "-G", ":all", "-vv"], obj=project, strict=True, cleanup=True).print() diff --git a/tests/test_lock.py b/tests/test_lock.py index 2b4feb6..4551f4e 100644 --- a/tests/test_lock.py +++ b/tests/test_lock.py @@ -291,7 +291,8 @@ def test_lock_inactive( config.runner = runner config.solver = solver assert config.is_initialized - config.active = False + project.pyproject._data.update({"tool": {"pdm": {"conda": {"active": False}}}}) + assert not config.active assert not config.is_initialized from pdm_conda.mapping import conda_to_pypi diff --git a/tests/test_plugin_config.py b/tests/test_plugin_config.py index e29f561..7eb29a7 100644 --- a/tests/test_plugin_config.py +++ b/tests/test_plugin_config.py @@ -1,3 +1,4 @@ +import os from typing import Any import pytest @@ -61,7 +62,7 @@ def test_set_configs(self, project, mocker, set_before, config_name, config_valu if config_value is not None: setattr(config, conda_config_name, assert_value) project.pyproject.write(False) - if not set_before and config_value == config_default: + if not set_before and (config_value == config_default or config_name == "active"): assert ( "conda" not in project.pyproject.settings or config_name not in project.pyproject.settings["conda"] ) @@ -161,3 +162,21 @@ def test_incorrect_config(self, project, name): }, }, ) + + @pytest.mark.parametrize("runner", ["micromamba", "mamba", "conda"]) + def test_temporary_config(self, project, runner): + """Test config changes are temporary.""" + project.conda_config.runner = runner + + @project.conda_config.check_active + def _test_temporary_config(project): + assert project.conda_config.active + assert project.conda_config.is_initialized + assert project.config["venv.backend"] == runner + assert "CONDA_DEFAULT_ENV" not in os.environ + + assert project.config["venv.backend"] != runner + assert "CONDA_DEFAULT_ENV" in os.environ + _test_temporary_config(project) + assert project.config["venv.backend"] != runner + assert "CONDA_DEFAULT_ENV" in os.environ From 13b671bae15cc56d655ba04ba89c0b3ce3da23ac Mon Sep 17 00:00:00 2001 From: macro128 <29261232+macro128@users.noreply.github.com> Date: Tue, 21 May 2024 16:09:06 -0300 Subject: [PATCH 07/18] update pdm version --- pdm.lock | 132 ++++--------------------------------------------- pyproject.toml | 2 +- 2 files changed, 10 insertions(+), 124 deletions(-) diff --git a/pdm.lock b/pdm.lock index c1796df..85526c9 100644 --- a/pdm.lock +++ b/pdm.lock @@ -5,7 +5,7 @@ groups = ["default", "dev"] strategy = ["cross_platform", "inherit_metadata"] lock_version = "4.4.1" -content_hash = "sha256:6947b2750a37a60744cf8e9a3d3839a17933404baaf18490a2a71616f468de8a" +content_hash = "sha256:50205dcfdb41344a13164f97f2651e905df0bce1763478435528c8e250560f4d" [[package]] name = "anyio" @@ -46,52 +46,6 @@ files = [ {file = "certifi-2024.2.2.tar.gz", hash = "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f"}, ] -[[package]] -name = "cffi" -version = "1.16.0" -requires_python = ">=3.8" -summary = "Foreign Function Interface for Python calling C code." -groups = ["default"] -marker = "platform_python_implementation == \"PyPy\"" -dependencies = [ - "pycparser", -] -files = [ - {file = "cffi-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6b3d6606d369fc1da4fd8c357d026317fbb9c9b75d36dc16e90e84c26854b088"}, - {file = "cffi-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ac0f5edd2360eea2f1daa9e26a41db02dd4b0451b48f7c318e217ee092a213e9"}, - {file = "cffi-1.16.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7e61e3e4fa664a8588aa25c883eab612a188c725755afff6289454d6362b9673"}, - {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a72e8961a86d19bdb45851d8f1f08b041ea37d2bd8d4fd19903bc3083d80c896"}, - {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5b50bf3f55561dac5438f8e70bfcdfd74543fd60df5fa5f62d94e5867deca684"}, - {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7651c50c8c5ef7bdb41108b7b8c5a83013bfaa8a935590c5d74627c047a583c7"}, - {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4108df7fe9b707191e55f33efbcb2d81928e10cea45527879a4749cbe472614"}, - {file = "cffi-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:32c68ef735dbe5857c810328cb2481e24722a59a2003018885514d4c09af9743"}, - {file = "cffi-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:673739cb539f8cdaa07d92d02efa93c9ccf87e345b9a0b556e3ecc666718468d"}, - {file = "cffi-1.16.0-cp310-cp310-win32.whl", hash = "sha256:9f90389693731ff1f659e55c7d1640e2ec43ff725cc61b04b2f9c6d8d017df6a"}, - {file = "cffi-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:e6024675e67af929088fda399b2094574609396b1decb609c55fa58b028a32a1"}, - {file = "cffi-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b84834d0cf97e7d27dd5b7f3aca7b6e9263c56308ab9dc8aae9784abb774d404"}, - {file = "cffi-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b8ebc27c014c59692bb2664c7d13ce7a6e9a629be20e54e7271fa696ff2b417"}, - {file = "cffi-1.16.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ee07e47c12890ef248766a6e55bd38ebfb2bb8edd4142d56db91b21ea68b7627"}, - {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8a9d3ebe49f084ad71f9269834ceccbf398253c9fac910c4fd7053ff1386936"}, - {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e70f54f1796669ef691ca07d046cd81a29cb4deb1e5f942003f401c0c4a2695d"}, - {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5bf44d66cdf9e893637896c7faa22298baebcd18d1ddb6d2626a6e39793a1d56"}, - {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b78010e7b97fef4bee1e896df8a4bbb6712b7f05b7ef630f9d1da00f6444d2e"}, - {file = "cffi-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c6a164aa47843fb1b01e941d385aab7215563bb8816d80ff3a363a9f8448a8dc"}, - {file = "cffi-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e09f3ff613345df5e8c3667da1d918f9149bd623cd9070c983c013792a9a62eb"}, - {file = "cffi-1.16.0-cp311-cp311-win32.whl", hash = "sha256:2c56b361916f390cd758a57f2e16233eb4f64bcbeee88a4881ea90fca14dc6ab"}, - {file = "cffi-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:db8e577c19c0fda0beb7e0d4e09e0ba74b1e4c092e0e40bfa12fe05b6f6d75ba"}, - {file = "cffi-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:fa3a0128b152627161ce47201262d3140edb5a5c3da88d73a1b790a959126956"}, - {file = "cffi-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:68e7c44931cc171c54ccb702482e9fc723192e88d25a0e133edd7aff8fcd1f6e"}, - {file = "cffi-1.16.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abd808f9c129ba2beda4cfc53bde801e5bcf9d6e0f22f095e45327c038bfe68e"}, - {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88e2b3c14bdb32e440be531ade29d3c50a1a59cd4e51b1dd8b0865c54ea5d2e2"}, - {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fcc8eb6d5902bb1cf6dc4f187ee3ea80a1eba0a89aba40a5cb20a5087d961357"}, - {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b7be2d771cdba2942e13215c4e340bfd76398e9227ad10402a8767ab1865d2e6"}, - {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e715596e683d2ce000574bae5d07bd522c781a822866c20495e52520564f0969"}, - {file = "cffi-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2d92b25dbf6cae33f65005baf472d2c245c050b1ce709cc4588cdcdd5495b520"}, - {file = "cffi-1.16.0-cp312-cp312-win32.whl", hash = "sha256:b2ca4e77f9f47c55c194982e10f058db063937845bb2b7a86c84a6cfe0aefa8b"}, - {file = "cffi-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:68678abf380b42ce21a5f2abde8efee05c114c2fdb2e9eef2efdb0257fba1235"}, - {file = "cffi-1.16.0.tar.gz", hash = "sha256:bcb3ef43e58665bbda2fb198698fcae6776483e0c4a631aa5647806c25e02cc0"}, -] - [[package]] name = "colorama" version = "0.4.6" @@ -450,25 +404,9 @@ files = [ {file = "pbs_installer-2024.4.1.tar.gz", hash = "sha256:1f2aca82511fb9e1973b14708d7386780a8c56d111b680ae5786b3f430fa918a"}, ] -[[package]] -name = "pbs-installer" -version = "2024.4.1" -extras = ["install"] -requires_python = ">=3.8" -summary = "Installer for Python Build Standalone" -groups = ["default"] -dependencies = [ - "pbs-installer==2024.4.1", - "zstandard>=0.21.0", -] -files = [ - {file = "pbs_installer-2024.4.1-py3-none-any.whl", hash = "sha256:762e1b5b95a48389051205c48fcd4635e946b48ab3252d2c79a8a77dc87e91ff"}, - {file = "pbs_installer-2024.4.1.tar.gz", hash = "sha256:1f2aca82511fb9e1973b14708d7386780a8c56d111b680ae5786b3f430fa918a"}, -] - [[package]] name = "pdm" -version = "2.15.2" +version = "2.15.3" requires_python = ">=3.8" summary = "A modern Python package and dependency manager supporting the latest PEP standards" groups = ["default"] @@ -482,7 +420,7 @@ dependencies = [ "installer<0.8,>=0.7", "msgpack>=1.0", "packaging!=22.0,>=20.9", - "pbs-installer[install]", + "pbs-installer", "platformdirs", "pyproject-hooks", "python-dotenv>=0.15", @@ -496,8 +434,8 @@ dependencies = [ "virtualenv>=20", ] files = [ - {file = "pdm-2.15.2-py3-none-any.whl", hash = "sha256:04cf106fbf2cf4564eda70b40ffb33acf4637e1cee55d6cec8f8c21fe1f70b65"}, - {file = "pdm-2.15.2.tar.gz", hash = "sha256:c08e87078c29c00e7ad9681dc6a23419dc5617dcbe6cc205024ef4b4e7e28475"}, + {file = "pdm-2.15.3-py3-none-any.whl", hash = "sha256:edfb3ca07e46745ea877ec2f973d4ebdaa8e7592cf5c5f6db718a5cc775f95ec"}, + {file = "pdm-2.15.3.tar.gz", hash = "sha256:c227d81f6bf109626a5643a7bb531c5f5b777a850c4eac8d08b472c1146beee5"}, ] [[package]] @@ -522,18 +460,6 @@ files = [ {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, ] -[[package]] -name = "pycparser" -version = "2.22" -requires_python = ">=3.8" -summary = "C parser in Python" -groups = ["default"] -marker = "platform_python_implementation == \"PyPy\"" -files = [ - {file = "pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc"}, - {file = "pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6"}, -] - [[package]] name = "pygments" version = "2.17.2" @@ -561,7 +487,7 @@ files = [ [[package]] name = "pytest" -version = "8.1.1" +version = "8.2.1" requires_python = ">=3.8" summary = "pytest: simple powerful testing with Python" groups = ["dev"] @@ -570,12 +496,12 @@ dependencies = [ "exceptiongroup>=1.0.0rc8; python_version < \"3.11\"", "iniconfig", "packaging", - "pluggy<2.0,>=1.4", + "pluggy<2.0,>=1.5", "tomli>=1; python_version < \"3.11\"", ] files = [ - {file = "pytest-8.1.1-py3-none-any.whl", hash = "sha256:2a8386cfc11fa9d2c50ee7b2a57e7d898ef90470a7a34c4b949ff59662bb78b7"}, - {file = "pytest-8.1.1.tar.gz", hash = "sha256:ac978141a75948948817d360297b7aae0fcb9d6ff6bc9ec6d514b85d5a65c044"}, + {file = "pytest-8.2.1-py3-none-any.whl", hash = "sha256:faccc5d332b8c3719f40283d0d44aa5cf101cec36f88cde9ed8f2bc0538612b1"}, + {file = "pytest-8.2.1.tar.gz", hash = "sha256:5046e5b46d8e4cac199c373041f26be56fdb81eb4e67dc11d4e10811fc3408fd"}, ] [[package]] @@ -794,43 +720,3 @@ files = [ {file = "virtualenv-20.25.3-py3-none-any.whl", hash = "sha256:8aac4332f2ea6ef519c648d0bc48a5b1d324994753519919bddbb1aff25a104e"}, {file = "virtualenv-20.25.3.tar.gz", hash = "sha256:7bb554bbdfeaacc3349fa614ea5bff6ac300fc7c335e9facf3a3bcfc703f45be"}, ] - -[[package]] -name = "zstandard" -version = "0.22.0" -requires_python = ">=3.8" -summary = "Zstandard bindings for Python" -groups = ["default"] -dependencies = [ - "cffi>=1.11; platform_python_implementation == \"PyPy\"", -] -files = [ - {file = "zstandard-0.22.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:275df437ab03f8c033b8a2c181e51716c32d831082d93ce48002a5227ec93019"}, - {file = "zstandard-0.22.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2ac9957bc6d2403c4772c890916bf181b2653640da98f32e04b96e4d6fb3252a"}, - {file = "zstandard-0.22.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fe3390c538f12437b859d815040763abc728955a52ca6ff9c5d4ac707c4ad98e"}, - {file = "zstandard-0.22.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1958100b8a1cc3f27fa21071a55cb2ed32e9e5df4c3c6e661c193437f171cba2"}, - {file = "zstandard-0.22.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:93e1856c8313bc688d5df069e106a4bc962eef3d13372020cc6e3ebf5e045202"}, - {file = "zstandard-0.22.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:1a90ba9a4c9c884bb876a14be2b1d216609385efb180393df40e5172e7ecf356"}, - {file = "zstandard-0.22.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:3db41c5e49ef73641d5111554e1d1d3af106410a6c1fb52cf68912ba7a343a0d"}, - {file = "zstandard-0.22.0-cp310-cp310-win32.whl", hash = "sha256:d8593f8464fb64d58e8cb0b905b272d40184eac9a18d83cf8c10749c3eafcd7e"}, - {file = "zstandard-0.22.0-cp310-cp310-win_amd64.whl", hash = "sha256:f1a4b358947a65b94e2501ce3e078bbc929b039ede4679ddb0460829b12f7375"}, - {file = "zstandard-0.22.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:589402548251056878d2e7c8859286eb91bd841af117dbe4ab000e6450987e08"}, - {file = "zstandard-0.22.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a97079b955b00b732c6f280d5023e0eefe359045e8b83b08cf0333af9ec78f26"}, - {file = "zstandard-0.22.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:445b47bc32de69d990ad0f34da0e20f535914623d1e506e74d6bc5c9dc40bb09"}, - {file = "zstandard-0.22.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:33591d59f4956c9812f8063eff2e2c0065bc02050837f152574069f5f9f17775"}, - {file = "zstandard-0.22.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:888196c9c8893a1e8ff5e89b8f894e7f4f0e64a5af4d8f3c410f0319128bb2f8"}, - {file = "zstandard-0.22.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:53866a9d8ab363271c9e80c7c2e9441814961d47f88c9bc3b248142c32141d94"}, - {file = "zstandard-0.22.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:4ac59d5d6910b220141c1737b79d4a5aa9e57466e7469a012ed42ce2d3995e88"}, - {file = "zstandard-0.22.0-cp311-cp311-win32.whl", hash = "sha256:2b11ea433db22e720758cba584c9d661077121fcf60ab43351950ded20283440"}, - {file = "zstandard-0.22.0-cp311-cp311-win_amd64.whl", hash = "sha256:11f0d1aab9516a497137b41e3d3ed4bbf7b2ee2abc79e5c8b010ad286d7464bd"}, - {file = "zstandard-0.22.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:6c25b8eb733d4e741246151d895dd0308137532737f337411160ff69ca24f93a"}, - {file = "zstandard-0.22.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f9b2cde1cd1b2a10246dbc143ba49d942d14fb3d2b4bccf4618d475c65464912"}, - {file = "zstandard-0.22.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a88b7df61a292603e7cd662d92565d915796b094ffb3d206579aaebac6b85d5f"}, - {file = "zstandard-0.22.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:466e6ad8caefb589ed281c076deb6f0cd330e8bc13c5035854ffb9c2014b118c"}, - {file = "zstandard-0.22.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a1d67d0d53d2a138f9e29d8acdabe11310c185e36f0a848efa104d4e40b808e4"}, - {file = "zstandard-0.22.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:39b2853efc9403927f9065cc48c9980649462acbdf81cd4f0cb773af2fd734bc"}, - {file = "zstandard-0.22.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8a1b2effa96a5f019e72874969394edd393e2fbd6414a8208fea363a22803b45"}, - {file = "zstandard-0.22.0-cp312-cp312-win32.whl", hash = "sha256:88c5b4b47a8a138338a07fc94e2ba3b1535f69247670abfe422de4e0b344aae2"}, - {file = "zstandard-0.22.0-cp312-cp312-win_amd64.whl", hash = "sha256:de20a212ef3d00d609d0b22eb7cc798d5a69035e81839f549b538eff4105d01c"}, - {file = "zstandard-0.22.0.tar.gz", hash = "sha256:8226a33c542bcb54cd6bd0a366067b610b41713b64c9abec1bc4533d69f51e70"}, -] diff --git a/pyproject.toml b/pyproject.toml index d6629c9..2a60a93 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -28,7 +28,7 @@ classifiers = [ ] dependencies = [ - "pdm==2.15.2", + "pdm==2.15.3", "typing-extensions>=4.10.0", "httpx>=0.27.0", ] From d7687f696217ad11c4eb608c3a5446eafcd7bd83 Mon Sep 17 00:00:00 2001 From: macro128 <29261232+macro128@users.noreply.github.com> Date: Tue, 21 May 2024 16:10:03 -0300 Subject: [PATCH 08/18] update README.md --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 8c80aea..546ad4e 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,7 @@ A PDM plugin to resolve/install/uninstall project dependencies with Conda. | Config item | Description | Default value | Possible values | Environment variable | |-----------------------------------|------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------|--------------------------------|---------------------------------| +| `conda.active` | Force plugin usage or not | `True` | | `PDM_CONDA_ACTIVE` | | `conda.runner` | Conda runner executable | `conda` | `conda`, `mamba`, `micromamba` | `PDM_CONDA_RUNNER` | | `conda.solver` | Solver to use for Conda resolution | `conda` | `conda`, `libmamba` | `PDM_CONDA_SOLVER` | | `conda.channels` | Conda channels to use, order will be enforced | `[]` | | | @@ -33,6 +34,7 @@ solver = "libmamba" excludes = ["pytest-cov"] # don't install with conda even if it's a dependency from other packages installation-method = "copy" batched-commands = true +active = false [tool.pdm.conda.pypi-mapping] download-dir = "/tmp" @@ -108,6 +110,9 @@ Some environment variables were overridden too: * `PDM_IGNORE_ACTIVE_VENV` if conda settings detected in `pyproject.toml` and `VIRTUAL_ENV` or `CONDA_PREFIX` environment variables are set then this variable is set to `False`. +All this changes will be maintained only during the execution of the command, after that the settings will be restored +to the previous values. + #### Lock strategy * Lock strategy `no_cross_platform` for `pdm lock` is always forced as Conda doesn't produce cross-platform locks. From 436be32571f6034bd9027972a828071d11f6aedc Mon Sep 17 00:00:00 2001 From: macro128 <29261232+macro128@users.noreply.github.com> Date: Tue, 21 May 2024 16:10:17 -0300 Subject: [PATCH 09/18] update CHANGELOG.md --- CHANGELOG.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 612bff0..03f5525 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,13 +7,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.18.0] - 21/05/2024 + +### Added + +* Now compatible with `pdm==v2.15.3`. +* Add `conda.active` config to activate/deactivate pdm-conda plugin. + +### Changed + +* Only modify PDM config while the plugin is active. + ## [0.17.6] - 16/05/2024 ### Added * Now compatible with `pdm==v2.15.2`. - ## [0.17.5] - 08/05/2024 ### Changed From 6d54397fa99915e5e97e0aab856e5cdc0a112dea Mon Sep 17 00:00:00 2001 From: macro128 <29261232+macro128@users.noreply.github.com> Date: Tue, 21 May 2024 16:10:31 -0300 Subject: [PATCH 10/18] update Dockerfile --- deploy/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/Dockerfile b/deploy/Dockerfile index 8480691..1a35f38 100644 --- a/deploy/Dockerfile +++ b/deploy/Dockerfile @@ -42,7 +42,7 @@ FROM ${base} AS src-app # install PDM and create app environment ARG app_env ARG python_version="3.10.*" -ARG pdm_version="2.15.2" +ARG pdm_version="2.15.3" ENV BIN_PATH=/opt/conda/_bin RUN --mount=type=cache,target=/opt/conda/pkgs,id=mamba,mode=0775,uid=1000,gid=1000,sharing=locked \ micromamba install -y pdm==${pdm_version} -n base -c conda-forge --always-copy && \ From dfcc0b2887008ef05fc04c334fc60f493a4d7600 Mon Sep 17 00:00:00 2001 From: macro128 <29261232+macro128@users.noreply.github.com> Date: Wed, 5 Jun 2024 23:53:22 -0300 Subject: [PATCH 11/18] bump pdm version --- pdm.lock | 20 ++++++++++---------- pyproject.toml | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/pdm.lock b/pdm.lock index 85526c9..0703bd9 100644 --- a/pdm.lock +++ b/pdm.lock @@ -5,7 +5,7 @@ groups = ["default", "dev"] strategy = ["cross_platform", "inherit_metadata"] lock_version = "4.4.1" -content_hash = "sha256:50205dcfdb41344a13164f97f2651e905df0bce1763478435528c8e250560f4d" +content_hash = "sha256:3abb21b58249b0536e8e8d17e703a371b72758eec9e573e1c583d01a58010373" [[package]] name = "anyio" @@ -406,7 +406,7 @@ files = [ [[package]] name = "pdm" -version = "2.15.3" +version = "2.15.4" requires_python = ">=3.8" summary = "A modern Python package and dependency manager supporting the latest PEP standards" groups = ["default"] @@ -434,8 +434,8 @@ dependencies = [ "virtualenv>=20", ] files = [ - {file = "pdm-2.15.3-py3-none-any.whl", hash = "sha256:edfb3ca07e46745ea877ec2f973d4ebdaa8e7592cf5c5f6db718a5cc775f95ec"}, - {file = "pdm-2.15.3.tar.gz", hash = "sha256:c227d81f6bf109626a5643a7bb531c5f5b777a850c4eac8d08b472c1146beee5"}, + {file = "pdm-2.15.4-py3-none-any.whl", hash = "sha256:4582ea62d3b184146d1aa81bca4b34ae6b8979bc02aa38f44b75fd4bfdae4738"}, + {file = "pdm-2.15.4.tar.gz", hash = "sha256:58e225850567dcadce42418db4638996df2b1378cd0830cd48afda1b455d9c72"}, ] [[package]] @@ -487,7 +487,7 @@ files = [ [[package]] name = "pytest" -version = "8.2.1" +version = "8.2.2" requires_python = ">=3.8" summary = "pytest: simple powerful testing with Python" groups = ["dev"] @@ -500,8 +500,8 @@ dependencies = [ "tomli>=1; python_version < \"3.11\"", ] files = [ - {file = "pytest-8.2.1-py3-none-any.whl", hash = "sha256:faccc5d332b8c3719f40283d0d44aa5cf101cec36f88cde9ed8f2bc0538612b1"}, - {file = "pytest-8.2.1.tar.gz", hash = "sha256:5046e5b46d8e4cac199c373041f26be56fdb81eb4e67dc11d4e10811fc3408fd"}, + {file = "pytest-8.2.2-py3-none-any.whl", hash = "sha256:c434598117762e2bd304e526244f67bf66bbd7b5d6cf22138be51ff661980343"}, + {file = "pytest-8.2.2.tar.gz", hash = "sha256:de4bb8104e201939ccdc688b27a89a7be2079b22e2bd2b07f806b6ba71117977"}, ] [[package]] @@ -681,13 +681,13 @@ files = [ [[package]] name = "typing-extensions" -version = "4.11.0" +version = "4.12.1" requires_python = ">=3.8" summary = "Backported and Experimental Type Hints for Python 3.8+" groups = ["default", "dev"] files = [ - {file = "typing_extensions-4.11.0-py3-none-any.whl", hash = "sha256:c1f94d72897edaf4ce775bb7558d5b79d8126906a14ea5ed1635921406c0387a"}, - {file = "typing_extensions-4.11.0.tar.gz", hash = "sha256:83f085bd5ca59c80295fc2a82ab5dac679cbe02b9f33f7d83af68e241bea51b0"}, + {file = "typing_extensions-4.12.1-py3-none-any.whl", hash = "sha256:6024b58b69089e5a89c347397254e35f1bf02a907728ec7fee9bf0fe837d203a"}, + {file = "typing_extensions-4.12.1.tar.gz", hash = "sha256:915f5e35ff76f56588223f15fdd5938f9a1cf9195c0de25130c627e4d597f6d1"}, ] [[package]] diff --git a/pyproject.toml b/pyproject.toml index 2a60a93..d60ab51 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -28,7 +28,7 @@ classifiers = [ ] dependencies = [ - "pdm==2.15.3", + "pdm==2.15.4", "typing-extensions>=4.10.0", "httpx>=0.27.0", ] From a9373686b15964ed6d66489181d738595b38bd73 Mon Sep 17 00:00:00 2001 From: macro128 <29261232+macro128@users.noreply.github.com> Date: Thu, 6 Jun 2024 00:14:28 -0300 Subject: [PATCH 12/18] bump pdm version --- deploy/Dockerfile | 2 +- deploy/docker-compose.dev.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/deploy/Dockerfile b/deploy/Dockerfile index 1a35f38..ca8aefd 100644 --- a/deploy/Dockerfile +++ b/deploy/Dockerfile @@ -42,7 +42,7 @@ FROM ${base} AS src-app # install PDM and create app environment ARG app_env ARG python_version="3.10.*" -ARG pdm_version="2.15.3" +ARG pdm_version="2.15.4" ENV BIN_PATH=/opt/conda/_bin RUN --mount=type=cache,target=/opt/conda/pkgs,id=mamba,mode=0775,uid=1000,gid=1000,sharing=locked \ micromamba install -y pdm==${pdm_version} -n base -c conda-forge --always-copy && \ diff --git a/deploy/docker-compose.dev.yaml b/deploy/docker-compose.dev.yaml index 5532b22..5b54712 100644 --- a/deploy/docker-compose.dev.yaml +++ b/deploy/docker-compose.dev.yaml @@ -9,7 +9,7 @@ services: dependencies: ":all" local_path: $PWD image: pdm-conda:latest-dev - platform: linux/arm64 + platform: linux/x86_64 volumes: - ../tests:/app/tests - ../src/pdm_conda:/app/src/pdm_conda From 175bbe69ef3bbbc595e137464493bfde7f2d5d69 Mon Sep 17 00:00:00 2001 From: macro128 <29261232+macro128@users.noreply.github.com> Date: Thu, 6 Jun 2024 00:16:59 -0300 Subject: [PATCH 13/18] copy base scripts --- scripts/docker-compose.sh | 37 ++++++++++++++++++++++++++++++++++++- scripts/fix_report.py | 12 +++++++++++- 2 files changed, 47 insertions(+), 2 deletions(-) mode change 120000 => 100644 scripts/docker-compose.sh mode change 120000 => 100644 scripts/fix_report.py diff --git a/scripts/docker-compose.sh b/scripts/docker-compose.sh deleted file mode 120000 index 1613aff..0000000 --- a/scripts/docker-compose.sh +++ /dev/null @@ -1 +0,0 @@ -/Users/mpastorini/personal/pdm-conda/base/scripts/docker-compose.sh \ No newline at end of file diff --git a/scripts/docker-compose.sh b/scripts/docker-compose.sh new file mode 100644 index 0000000..102aec6 --- /dev/null +++ b/scripts/docker-compose.sh @@ -0,0 +1,36 @@ +DEV=false +COMMAND='' +while [[ $# -gt 0 ]]; do + case "$1" in + --dev | -d) + DEV=true + ;; + *) + COMMAND=$* + shift $(($# - 1)) + ;; + esac + shift +done + +ENV_FILE="$PWD"/.env +ENV_FILE_DEST="$PWD"/deploy/.env +if [[ -f "$ENV_FILE" ]] && [[ ! -f "$ENV_FILE_DEST" ]]; then + ln -s "$ENV_FILE" "$ENV_FILE_DEST" +fi + +OPTS="" +if $DEV; then + OPTS="-f deploy/docker-compose.dev.yaml" + UID_GID="$(id -u):$(id -g)" + export UID_GID +fi + +if [[ "$COMMAND" == run* ]] && [[ "$COMMAND" != run*--rm* ]]; then + readarray -td ' ' _COMMAND <<<"$COMMAND" + COMMAND="${_COMMAND[0]} --rm " + unset "_COMMAND[0]" + COMMAND+="${_COMMAND[*]}" +fi + +docker compose -f deploy/docker-compose.yaml $OPTS $COMMAND diff --git a/scripts/fix_report.py b/scripts/fix_report.py deleted file mode 120000 index df0c6ce..0000000 --- a/scripts/fix_report.py +++ /dev/null @@ -1 +0,0 @@ -/Users/mpastorini/personal/pdm-conda/base/scripts/fix_report.py \ No newline at end of file diff --git a/scripts/fix_report.py b/scripts/fix_report.py new file mode 100644 index 0000000..15e2b68 --- /dev/null +++ b/scripts/fix_report.py @@ -0,0 +1,11 @@ +import os +from pathlib import Path + +if __name__ == "__main__": + if (local_path := os.getenv("LOCAL_PATH", None)) is not None: + coverage_file = Path("coverage.xml") + + with coverage_file.open("r+") as f: + contents = f.read().replace("/app/", f"{local_path}/") + f.seek(0) + f.write(contents) From 1b86707a694e4447050639a2901355efc066f88b Mon Sep 17 00:00:00 2001 From: macro128 <29261232+macro128@users.noreply.github.com> Date: Thu, 6 Jun 2024 00:43:12 -0300 Subject: [PATCH 14/18] better parse python dir --- src/pdm_conda/utils.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pdm_conda/utils.py b/src/pdm_conda/utils.py index 3e2cc89..d149042 100644 --- a/src/pdm_conda/utils.py +++ b/src/pdm_conda/utils.py @@ -36,8 +36,8 @@ def fix_path(path: str | Path) -> Path: def get_python_dir(path: Path) -> Path: """Get the python directory for given interpreter path.""" - if str(path).endswith("/bin/python"): + if path.parent.name == "bin" and path.name.startswith("python"): return path.parents[1] - if str(path).endswith("python.exe"): + if path.name == "python.exe": return path.parent return path From 5db0848c97c603a3cab649142eb5fecb17eca402 Mon Sep 17 00:00:00 2001 From: macro128 <29261232+macro128@users.noreply.github.com> Date: Thu, 6 Jun 2024 00:47:54 -0300 Subject: [PATCH 15/18] update CHANGELOG.md --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 03f5525..f9132ee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,11 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -## [0.18.0] - 21/05/2024 +## [0.18.0] - 06/06/2024 ### Added -* Now compatible with `pdm==v2.15.3`. +* Now compatible with `pdm==v2.15.4`. * Add `conda.active` config to activate/deactivate pdm-conda plugin. ### Changed From 61783e3e8d0d445936caa4bd5175cc62e7d4ca4e Mon Sep 17 00:00:00 2001 From: macro128 <29261232+macro128@users.noreply.github.com> Date: Thu, 6 Jun 2024 00:48:38 -0300 Subject: [PATCH 16/18] update base --- base | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base b/base index 5b097fd..95e94d0 160000 --- a/base +++ b/base @@ -1 +1 @@ -Subproject commit 5b097fd428dda8a7eaccb2769c6b8b3538a22992 +Subproject commit 95e94d01d50fc9d75487b262375f428b5b683852 From 046ef1514c08cd60abf717386ed8b64aa0d74404 Mon Sep 17 00:00:00 2001 From: macro128 <29261232+macro128@users.noreply.github.com> Date: Sat, 8 Jun 2024 18:00:16 -0300 Subject: [PATCH 17/18] bump version --- src/pdm_conda/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pdm_conda/__init__.py b/src/pdm_conda/__init__.py index 0699eeb..b0ae56b 100644 --- a/src/pdm_conda/__init__.py +++ b/src/pdm_conda/__init__.py @@ -8,7 +8,7 @@ from pdm.core import Core logger = termui.logger -__version__ = "0.17.6" +__version__ = "0.18.0" def main(core: Core): From 677183f812cd4ec0936f7c1ed7120ed04fb980ab Mon Sep 17 00:00:00 2001 From: macro128 <29261232+macro128@users.noreply.github.com> Date: Sat, 8 Jun 2024 18:00:40 -0300 Subject: [PATCH 18/18] update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f9132ee..66b5528 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -## [0.18.0] - 06/06/2024 +## [0.18.0] - 08/06/2024 ### Added