diff --git a/dnf5/commands/repo/repo_list.cpp b/dnf5/commands/repo/repo_list.cpp
index 3a7bc9389..e688712b8 100644
--- a/dnf5/commands/repo/repo_list.cpp
+++ b/dnf5/commands/repo/repo_list.cpp
@@ -19,6 +19,7 @@ along with libdnf. If not, see .
#include "repo_list.hpp"
+#include
#include
#include
@@ -39,6 +40,8 @@ void RepoListCommand::set_argument_parser() {
all->get_arg()->add_conflict_argument(*enabled->get_arg());
all->get_arg()->add_conflict_argument(*disabled->get_arg());
enabled->get_arg()->add_conflict_argument(*disabled->get_arg());
+
+ create_json_option(*this);
}
void RepoListCommand::run() {
@@ -82,7 +85,12 @@ void RepoListCommand::print(const libdnf5::repo::RepoQuery & query, bool with_st
cli_repos.emplace_back(new libdnf5::cli::output::RepoAdapter(repo));
}
- libdnf5::cli::output::print_repolist_table(cli_repos, with_status, libdnf5::cli::output::COL_REPO_ID);
+ auto & ctx = get_context();
+ if (ctx.get_json_output_requested()) {
+ libdnf5::cli::output::print_repolist_json(cli_repos);
+ } else {
+ libdnf5::cli::output::print_repolist_table(cli_repos, with_status, libdnf5::cli::output::COL_REPO_ID);
+ }
}
} // namespace dnf5
diff --git a/dnf5/context.cpp b/dnf5/context.cpp
index 3ebebb22f..6415db577 100644
--- a/dnf5/context.cpp
+++ b/dnf5/context.cpp
@@ -173,6 +173,9 @@ class Context::Impl {
void set_should_store_offline(bool should_store_offline) { this->should_store_offline = should_store_offline; }
bool get_should_store_offline() const { return should_store_offline; }
+ void set_json_output_requested(bool json_output) { this->json_output = json_output; }
+ bool get_json_output_requested() const { return json_output; }
+
libdnf5::Base & get_base() { return base; };
std::vector> & get_setopts() { return setopts; }
@@ -206,6 +209,7 @@ class Context::Impl {
const char * comment{nullptr};
bool should_store_offline = false;
+ bool json_output = false;
bool quiet{false};
bool dump_main_config{false};
@@ -658,6 +662,14 @@ bool Context::get_should_store_offline() const {
return p_impl->get_should_store_offline();
}
+void Context::set_json_output_requested(bool json_output) {
+ p_impl->set_json_output_requested(json_output);
+}
+
+bool Context::get_json_output_requested() const {
+ return p_impl->get_json_output_requested();
+}
+
libdnf5::Base & Context::get_base() {
return p_impl->get_base();
};
diff --git a/dnf5/include/dnf5/context.hpp b/dnf5/include/dnf5/context.hpp
index e1448fdb1..cf1c530a3 100644
--- a/dnf5/include/dnf5/context.hpp
+++ b/dnf5/include/dnf5/context.hpp
@@ -149,6 +149,9 @@ class Context : public libdnf5::cli::session::Session {
void set_should_store_offline(bool should_store_offline);
bool get_should_store_offline() const;
+ void set_json_output_requested(bool json_output);
+ bool get_json_output_requested() const;
+
libdnf5::Base & get_base();
std::vector> & get_setopts();
diff --git a/dnf5/include/dnf5/shared_options.hpp b/dnf5/include/dnf5/shared_options.hpp
index 49e2b36dc..522794006 100644
--- a/dnf5/include/dnf5/shared_options.hpp
+++ b/dnf5/include/dnf5/shared_options.hpp
@@ -63,10 +63,12 @@ void create_downloadonly_option(dnf5::Command & command);
/// The value is stored in Context::transaction_store_path.
void create_store_option(dnf5::Command & command);
-
/// Create the `--offline` option for a command provided as an argument.
void create_offline_option(dnf5::Command & command);
+/// Create the `--json` option for a command provided as an argument.
+void create_json_option(dnf5::Command & command);
+
} // namespace dnf5
#endif // DNF5_COMMANDS_SHARED_OPTIONS_HPP
diff --git a/dnf5/shared_options.cpp b/dnf5/shared_options.cpp
index 59ffa0dcd..4042fe1ec 100644
--- a/dnf5/shared_options.cpp
+++ b/dnf5/shared_options.cpp
@@ -139,5 +139,22 @@ void create_store_option(dnf5::Command & command) {
});
}
+void create_json_option(dnf5::Command & command) {
+ auto & ctx = command.get_context();
+ auto & parser = command.get_context().get_argument_parser();
+ auto json = parser.add_new_named_arg("json");
+ json->set_long_name("json");
+ json->set_description("Request json output format");
+ json->set_const_value("true");
+ json->set_parse_hook_func([&ctx](
+ [[maybe_unused]] libdnf5::cli::ArgumentParser::NamedArg * arg,
+ [[maybe_unused]] const char * option,
+ [[maybe_unused]] const char * value) {
+ ctx.set_json_output_requested(true);
+ return true;
+ });
+ command.get_argument_parser_command()->register_named_arg(json);
+}
+
} // namespace dnf5
diff --git a/include/libdnf5-cli/output/repolist.hpp b/include/libdnf5-cli/output/repolist.hpp
index f0401d1ff..45680b0d2 100644
--- a/include/libdnf5-cli/output/repolist.hpp
+++ b/include/libdnf5-cli/output/repolist.hpp
@@ -31,6 +31,7 @@ namespace libdnf5::cli::output {
enum { COL_REPO_ID, COL_REPO_NAME, COL_REPO_STATUS };
void print_repolist_table(const std::vector> & repos, bool with_status, size_t sort_column);
+void print_repolist_json(const std::vector> & repos);
} // namespace libdnf5::cli::output
diff --git a/libdnf5-cli/CMakeLists.txt b/libdnf5-cli/CMakeLists.txt
index 8cfa9d1e0..8025730db 100644
--- a/libdnf5-cli/CMakeLists.txt
+++ b/libdnf5-cli/CMakeLists.txt
@@ -41,6 +41,10 @@ pkg_check_modules(SMARTCOLS REQUIRED smartcols)
list(APPEND LIBDNF5_CLI_PC_REQUIRES_PRIVATE "${SMARTCOLS_MODULE_NAME}")
target_link_libraries(libdnf5-cli PRIVATE ${SMARTCOLS_LIBRARIES})
+pkg_check_modules(JSONC REQUIRED json-c)
+include_directories(${JSONC_INCLUDE_DIRS})
+target_link_libraries(libdnf5-cli PRIVATE ${JSONC_LIBRARIES})
+
# sort the pkg-config requires and concatenate them into a string
list(SORT LIBDNF5_CLI_PC_REQUIRES)
diff --git a/libdnf5-cli/output/repolist.cpp b/libdnf5-cli/output/repolist.cpp
index d03b97803..ff215f8ee 100644
--- a/libdnf5-cli/output/repolist.cpp
+++ b/libdnf5-cli/output/repolist.cpp
@@ -21,6 +21,7 @@ along with libdnf. If not, see .
#include "libdnf5-cli/tty.hpp"
+#include
#include
namespace libdnf5::cli::output {
@@ -75,4 +76,18 @@ void print_repolist_table(const std::vector> & repos, boo
scols_unref_table(table);
}
+
+void print_repolist_json([[maybe_unused]] const std::vector> & 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_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