Skip to content

Commit

Permalink
Add history store command
Browse files Browse the repository at this point in the history
  • Loading branch information
kontura committed Nov 15, 2023
1 parent 0762ff9 commit 5cbfc19
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 3 deletions.
2 changes: 1 addition & 1 deletion dnf5/commands/history/history.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ void HistoryCommand::register_subcommands() {
// register_subcommand(std::make_unique<HistoryUndoCommand>(get_context()), software_management_commands_group);
// register_subcommand(std::make_unique<HistoryRedoCommand>(get_context()), software_management_commands_group);
// register_subcommand(std::make_unique<HistoryRollbackCommand>(get_context()), software_management_commands_group);
// register_subcommand(std::make_unique<HistoryStoreCommand>(get_context()), software_management_commands_group);
register_subcommand(std::make_unique<HistoryStoreCommand>(get_context()), software_management_commands_group);
register_subcommand(std::make_unique<HistoryReplayCommand>(get_context()), software_management_commands_group);
}

Expand Down
65 changes: 63 additions & 2 deletions dnf5/commands/history/history_store.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,75 @@ along with libdnf. If not, see <https://www.gnu.org/licenses/>.

#include "history_store.hpp"

#include "commands/history/transaction_id.hpp"

#include <libdnf5/utils/bgettext/bgettext-mark-domain.h>

#include <fstream>

namespace dnf5 {

using namespace libdnf5::cli;

void HistoryStoreCommand::set_argument_parser() {
get_argument_parser_command()->set_description("Store transaction to a file");
auto & cmd = *get_argument_parser_command();
cmd.set_description("Store transaction to a file");
auto & ctx = get_context();
auto & parser = ctx.get_argument_parser();

output_option = dynamic_cast<libdnf5::OptionString *>(
parser.add_init_value(std::make_unique<libdnf5::OptionString>("./transaction.json")));
auto query_format = parser.add_new_named_arg("output");
query_format->set_long_name("output");
query_format->set_short_name('o');
query_format->set_description("File path for storing the transaction, default is \"./transaction.json\"");
query_format->set_has_value(true);
query_format->set_arg_value_help("PATH");
query_format->link_value(output_option);
cmd.register_named_arg(query_format);

transaction_specs = std::make_unique<TransactionSpecArguments>(*this);
}

void HistoryStoreCommand::run() {}
void HistoryStoreCommand::run() {
const auto ts_specs = transaction_specs->get_value();
auto & history = *get_context().base.get_transaction_history();
std::vector<libdnf5::transaction::Transaction> transactions;

if (ts_specs.empty()) {
transactions = list_transactions_from_specs(history, {"last"});
} else {
transactions = list_transactions_from_specs(history, ts_specs);
}

//TODO(amatej): Allow storing multiple transactions at once?
if (transactions.size() != 1) {
throw libdnf5::cli::CommandExitError(1, M_("Multiple transactions selected for storing, only one allowed."));
}

const std::string json = transactions[0].serialize_to_json();

//TODO(amatej): maybe we could expose libdnf5/utils/fs/temp.hpp and use it here
std::filesystem::path tmp_path(output_option->get_value() + ".XXXXXX");
std::string dest = tmp_path;
int fd = mkstemp(dest.data());
if (fd == -1) {
throw std::filesystem::filesystem_error(
"cannot create temporary file", dest, std::error_code(errno, std::system_category()));
}

if (write(fd, json.data(), json.size()) == -1) {
throw std::filesystem::filesystem_error(
"cannot write to temporary file", dest, std::error_code(errno, std::system_category()));
}

if (close(fd) != 0) {
throw std::filesystem::filesystem_error(
"cannot close temporary file", dest, std::error_code(errno, std::system_category()));
}

//TODO(amatej): add warning if file already exists?
std::filesystem::rename(dest, output_option->get_value());
}

} // namespace dnf5
6 changes: 6 additions & 0 deletions dnf5/commands/history/history_store.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ along with libdnf. If not, see <https://www.gnu.org/licenses/>.
#ifndef DNF5_COMMANDS_HISTORY_HISTORY_STORE_HPP
#define DNF5_COMMANDS_HISTORY_HISTORY_STORE_HPP

#include "commands/history/arguments.hpp"

#include <dnf5/context.hpp>


Expand All @@ -32,6 +34,10 @@ class HistoryStoreCommand : public Command {
explicit HistoryStoreCommand(Context & context) : Command(context, "store") {}
void set_argument_parser() override;
void run() override;

private:
std::unique_ptr<TransactionSpecArguments> transaction_specs{nullptr};
libdnf5::OptionString * output_option{nullptr};
};


Expand Down

0 comments on commit 5cbfc19

Please sign in to comment.