diff --git a/dnf5/commands/advisory/advisory_list.cpp b/dnf5/commands/advisory/advisory_list.cpp index 7ec507fe0..5eaf1cc91 100644 --- a/dnf5/commands/advisory/advisory_list.cpp +++ b/dnf5/commands/advisory/advisory_list.cpp @@ -66,10 +66,19 @@ void AdvisoryListCommand::process_and_print_queries( std::vector> cli_installed_pkgs; std::vector> 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) { @@ -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); + } } } diff --git a/dnf5/commands/advisory/advisory_list.hpp b/dnf5/commands/advisory/advisory_list.hpp index 20733cac3..3c63a6047 100644 --- a/dnf5/commands/advisory/advisory_list.hpp +++ b/dnf5/commands/advisory/advisory_list.hpp @@ -22,6 +22,8 @@ along with libdnf. If not, see . #include "advisory_subcommand.hpp" +#include + namespace dnf5 { class AdvisoryListCommand : public AdvisorySubCommand { @@ -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: diff --git a/include/libdnf5-cli/output/advisorylist.hpp b/include/libdnf5-cli/output/advisorylist.hpp index b00b306e3..e96ddf432 100644 --- a/include/libdnf5-cli/output/advisorylist.hpp +++ b/include/libdnf5-cli/output/advisorylist.hpp @@ -34,11 +34,20 @@ LIBDNF_CLI_API void print_advisorylist_table( std::vector> & advisory_package_list_not_installed, std::vector> & advisory_package_list_installed); +LIBDNF_CLI_API void print_advisorylist_json( + std::vector> & advisory_package_list_not_installed, + std::vector> & advisory_package_list_installed); + LIBDNF_CLI_API void print_advisorylist_references_table( std::vector & advisory_package_list_not_installed, std::vector & advisory_package_list_installed, std::string reference_type); +LIBDNF_CLI_API void print_advisorylist_references_json( + std::vector & advisory_package_list_not_installed, + std::vector & advisory_package_list_installed, + std::string reference_type); + } // namespace libdnf5::cli::output #endif // LIBDNF5_CLI_OUTPUT_ADVISORYLIST_HPP diff --git a/libdnf5-cli/output/advisorylist.cpp b/libdnf5-cli/output/advisorylist.cpp index 2501ba143..1031f14bd 100644 --- a/libdnf5-cli/output/advisorylist.cpp +++ b/libdnf5-cli/output/advisorylist.cpp @@ -21,9 +21,12 @@ along with libdnf. If not, see . #include "utils/string.hpp" +#include #include #include +#include + namespace libdnf5::cli::output { namespace { @@ -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> & advisory_package_list_not_installed, @@ -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> & advisory_package_list_not_installed, + std::vector> & 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 & advisory_package_list_not_installed, std::vector & 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}); @@ -149,4 +207,23 @@ void print_advisorylist_references_table( scols_unref_table(table); } +void print_advisorylist_references_json( + std::vector & advisory_package_list_not_installed, + std::vector & 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