Skip to content

Add JSON output to advisory list #1531

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all 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
19 changes: 16 additions & 3 deletions dnf5/commands/advisory/advisory_list.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,19 @@ void AdvisoryListCommand::process_and_print_queries(

std::vector<std::unique_ptr<libdnf5::cli::output::IAdvisoryPackage>> cli_installed_pkgs;
std::vector<std::unique_ptr<libdnf5::cli::output::IAdvisoryPackage>> cli_not_installed_pkgs;
std::string reference_type;
if (with_bz->get_value()) {
libdnf5::cli::output::print_advisorylist_references_table(not_installed_pkgs, installed_pkgs, "bugzilla");
reference_type = "bugzilla";
} else if (with_cve->get_value()) {
libdnf5::cli::output::print_advisorylist_references_table(not_installed_pkgs, installed_pkgs, "cve");
reference_type = "cve";
}
if (with_bz->get_value() || with_cve->get_value()) {
if (ctx.get_json_output_requested())
libdnf5::cli::output::print_advisorylist_references_json(
not_installed_pkgs, installed_pkgs, reference_type);
else
libdnf5::cli::output::print_advisorylist_references_table(
not_installed_pkgs, installed_pkgs, reference_type);
} else {
cli_installed_pkgs.reserve(installed_pkgs.size());
for (const auto & obj : installed_pkgs) {
Expand All @@ -79,7 +88,11 @@ void AdvisoryListCommand::process_and_print_queries(
for (const auto & obj : not_installed_pkgs) {
cli_not_installed_pkgs.emplace_back(new output::AdvisoryPackageAdapter(obj));
}
libdnf5::cli::output::print_advisorylist_table(cli_not_installed_pkgs, cli_installed_pkgs);
if (ctx.get_json_output_requested()) {
libdnf5::cli::output::print_advisorylist_json(cli_not_installed_pkgs, cli_installed_pkgs);
} else {
libdnf5::cli::output::print_advisorylist_table(cli_not_installed_pkgs, cli_installed_pkgs);
}
}
}

Expand Down
3 changes: 3 additions & 0 deletions dnf5/commands/advisory/advisory_list.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ along with libdnf. If not, see <https://www.gnu.org/licenses/>.

#include "advisory_subcommand.hpp"

#include <dnf5/shared_options.hpp>

namespace dnf5 {

class AdvisoryListCommand : public AdvisorySubCommand {
Expand All @@ -31,6 +33,7 @@ class AdvisoryListCommand : public AdvisorySubCommand {
void set_argument_parser() override {
AdvisorySubCommand::set_argument_parser();
get_argument_parser_command()->set_description(_("List advisories"));
create_json_option(*this);
}

protected:
Expand Down
9 changes: 9 additions & 0 deletions include/libdnf5-cli/output/advisorylist.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,20 @@ LIBDNF_CLI_API void print_advisorylist_table(
std::vector<std::unique_ptr<IAdvisoryPackage>> & advisory_package_list_not_installed,
std::vector<std::unique_ptr<IAdvisoryPackage>> & advisory_package_list_installed);

LIBDNF_CLI_API void print_advisorylist_json(
std::vector<std::unique_ptr<IAdvisoryPackage>> & advisory_package_list_not_installed,
std::vector<std::unique_ptr<IAdvisoryPackage>> & advisory_package_list_installed);

LIBDNF_CLI_API void print_advisorylist_references_table(
std::vector<libdnf5::advisory::AdvisoryPackage> & advisory_package_list_not_installed,
std::vector<libdnf5::advisory::AdvisoryPackage> & advisory_package_list_installed,
std::string reference_type);

LIBDNF_CLI_API void print_advisorylist_references_json(
std::vector<libdnf5::advisory::AdvisoryPackage> & advisory_package_list_not_installed,
std::vector<libdnf5::advisory::AdvisoryPackage> & advisory_package_list_installed,
std::string reference_type);

} // namespace libdnf5::cli::output

#endif // LIBDNF5_CLI_OUTPUT_ADVISORYLIST_HPP
91 changes: 84 additions & 7 deletions libdnf5-cli/output/advisorylist.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,12 @@ along with libdnf. If not, see <https://www.gnu.org/licenses/>.

#include "utils/string.hpp"

#include <json.h>
#include <libsmartcols/libsmartcols.h>
#include <unistd.h>

#include <iostream>

namespace libdnf5::cli::output {

namespace {
Expand Down Expand Up @@ -72,6 +75,14 @@ void add_line_into_advisorylist_table(

} // namespace

static std::string get_reference_type_pretty_name(std::string type) {
if (type == "bugzilla") {
return "Bugzilla";
} else if (type == "cve") {
return "CVE";
}
return type;
}

void print_advisorylist_table(
std::vector<std::unique_ptr<IAdvisoryPackage>> & advisory_package_list_not_installed,
Expand Down Expand Up @@ -104,18 +115,65 @@ void print_advisorylist_table(
scols_unref_table(table);
}

static json_object * adv_pkg_as_json(auto & adv_pkg) {
auto advisory = adv_pkg->get_advisory();
json_object * json_advisory = json_object_new_object();
json_object_object_add(json_advisory, "name", json_object_new_string(advisory->get_name().c_str()));
json_object_object_add(json_advisory, "type", json_object_new_string(advisory->get_type().c_str()));
json_object_object_add(json_advisory, "severity", json_object_new_string(advisory->get_severity().c_str()));
json_object_object_add(json_advisory, "nevra", json_object_new_string(adv_pkg->get_nevra().c_str()));
unsigned long long buildtime = advisory->get_buildtime();
json_object_object_add(
json_advisory, "buildtime", json_object_new_string(libdnf5::utils::string::format_epoch(buildtime).c_str()));
return json_advisory;
}

static json_object * adv_refs_as_json(auto & reference_type, auto & adv_pkg, auto & advisory) {
json_object * json_advisory = json_object_new_object();
json_object_object_add(json_advisory, "advisory_name", json_object_new_string(advisory.get_name().c_str()));
json_object_object_add(json_advisory, "advisory_type", json_object_new_string(advisory.get_type().c_str()));
json_object_object_add(json_advisory, "advisory_severity", json_object_new_string(advisory.get_type().c_str()));
unsigned long long buildtime = advisory.get_buildtime();
json_object_object_add(
json_advisory,
"advisory_buildtime",
json_object_new_string(libdnf5::utils::string::format_epoch(buildtime).c_str()));
json_object_object_add(json_advisory, "nevra", json_object_new_string(adv_pkg.get_nevra().c_str()));

json_object * json_adv_references = json_object_new_array();
auto references = advisory.get_references({reference_type});
for (auto reference : references) {
json_object * json_reference = json_object_new_object();
json_object_object_add(json_reference, "reference_id", json_object_new_string(reference.get_id().c_str()));
json_object_object_add(json_reference, "reference_type", json_object_new_string(reference_type.c_str()));
json_object_array_add(json_adv_references, json_reference);
}
json_object_object_add(json_advisory, "references", json_adv_references);
return json_advisory;
}


void print_advisorylist_json(
std::vector<std::unique_ptr<IAdvisoryPackage>> & advisory_package_list_not_installed,
std::vector<std::unique_ptr<IAdvisoryPackage>> & advisory_package_list_installed) {
json_object * json_advisorylist = json_object_new_array();

for (auto & adv_pkg : advisory_package_list_not_installed) {
json_object_array_add(json_advisorylist, adv_pkg_as_json(adv_pkg));
}
for (auto & adv_pkg : advisory_package_list_installed) {
json_object_array_add(json_advisorylist, adv_pkg_as_json(adv_pkg));
}
std::cout << json_object_to_json_string_ext(json_advisorylist, JSON_C_TO_STRING_PRETTY) << std::endl;
json_object_put(json_advisorylist);
}


void print_advisorylist_references_table(
std::vector<libdnf5::advisory::AdvisoryPackage> & advisory_package_list_not_installed,
std::vector<libdnf5::advisory::AdvisoryPackage> & advisory_package_list_installed,
std::string reference_type) {
std::string first_column_name;
if (reference_type == "cve") {
first_column_name = "CVE";
} else {
first_column_name = "Bugzilla";
}
struct libscols_table * table = create_advisorylist_table(first_column_name);
struct libscols_table * table = create_advisorylist_table(get_reference_type_pretty_name(reference_type));
for (auto adv_pkg : advisory_package_list_not_installed) {
auto advisory = adv_pkg.get_advisory();
auto references = advisory.get_references({reference_type});
Expand Down Expand Up @@ -149,4 +207,23 @@ void print_advisorylist_references_table(
scols_unref_table(table);
}

void print_advisorylist_references_json(
std::vector<libdnf5::advisory::AdvisoryPackage> & advisory_package_list_not_installed,
std::vector<libdnf5::advisory::AdvisoryPackage> & advisory_package_list_installed,
std::string reference_type) {
json_object * json_advisory_refs = json_object_new_array();
for (auto adv_pkg : advisory_package_list_not_installed) {
auto advisory = adv_pkg.get_advisory();
auto json_refs = adv_refs_as_json(reference_type, adv_pkg, advisory);
json_object_array_add(json_advisory_refs, json_refs);
}
for (auto adv_pkg : advisory_package_list_installed) {
auto advisory = adv_pkg.get_advisory();
auto json_refs = adv_refs_as_json(reference_type, adv_pkg, advisory);
json_object_array_add(json_advisory_refs, json_refs);
}
std::cout << json_object_to_json_string_ext(json_advisory_refs, JSON_C_TO_STRING_PRETTY) << std::endl;
json_object_put(json_advisory_refs);
}

} // namespace libdnf5::cli::output
Loading