mirror of https://github.com/mamba-org/mamba.git
Further improve `micromamba search` output (#2823)
This commit is contained in:
parent
a8d595b6ff
commit
a2b0f9c3b8
|
@ -99,7 +99,7 @@ namespace mamba
|
|||
std::ostream& tree(std::ostream&, const GraphicsParams& graphics) const;
|
||||
nlohmann::json json(ChannelContext& channel_context) const;
|
||||
|
||||
std::ostream& pretty(std::ostream&) const;
|
||||
std::ostream& pretty(std::ostream&, const Context::OutputParams& outputParams) const;
|
||||
|
||||
bool empty() const;
|
||||
|
||||
|
|
|
@ -87,7 +87,7 @@ namespace mamba
|
|||
std::cout << res.json(pool.channel_context()).dump(4);
|
||||
break;
|
||||
case QueryResultFormat::kPRETTY:
|
||||
res.pretty(std::cout);
|
||||
res.pretty(std::cout, ctx.output_params);
|
||||
break;
|
||||
default:
|
||||
res.groupby("name").table(std::cout);
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <stack>
|
||||
#include <unordered_set>
|
||||
|
||||
#include <fmt/chrono.h>
|
||||
#include <fmt/color.h>
|
||||
|
@ -157,36 +158,17 @@ namespace mamba
|
|||
|
||||
namespace
|
||||
{
|
||||
auto print_solvable(const PackageInfo& pkg, const std::vector<PackageInfo>& otherBuilds)
|
||||
{
|
||||
std::map<std::string, std::vector<PackageInfo>> buildsByVersion;
|
||||
auto numOtherBuildsForLatestVersion = 0;
|
||||
for (const auto& p : otherBuilds)
|
||||
{
|
||||
if (p.version != pkg.version)
|
||||
{
|
||||
buildsByVersion[p.version].push_back(p);
|
||||
}
|
||||
else
|
||||
{
|
||||
++numOtherBuildsForLatestVersion;
|
||||
}
|
||||
}
|
||||
auto out = Console::stream();
|
||||
std::string additionalBuilds = "";
|
||||
if (numOtherBuildsForLatestVersion > 0)
|
||||
{
|
||||
additionalBuilds = fmt::format(" (+ {} builds)", numOtherBuildsForLatestVersion);
|
||||
}
|
||||
std::string header = fmt::format("{} {} {}", pkg.name, pkg.version, pkg.build_string)
|
||||
+ additionalBuilds;
|
||||
fmt::print(out, "{:^40}\n{:_^{}}\n\n", header, "", header.size() > 40 ? header.size() : 40);
|
||||
|
||||
static constexpr const char* fmtstring = " {:<15} {}\n";
|
||||
/**
|
||||
* Prints metadata for a given package.
|
||||
*/
|
||||
auto print_metadata(std::ostream& out, const PackageInfo& pkg)
|
||||
{
|
||||
static constexpr const char* fmtstring = " {:<15} {}\n";
|
||||
fmt::print(out, fmtstring, "Name", pkg.name);
|
||||
fmt::print(out, fmtstring, "Version", pkg.version);
|
||||
fmt::print(out, fmtstring, "Build", pkg.build_string);
|
||||
fmt::print(out, " {:<15} {} kB\n", "Size", pkg.size / 1000);
|
||||
fmt::print(out, " {:<15} {} kB\n", "Size", pkg.size / 1000);
|
||||
fmt::print(out, fmtstring, "License", pkg.license);
|
||||
fmt::print(out, fmtstring, "Subdir", pkg.subdir);
|
||||
fmt::print(out, fmtstring, "File Name", pkg.fn);
|
||||
|
@ -195,7 +177,7 @@ namespace mamba
|
|||
auto url = CondaURL::parse(pkg.url);
|
||||
fmt::print(
|
||||
out,
|
||||
" {:<15} {}\n",
|
||||
" {:<15} {}\n",
|
||||
"URL",
|
||||
url.pretty_str(CondaURL::StripScheme::no, '/', CondaURL::HideConfidential::yes)
|
||||
);
|
||||
|
@ -227,42 +209,138 @@ namespace mamba
|
|||
fmt::print(out, " - {}\n", d);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!buildsByVersion.empty())
|
||||
/**
|
||||
* Prints all other versions/builds in a table format for a given package.
|
||||
*/
|
||||
auto print_other_builds(
|
||||
std::ostream& out,
|
||||
const PackageInfo& pkg,
|
||||
const std::map<std::string, std::vector<PackageInfo>> groupedOtherBuilds,
|
||||
bool showAllBuilds
|
||||
)
|
||||
{
|
||||
fmt::print(
|
||||
out,
|
||||
"\n Other {} ({}):\n\n",
|
||||
showAllBuilds ? "Builds" : "Versions",
|
||||
groupedOtherBuilds.size()
|
||||
);
|
||||
|
||||
std::stringstream buffer;
|
||||
|
||||
using namespace printers;
|
||||
Table printer({ "Version", "Build", "", "" });
|
||||
printer.set_alignment(
|
||||
{ alignment::left, alignment::left, alignment::left, alignment::right }
|
||||
);
|
||||
bool collapseVersions = !showAllBuilds && groupedOtherBuilds.size() > 5;
|
||||
size_t counter = 0;
|
||||
// We want the newest version to be on top, therefore we iterate in reverse.
|
||||
for (auto it = groupedOtherBuilds.rbegin(); it != groupedOtherBuilds.rend(); it++)
|
||||
{
|
||||
fmt::print(out, "\n Other Versions ({}):\n\n", buildsByVersion.size());
|
||||
|
||||
std::stringstream buffer;
|
||||
|
||||
using namespace printers;
|
||||
Table printer({ "Version", "Build", "", "" });
|
||||
printer.set_alignment(
|
||||
{ alignment::left, alignment::left, alignment::left, alignment::right }
|
||||
);
|
||||
// We want the newest version to be on top, therefore we iterate in reverse.
|
||||
for (auto it = buildsByVersion.rbegin(); it != buildsByVersion.rend(); it++)
|
||||
++counter;
|
||||
if (collapseVersions)
|
||||
{
|
||||
std::vector<FormattedString> row;
|
||||
row.push_back(it->second.front().version);
|
||||
row.push_back(it->second.front().build_string);
|
||||
if (it->second.size() > 1)
|
||||
if (counter == 3)
|
||||
{
|
||||
row.push_back("(+");
|
||||
row.push_back(fmt::format("{} builds)", it->second.size() - 1));
|
||||
printer.add_row(
|
||||
{ "...",
|
||||
fmt::format("({} hidden versions)", groupedOtherBuilds.size() - 4),
|
||||
"",
|
||||
"..." }
|
||||
);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
else if (counter > 3 && counter < groupedOtherBuilds.size() - 1)
|
||||
{
|
||||
row.push_back("");
|
||||
row.push_back("");
|
||||
continue;
|
||||
}
|
||||
printer.add_row(row);
|
||||
}
|
||||
printer.print(buffer);
|
||||
std::string line;
|
||||
while (std::getline(buffer, line))
|
||||
|
||||
std::vector<FormattedString> row;
|
||||
row.push_back(it->second.front().version);
|
||||
row.push_back(it->second.front().build_string);
|
||||
if (it->second.size() > 1)
|
||||
{
|
||||
out << " " << line << std::endl;
|
||||
row.push_back("(+");
|
||||
row.push_back(fmt::format("{} builds)", it->second.size() - 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
row.push_back("");
|
||||
row.push_back("");
|
||||
}
|
||||
printer.add_row(row);
|
||||
}
|
||||
printer.print(buffer);
|
||||
std::string line;
|
||||
while (std::getline(buffer, line))
|
||||
{
|
||||
out << " " << line << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints detailed information about a given package, including a list of other
|
||||
* versions/builds.
|
||||
*/
|
||||
auto print_solvable(
|
||||
std::ostream& out,
|
||||
const PackageInfo& pkg,
|
||||
const std::vector<PackageInfo>& otherBuilds,
|
||||
bool showAllBuilds
|
||||
)
|
||||
{
|
||||
// Filter and group builds/versions.
|
||||
std::map<std::string, std::vector<PackageInfo>> groupedOtherBuilds;
|
||||
auto numOtherBuildsForLatestVersion = 0;
|
||||
if (showAllBuilds)
|
||||
{
|
||||
for (const auto& p : otherBuilds)
|
||||
{
|
||||
if (p.sha256 != pkg.sha256)
|
||||
{
|
||||
groupedOtherBuilds[p.version + p.sha256].push_back(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::unordered_set<std::string> distinctBuildSHAs;
|
||||
for (const auto& p : otherBuilds)
|
||||
{
|
||||
if (distinctBuildSHAs.insert(p.sha256).second)
|
||||
{
|
||||
if (p.version != pkg.version)
|
||||
{
|
||||
groupedOtherBuilds[p.version].push_back(p);
|
||||
}
|
||||
else
|
||||
{
|
||||
++numOtherBuildsForLatestVersion;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Construct and print header line.
|
||||
std::string additionalBuilds;
|
||||
if (numOtherBuildsForLatestVersion > 0)
|
||||
{
|
||||
additionalBuilds = fmt::format(" (+ {} builds)", numOtherBuildsForLatestVersion);
|
||||
}
|
||||
std::string header = fmt::format("{} {} {}", pkg.name, pkg.version, pkg.build_string)
|
||||
+ additionalBuilds;
|
||||
fmt::print(out, "{:^40}\n{:─^{}}\n\n", header, "", header.size() > 40 ? header.size() : 40);
|
||||
|
||||
// Print metadata.
|
||||
print_metadata(out, pkg);
|
||||
|
||||
if (!groupedOtherBuilds.empty())
|
||||
{
|
||||
print_other_builds(out, pkg, groupedOtherBuilds, showAllBuilds);
|
||||
}
|
||||
|
||||
out << '\n';
|
||||
|
@ -600,12 +678,16 @@ namespace mamba
|
|||
if (!m_ordered_pkg_id_list.empty())
|
||||
{
|
||||
std::map<std::string, std::map<std::string, std::vector<PackageInfo>>> packageBuildsByVersion;
|
||||
std::unordered_set<std::string> distinctBuildSHAs;
|
||||
for (auto& entry : m_ordered_pkg_id_list)
|
||||
{
|
||||
for (const auto& id : entry.second)
|
||||
{
|
||||
auto package = m_dep_graph.node(id);
|
||||
packageBuildsByVersion[package.name][package.version].push_back(package);
|
||||
if (distinctBuildSHAs.insert(package.sha256).second)
|
||||
{
|
||||
packageBuildsByVersion[package.name][package.version].push_back(package);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -797,7 +879,8 @@ namespace mamba
|
|||
return j;
|
||||
}
|
||||
|
||||
std::ostream& query_result::pretty(std::ostream& out) const
|
||||
std::ostream&
|
||||
query_result::pretty(std::ostream& out, const Context::OutputParams& outputParams) const
|
||||
{
|
||||
if (m_pkg_id_list.empty())
|
||||
{
|
||||
|
@ -812,11 +895,14 @@ namespace mamba
|
|||
packages[package.name].push_back(package);
|
||||
}
|
||||
|
||||
auto out = Console::stream();
|
||||
for (const auto& entry : packages)
|
||||
{
|
||||
print_solvable(
|
||||
out,
|
||||
entry.second[0],
|
||||
std::vector(entry.second.begin() + 1, entry.second.end())
|
||||
std::vector(entry.second.begin() + 1, entry.second.end()),
|
||||
outputParams.verbosity > 0
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -435,7 +435,10 @@ PYBIND11_MODULE(bindings, m)
|
|||
res.groupby("name").table(res_stream);
|
||||
break;
|
||||
case query::PRETTY:
|
||||
res.groupby("name").pretty(res_stream);
|
||||
res.groupby("name").pretty(
|
||||
res_stream,
|
||||
mambapy::singletons.context().output_params
|
||||
);
|
||||
}
|
||||
if (res.empty() && format != query::JSON)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue