Skip to content

Commit

Permalink
repoinfo: Implement json output
Browse files Browse the repository at this point in the history
  • Loading branch information
jan-kolarik authored and kontura committed Jun 6, 2024
1 parent 4ffa9d1 commit 7e57a92
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 12 deletions.
20 changes: 15 additions & 5 deletions dnf5/commands/repo/repo_info.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ void RepoInfoCommand::print(const libdnf5::repo::RepoQuery & query, [[maybe_unus
}
std::sort(repos.begin(), repos.end(), [](const auto & l, const auto & r) { return l->get_id() < r->get_id(); });

std::vector<std::unique_ptr<libdnf5::cli::output::IRepoInfo>> repo_wrappers;
for (auto & repo : repos) {
libdnf5::rpm::PackageQuery pkgs(get_context().get_base(), libdnf5::sack::ExcludeFlags::IGNORE_EXCLUDES);
pkgs.filter_repo_id({repo->get_id()});
Expand All @@ -118,11 +119,20 @@ void RepoInfoCommand::print(const libdnf5::repo::RepoQuery & query, [[maybe_unus
repo_size += pkg.get_download_size();
}

libdnf5::cli::output::RepoInfo repo_info_table;
RepoInfoWrapper repo_wrapper(*repo, repo_size, pkgs.size(), available_pkgs.size());
repo_info_table.add_repo(repo_wrapper);
repo_info_table.print();
std::cout << std::endl;
repo_wrappers.emplace_back(
std::make_unique<RepoInfoWrapper>(*repo, repo_size, pkgs.size(), available_pkgs.size()));
}

auto & context = get_context();
if (context.get_json_output_requested()) {
libdnf5::cli::output::print_repoinfo_json(repo_wrappers);
} else {
for (auto & repo : repo_wrappers) {
libdnf5::cli::output::RepoInfo repo_info_table;
repo_info_table.add_repo(*repo);
repo_info_table.print();
std::cout << std::endl;
}
}
}

Expand Down
2 changes: 2 additions & 0 deletions include/libdnf5-cli/output/repo_info.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ class RepoInfo {
std::unique_ptr<Impl> p_impl;
};

void print_repoinfo_json(const std::vector<std::unique_ptr<IRepoInfo>> & repos);

} // namespace libdnf5::cli::output

#endif // LIBDNF5_CLI_OUTPUT_REPO_INFO_HPP
96 changes: 89 additions & 7 deletions libdnf5-cli/output/repo_info.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,24 @@ along with libdnf. If not, see <https://www.gnu.org/licenses/>.

#include "libdnf5-cli/utils/units.hpp"

#include <json-c/json_object.h>

#include <iostream>

namespace libdnf5::cli::output {

namespace {

std::vector<std::string> flatten_distro_tags(const std::vector<std::pair<std::string, std::string>> & distro_tags) {
std::vector<std::string> distro_tags_flat;
for (auto & key_value : distro_tags) {
distro_tags_flat.push_back(key_value.second + " (" + key_value.first + ")");
}
return distro_tags_flat;
}

} // namespace

class RepoInfo::Impl : public KeyValueTable {
public:
void add_repo(IRepoInfo & repo);
Expand Down Expand Up @@ -155,13 +171,9 @@ void RepoInfo::Impl::add_repo(IRepoInfo & repo) {
add_line("Content tags", content_tags, nullptr, group_repodata);
}

auto distro_tags_flat = repo.get_distro_tags();
if (!distro_tags_flat.empty()) {
std::vector<std::string> distro_tags;
for (auto & key_value : distro_tags_flat) {
distro_tags.push_back(key_value.second + " (" + key_value.first + ")");
}
add_line("Distro tags", distro_tags, nullptr, group_repodata);
auto distro_tags = repo.get_distro_tags();
if (!distro_tags.empty()) {
add_line("Distro tags", flatten_distro_tags(distro_tags), nullptr, group_repodata);
}

add_line("Revision", repo.get_revision(), nullptr, group_repodata);
Expand Down Expand Up @@ -195,4 +207,74 @@ void RepoInfo::print() {
p_impl->print();
}

void print_repoinfo_json([[maybe_unused]] const std::vector<std::unique_ptr<IRepoInfo>> & repos) {
json_object * json_repos = json_object_new_array();
for (const auto & repo : repos) {
json_object * json_repo = json_object_new_object();
json_object_object_add(json_repo, "id", json_object_new_string(repo->get_id().c_str()));
json_object_object_add(json_repo, "name", json_object_new_string(repo->get_name().c_str()));
json_object_object_add(json_repo, "is_enabled", json_object_new_boolean(repo->is_enabled()));
json_object_object_add(json_repo, "priority", json_object_new_int(repo->get_priority()));
json_object_object_add(json_repo, "cost", json_object_new_int(repo->get_cost()));
json_object_object_add(json_repo, "type", json_object_new_string(repo->get_type().c_str()));

json_object * json_exclude_pkgs = json_object_new_array();
for (const auto & pkg : repo->get_excludepkgs()) {
json_object_array_add(json_exclude_pkgs, json_object_new_string(pkg.c_str()));
}
json_object_object_add(json_repo, "exclude_pkgs", json_exclude_pkgs);

json_object * json_include_pkgs = json_object_new_array();
for (const auto & pkg : repo->get_includepkgs()) {
json_object_array_add(json_include_pkgs, json_object_new_string(pkg.c_str()));
}
json_object_object_add(json_repo, "include_pkgs", json_include_pkgs);

json_object_object_add(json_repo, "timestamp", json_object_new_int64(repo->get_timestamp()));
json_object_object_add(json_repo, "metadata_expire", json_object_new_int(repo->get_metadata_expire()));
json_object_object_add(
json_repo, "skip_if_unavailable", json_object_new_boolean(repo->get_skip_if_unavailable()));
json_object_object_add(json_repo, "repo_file_path", json_object_new_string(repo->get_repo_file_path().c_str()));

json_object * json_baseurls = json_object_new_array();
for (const auto & url : repo->get_baseurl()) {
json_object_array_add(json_baseurls, json_object_new_string(url.c_str()));
}
json_object_object_add(json_repo, "base_url", json_baseurls);

json_object_object_add(json_repo, "metalink", json_object_new_string(repo->get_metalink().c_str()));
json_object_object_add(json_repo, "mirrorlist", json_object_new_string(repo->get_mirrorlist().c_str()));

json_object * json_gpg_keys = json_object_new_array();
for (const auto & key : repo->get_gpgkey()) {
json_object_array_add(json_gpg_keys, json_object_new_string(key.c_str()));
}
json_object_object_add(json_repo, "gpg_key", json_gpg_keys);

json_object_object_add(json_repo, "repo_gpgcheck", json_object_new_boolean(repo->get_repo_gpgcheck()));
json_object_object_add(json_repo, "gpgcheck", json_object_new_boolean(repo->get_gpgcheck()));
json_object_object_add(json_repo, "available_pkgs", json_object_new_uint64(repo->get_available_pkgs()));
json_object_object_add(json_repo, "pkgs", json_object_new_uint64(repo->get_pkgs()));
json_object_object_add(json_repo, "size", json_object_new_uint64(repo->get_size()));

json_object * json_content_tags = json_object_new_array();
for (const auto & tag : repo->get_content_tags()) {
json_object_array_add(json_content_tags, json_object_new_string(tag.c_str()));
}
json_object_object_add(json_repo, "content_tags", json_content_tags);

json_object * json_distro_tags = json_object_new_array();
for (const auto & tag : flatten_distro_tags(repo->get_distro_tags())) {
json_object_array_add(json_distro_tags, json_object_new_string(tag.c_str()));
}
json_object_object_add(json_repo, "distro_tags", json_distro_tags);

json_object_object_add(json_repo, "revision", json_object_new_string(repo->get_revision().c_str()));
json_object_object_add(json_repo, "max_timestamp", json_object_new_int(repo->get_max_timestamp()));
json_object_array_add(json_repos, json_repo);
}
std::cout << json_object_to_json_string_ext(json_repos, JSON_C_TO_STRING_PRETTY) << std::endl;
json_object_put(json_repos);
}

} // namespace libdnf5::cli::output

0 comments on commit 7e57a92

Please sign in to comment.