Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 29 additions & 16 deletions libmamba/src/api/list.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,12 @@ namespace mamba
bool full_name;
bool no_pip;
bool reverse;
bool explicit_;
};

struct formatted_pkg
{
std::string name, version, build, channel;
std::string name, version, build, channel, url;
};

bool compare_alphabetically(const formatted_pkg& a, const formatted_pkg& b)
Expand Down Expand Up @@ -134,6 +135,7 @@ namespace mamba
pkg_info.platform
);
}
obj["url"] = pkg_info.package_url;
obj["build_number"] = pkg_info.build_number;
obj["build_string"] = pkg_info.build_string;
obj["dist_name"] = pkg_info.str();
Expand Down Expand Up @@ -163,6 +165,7 @@ namespace mamba
formatted_pkgs.name = package.second.name;
formatted_pkgs.version = package.second.version;
formatted_pkgs.build = package.second.build_string;
formatted_pkgs.url = package.second.package_url;
if (package.second.channel.find("https://repo.anaconda.com/pkgs/") == 0)
{
formatted_pkgs.channel = "";
Expand Down Expand Up @@ -190,25 +193,34 @@ namespace mamba
std::sort(packages.begin(), packages.end(), comparator);

// format and print table
printers::Table t({ "Name", "Version", "Build", "Channel" });
t.set_alignment({ printers::alignment::left,
printers::alignment::left,
printers::alignment::left,
printers::alignment::left });
t.set_padding({ 2, 2, 2, 2 });

for (auto p : packages)
if (options.explicit_)
{
printers::FormattedString formatted_name(p.name);
if (requested_specs.find(p.name) != requested_specs.end())
for (auto p : packages)
{
formatted_name = printers::FormattedString(p.name);
formatted_name.style = ctx.graphics_params.palette.user;
std::cout << p.url << std::endl;
}
t.add_row({ formatted_name, p.version, p.build, p.channel });
}

t.print(std::cout);
else
{
printers::Table t({ "Name", "Version", "Build", "Channel" });
t.set_alignment({ printers::alignment::left,
printers::alignment::left,
printers::alignment::left,
printers::alignment::left });
t.set_padding({ 2, 2, 2, 2 });

for (auto p : packages)
{
printers::FormattedString formatted_name(p.name);
if (requested_specs.find(p.name) != requested_specs.end())
{
formatted_name = printers::FormattedString(p.name);
formatted_name.style = ctx.graphics_params.palette.user;
}
t.add_row({ formatted_name, p.version, p.build, p.channel });
}
t.print(std::cout);
}
}
}

Expand All @@ -228,6 +240,7 @@ namespace mamba
options.full_name = config.at("full_name").value<bool>();
options.no_pip = config.at("no_pip").value<bool>();
options.reverse = config.at("reverse").value<bool>();
options.explicit_ = config.at("explicit_").value<bool>();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the underscore required for this string? I understand explicit is a C++ keyword, but that doesn't apply to strings.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not, good catch!
Btw, is adding an underscore after explicit an acceptable way to write a variable name or is there a better practice?

Copy link
Member

@Klaim Klaim Jan 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No best practice, if you ideally need to name something in a way that's already reserved as a keyword, you either add somethnig to it like you did, or change the name to mean the same thing but make it still readable. For example it could have been explicit_list or explicit_print or as_explicit etc. As long as it's clear in the code and easy to follow when reading it's ok.


auto channel_context = ChannelContext::make_conda_compatible(config.context());
detail::list_packages(config.context(), regex, channel_context, std::move(options));
Expand Down
8 changes: 8 additions & 0 deletions micromamba/src/list.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,14 @@ init_list_parser(CLI::App* subcom, Configuration& config)
Configurable("reverse", false).group("cli").description("List installed packages in reverse order.")
);
subcom->add_flag("--reverse", reverse.get_cli_config<bool>(), reverse.description());

auto& explicit_ = config.insert(Configurable("explicit_", false)
.group("cli")
.description("List explicitly all installed packages with URL."
));
subcom->add_flag("--explicit", explicit_.get_cli_config<bool>(), explicit_.description());


// TODO: implement this in libmamba/list.cpp
/*auto& canonical = config.insert(Configurable("canonical", false)
.group("cli")
Expand Down
26 changes: 24 additions & 2 deletions micromamba/tests/test_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@ def test_list(
assert "xtensor" in names
assert "xtl" in names
assert all(
i["channel"] == "conda-forge" and i["base_url"] == "https://conda.anaconda.org/conda-forge"
i["channel"] == "conda-forge"
and i["base_url"] == "https://conda.anaconda.org/conda-forge"
and i["name"] in i["url"]
and "conda-forge" in i["url"]
for i in res
)

Expand Down Expand Up @@ -56,7 +59,7 @@ def test_list_no_json(
assert "xtensor" in res
assert "xtl" in res

# This is what res looks like in this case (with or without a header delimiter):
# This is what res looks like in this case:
# List of packages in environment: "xxx"

# Name Version Build Channel
Expand All @@ -76,6 +79,25 @@ def test_list_no_json(
assert res.find("xtensor") < res.find("xtl")


@pytest.mark.parametrize("explicit_flag", ["", "--explicit"])
@pytest.mark.parametrize("env_selector", ["", "name", "prefix"])
@pytest.mark.parametrize("shared_pkgs_dirs", [True], indirect=True)
def test_list_explicit_no_json(
tmp_home, tmp_root_prefix, tmp_env_name, tmp_xtensor_env, env_selector, explicit_flag
):
if env_selector == "prefix":
res = helpers.umamba_list("-p", tmp_xtensor_env, explicit_flag)
elif env_selector == "name":
res = helpers.umamba_list("-n", tmp_env_name, explicit_flag)
else:
res = helpers.umamba_list(explicit_flag)

packages_url_list = res.strip().split("\n")[2:]
if explicit_flag == "--explicit":
for url in packages_url_list:
assert "conda-forge" in url


@pytest.mark.parametrize("quiet_flag", ["", "-q", "--quiet"])
@pytest.mark.parametrize("shared_pkgs_dirs", [True], indirect=True)
def test_list_name(tmp_home, tmp_root_prefix, tmp_xtensor_env, quiet_flag):
Expand Down
Loading