diff --git a/dnf5/commands/advisory/advisory_info.cpp b/dnf5/commands/advisory/advisory_info.cpp index 2c876627e..5e26c80b1 100644 --- a/dnf5/commands/advisory/advisory_info.cpp +++ b/dnf5/commands/advisory/advisory_info.cpp @@ -61,12 +61,22 @@ void AdvisoryInfoCommand::process_and_print_queries( advisories.filter_packages(installed_packages, libdnf5::sack::QueryCmp::GT); } - for (auto advisory : advisories) { - libdnf5::cli::output::AdvisoryInfo advisory_info; - output::AdvisoryAdapter cli_advisory(advisory); - advisory_info.add_advisory(cli_advisory); + if (ctx.get_json_output_requested()) { + libdnf5::cli::output::AdvisoryInfoJSON advisory_info; + for (auto advisory : advisories) { + output::AdvisoryAdapter cli_advisory(advisory); + advisory_info.add_advisory(cli_advisory); + } advisory_info.print(); std::cout << std::endl; + } else { + for (auto advisory : advisories) { + libdnf5::cli::output::AdvisoryInfo advisory_info; + output::AdvisoryAdapter cli_advisory(advisory); + advisory_info.add_advisory(cli_advisory); + advisory_info.print(); + std::cout << std::endl; + } } } diff --git a/dnf5/commands/advisory/advisory_info.hpp b/dnf5/commands/advisory/advisory_info.hpp index a4e9e9f5e..2a833b973 100644 --- a/dnf5/commands/advisory/advisory_info.hpp +++ b/dnf5/commands/advisory/advisory_info.hpp @@ -22,6 +22,8 @@ along with libdnf. If not, see . #include "advisory_subcommand.hpp" +#include + namespace dnf5 { class AdvisoryInfoCommand : public AdvisorySubCommand { @@ -31,6 +33,7 @@ class AdvisoryInfoCommand : public AdvisorySubCommand { void set_argument_parser() override { AdvisorySubCommand::set_argument_parser(); get_argument_parser_command()->set_description(_("Print details about advisories")); + create_json_option(*this); } protected: diff --git a/include/libdnf5-cli/output/advisoryinfo.hpp b/include/libdnf5-cli/output/advisoryinfo.hpp index 4f24e9785..cffada110 100644 --- a/include/libdnf5-cli/output/advisoryinfo.hpp +++ b/include/libdnf5-cli/output/advisoryinfo.hpp @@ -40,6 +40,19 @@ class LIBDNF_CLI_API AdvisoryInfo { std::unique_ptr p_impl; }; +class LIBDNF_CLI_API AdvisoryInfoJSON { +public: + AdvisoryInfoJSON(); + ~AdvisoryInfoJSON(); + + void add_advisory(IAdvisory & advisory); + void print(); + +private: + class LIBDNF_CLI_LOCAL Impl; + std::unique_ptr p_impl; +}; + } // namespace libdnf5::cli::output #endif // LIBDNF5_CLI_OUTPUT_ADVISORYLIST_HPP diff --git a/libdnf5-cli/output/advisoryinfo.cpp b/libdnf5-cli/output/advisoryinfo.cpp index b80ddf5c7..94dfe7f9f 100644 --- a/libdnf5-cli/output/advisoryinfo.cpp +++ b/libdnf5-cli/output/advisoryinfo.cpp @@ -22,6 +22,12 @@ along with libdnf. If not, see . #include "key_value_table.hpp" #include "utils/string.hpp" + +#include + + +#include + namespace libdnf5::cli::output { class AdvisoryInfo::Impl : public KeyValueTable { @@ -29,6 +35,17 @@ class AdvisoryInfo::Impl : public KeyValueTable { void add_advisory(IAdvisory & advisory); }; +class AdvisoryInfoJSON::Impl { +public: + Impl() { json_advisories = json_object_new_object(); }; + ~Impl() { json_object_put(json_advisories); }; + void add_advisory(IAdvisory & advisory); + void print() { + std::cout << json_object_to_json_string_ext(json_advisories, JSON_C_TO_STRING_PRETTY) << std::endl; + }; + json_object * json_advisories; +}; + void AdvisoryInfo::Impl::add_advisory(IAdvisory & advisory) { add_line("Name", advisory.get_name(), "bold"); @@ -81,17 +98,90 @@ void AdvisoryInfo::Impl::add_advisory(IAdvisory & advisory) { } } +void AdvisoryInfoJSON::Impl::add_advisory(IAdvisory & 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, "Title", json_object_new_string(advisory.get_title().c_str())); + json_object_object_add(json_advisory, "Severity", json_object_new_string(advisory.get_severity().c_str())); + json_object_object_add(json_advisory, "Type", json_object_new_string(advisory.get_type().c_str())); + json_object_object_add(json_advisory, "Status", json_object_new_string(advisory.get_status().c_str())); + json_object_object_add(json_advisory, "Vendor", json_object_new_string(advisory.get_vendor().c_str())); + json_object_object_add( + json_advisory, + "Issued", + json_object_new_string(libdnf5::utils::string::format_epoch(advisory.get_buildtime()).c_str())); + json_object_object_add(json_advisory, "Description", json_object_new_string(advisory.get_description().c_str())); + json_object_object_add(json_advisory, "Message", json_object_new_string(advisory.get_message().c_str())); + json_object_object_add(json_advisory, "Rights", json_object_new_string(advisory.get_rights().c_str())); + + // References + json_object * json_references = json_object_new_array(); + for (auto & reference : advisory.get_references()) { + json_object * json_reference = json_object_new_object(); + json_object_object_add(json_reference, "Title", json_object_new_string(reference->get_title().c_str())); + json_object_object_add(json_reference, "Id", json_object_new_string(reference->get_id().c_str())); + json_object_object_add(json_reference, "Type", json_object_new_string(reference->get_type_cstring())); + json_object_object_add(json_reference, "Url", json_object_new_string(reference->get_url().c_str())); + json_object_array_add(json_references, json_reference); + } + json_object_object_add(json_advisory, "references", json_references); + + // Collections + json_object * json_collections = json_object_new_object(); + for (auto & collection : advisory.get_collections()) { + // Modules + auto modules = collection->get_modules(); + if (!modules.empty()) { + json_object * json_modules = json_object_new_array(); + auto module_iter = modules.begin(); + json_object_array_add(json_modules, json_object_new_string((*module_iter)->get_nsvca().c_str())); + module_iter++; + while (module_iter != modules.end()) { + json_object_array_add(json_modules, json_object_new_string((*module_iter)->get_nsvca().c_str())); + module_iter++; + } + json_object_object_add(json_collections, "modules", json_modules); + } + + // Packages + auto packages = collection->get_packages(); + if (!packages.empty()) { + json_object * json_pkgs = json_object_new_array(); + auto package_iter = packages.begin(); + json_object_array_add(json_pkgs, json_object_new_string((*package_iter)->get_nevra().c_str())); + package_iter++; + while (package_iter != packages.end()) { + json_object_array_add(json_pkgs, json_object_new_string((*package_iter)->get_nevra().c_str())); + package_iter++; + } + json_object_object_add(json_collections, "packages", json_pkgs); + } + json_object_object_add(json_advisory, "collections", json_collections); + } + json_object_object_add(json_advisories, advisory.get_name().c_str(), json_advisory); +} + AdvisoryInfo::AdvisoryInfo() : p_impl{new AdvisoryInfo::Impl} {} +AdvisoryInfoJSON::AdvisoryInfoJSON() : p_impl{new AdvisoryInfoJSON::Impl} {} AdvisoryInfo::~AdvisoryInfo() = default; +AdvisoryInfoJSON::~AdvisoryInfoJSON() = default; void AdvisoryInfo::add_advisory(IAdvisory & advisory) { p_impl->add_advisory(advisory); } +void AdvisoryInfoJSON::add_advisory(IAdvisory & advisory) { + p_impl->add_advisory(advisory); +} + void AdvisoryInfo::print() { p_impl->print(); } +void AdvisoryInfoJSON::print() { + p_impl->print(); +} + } // namespace libdnf5::cli::output