feat: add envs flag to info command (#3837)

This commit is contained in:
Sandrine Pataut 2025-03-05 16:11:55 +01:00 committed by GitHub
parent b117f3acae
commit b6b1143b1b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 290 additions and 188 deletions

View File

@ -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

View File

@ -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

78
libmamba/src/api/env.cpp Normal file
View File

@ -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 <iostream>
#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<std::string> 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);
}
}
}

View File

@ -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<std::tuple<std::string, nlohmann::json>> 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 <typename T>
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<std::string>();
if (v != (val.end() - 1))
stream << (*v).template get<std::string>();
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<std::tuple<std::string, nlohmann::json>> 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 <typename T>
void info_json_print(const T& items)
{
std::map<std::string, nlohmann::json> 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<std::tuple<std::string, nlohmann::json>> items;
using info_sequence = std::vector<std::tuple<std::string, nlohmann::json>>;
if (options.print_licenses)
{
static const std::vector<std::pair<std::string, nlohmann::json>> 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 <s.schuemann@pobox.com>" },
{ "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<bool>();
options.base = config.at("base").value<bool>();
options.environments = config.at("environments").value<bool>();
auto channel_context = ChannelContext::make_conda_compatible(config.context());
detail::print_info(config.context(), channel_context, config, std::move(options));

View File

@ -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<std::string> 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 <env> --file <this 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<std::string>
[&](const auto&) -> mamba::specs::expected_parse_t<std::string>
{ 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<std::string>({ "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);

View File

@ -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<bool>(), 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<bool>(), base.description());
subcom->add_flag("--licenses", print_licenses, "Print licenses");
subcom->callback(
[&config]
{
// TODO: Print full license texts.
if (print_licenses)
{
const std::vector<std::pair<std::string, std::string>> 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 <s.schuemann@pobox.com>" },
{ "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<bool>(), environments.description());
}
void
set_info_command(CLI::App* subcom, mamba::Configuration& config)
{
init_info_parser(subcom, config);
subcom->callback([&config] { info(config); });
}

View File

@ -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)