diff --git a/libmamba/include/mamba/api/configuration_impl.hpp b/libmamba/include/mamba/api/configuration_impl.hpp index 365205b800..45e82424be 100644 --- a/libmamba/include/mamba/api/configuration_impl.hpp +++ b/libmamba/include/mamba/api/configuration_impl.hpp @@ -83,7 +83,7 @@ namespace mamba { static std::vector default_value(const std::vector& init) { - return std::vector(init.size(), "default"); + return std::vector(std::max(1, init.size()), "default"); }; static void merge( diff --git a/libmamba/src/core/context.cpp b/libmamba/src/core/context.cpp index e436c59f97..b0b1310f47 100644 --- a/libmamba/src/core/context.cpp +++ b/libmamba/src/core/context.cpp @@ -181,7 +181,7 @@ namespace mamba prefix_params.root_prefix = detail::get_root_prefix(); prefix_params.conda_prefix = prefix_params.root_prefix; - envs_dirs = { prefix_params.root_prefix / "envs" }; + envs_dirs = {}; pkgs_dirs = { prefix_params.root_prefix / "pkgs", fs::u8path("~") / ".mamba" / "pkgs" #ifdef _WIN32 diff --git a/micromamba/tests/test_create.py b/micromamba/tests/test_create.py index 56b0089c4d..562f744f3d 100644 --- a/micromamba/tests/test_create.py +++ b/micromamba/tests/test_create.py @@ -253,6 +253,7 @@ def test_env_logging_overhead_regression(tmp_home, tmp_root_prefix, tmp_path): "similar_non_canonical,non_canonical_position", ((False, None), (True, "append"), (True, "prepend")), ) +@pytest.mark.parametrize("root_prefix_env_exists", (False, True)) def test_target_prefix( tmp_home, tmp_root_prefix, @@ -266,6 +267,7 @@ def test_target_prefix( current_target_prefix_fallback, similar_non_canonical, non_canonical_position, + root_prefix_env_exists, ): cmd = [] @@ -277,6 +279,11 @@ def test_target_prefix( else: root_prefix = Path(os.environ["MAMBA_ROOT_PREFIX"]) + # TODO: Remove this call to `os.makedirs` once + # https://github.com/mamba-org/mamba/issues/3790 is fixed + if root_prefix_env_exists: + os.makedirs(Path(os.environ["MAMBA_ROOT_PREFIX"]) / "envs", exist_ok=True) + env_prefix = tmp_path / "myenv" if target_is_root: @@ -661,6 +668,93 @@ def test_create_envs_dirs(tmp_root_prefix: Path, tmp_path: Path): assert (tmp_path / env_name / "conda-meta" / "history").exists() +@pytest.mark.parametrize("set_in_conda_envs_dirs", (False, True)) +@pytest.mark.parametrize("set_in_condarc", (False, True)) +@pytest.mark.parametrize("cli_root_prefix", (False, True)) +@pytest.mark.parametrize("check_config_only", (False, True)) +def test_root_prefix_precedence( + tmp_path, + tmp_home, + monkeypatch, + set_in_condarc, + set_in_conda_envs_dirs, + cli_root_prefix, + check_config_only, +): + """ + Test for root prefix precedence + + Environments can be created in several places depending, in this order: + - 1. in the folder of `CONDA_ENVS_DIRS` if it is set + - 2. in the folder of `envs_dirs` if set in the rc file + - 3. the root prefix given by the user's command (e.g. specified via the `-r` option) + - 4. the usual root prefix (set generally by `MAMBA_ROOT_PREFIX`) + """ + + # Given by `CONDA_ENVS_DIRS` + conda_envs_dirs = tmp_path / "conda_envs_dirs" / "envs" + # Given by `envs_dirs` in the rc file + condarc_envs_dirs = tmp_path / "condarc_envs_dirs" / "envs" + # Given via the CLI + cli_provided_root = tmp_path / "cliroot" + cli_provided_root_envs = cli_provided_root / "envs" + # Given by `MAMBA_ROOT_PREFIX` + mamba_root_prefix = tmp_path / "envroot" + mamba_root_prefix_envs = mamba_root_prefix / "envs" + + env_name = "foo" + monkeypatch.setenv("MAMBA_ROOT_PREFIX", str(mamba_root_prefix)) + if set_in_conda_envs_dirs: + monkeypatch.setenv("CONDA_ENVS_DIRS", str(conda_envs_dirs)) + + with open(tmp_home / ".condarc", "w+") as f: + if set_in_condarc: + f.write(f"envs_dirs: [{str(condarc_envs_dirs)}]") + + # TODO: Remove this call to `os.makedirs` once + # https://github.com/mamba-org/mamba/issues/3790 is fixed + for envs_folder in (condarc_envs_dirs, conda_envs_dirs, cli_provided_root, mamba_root_prefix): + os.makedirs(envs_folder, exist_ok=True) + + cmd = ["-n", env_name, "--rc-file", tmp_home / ".condarc"] + + if check_config_only: + cmd += ["--print-config-only", "--debug"] + + if cli_root_prefix: + cmd += ["-r", cli_provided_root] + + res = helpers.create(*cmd, no_rc=False) + + def assert_env_exists(prefix_path): + assert Path(prefix_path / env_name).exists() + + if check_config_only: + expected_envs_dirs = [] + if set_in_conda_envs_dirs: + expected_envs_dirs.append(str(conda_envs_dirs)) + if set_in_condarc: + expected_envs_dirs.append(str(condarc_envs_dirs)) + if cli_root_prefix: + expected_envs_dirs.append(str(cli_provided_root_envs)) + else: + expected_envs_dirs.append(str(mamba_root_prefix_envs)) + + effective_envs_dirs = res["envs_dirs"] + assert effective_envs_dirs == expected_envs_dirs + + # Otherwise, we check that `foo` has been created in the directory + # based on precedence given above. + elif set_in_conda_envs_dirs: + assert_env_exists(conda_envs_dirs) + elif set_in_condarc: + assert_env_exists(condarc_envs_dirs) + elif cli_root_prefix: + assert_env_exists(cli_provided_root_envs) + else: + assert_env_exists(mamba_root_prefix_envs) + + @pytest.mark.skipif( helpers.dry_run_tests is helpers.DryRun.ULTRA_DRY, reason="Running only ultra-dry tests",