From c4d5bbf287e8ea16290debc3c52bc7bc4ce77887 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ale=C5=A1=20Mat=C4=9Bj?= Date: Fri, 17 May 2024 11:39:21 +0200 Subject: [PATCH] Add `history rollback` command --- dnf5/commands/history/history.cpp | 2 +- dnf5/commands/history/history_rollback.cpp | 53 +++++++++++++++++++++- dnf5/commands/history/history_rollback.hpp | 8 ++++ 3 files changed, 61 insertions(+), 2 deletions(-) diff --git a/dnf5/commands/history/history.cpp b/dnf5/commands/history/history.cpp index 693485366..791c516ce 100644 --- a/dnf5/commands/history/history.cpp +++ b/dnf5/commands/history/history.cpp @@ -58,7 +58,7 @@ void HistoryCommand::register_subcommands() { cmd.register_group(software_management_commands_group); register_subcommand(std::make_unique(get_context()), software_management_commands_group); // register_subcommand(std::make_unique(get_context()), software_management_commands_group); - // register_subcommand(std::make_unique(get_context()), software_management_commands_group); + register_subcommand(std::make_unique(get_context()), software_management_commands_group); register_subcommand(std::make_unique(get_context()), software_management_commands_group); } diff --git a/dnf5/commands/history/history_rollback.cpp b/dnf5/commands/history/history_rollback.cpp index 51479f484..46783331f 100644 --- a/dnf5/commands/history/history_rollback.cpp +++ b/dnf5/commands/history/history_rollback.cpp @@ -19,14 +19,65 @@ along with libdnf. If not, see . #include "history_rollback.hpp" +#include "arguments.hpp" +#include "dnf5/shared_options.hpp" +#include "transaction_id.hpp" + +#include + namespace dnf5 { using namespace libdnf5::cli; void HistoryRollbackCommand::set_argument_parser() { get_argument_parser_command()->set_description("Undo all transactions performed after the specified transaction"); + transaction_specs = std::make_unique(*this, 1); + auto & ctx = get_context(); + transaction_specs->get_arg()->set_complete_hook_func(create_history_id_autocomplete(ctx)); + auto skip_unavailable = std::make_unique(*this); + ignore_extras = std::make_unique(*this); + ignore_installed = std::make_unique(*this); +} + +void HistoryRollbackCommand::configure() { + auto & context = get_context(); + context.set_load_system_repo(true); + context.set_load_available_repos(Context::LoadAvailableRepos::ENABLED); } -void HistoryRollbackCommand::run() {} +void HistoryRollbackCommand::run() { + auto ts_specs = transaction_specs->get_value(); + libdnf5::transaction::TransactionHistory history(get_context().get_base()); + std::vector transactions; + std::vector target_trans; + + target_trans = list_transactions_from_specs(history, ts_specs); + + if (target_trans.size() < 1) { + throw libdnf5::cli::CommandExitError(1, M_("No matching transaction ID found, exactly one required.")); + } + + if (target_trans.size() > 1) { + throw libdnf5::cli::CommandExitError(1, M_("Matched more than one transaction ID, exactly one required.")); + } + + auto max_id = history.list_transaction_ids().back(); + + int64_t target_id = target_trans[0].get_id() + 1; + if (target_id <= max_id) { + transactions = history.list_transactions(target_id, max_id); + } + + auto goal = get_context().get_goal(); + // To enable removal of dependency packages not present in the selected transactions + // it requires allow_erasing. This will inform the user that additional removes + // are required and the transaction won't proceed without --ignore-extras. + goal->set_allow_erasing(true); + + auto settings = libdnf5::GoalJobSettings(); + settings.set_ignore_extras(ignore_extras->get_value()); + settings.set_ignore_installed(ignore_installed->get_value()); + goal->add_revert_transactions(transactions, settings); +} } // namespace dnf5 diff --git a/dnf5/commands/history/history_rollback.hpp b/dnf5/commands/history/history_rollback.hpp index 33559edda..c60fe1d41 100644 --- a/dnf5/commands/history/history_rollback.hpp +++ b/dnf5/commands/history/history_rollback.hpp @@ -21,6 +21,8 @@ along with libdnf. If not, see . #ifndef DNF5_COMMANDS_HISTORY_HISTORY_ROLLBACK_HPP #define DNF5_COMMANDS_HISTORY_HISTORY_ROLLBACK_HPP +#include "commands/history/arguments.hpp" + #include @@ -31,7 +33,13 @@ class HistoryRollbackCommand : public Command { public: explicit HistoryRollbackCommand(Context & context) : Command(context, "rollback") {} void set_argument_parser() override; + void configure() override; void run() override; + +private: + std::unique_ptr transaction_specs{nullptr}; + std::unique_ptr ignore_extras{nullptr}; + std::unique_ptr ignore_installed{nullptr}; };