diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ffcdd05c..e8d86f9b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -38,21 +38,19 @@ jobs: ref: poc-libsolv path: conda - - name: Merge repositories - run: mv conda-libmamba-solver conda/ - - name: Python ${{ matrix.python-version }} - working-directory: conda run: > docker run - --rm -v ${PWD}:/opt/conda-src + --rm + -v ${GITHUB_WORKSPACE}/conda:/opt/conda-src + -v ${GITHUB_WORKSPACE}/conda-libmamba-solver:/opt/conda-libmamba-solver-src -e TEST_SPLITS -e TEST_GROUP -e CONDA_SOLVER_LOGIC ghcr.io/conda/conda-ci:poc-libsolv-linux-python${{ matrix.python-version }}-mamba - bash -c "/opt/conda/bin/python -m pip install /opt/conda-src/conda-libmamba-solver --no-deps -vvv && + bash -c "/opt/conda/bin/python -m pip install /opt/conda-libmamba-solver-src --no-deps -vvv && source /opt/conda-src/dev/linux/bashrc.sh && - /opt/conda/bin/python -m pytest /opt/conda-src/conda-libmamba-solver/ -vv" + /opt/conda/bin/python -m pytest /opt/conda-libmamba-solver-src -vv" macos: name: MacOS, Python ${{ matrix.python-version }} diff --git a/.github/workflows/upstream_ci.yml b/.github/workflows/upstream_ci.yml index 85c65802..22d02580 100644 --- a/.github/workflows/upstream_ci.yml +++ b/.github/workflows/upstream_ci.yml @@ -58,19 +58,18 @@ jobs: ref: poc-libsolv path: conda - - name: Merge repositories - run: mv conda-libmamba-solver conda/ - - name: Python ${{ matrix.python-version }} ${{ matrix.test-type }} tests, group ${{ matrix.test-group }} working-directory: conda run: > docker run - --rm -v ${PWD}:/opt/conda-src + --rm + -v ${GITHUB_WORKSPACE}/conda:/opt/conda-src + -v ${GITHUB_WORKSPACE}/conda-libmamba-solver:/opt/conda-libmamba-solver-src -e TEST_SPLITS -e TEST_GROUP -e CONDA_SOLVER_LOGIC ghcr.io/conda/conda-ci:poc-libsolv-linux-python${{ matrix.python-version }}-mamba - bash -c "/opt/conda/bin/python -m pip install /opt/conda-src/conda-libmamba-solver --no-deps -vvv && + bash -c "/opt/conda/bin/python -m pip install /opt/conda-libmamba-solver-src --no-deps -vvv && source /opt/conda-src/dev/linux/${{ matrix.test-type }}.sh" macos: diff --git a/conda_libmamba_solver/_libmamba.py b/conda_libmamba_solver/_libmamba.py index 71bc1abf..b39c85b7 100644 --- a/conda_libmamba_solver/_libmamba.py +++ b/conda_libmamba_solver/_libmamba.py @@ -9,6 +9,7 @@ from itertools import chain from collections import defaultdict, OrderedDict from logging import getLogger +import os from conda.core.index import _supplement_index_with_system from conda.core.prefix_data import PrefixData @@ -28,6 +29,7 @@ PackagesNotFoundError, SpecsConfigurationConflictError, RawStrUnsatisfiableError, + CondaEnvironmentError, ) from conda.history import History from conda.models.channel import Channel @@ -73,6 +75,12 @@ def solve_final_state( if not context.json and not context.quiet: print("------ USING EXPERIMENTAL LIBMAMBA INTEGRATIONS ------") + if "PYTEST_CURRENT_TEST" not in os.environ and paths_equal(self.prefix, context.root_prefix): + raise CondaEnvironmentError( + f"{self.__class__.__name__} is not allowed on the base environment during " + "the experimental release phase. Try using it on a non-base environment!" + ) + # 0. Identify strategies kwargs = self._merge_signature_flags_with_context( update_modifier=update_modifier, diff --git a/conda_libmamba_solver/solver.py b/conda_libmamba_solver/solver.py index a3970412..5114df69 100644 --- a/conda_libmamba_solver/solver.py +++ b/conda_libmamba_solver/solver.py @@ -18,6 +18,7 @@ from conda.common.constants import NULL from conda.common.io import CapturedDescriptor from conda.common.serialize import json_dump, json_load +from conda.common.path import paths_equal from conda.common.url import ( escape_channel_url, split_anaconda_token, @@ -28,6 +29,7 @@ RawStrUnsatisfiableError, SpecsConfigurationConflictError, UnsatisfiableError, + CondaEnvironmentError, ) from conda.models.channel import Channel from conda.models.match_spec import MatchSpec @@ -36,7 +38,12 @@ import libmambapy as api from .state import SolverInputState, SolverOutputState, IndexHelper -from .mamba_utils import load_channels, to_package_record_from_subjson, init_api_context, mamba_version +from .mamba_utils import ( + load_channels, + to_package_record_from_subjson, + init_api_context, + mamba_version, +) log = logging.getLogger(__name__) @@ -181,6 +188,7 @@ def solve_final_state( ): # Temporary, only during experimental phase to ease debugging self._print_info() + self._check_env_is_base() in_state = SolverInputState( prefix=self.prefix, @@ -287,7 +295,7 @@ def _print_info(self): print( dedent( f""" - ---- USING EXPERIMENTAL LIBMAMBA2 INTEGRATIONS ---- + ---- USING EXPERIMENTAL LIBMAMBA INTEGRATIONS ---- This is a highly experimental product. If something is not working as expected, please submit an issue at https://github.com/conda/conda and attach the log file @@ -300,7 +308,7 @@ def _print_info(self): ) ) - log.info("Using experimental libmamba2 integrations") + log.info("Using experimental libmamba integrations") log.info("Conda version: %s", _conda_version) log.info("Mamba version: %s", mamba_version()) log.info("Target prefix: %s", self.prefix) @@ -308,6 +316,16 @@ def _print_info(self): log.info("Specs to add: %s", self.specs_to_add) log.info("Specs to remove: %s", self.specs_to_remove) + def _check_env_is_base(self): + if "PYTEST_CURRENT_TEST" in os.environ: + return + + if paths_equal(self.prefix, context.root_prefix): + raise CondaEnvironmentError( + f"{self.__class__.__name__} is not allowed on the base environment during " + "the experimental release phase. Try using it on a non-base environment!" + ) + def _setup_solver(self, index: LibMambaIndexHelper): self._solver_options = solver_options = [ (api.SOLVER_FLAG_ALLOW_DOWNGRADE, 1), diff --git a/tests/test_experimental.py b/tests/test_experimental.py new file mode 100644 index 00000000..a682c0e0 --- /dev/null +++ b/tests/test_experimental.py @@ -0,0 +1,16 @@ +""" +Ensure experimental features work accordingly. +""" +import os +import pytest + +from conda.base.context import fresh_context, context +from conda.exceptions import CondaEnvironmentError +from conda.testing.integration import run_command, Commands + + +@pytest.mark.parametrize("solver", ("libmamba", "libmamba-draft")) +def test_protection_for_base_env(solver): + with pytest.raises(CondaEnvironmentError), fresh_context(CONDA_SOLVER_LOGIC=solver): + os.environ.pop("PYTEST_CURRENT_TEST", None) + run_command(Commands.INSTALL, context.root_prefix, "--dry-run", "scipy", no_capture=True) diff --git a/tests/test_solvers.py b/tests/test_solvers.py index 07f31934..7dc73bfe 100644 --- a/tests/test_solvers.py +++ b/tests/test_solvers.py @@ -7,13 +7,11 @@ from conda_libmamba_solver import LibMambaSolver, LibMambaSolverDraft - class TestLibMambaSolver(SolverTests): @property def solver_class(self): return LibMambaSolver - @property def tests_to_skip(self): return { diff --git a/tests/test_state.py b/tests/test_state.py index 23872f12..1dd926e4 100644 --- a/tests/test_state.py +++ b/tests/test_state.py @@ -8,27 +8,22 @@ behavioral units that, eventually, will allow us to further split the logic into discrete, composable parts. """ -from tempfile import TemporaryDirectory import pytest from conda.base.context import context, fresh_context -from conda.core.solve import Solver from conda.models.match_spec import MatchSpec -from conda.testing.solver_helpers import SimpleEnvironment, index_packages +from conda.testing.solver_helpers import ( + SimpleEnvironment, + index_packages, + empty_prefix, + temp_simple_env, +) from conda_libmamba_solver.solver import LibMambaIndexHelper from conda_libmamba_solver.state import SolverInputState, SolverOutputState - -def empty_prefix(): - return TemporaryDirectory(prefix="conda-test-repo-") - - -@pytest.fixture() -def env(solver_class=Solver) -> SimpleEnvironment: - with empty_prefix() as prefix: - yield SimpleEnvironment(prefix, solver_class) +env = temp_simple_env @pytest.mark.parametrize(