From b6b1143b1be1d59a06e5ae1847e6e6a25c242b11 Mon Sep 17 00:00:00 2001 From: Sandrine Pataut Date: Wed, 5 Mar 2025 16:11:55 +0100 Subject: [PATCH] feat: add envs flag to info command (#3837) --- libmamba/CMakeLists.txt | 2 + libmamba/include/mamba/api/env.hpp | 27 ++++++ libmamba/src/api/env.cpp | 78 +++++++++++++++++ libmamba/src/api/info.cpp | 96 +++++++++++++++------ micromamba/src/env.cpp | 130 +++++++++-------------------- micromamba/src/info.cpp | 72 ++++------------ micromamba/tests/test_info.py | 73 ++++++++++++---- 7 files changed, 290 insertions(+), 188 deletions(-) create mode 100644 libmamba/include/mamba/api/env.hpp create mode 100644 libmamba/src/api/env.cpp diff --git a/libmamba/CMakeLists.txt b/libmamba/CMakeLists.txt index fb6e4b66e..16754c140 100644 --- a/libmamba/CMakeLists.txt +++ b/libmamba/CMakeLists.txt @@ -259,6 +259,7 @@ set( ${LIBMAMBA_SOURCE_DIR}/api/config.cpp ${LIBMAMBA_SOURCE_DIR}/api/configuration.cpp ${LIBMAMBA_SOURCE_DIR}/api/create.cpp + ${LIBMAMBA_SOURCE_DIR}/api/env.cpp ${LIBMAMBA_SOURCE_DIR}/api/info.cpp ${LIBMAMBA_SOURCE_DIR}/api/install.cpp ${LIBMAMBA_SOURCE_DIR}/api/list.cpp @@ -409,6 +410,7 @@ set( ${LIBMAMBA_INCLUDE_DIR}/mamba/api/configuration.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/api/constants.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/api/create.hpp + ${LIBMAMBA_INCLUDE_DIR}/mamba/api/env.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/api/info.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/api/install.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/api/list.hpp diff --git a/libmamba/include/mamba/api/env.hpp b/libmamba/include/mamba/api/env.hpp new file mode 100644 index 000000000..580caa4b3 --- /dev/null +++ b/libmamba/include/mamba/api/env.hpp @@ -0,0 +1,27 @@ +// Copyright (c) 2025, QuantStack and Mamba Contributors +// +// Distributed under the terms of the BSD 3-Clause License. +// +// The full license is in the file LICENSE, distributed with this software. + +#ifndef MAMBA_API_ENV_HPP +#define MAMBA_API_ENV_HPP + +#include "mamba/api/configuration.hpp" + +namespace mamba +{ + class ChannelContext; + class Configuration; + class Context; + + void print_envs(Configuration& config); + + namespace detail + { + std::string get_env_name(const Context& ctx, const mamba::fs::u8path& px); + void print_envs_impl(const Configuration& config); + } +} + +#endif diff --git a/libmamba/src/api/env.cpp b/libmamba/src/api/env.cpp new file mode 100644 index 000000000..ce945be10 --- /dev/null +++ b/libmamba/src/api/env.cpp @@ -0,0 +1,78 @@ +// Copyright (c) 2025, QuantStack and Mamba Contributors +// +// Distributed under the terms of the BSD 3-Clause License. +// +// The full license is in the file LICENSE, distributed with this software. + +#include + +#include "mamba/api/configuration.hpp" +#include "mamba/api/env.hpp" +#include "mamba/core/environments_manager.hpp" +#include "mamba/util/string.hpp" + +namespace mamba +{ + void print_envs(Configuration& config) + { + config.load(); + mamba::detail::print_envs_impl(config); + } + + namespace detail + { + std::string get_env_name(const Context& ctx, const mamba::fs::u8path& px) + { + auto& ed = ctx.envs_dirs[0]; + if (px == ctx.prefix_params.root_prefix) + { + return "base"; + } + else if (util::starts_with(px.string(), ed.string())) + { + return mamba::fs::relative(px, ed).string(); + } + else + { + return ""; + } + } + + void print_envs_impl(const Configuration& config) + { + const auto& ctx = config.context(); + + EnvironmentsManager env_manager{ ctx }; + + if (ctx.output_params.json) + { + nlohmann::json res; + const auto pfxs = env_manager.list_all_known_prefixes(); + std::vector envs(pfxs.size()); + std::transform( + pfxs.begin(), + pfxs.end(), + envs.begin(), + [](const mamba::fs::u8path& path) { return path.string(); } + ); + res["envs"] = envs; + std::cout << res.dump(4) << std::endl; + return; + } + + // format and print table + printers::Table t({ "Name", "Active", "Path" }); + t.set_alignment( + { printers::alignment::left, printers::alignment::left, printers::alignment::left } + ); + t.set_padding({ 2, 2, 2 }); + + for (auto& env : env_manager.list_all_known_prefixes()) + { + bool is_active = (env == ctx.prefix_params.target_prefix); + t.add_row({ get_env_name(ctx, env), is_active ? "*" : "", env.string() }); + } + t.print(std::cout); + } + } +} diff --git a/libmamba/src/api/info.cpp b/libmamba/src/api/info.cpp index b94b65003..12a7ed9f9 100644 --- a/libmamba/src/api/info.cpp +++ b/libmamba/src/api/info.cpp @@ -5,6 +5,7 @@ // The full license is in the file LICENSE, distributed with this software. #include "mamba/api/configuration.hpp" +#include "mamba/api/env.hpp" #include "mamba/api/info.hpp" #include "mamba/core/channel_context.hpp" #include "mamba/core/context.hpp" @@ -27,13 +28,17 @@ namespace mamba { struct InfoOptions { + bool print_licenses = false; bool base = false; + bool environments = false; }; - void info_pretty_print( - std::vector> items, - const Context::OutputParams& params - ) + // Prints a sequence of string/json-value pairs in a pretty table. + // requirements: + // - T must be a sequence of pair-like elements; + // - the elements of T must be composed of a `std::string` and a `nlhomann::json` objects + template + void info_pretty_print(const T& items, const Context::OutputParams& params) { if (params.json) { @@ -41,26 +46,24 @@ namespace mamba } std::size_t key_max_length = 0; - for (auto& item : items) + for (const auto& [key, value] : items) { - std::size_t key_length = std::get<0>(item).size(); + std::size_t key_length = key.size(); key_max_length = std::max(key_length, key_max_length); } ++key_max_length; auto stream = Console::stream(); - for (auto& item : items) + for (const auto& [key, value] : items) { - auto key = std::get<0>(item); - auto val = std::get<1>(item); - auto blk_size = key_max_length - std::get<0>(item).size(); + auto blk_size = key_max_length - key.size(); stream << "\n" << std::string(blk_size, ' ') << key << " : "; - for (auto v = val.begin(); v != val.end(); ++v) + for (auto v = value.begin(); v != value.end(); ++v) { - stream << (*v).get(); - if (v != (val.end() - 1)) + stream << (*v).template get(); + if (v != (value.end() - 1)) { stream << "\n" << std::string(key_max_length + 3, ' '); } @@ -68,10 +71,15 @@ namespace mamba } } - void info_json_print(std::vector> items) + // Prints a sequence of string/json-value pairs in a json format. + // requirements: + // - T must be a sequence of pair-like elements; + // - the elements of T must be composed of a `std::string` and a `nlhomann::json` objects + template + void info_json_print(const T& items) { std::map items_map; - for (auto& [key, val] : items) + for (const auto& [key, val] : items) { items_map.insert({ key, val }); } @@ -79,27 +87,65 @@ namespace mamba Console::instance().json_write(items_map); } - void print_info( - Context& ctx, - ChannelContext& channel_context, - const Configuration& config, - InfoOptions options - ) + void + print_info(Context& ctx, ChannelContext& channel_context, Configuration& config, InfoOptions options) { assert(&ctx == &config.context()); - std::vector> items; + using info_sequence = std::vector>; + if (options.print_licenses) + { + static const std::vector> licenses = { + { "micromamba", + "BSD license, Copyright 2019 QuantStack and the Mamba contributors." }, + { "c_ares", + "MIT license, Copyright (c) 2007 - 2018, Daniel Stenberg with many contributors, see AUTHORS file." }, + { "cli11", + "BSD license, CLI11 1.8 Copyright (c) 2017-2019 University of Cincinnati, developed by Henry Schreiner under NSF AWARD 1414736. All rights reserved." }, + { "cpp_filesystem", + "MIT license, Copyright (c) 2018, Steffen Schümann " }, + { "curl", + "MIT license, Copyright (c) 1996 - 2020, Daniel Stenberg, daniel@haxx.se, and many contributors, see the THANKS file." }, + { "krb5", + "MIT license, Copyright 1985-2020 by the Massachusetts Institute of Technology." }, + { "libarchive", + "New BSD license, The libarchive distribution as a whole is Copyright by Tim Kientzle and is subject to the copyright notice reproduced at the bottom of this file." }, + { "libev", + "BSD license, All files in libev are Copyright (c)2007,2008,2009,2010,2011,2012,2013 Marc Alexander Lehmann." }, + { "liblz4", "LZ4 Library, Copyright (c) 2011-2016, Yann Collet" }, + { "libnghttp2", + "MIT license, Copyright (c) 2012, 2014, 2015, 2016 Tatsuhiro Tsujikawa; 2012, 2014, 2015, 2016 nghttp2 contributors" }, + { "libopenssl_3", "Apache license, Version 2.0, January 2004" }, + { "libopenssl", + "Apache license, Copyright (c) 1998-2019 The OpenSSL Project, All rights reserved; 1995-1998 Eric Young (eay@cryptsoft.com)" }, + { "libsolv", "BSD license, Copyright (c) 2019, SUSE LLC" }, + { "nlohmann_json", "MIT license, Copyright (c) 2013-2020 Niels Lohmann" }, + { "reproc", "MIT license, Copyright (c) Daan De Meyer" }, + { "fmt", "MIT license, Copyright (c) 2012-present, Victor Zverovich." }, + { "spdlog", "MIT license, Copyright (c) 2016 Gabi Melman." }, + { "zstd", + "BSD license, Copyright (c) 2016-present, Facebook, Inc. All rights reserved." }, + }; + info_json_print(licenses); + info_pretty_print(licenses, ctx.output_params); + return; + } if (options.base) { - items.push_back({ "base environment", ctx.prefix_params.root_prefix.string() }); + info_sequence items{ { "base environment", ctx.prefix_params.root_prefix.string() } }; info_json_print(items); info_pretty_print(items, ctx.output_params); return; } + if (options.environments) + { + mamba::detail::print_envs_impl(config); + return; + } - items.push_back({ "libmamba version", version() }); + info_sequence items{ { "libmamba version", version() } }; if (ctx.command_params.is_mamba_exe && !ctx.command_params.caller_version.empty()) { @@ -205,7 +251,9 @@ namespace mamba config.load(); detail::InfoOptions options; + options.print_licenses = config.at("print_licenses").value(); options.base = config.at("base").value(); + options.environments = config.at("environments").value(); auto channel_context = ChannelContext::make_conda_compatible(config.context()); detail::print_info(config.context(), channel_context, config, std::move(options)); diff --git a/micromamba/src/env.cpp b/micromamba/src/env.cpp index e86a9ea1d..44f6c6fc2 100644 --- a/micromamba/src/env.cpp +++ b/micromamba/src/env.cpp @@ -8,6 +8,7 @@ #include "mamba/api/configuration.hpp" #include "mamba/api/create.hpp" +#include "mamba/api/env.hpp" #include "mamba/api/remove.hpp" #include "mamba/api/update.hpp" #include "mamba/core/channel_context.hpp" @@ -20,29 +21,8 @@ #include "common_options.hpp" - -using namespace mamba; // NOLINT(build/namespaces) - -std::string -get_env_name(const Context& ctx, const mamba::fs::u8path& px) -{ - auto& ed = ctx.envs_dirs[0]; - if (px == ctx.prefix_params.root_prefix) - { - return "base"; - } - else if (util::starts_with(px.string(), ed.string())) - { - return mamba::fs::relative(px, ed).string(); - } - else - { - return ""; - } -} - void -set_env_command(CLI::App* com, Configuration& config) +set_env_command(CLI::App* com, mamba::Configuration& config) { init_general_options(com, config); init_prefix_options(com, config); @@ -52,45 +32,7 @@ set_env_command(CLI::App* com, Configuration& config) init_general_options(list_subcom, config); init_prefix_options(list_subcom, config); - list_subcom->callback( - [&config] - { - const auto& ctx = config.context(); - config.load(); - - EnvironmentsManager env_manager{ ctx }; - - if (ctx.output_params.json) - { - nlohmann::json res; - const auto pfxs = env_manager.list_all_known_prefixes(); - std::vector envs(pfxs.size()); - std::transform( - pfxs.begin(), - pfxs.end(), - envs.begin(), - [](const mamba::fs::u8path& path) { return path.string(); } - ); - res["envs"] = envs; - std::cout << res.dump(4) << std::endl; - return; - } - - // format and print table - printers::Table t({ "Name", "Active", "Path" }); - t.set_alignment( - { printers::alignment::left, printers::alignment::left, printers::alignment::left } - ); - t.set_padding({ 2, 2, 2 }); - - for (auto& env : env_manager.list_all_known_prefixes()) - { - bool is_active = (env == ctx.prefix_params.target_prefix); - t.add_row({ get_env_name(ctx, env), is_active ? "*" : "", env.string() }); - } - t.print(std::cout); - } - ); + list_subcom->callback([&config] { mamba::print_envs(config); }); // env create subcommand auto* create_subcom = com->add_subcommand( @@ -143,7 +85,8 @@ set_env_command(CLI::App* com, Configuration& config) if (explicit_format) { // TODO: handle error - auto pd = PrefixData::create(ctx.prefix_params.target_prefix, channel_context).value(); + auto pd = mamba::PrefixData::create(ctx.prefix_params.target_prefix, channel_context) + .value(); auto records = pd.sorted_records(); std::cout << "# This file may be used to create an environment using:\n" << "# $ conda create --name --file \n" @@ -153,19 +96,19 @@ set_env_command(CLI::App* com, Configuration& config) for (const auto& record : records) { std::cout << // - specs::CondaURL::parse(record.package_url) + mamba::specs::CondaURL::parse(record.package_url) .transform( - [](specs::CondaURL&& url) + [](mamba::specs::CondaURL&& url) { return url.pretty_str( - specs::CondaURL::StripScheme::no, + mamba::specs::CondaURL::StripScheme::no, 0, // don't strip any path characters - specs::CondaURL::Credentials::Remove + mamba::specs::CondaURL::Credentials::Remove ); } ) .or_else( - [&](const auto&) -> specs::expected_parse_t + [&](const auto&) -> mamba::specs::expected_parse_t { return record.package_url; } ) .value(); @@ -179,8 +122,9 @@ set_env_command(CLI::App* com, Configuration& config) } else if (json_format) { - auto pd = PrefixData::create(ctx.prefix_params.target_prefix, channel_context).value(); - History& hist = pd.history(); + auto pd = mamba::PrefixData::create(ctx.prefix_params.target_prefix, channel_context) + .value(); + mamba::History& hist = pd.history(); const auto& versions_map = pd.records(); const auto& pip_versions_map = pd.pip_records(); @@ -260,7 +204,8 @@ set_env_command(CLI::App* com, Configuration& config) std::cout << " \"dependencies\": [\n" << dependencies.str() << " ],\n"; - std::cout << " \"name\": \"" << get_env_name(ctx, ctx.prefix_params.target_prefix) + std::cout << " \"name\": \"" + << mamba::detail::get_env_name(ctx, ctx.prefix_params.target_prefix) << "\",\n"; std::cout << " \"prefix\": " << ctx.prefix_params.target_prefix << "\n"; @@ -270,13 +215,16 @@ set_env_command(CLI::App* com, Configuration& config) } else { - auto pd = PrefixData::create(ctx.prefix_params.target_prefix, channel_context).value(); - History& hist = pd.history(); + auto pd = mamba::PrefixData::create(ctx.prefix_params.target_prefix, channel_context) + .value(); + mamba::History& hist = pd.history(); const auto& versions_map = pd.records(); const auto& pip_versions_map = pd.pip_records(); - std::cout << "name: " << get_env_name(ctx, ctx.prefix_params.target_prefix) << "\n"; + std::cout << "name: " + << mamba::detail::get_env_name(ctx, ctx.prefix_params.target_prefix) + << "\n"; std::cout << "channels:\n"; auto requested_specs_map = hist.get_requested_specs_map(); @@ -355,22 +303,22 @@ set_env_command(CLI::App* com, Configuration& config) [&config] { // Remove specs if exist - RemoveResult remove_env_result = remove(config, MAMBA_REMOVE_ALL); + mamba::RemoveResult remove_env_result = remove(config, mamba::MAMBA_REMOVE_ALL); - if (remove_env_result == RemoveResult::NO) + if (remove_env_result == mamba::RemoveResult::NO) { - Console::stream() << "The environment was not removed."; + mamba::Console::stream() << "The environment was not removed."; return; } - if (remove_env_result == RemoveResult::EMPTY) + if (remove_env_result == mamba::RemoveResult::EMPTY) { - Console::stream() << "No packages to remove from environment."; + mamba::Console::stream() << "No packages to remove from environment."; - auto res = Console::prompt("Do you want to remove the environment?", 'Y'); + auto res = mamba::Console::prompt("Do you want to remove the environment?", 'Y'); if (!res) { - Console::stream() << "The environment was not removed."; + mamba::Console::stream() << "The environment was not removed."; return; } } @@ -380,21 +328,21 @@ set_env_command(CLI::App* com, Configuration& config) { const auto& prefix = ctx.prefix_params.target_prefix; // Remove env directory or rename it (e.g. if used) - remove_or_rename(ctx, util::expand_home(prefix.string())); + remove_or_rename(ctx, mamba::util::expand_home(prefix.string())); - EnvironmentsManager env_manager{ ctx }; + mamba::EnvironmentsManager env_manager{ ctx }; // Unregister environment - env_manager.unregister_env(util::expand_home(prefix.string())); + env_manager.unregister_env(mamba::util::expand_home(prefix.string())); - Console::instance().print(util::join( + mamba::Console::instance().print(mamba::util::join( "", std::vector({ "Environment removed at prefix: ", prefix.string() }) )); - Console::instance().json_write({ { "success", true } }); + mamba::Console::instance().json_write({ { "success", true } }); } else { - Console::stream() << "Dry run. The environment was not removed."; + mamba::Console::stream() << "Dry run. The environment was not removed."; } } ); @@ -424,11 +372,11 @@ set_env_command(CLI::App* com, Configuration& config) update_subcom->callback( [&config] { - auto update_params = UpdateParams{ - UpdateAll::No, - PruneDeps::Yes, - EnvUpdate::Yes, - remove_not_specified ? RemoveNotSpecified::Yes : RemoveNotSpecified::No, + auto update_params = mamba::UpdateParams{ + mamba::UpdateAll::No, + mamba::PruneDeps::Yes, + mamba::EnvUpdate::Yes, + remove_not_specified ? mamba::RemoveNotSpecified::Yes : mamba::RemoveNotSpecified::No, }; update(config, update_params); diff --git a/micromamba/src/info.cpp b/micromamba/src/info.cpp index bfef05071..0c8dae683 100644 --- a/micromamba/src/info.cpp +++ b/micromamba/src/info.cpp @@ -15,69 +15,27 @@ init_info_parser(CLI::App* subcom, mamba::Configuration& config) { init_general_options(subcom, config); init_prefix_options(subcom, config); -} -void -set_info_command(CLI::App* subcom, mamba::Configuration& config) -{ - init_info_parser(subcom, config); - static bool print_licenses; + auto& print_licenses = config.insert( + mamba::Configurable("print_licenses", false).group("cli").description("Print licenses.") + ); + subcom->add_flag("--licenses", print_licenses.get_cli_config(), print_licenses.description()); auto& base = config.insert( mamba::Configurable("base", false).group("cli").description("Display base environment path.") ); subcom->add_flag("--base", base.get_cli_config(), base.description()); - subcom->add_flag("--licenses", print_licenses, "Print licenses"); - - subcom->callback( - [&config] - { - // TODO: Print full license texts. - if (print_licenses) - { - const std::vector> licenses = { - { "micromamba", - "BSD license, Copyright 2019 QuantStack and the Mamba contributors." }, - { "c_ares", - "MIT license, Copyright (c) 2007 - 2018, Daniel Stenberg with many contributors, see AUTHORS file." }, - { "cli11", - "BSD license, CLI11 1.8 Copyright (c) 2017-2019 University of Cincinnati, developed by Henry Schreiner under NSF AWARD 1414736. All rights reserved." }, - { "cpp_filesystem", - "MIT license, Copyright (c) 2018, Steffen Schümann " }, - { "curl", - "MIT license, Copyright (c) 1996 - 2020, Daniel Stenberg, daniel@haxx.se, and many contributors, see the THANKS file." }, - { "krb5", - "MIT license, Copyright 1985-2020 by the Massachusetts Institute of Technology." }, - { "libarchive", - "New BSD license, The libarchive distribution as a whole is Copyright by Tim Kientzle and is subject to the copyright notice reproduced at the bottom of this file." }, - { "libev", - "BSD license, All files in libev are Copyright (c)2007,2008,2009,2010,2011,2012,2013 Marc Alexander Lehmann." }, - { "liblz4", "LZ4 Library, Copyright (c) 2011-2016, Yann Collet" }, - { "libnghttp2", - "MIT license, Copyright (c) 2012, 2014, 2015, 2016 Tatsuhiro Tsujikawa; 2012, 2014, 2015, 2016 nghttp2 contributors" }, - { "libopenssl_3", "Apache license, Version 2.0, January 2004" }, - { "libopenssl", - "Apache license, Copyright (c) 1998-2019 The OpenSSL Project, All rights reserved; 1995-1998 Eric Young (eay@cryptsoft.com)" }, - { "libsolv", "BSD license, Copyright (c) 2019, SUSE LLC" }, - { "nlohmann_json", "MIT license, Copyright (c) 2013-2020 Niels Lohmann" }, - { "reproc", "MIT license, Copyright (c) Daan De Meyer" }, - { "fmt", "MIT license, Copyright (c) 2012-present, Victor Zverovich." }, - { "spdlog", "MIT license, Copyright (c) 2016 Gabi Melman." }, - { "zstd", - "BSD license, Copyright (c) 2016-present, Facebook, Inc. All rights reserved." }, - }; - for (const auto& [dep, text] : licenses) - { - std::cout << dep << "\n" - << std::string(dep.size(), '-') << "\n" - << text << "\n\n"; - } - } - else - { - info(config); - } - } + auto& environments = config.insert( + mamba::Configurable("environments", false).group("cli").description("List known environments.") ); + subcom->add_flag("-e,--envs", environments.get_cli_config(), environments.description()); +} + +void +set_info_command(CLI::App* subcom, mamba::Configuration& config) +{ + init_info_parser(subcom, config); + + subcom->callback([&config] { info(config); }); } diff --git a/micromamba/tests/test_info.py b/micromamba/tests/test_info.py index c71ab4e92..563571bb4 100644 --- a/micromamba/tests/test_info.py +++ b/micromamba/tests/test_info.py @@ -79,21 +79,7 @@ def test_not_env(tmp_home, tmp_root_prefix, prefix_selection, existing_prefix): assert f"base environment : {tmp_root_prefix}" in infos -@pytest.mark.parametrize("base_flag", ["", "--base"]) -@pytest.mark.parametrize("json_flag", ["", "--json"]) -@pytest.mark.parametrize("prefix_selection", [None, "prefix", "name"]) -def test_base_subcommand( - tmp_home, tmp_root_prefix, prefix_selection, base_flag, json_flag, monkeypatch -): - monkeypatch.setenv("CONDA_PREFIX", str(tmp_root_prefix)) - - if prefix_selection == "prefix": - infos = helpers.info("-p", tmp_root_prefix, base_flag, json_flag) - elif prefix_selection == "name": - infos = helpers.info("-n", "base", base_flag, json_flag) - else: - infos = helpers.info(base_flag, json_flag) - +def flags_test(tmp_root_prefix, infos, base_flag, envs_flag, json_flag): items = [ "libmamba version", "mamba version", @@ -117,13 +103,68 @@ def test_base_subcommand( else: assert all( (f"{i} :" not in infos) | (f"\n{i} :" not in infos) for i in items - ) # f"\n{i} :" is to handle the case of the "environment" item + ) # f"\n{i} :" is there to handle the case of the "environment" item (which appears in "base environment" as well) base_environment_path = infos.replace("base environment :", "").strip() assert os.path.exists(base_environment_path) assert base_environment_path == str(tmp_root_prefix) + elif envs_flag in ["-e", "--envs"]: + if json_flag == "--json": + assert str(tmp_root_prefix) in infos["envs"] + else: + assert "Name" in infos + assert "base" in infos + assert str(tmp_root_prefix) in infos + all_lines = infos.splitlines() + for line in all_lines: + if "*" in line: + active_env_l = line + assert str(tmp_root_prefix) in active_env_l else: items += ["base environment"] if json_flag == "--json": assert all(i in infos.keys() for i in items) else: assert all(f"{i} :" in infos for i in items) + + +@pytest.mark.parametrize("base_flag", ["", "--base"]) +@pytest.mark.parametrize("envs_flag", ["", "-e", "--envs"]) +@pytest.mark.parametrize("json_flag", ["", "--json"]) +@pytest.mark.parametrize("prefix_selection", [None, "prefix", "name"]) +def test_base_flags( + tmp_home, tmp_root_prefix, prefix_selection, base_flag, envs_flag, json_flag, monkeypatch +): + monkeypatch.setenv("CONDA_PREFIX", str(tmp_root_prefix)) + + if prefix_selection == "prefix": + infos = helpers.info("-p", tmp_root_prefix, base_flag, envs_flag, json_flag) + elif prefix_selection == "name": + infos = helpers.info("-n", "base", base_flag, envs_flag, json_flag) + else: + infos = helpers.info(base_flag, envs_flag, json_flag) + + flags_test(tmp_root_prefix, infos, base_flag, envs_flag, json_flag) + + +@pytest.mark.parametrize("base_flag", ["", "--base"]) +@pytest.mark.parametrize("envs_flag", ["", "-e", "--envs"]) +@pytest.mark.parametrize("json_flag", ["", "--json"]) +@pytest.mark.parametrize("prefix_selection", [None, "prefix", "name"]) +def test_env_flags( + tmp_home, + tmp_root_prefix, + tmp_env_name, + tmp_prefix, + prefix_selection, + base_flag, + envs_flag, + json_flag, +): + if prefix_selection == "prefix": + infos = helpers.info("-p", tmp_prefix, base_flag, envs_flag, json_flag) + elif prefix_selection == "name": + infos = helpers.info("-n", tmp_env_name, base_flag, envs_flag, json_flag) + else: + infos = helpers.info(base_flag, envs_flag, json_flag) + + flags_test(tmp_root_prefix, infos, base_flag, envs_flag, json_flag)