Skip to content

Commit

Permalink
[format utils] remove duplicate code
Browse files Browse the repository at this point in the history
  • Loading branch information
sharder996 committed Sep 29, 2023
1 parent 1868102 commit a59f102
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 56 deletions.
78 changes: 26 additions & 52 deletions include/multipass/cli/format_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,8 @@ std::string status_string_for(const InstanceStatus& status);
std::string image_string_for(const multipass::FindReply_AliasInfo& alias);
Formatter* formatter_for(const std::string& format);

template <typename Instances>
Instances sorted(const Instances& instances);

template <typename Details>
Details sort_instances_and_snapshots(const Details& details);
template <typename Container>
Container sorted(const Container& items);

void filter_aliases(google::protobuf::RepeatedPtrField<multipass::FindReply_AliasInfo>& aliases);

Expand All @@ -63,71 +60,48 @@ static constexpr auto column_width = [](const auto begin, const auto end, const
} // namespace multipass

template <typename Container>
Container multipass::format::sorted(const Container& instances)
Container multipass::format::sorted(const Container& items)
{
if (instances.empty())
return instances;
if (items.empty())
return items;

auto ret = instances;
auto ret = items;
const auto petenv_name = MP_SETTINGS.get(petenv_key).toStdString();
std::sort(std::begin(ret), std::end(ret), [&petenv_name](const auto& a, const auto& b) {
using T = std::decay_t<decltype(a)>;
using google::protobuf::util::TimeUtil;

// Put instances first when sorting info reply
if constexpr (std::is_same_v<T, multipass::DetailedInfoItem>)
{
if (a.has_instance_info() && b.has_snapshot_info())
return true;
else if (a.has_snapshot_info() && b.has_instance_info())
return false;
}

// Put petenv related entries first
if (a.name() == petenv_name && b.name() != petenv_name)
return true;
else if (b.name() == petenv_name && a.name() != petenv_name)
return false;
else
{
if constexpr (std::is_same_v<T, multipass::ListVMSnapshot>)
// Sort by timestamp when names are the same for snapshots
if constexpr (std::is_same_v<T, multipass::DetailedInfoItem>)
{
if (a.name() < b.name())
return true;
else if (a.name() > b.name())
return false;

return TimeUtil::TimestampToNanoseconds(a.fundamentals().creation_timestamp()) <
TimeUtil::TimestampToNanoseconds(b.fundamentals().creation_timestamp());
if (a.has_snapshot_info() && a.name() == b.name())
return TimeUtil::TimestampToNanoseconds(a.snapshot_info().fundamentals().creation_timestamp()) <
TimeUtil::TimestampToNanoseconds(b.snapshot_info().fundamentals().creation_timestamp());
}
else
else if constexpr (std::is_same_v<T, multipass::ListVMSnapshot>)
{
return a.name() < b.name();
if (a.name() == b.name())
return TimeUtil::TimestampToNanoseconds(a.fundamentals().creation_timestamp()) <
TimeUtil::TimestampToNanoseconds(b.fundamentals().creation_timestamp());
}
}
});

return ret;
}

template <typename Details>
Details multipass::format::sort_instances_and_snapshots(const Details& details)
{
using google::protobuf::util::TimeUtil;
if (details.empty())
return details;

auto ret = details;
const auto petenv_name = MP_SETTINGS.get(petenv_key).toStdString();
std::sort(std::begin(ret), std::end(ret), [&petenv_name](const auto& a, const auto& b) {
if (a.has_instance_info() && b.has_snapshot_info())
return true;
else if (a.has_snapshot_info() && b.has_instance_info())
return false;

if (a.name() == petenv_name && b.name() != petenv_name)
return true;
else if (a.name() != petenv_name && b.name() == petenv_name)
return false;

if (a.has_instance_info())
return a.name() < b.name();
else
{
if (a.name() == b.name())
return TimeUtil::TimestampToNanoseconds(a.snapshot_info().fundamentals().creation_timestamp()) <
TimeUtil::TimestampToNanoseconds(b.snapshot_info().fundamentals().creation_timestamp());

// Lastly, sort by name
return a.name() < b.name();
}
});
Expand Down
4 changes: 2 additions & 2 deletions src/client/cli/formatter/csv_formatter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ std::string generate_snapshot_details(const mp::InfoReply reply)
fmt::format_to(std::back_inserter(buf),
"Snapshot,Instance,CPU(s),Disk space,Memory size,Mounts,Created,Parent,Children,Comment\n");

for (const auto& info : mp::format::sort_instances_and_snapshots(reply.details()))
for (const auto& info : mp::format::sorted(reply.details()))
{
const auto& fundamentals = info.snapshot_info().fundamentals();

Expand All @@ -95,7 +95,7 @@ std::string generate_instance_details(const mp::InfoReply reply)
"Name,State,Ipv4,Ipv6,Release,Image hash,Image release,Load,Disk usage,Disk total,Memory usage,Memory "
"total,Mounts,AllIPv4,CPU(s),Snapshots\n");

for (const auto& info : mp::format::sort_instances_and_snapshots(reply.details()))
for (const auto& info : mp::format::sorted(reply.details()))
{
assert(info.has_instance_info() &&
"outputting instance and snapshot details together is not supported in csv format");
Expand Down
2 changes: 1 addition & 1 deletion src/client/cli/formatter/table_formatter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ std::string mp::TableFormatter::format(const InfoReply& reply) const
{
fmt::memory_buffer buf;

for (const auto& info : mp::format::sort_instances_and_snapshots(reply.details()))
for (const auto& info : mp::format::sorted(reply.details()))
{
if (info.has_instance_info())
{
Expand Down
2 changes: 1 addition & 1 deletion src/client/cli/formatter/yaml_formatter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ std::string mp::YamlFormatter::format(const InfoReply& reply) const

info_node["errors"].push_back(YAML::Null);

for (const auto& info : mp::format::sort_instances_and_snapshots(reply.details()))
for (const auto& info : mp::format::sorted(reply.details()))
{
if (info.has_instance_info())
{
Expand Down

0 comments on commit a59f102

Please sign in to comment.