From 42dbc602e4432abd8a75c39d218fa1ea5f25abc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= Date: Thu, 12 Sep 2024 16:57:13 +0200 Subject: [PATCH] I18N: Mark messages in "dnf install" output for a translation Many texts were always in English because the code did not internatialinze them. This patch fixes it. fmt::format() calls were replaced with libdnf5::utils::sformat() calls to be able to pass a localized string as a formatting string. Sentences glued from words, e.g. "Installing dependencies:" in a transaction table, were changed to a single-string sentences in the code. Having a full sentece is important for the translators. I fixed spelling at few places, especially around importing PGP keys. I used internatinoalized plural forms in the transaction summary ("Installing: 1 package" vs "Installing: 2 packages"). I also internationalized output to DNF log. At the end, it's a human-oriented text. I intentionally left out libdnf_throw_assertion() arguments from the internationalization because that function needs changing its implmentation to accept nonconst-literal formatting string. That will be implemented in a separate patch. I manully tested significant parts of the output to be sure the messages propetly undergo localization. Resolves: https://github.com/rpm-software-management/dnf5/issues/1688 --- dnf5/context.cpp | 90 ++++++++------- dnf5/main.cpp | 76 ++++++------ libdnf5-cli/output/transaction_table.cpp | 140 ++++++++++++++--------- 3 files changed, 175 insertions(+), 131 deletions(-) diff --git a/dnf5/context.cpp b/dnf5/context.cpp index 523a363a5..fe9b73deb 100644 --- a/dnf5/context.cpp +++ b/dnf5/context.cpp @@ -70,12 +70,15 @@ class KeyImportRepoCB : public libdnf5::repo::RepoCallbacks { return false; } - std::cerr << "Importing PGP key 0x" << key_info.get_short_key_id() << ":\n"; + std::cerr << libdnf5::utils::sformat(_("Importing PGP key 0x{}:\n"), key_info.get_short_key_id()); for (auto & user_id : key_info.get_user_ids()) { - std::cerr << " Userid : \"" << user_id << "\"\n"; + std::cerr << libdnf5::utils::sformat(_(" UserID : \"{}\"\n"), user_id); } - std::cerr << " Fingerprint: " << key_info.get_fingerprint() << "\n"; - std::cerr << " From : " << key_info.get_url() << std::endl; + std::cerr << libdnf5::utils::sformat( + _(" Fingerprint: {}\n" + " From : {}\n"), + key_info.get_fingerprint(), + key_info.get_url()); return libdnf5::cli::utils::userconfirm::userconfirm(*config); } @@ -255,7 +258,8 @@ void Context::Impl::apply_repository_setopts() { repo->get_config().opt_binds().at(key).new_string( libdnf5::Option::Priority::COMMANDLINE, setopt.second); } catch (const std::exception & ex) { - print_error("setopt: \"" + setopt.first + "." + setopt.second + "\": " + ex.what()); + print_error( + libdnf5::utils::sformat(_("setopt: \"{}.{}\": {}"), setopt.first, setopt.second, ex.what())); } } } @@ -307,7 +311,7 @@ void Context::Impl::load_repos(bool load_system) { repo->set_callbacks(std::make_unique(base.get_config())); } - print_info("Updating and loading repositories:"); + print_info(_("Updating and loading repositories:")); if (load_system) { base.get_repo_sack()->load_repos(); } else { @@ -317,7 +321,7 @@ void Context::Impl::load_repos(bool load_system) { if (auto download_callbacks = dynamic_cast(base.get_download_callbacks())) { download_callbacks->reset_progress_bar(); } - print_info("Repositories loaded."); + print_info(_("Repositories loaded.")); } void Context::Impl::store_offline(libdnf5::base::Transaction & transaction) { @@ -334,9 +338,9 @@ void Context::Impl::store_offline(libdnf5::base::Transaction & transaction) { auto & offline_data = state.get_data(); if (offline_data.get_status() != libdnf5::offline::STATUS_DOWNLOAD_INCOMPLETE) { - print_error("There is already an offline transaction queued, initiated by the following command:"); + print_error(_("There is already an offline transaction queued, initiated by the following command:")); print_error(fmt::format("\t{}", offline_data.get_cmd_line())); - print_error("Continuing will cancel the old offline transaction and replace it with this one."); + print_error(_("Continuing will cancel the old offline transaction and replace it with this one.")); if (!libdnf5::cli::utils::userconfirm::userconfirm(base.get_config())) { throw libdnf5::cli::AbortedByUserError(); } @@ -362,16 +366,16 @@ void Context::Impl::store_offline(libdnf5::base::Transaction & transaction) { } base.get_config().get_tsflags_option().set(libdnf5::Option::Priority::RUNTIME, "test"); - print_info("Testing offline transaction"); + print_info(_("Testing offline transaction")); auto result = test_transaction.run(); if (result != libdnf5::base::Transaction::TransactionRunResult::SUCCESS) { - print_error( - fmt::format("Transaction failed: {}", libdnf5::base::Transaction::transaction_result_to_string(result))); + print_error(libdnf5::utils::sformat( + _("Transaction failed: {}"), libdnf5::base::Transaction::transaction_result_to_string(result))); for (auto const & entry : transaction.get_gpg_signature_problems()) { print_error(entry); } for (auto & problem : test_transaction.get_transaction_problems()) { - print_error(fmt::format(" - {}", problem)); + print_error(libdnf5::utils::sformat(_(" - {}"), problem)); } throw libdnf5::cli::SilentCommandExitError(1); } @@ -453,13 +457,13 @@ void Context::Impl::download_and_run(libdnf5::base::Transaction & transaction) { if (should_store_offline) { store_offline(transaction); print_info( - "Transaction stored to be performed offline. Run `dnf5 offline reboot` to reboot and run the " - "transaction. To cancel the transaction and delete the downloaded files, use `dnf5 " - "offline clean`."); + _("Transaction stored to be performed offline. Run `dnf5 offline reboot` to reboot and run the " + "transaction. To cancel the transaction and delete the downloaded files, use `dnf5 " + "offline clean`.")); return; } - print_info("Running transaction"); + print_info(_("Running transaction")); // Compute the total number of transaction actions (number of bars) // Total number of actions = number of packages in the transaction + @@ -487,13 +491,13 @@ void Context::Impl::download_and_run(libdnf5::base::Transaction & transaction) { auto result = transaction.run(); print_info(""); if (result != libdnf5::base::Transaction::TransactionRunResult::SUCCESS) { - print_error( - fmt::format("Transaction failed: {}", libdnf5::base::Transaction::transaction_result_to_string(result))); + print_error(libdnf5::utils::sformat( + _("Transaction failed: {}"), libdnf5::base::Transaction::transaction_result_to_string(result))); for (auto const & entry : transaction.get_gpg_signature_problems()) { print_error(entry); } for (auto & problem : transaction.get_transaction_problems()) { - print_error(fmt::format(" - {}", problem)); + print_error(libdnf5::utils::sformat(_(" - {}"), problem)); } throw libdnf5::cli::SilentCommandExitError(1); } @@ -767,13 +771,13 @@ void RpmTransCB::install_start(const libdnf5::base::TransactionPackage & item, u const char * msg{nullptr}; switch (item.get_action()) { case libdnf5::transaction::TransactionItemAction::UPGRADE: - msg = "Upgrading "; + msg = _("Upgrading {}"); break; case libdnf5::transaction::TransactionItemAction::DOWNGRADE: - msg = "Downgrading "; + msg = _("Downgrading {}"); break; case libdnf5::transaction::TransactionItemAction::REINSTALL: - msg = "Reinstalling "; + msg = _("Reinstalling {}"); break; case libdnf5::transaction::TransactionItemAction::INSTALL: case libdnf5::transaction::TransactionItemAction::REMOVE: @@ -786,15 +790,15 @@ void RpmTransCB::install_start(const libdnf5::base::TransactionPackage & item, u case libdnf5::transaction::TransactionItemAction::SWITCH: auto & logger = *context.get_base().get_logger(); logger.warning( - "Unexpected action in TransactionPackage: {}", + _("Unexpected action in TransactionPackage: {}"), static_cast>( item.get_action())); return; } if (!msg) { - msg = "Installing "; + msg = _("Installing {}"); } - new_progress_bar(static_cast(total), msg + item.get_package().get_full_nevra()); + new_progress_bar(static_cast(total), libdnf5::utils::sformat(msg, item.get_package().get_full_nevra())); } void RpmTransCB::install_stop( @@ -812,7 +816,7 @@ void RpmTransCB::transaction_progress(uint64_t amount, [[maybe_unused]] uint64_t } void RpmTransCB::transaction_start(uint64_t total) { - new_progress_bar(static_cast(total), "Prepare transaction"); + new_progress_bar(static_cast(total), _("Prepare transaction")); } void RpmTransCB::transaction_stop([[maybe_unused]] uint64_t total) { @@ -832,12 +836,12 @@ void RpmTransCB::uninstall_start(const libdnf5::base::TransactionPackage & item, const char * msg{nullptr}; if (item.get_action() == libdnf5::transaction::TransactionItemAction::REMOVE || item.get_action() == libdnf5::transaction::TransactionItemAction::REPLACED) { - msg = "Erasing "; + msg = _("Erasing {}"); } if (!msg) { - msg = "Cleanup "; + msg = _("Cleanup {}"); } - new_progress_bar(static_cast(total), msg + item.get_package().get_full_nevra()); + new_progress_bar(static_cast(total), libdnf5::utils::sformat(msg, item.get_package().get_full_nevra())); } void RpmTransCB::uninstall_stop( @@ -850,14 +854,16 @@ void RpmTransCB::uninstall_stop( void RpmTransCB::unpack_error(const libdnf5::base::TransactionPackage & item) { active_progress_bar->add_message( - libdnf5::cli::progressbar::MessageType::ERROR, "Unpack error: " + item.get_package().get_full_nevra()); + libdnf5::cli::progressbar::MessageType::ERROR, + libdnf5::utils::sformat(_("Unpack error: {}"), item.get_package().get_full_nevra())); active_progress_bar->set_state(libdnf5::cli::progressbar::ProgressBarState::ERROR); multi_progress_bar.print(); } void RpmTransCB::cpio_error(const libdnf5::base::TransactionPackage & item) { active_progress_bar->add_message( - libdnf5::cli::progressbar::MessageType::ERROR, "Cpio error: " + item.get_package().get_full_nevra()); + libdnf5::cli::progressbar::MessageType::ERROR, + libdnf5::utils::sformat(_("Cpio error: {}"), item.get_package().get_full_nevra())); active_progress_bar->set_state(libdnf5::cli::progressbar::ProgressBarState::ERROR); multi_progress_bar.print(); } @@ -866,7 +872,7 @@ void RpmTransCB::script_output_to_progress(const libdnf5::cli::progressbar::Mess auto transaction = context.get_transaction(); auto output = transaction->get_last_script_output(); if (!output.empty()) { - active_progress_bar->add_message(message_type, "Scriptlet output:"); + active_progress_bar->add_message(message_type, _("Scriptlet output:")); for (auto & line : libdnf5::utils::string::split(output, "\n")) { active_progress_bar->add_message(message_type, line); } @@ -880,8 +886,8 @@ void RpmTransCB::script_error( uint64_t return_code) { active_progress_bar->add_message( libdnf5::cli::progressbar::MessageType::ERROR, - fmt::format( - "Error in {} scriptlet: {} return code {}", + libdnf5::utils::sformat( + _("Error in {} scriptlet: {} return code {}"), script_type_to_string(type), to_full_nevra_string(nevra), return_code)); @@ -895,7 +901,8 @@ void RpmTransCB::script_start( libdnf5::rpm::TransactionCallbacks::ScriptType type) { active_progress_bar->add_message( libdnf5::cli::progressbar::MessageType::INFO, - fmt::format("Running {} scriptlet: {}", script_type_to_string(type), to_full_nevra_string(nevra))); + libdnf5::utils::sformat( + _("Running {} scriptlet: {}"), script_type_to_string(type), to_full_nevra_string(nevra))); multi_progress_bar.print(); } @@ -914,8 +921,8 @@ void RpmTransCB::script_stop( // Print the error message here. active_progress_bar->add_message( libdnf5::cli::progressbar::MessageType::WARNING, - fmt::format( - "Non-critical error in {} scriptlet: {}", + libdnf5::utils::sformat( + _("Non-critical error in {} scriptlet: {}"), script_type_to_string(type), to_full_nevra_string(nevra))); script_output_to_progress(libdnf5::cli::progressbar::MessageType::WARNING); @@ -923,7 +930,8 @@ void RpmTransCB::script_stop( default: active_progress_bar->add_message( libdnf5::cli::progressbar::MessageType::INFO, - fmt::format("Stop {} scriptlet: {}", script_type_to_string(type), to_full_nevra_string(nevra))); + libdnf5::utils::sformat( + _("Stop {} scriptlet: {}"), script_type_to_string(type), to_full_nevra_string(nevra))); } multi_progress_bar.print(); } @@ -932,7 +940,7 @@ void RpmTransCB::elem_progress( [[maybe_unused]] const libdnf5::base::TransactionPackage & item, [[maybe_unused]] uint64_t amount, [[maybe_unused]] uint64_t total) { - //std::cout << "Element progress: " << header.get_full_nevra() << " " << amount << '/' << total << std::endl; + //std::cout << libdnf5::utils::sformat(_("Element progress: {} {}/{}"), item.get_package().get_full_nevra(), amount, total) << std::endl; } void RpmTransCB::verify_progress(uint64_t amount, [[maybe_unused]] uint64_t total) { @@ -943,7 +951,7 @@ void RpmTransCB::verify_progress(uint64_t amount, [[maybe_unused]] uint64_t tota } void RpmTransCB::verify_start([[maybe_unused]] uint64_t total) { - new_progress_bar(static_cast(total), "Verify package files"); + new_progress_bar(static_cast(total), _("Verify package files")); } void RpmTransCB::verify_stop([[maybe_unused]] uint64_t total) { diff --git a/dnf5/main.cpp b/dnf5/main.cpp index 99083a5e2..87c61822c 100644 --- a/dnf5/main.cpp +++ b/dnf5/main.cpp @@ -739,34 +739,36 @@ static void print_versions(Context & context) { constexpr const char * appl_name = "dnf5"; { const auto & version = get_application_version(); - context.print_output(fmt::format( - "{} version {}.{}.{}.{}", appl_name, version.prime, version.major, version.minor, version.micro)); + context.print_output(libdnf5::utils::sformat( + _("{} version {}.{}.{}.{}"), appl_name, version.prime, version.major, version.minor, version.micro)); const auto & api_version = get_plugin_api_version(); context.print_output( - fmt::format("{} plugin API version {}.{}", appl_name, api_version.major, api_version.minor)); + libdnf5::utils::sformat(_("{} plugin API version {}.{}"), appl_name, api_version.major, api_version.minor)); } { const auto & version = libdnf5::get_library_version(); - context.print_output( - fmt::format("libdnf5 version {}.{}.{}.{}", version.prime, version.major, version.minor, version.micro)); + context.print_output(libdnf5::utils::sformat( + _("libdnf5 version {}.{}.{}.{}"), version.prime, version.major, version.minor, version.micro)); const auto & api_version = libdnf5::get_plugin_api_version(); - context.print_output(fmt::format("libdnf5 plugin API version {}.{}", api_version.major, api_version.minor)); + context.print_output( + libdnf5::utils::sformat(_("libdnf5 plugin API version {}.{}"), api_version.major, api_version.minor)); } bool first{true}; for (const auto & plugin : context.get_plugins().get_plugins()) { if (first) { first = false; - context.print_output(fmt::format("\nLoaded {} plugins:", appl_name)); + context.print_output(libdnf5::utils::sformat(_("\nLoaded {} plugins:"), appl_name)); } else { context.print_output(""); } auto * iplugin = plugin->get_iplugin(); - context.print_output(fmt::format(" name: {}", iplugin->get_name())); + context.print_output(libdnf5::utils::sformat(_(" name: {}"), iplugin->get_name())); const auto & version = iplugin->get_version(); - context.print_output(fmt::format(" version: {}.{}.{}", version.major, version.minor, version.micro)); + context.print_output( + libdnf5::utils::sformat(_(" version: {}.{}.{}"), version.major, version.minor, version.micro)); const auto & api_version = iplugin->get_api_version(); - context.print_output(fmt::format(" API version: {}.{}", api_version.major, api_version.minor)); + context.print_output(libdnf5::utils::sformat(_(" API version: {}.{}"), api_version.major, api_version.minor)); } } @@ -794,8 +796,8 @@ static void print_transaction_size_stats(Context & context) { const auto [in_pkgs_size_value, in_pkgs_size_unit] = libdnf5::cli::utils::units::to_size(in_pkgs_size); const auto [dwnl_pkgs_size_value, dwnl_pkgs_size_unit] = libdnf5::cli::utils::units::to_size(download_pkgs_size); - context.print_info(fmt::format( - "Total size of inbound packages is {:.0f} {:s}. Need to download {:.0f} {:s}.", + context.print_info(libdnf5::utils::sformat( + _("Total size of inbound packages is {:.0f} {:s}. Need to download {:.0f} {:s}."), in_pkgs_size_value, in_pkgs_size_unit, dwnl_pkgs_size_value, @@ -807,8 +809,8 @@ static void print_transaction_size_stats(Context & context) { const auto size_diff = install_size - remove_size; const auto [size_diff_value, size_diff_unit] = libdnf5::cli::utils::units::to_size(std::abs(size_diff)); if (size_diff >= 0) { - context.print_info(fmt::format( - "After this operation, {:.0f} {:s} extra will be used (install {:.0f} {:s}, remove {:.0f} {:s}).", + context.print_info(libdnf5::utils::sformat( + _("After this operation, {:.0f} {:s} extra will be used (install {:.0f} {:s}, remove {:.0f} {:s})."), size_diff_value, size_diff_unit, install_size_value, @@ -816,8 +818,8 @@ static void print_transaction_size_stats(Context & context) { remove_size_value, remove_size_unit)); } else { - context.print_info(fmt::format( - "After this operation, {:.0f} {:s} will be freed (install {:.0f} {:s}, remove {:.0f} {:s}).", + context.print_info(libdnf5::utils::sformat( + _("After this operation, {:.0f} {:s} will be freed (install {:.0f} {:s}, remove {:.0f} {:s})."), size_diff_value, size_diff_unit, install_size_value, @@ -866,7 +868,7 @@ static void dump_repository_configuration(Context & context, const std::vectorinfo("--- DNF5 launched with arguments: \"{}\" ---", cmdline); + loggers.front()->info(_("--- DNF5 launched with arguments: \"{}\" ---"), cmdline); // Creates a context and passes the loggers to it. We want to capture all messages from the context in the log. dnf5::Context context(std::move(loggers)); @@ -1236,17 +1238,17 @@ int main(int argc, char * argv[]) try { } } if (help_printed) { - context.print_error(fmt::format("{}.", ex.what())); + context.print_error(libdnf5::utils::sformat(_("{}."), ex.what())); } else { - context.print_error(fmt::format( - "{}{}", ex.what(), _(". Add \"--help\" for more information about the arguments."))); + context.print_error(libdnf5::utils::sformat( + _("{}. Add \"--help\" for more information about the arguments."), ex.what())); } // If the error is an unknown top-level command, suggest // installing a package that provides the command if (auto * unknown_arg_ex = dynamic_cast(&ex)) { if (unknown_arg_ex->get_command() == "dnf5" && unknown_arg_ex->get_argument()[0] != '-') { - context.print_error(fmt::format( - "It could be a command provided by a plugin, try: dnf5 install 'dnf5-command({})'", + context.print_error(libdnf5::utils::sformat( + _("It could be a command provided by a plugin, try: dnf5 install 'dnf5-command({})'"), unknown_arg_ex->get_argument())); } } @@ -1288,7 +1290,7 @@ int main(int argc, char * argv[]) try { // read and execute access. If not, chdir to / auto fd = open(".", O_RDONLY); if (fd == -1) { - log_router.warning("No read/execute access in current directory, moving to /"); + log_router.warning(_("No read/execute access in current directory, moving to /")); std::filesystem::current_path("/"); } else { close(fd); @@ -1385,16 +1387,16 @@ int main(int argc, char * argv[]) try { if (auto transaction_store_path = context.get_transaction_store_path(); !transaction_store_path.empty()) { - context.print_error(fmt::format( - "The operation will only store the transaction in {}", transaction_store_path.string())); + context.print_error(libdnf5::utils::sformat( + _("The operation will only store the transaction in {}"), transaction_store_path.string())); } else if (base.get_config().get_downloadonly_option().get_value()) { - context.print_error("The operation will only download packages for the transaction."); + context.print_error(_("The operation will only download packages for the transaction.")); } else { for (const auto & tsflag : base.get_config().get_tsflags_option().get_value()) { if (tsflag == "test") { context.print_error( - "Test mode enabled: Only package downloads, pgp key installations and transaction " - "checks will be performed."); + _("Test mode enabled: Only package downloads, PGP key installations and transaction " + "checks will be performed.")); } } } @@ -1410,8 +1412,8 @@ int main(int argc, char * argv[]) try { if (!any_repos_from_system_configuration && base.get_config().get_installroot_option().get_value() != "/" && !base.get_config().get_use_host_config_option().get_value()) { std::cerr - << "No repositories were loaded from the installroot. To use the configuration and repositories " - "of the host system, pass --use-host-config." + << _("No repositories were loaded from the installroot. To use the configuration and repositories " + "of the host system, pass --use-host-config.") << std::endl; } else { if (context.get_transaction() != nullptr) { @@ -1421,7 +1423,9 @@ int main(int argc, char * argv[]) try { } return static_cast(libdnf5::cli::ExitCode::ERROR); } catch (libdnf5::cli::ArgumentParserError & ex) { - std::cerr << ex.what() << _(". Add \"--help\" for more information about the arguments.") << std::endl; + std::cerr << libdnf5::utils::sformat( + _("{}. Add \"--help\" for more information about the arguments."), ex.what()) + << std::endl; return static_cast(libdnf5::cli::ExitCode::ARGPARSER_ERROR); } catch (libdnf5::cli::CommandExitError & ex) { std::cerr << ex.what() << std::endl; @@ -1430,7 +1434,7 @@ int main(int argc, char * argv[]) try { return ex.get_exit_code(); } catch (std::runtime_error & ex) { std::cerr << libdnf5::format(ex, libdnf5::FormatDetailLevel::Plain); - log_router.error("Command returned error: {}", ex.what()); + log_router.error(_("Command returned error: {}"), ex.what()); return static_cast(libdnf5::cli::ExitCode::ERROR); } } catch (std::runtime_error & ex) { @@ -1438,7 +1442,7 @@ int main(int argc, char * argv[]) try { return static_cast(libdnf5::cli::ExitCode::ERROR); } - log_router.info("DNF5 finished"); + log_router.info(_("DNF5 finished")); // Print Complete! message only when transaction is created to prevent poluting output from repoquery or other command if (auto * transaction = context.get_transaction(); transaction && !transaction->empty()) { diff --git a/libdnf5-cli/output/transaction_table.cpp b/libdnf5-cli/output/transaction_table.cpp index 0e8306a1b..810fb6486 100644 --- a/libdnf5-cli/output/transaction_table.cpp +++ b/libdnf5-cli/output/transaction_table.cpp @@ -30,6 +30,7 @@ along with libdnf. If not, see . #include #include #include +#include #include #include @@ -123,30 +124,63 @@ class TransactionSummary { void add_skip() { skips++; } void print(std::FILE * fd = stdout) const { - std::fputs("Transaction Summary:\n", fd); + std::fputs(_("Transaction Summary:\n"), fd); if (installs != 0) { - std::fputs(fmt::format(" {:15} {:4} packages\n", "Installing:", installs).c_str(), fd); + std::fputs( + libdnf5::utils::sformat( + P_(" Installing: {:4} package\n", " Installing: {:4} packages\n", installs), installs) + .c_str(), + fd); } if (reinstalls != 0) { - std::fputs(fmt::format(" {:15} {:4} packages\n", "Reinstalling:", reinstalls).c_str(), fd); + std::fputs( + libdnf5::utils::sformat( + P_(" Reinstalling: {:4} package\n", " Reinstalling: {:4} packages\n", reinstalls), reinstalls) + .c_str(), + fd); } if (upgrades != 0) { - std::fputs(fmt::format(" {:15} {:4} packages\n", "Upgrading:", upgrades).c_str(), fd); + std::fputs( + libdnf5::utils::sformat( + P_(" Upgrading: {:4} package\n", " Upgrading: {:4} packages\n", upgrades), upgrades) + .c_str(), + fd); } if (replaced != 0) { - std::fputs(fmt::format(" {:15} {:4} packages\n", "Replacing:", replaced).c_str(), fd); + std::fputs( + libdnf5::utils::sformat( + P_(" Replacing: {:4} package\n", " Replacing: {:4} package\n", replaced), replaced) + .c_str(), + fd); } if (removes != 0) { - std::fputs(fmt::format(" {:15} {:4} packages\n", "Removing:", removes).c_str(), fd); + std::fputs( + libdnf5::utils::sformat( + P_(" Removing: {:4} package\n", " Removing: {:4} packages\n", removes), removes) + .c_str(), + fd); } if (downgrades != 0) { - std::fputs(fmt::format(" {:15} {:4} packages\n", "Downgrading:", downgrades).c_str(), fd); + std::fputs( + libdnf5::utils::sformat( + P_(" Downgrading: {:4} package\n", " Downgrading: {:4} packages\n", downgrades), downgrades) + .c_str(), + fd); } if (reason_changes != 0) { - std::fputs(fmt::format(" {:15} {:4} packages\n", "Changing reason:", reason_changes).c_str(), fd); + std::fputs( + libdnf5::utils::sformat( + P_(" Changing reason: {:4} package\n", " Changing reason: {:4} packages\n", reason_changes), + reason_changes) + .c_str(), + fd); } if (skips != 0) { - std::fputs(fmt::format(" {:15} {:4} packages\n", "Skipping:", skips).c_str(), fd); + std::fputs( + libdnf5::utils::sformat( + P_(" Skipping: {:4} package\n", " Skipping: {:4} packages\n", skips), skips) + .c_str(), + fd); } std::fputc('\n', fd); } @@ -225,31 +259,31 @@ TransactionTable::Impl::Impl(ITransaction & transaction) { scols_table_enable_noheadings(*tb, 1); struct libscols_line * header_ln = scols_table_new_line(*tb, NULL); - auto column = scols_table_new_column(*tb, "Package", 0.3, 0); + auto column = scols_table_new_column(*tb, _("Package"), 0.3, 0); auto header = scols_column_get_header(column); auto cell = scols_line_get_cell(header_ln, COL_NAME); scols_cell_set_data(cell, scols_cell_get_data(header)); scols_cell_set_color(cell, "bold"); - column = scols_table_new_column(*tb, "Arch", 6, 0); + column = scols_table_new_column(*tb, _("Arch"), 6, 0); header = scols_column_get_header(column); cell = scols_line_get_cell(header_ln, COL_ARCH); scols_cell_set_data(cell, scols_cell_get_data(header)); scols_cell_set_color(cell, "bold"); - column = scols_table_new_column(*tb, "Version", 0.3, SCOLS_FL_TRUNC); + column = scols_table_new_column(*tb, _("Version"), 0.3, SCOLS_FL_TRUNC); header = scols_column_get_header(column); cell = scols_line_get_cell(header_ln, COL_EVR); scols_cell_set_data(cell, scols_cell_get_data(header)); scols_cell_set_color(cell, "bold"); - column = scols_table_new_column(*tb, "Repository", 0.1, SCOLS_FL_TRUNC); + column = scols_table_new_column(*tb, _("Repository"), 0.1, SCOLS_FL_TRUNC); header = scols_column_get_header(column); cell = scols_line_get_cell(header_ln, COL_REPO); scols_cell_set_data(cell, scols_cell_get_data(header)); scols_cell_set_color(cell, "bold"); - column = scols_table_new_column(*tb, "Size", 9, SCOLS_FL_RIGHT); + column = scols_table_new_column(*tb, _("Size"), 9, SCOLS_FL_RIGHT); header = scols_column_get_header(column); cell = scols_line_get_cell(header_ln, COL_SIZE); scols_cell_set_data(cell, scols_cell_get_data(header)); @@ -304,8 +338,8 @@ TransactionTable::Impl::Impl(ITransaction & transaction) { if (tspkg->get_action() == libdnf5::transaction::TransactionItemAction::REASON_CHANGE) { auto replaced_color = action_color(libdnf5::transaction::TransactionItemAction::REPLACED); struct libscols_line * ln_reason = scols_table_new_line(*tb, ln); - std::string reason = fmt::format( - "{} -> {}", + std::string reason = libdnf5::utils::sformat( + _("{} -> {}"), libdnf5::transaction::transaction_item_reason_to_string(pkg->get_reason()), libdnf5::transaction::transaction_item_reason_to_string(tspkg->get_reason())); scols_line_set_data(ln_reason, COL_NAME, (" " + reason).c_str()); @@ -321,9 +355,7 @@ TransactionTable::Impl::Impl(ITransaction & transaction) { } struct libscols_line * ln_replaced = scols_table_new_line(*tb, ln); - // TODO(jmracek) Translate it - std::string name("replacing "); - name.append(replaced->get_name()); + std::string name(libdnf5::utils::sformat(_("replacing {}"), replaced->get_name())); scols_line_set_data(ln_replaced, COL_NAME, (" " + name).c_str()); scols_line_set_data(ln_replaced, COL_ARCH, replaced->get_arch().c_str()); scols_line_set_data(ln_replaced, COL_EVR, replaced->get_evr().c_str()); @@ -359,7 +391,7 @@ TransactionTable::Impl::Impl(ITransaction & transaction) { struct libscols_line * ln = scols_table_new_line(*tb, header_ln); auto const grp_name = grp->get_name(); if (grp_name.empty()) { - scols_line_set_data(ln, COL_NAME, " "); + scols_line_set_data(ln, COL_NAME, _(" ")); } else { scols_line_set_data(ln, COL_NAME, (" " + grp_name).c_str()); } @@ -376,7 +408,7 @@ TransactionTable::Impl::Impl(ITransaction & transaction) { struct libscols_line * ln = scols_table_new_line(*tb, header_ln); auto const env_name = env->get_name(); if (env_name.empty()) { - scols_line_set_data(ln, COL_NAME, " "); + scols_line_set_data(ln, COL_NAME, _(" ")); } else { scols_line_set_data(ln, COL_NAME, (" " + env_name).c_str()); } @@ -399,15 +431,15 @@ TransactionTable::Impl::Impl(ITransaction & transaction) { if (replaces.size() == 1 && replaces[0].first == tsmodule->get_module_name()) { // There is only one replaced module and the module name is the same, report it on one line scols_line_set_data( - ln, COL_EVR, fmt::format("{} -> {}", tsmodule->get_module_stream(), replaces[0].second).c_str()); + ln, + COL_EVR, + libdnf5::utils::sformat(_("{} -> {}"), tsmodule->get_module_stream(), replaces[0].second).c_str()); } else { // There are multiple replaced modules, report it using the "replacing" lines scols_line_set_data(ln, COL_EVR, tsmodule->get_module_stream().c_str()); for (auto & replaced : replaces) { struct libscols_line * ln_replaced = scols_table_new_line(*tb, ln); - // TODO(jmracek) Translate it - std::string name("replacing "); - name.append(replaced.first); + std::string name(libdnf5::utils::sformat(_("replacing "), replaced.first)); scols_line_set_data(ln_replaced, COL_NAME, (" " + name).c_str()); scols_line_set_data(ln_replaced, COL_EVR, replaced.second.c_str()); auto replaced_color = action_color(libdnf5::transaction::TransactionItemAction::REPLACED); @@ -420,8 +452,9 @@ TransactionTable::Impl::Impl(ITransaction & transaction) { // vector of different types of skipped packages along with the header for the type std::vector>, std::string>> skipped; - skipped.emplace_back(transaction.get_conflicting_packages(), "Skipping packages with conflicts:"); - skipped.emplace_back(transaction.get_broken_dependency_packages(), "Skipping packages with broken dependencies:"); + skipped.emplace_back(transaction.get_conflicting_packages(), _("Skipping packages with conflicts:")); + skipped.emplace_back( + transaction.get_broken_dependency_packages(), _("Skipping packages with broken dependencies:")); for (const auto & [skipped_packages, header] : skipped) { std::optional> section; for (const auto & pkg : skipped_packages) { @@ -481,34 +514,36 @@ TransactionTableSection & TransactionTable::Impl::add_section( switch (action) { case libdnf5::transaction::TransactionItemAction::INSTALL: - text = "Installing"; if (reason == libdnf5::transaction::TransactionItemReason::DEPENDENCY) { - text += " dependencies"; + text = _("Installing dependencies:"); } else if (reason == libdnf5::transaction::TransactionItemReason::WEAK_DEPENDENCY) { - text += " weak dependencies"; + text = _("Installing weak dependencies:"); } else if (reason == libdnf5::transaction::TransactionItemReason::GROUP) { - text += " group/module packages"; + text = _("Installing group/module packages:"); + } else { + text = _("Installing:"); } break; case libdnf5::transaction::TransactionItemAction::UPGRADE: - text = "Upgrading"; + text = _("Upgrading:"); break; case libdnf5::transaction::TransactionItemAction::DOWNGRADE: - text = "Downgrading"; + text = _("Downgrading:"); break; case libdnf5::transaction::TransactionItemAction::REINSTALL: - text = "Reinstalling"; + text = _("Reinstalling:"); break; case libdnf5::transaction::TransactionItemAction::REMOVE: - text = "Removing"; if (reason == libdnf5::transaction::TransactionItemReason::DEPENDENCY) { - text += " dependent packages"; + text = _("Removing dependent packages:"); } else if (reason == libdnf5::transaction::TransactionItemReason::CLEAN) { - text += " unused dependencies"; + text = _("Removing unused dependencies:"); + } else { + text = _("Removing:"); } break; case libdnf5::transaction::TransactionItemAction::REASON_CHANGE: - text = "Changing reason"; + text = _("Changing reason:"); break; case libdnf5::transaction::TransactionItemAction::REPLACED: case libdnf5::transaction::TransactionItemAction::ENABLE: @@ -519,7 +554,6 @@ TransactionTableSection & TransactionTable::Impl::add_section( "Unexpected action in print_transaction_table: {}", libdnf5::utils::to_underlying(action)); } - text += ":"; sections.emplace_back(text, line); current_type = libdnf5::transaction::TransactionItemType::PACKAGE; @@ -540,23 +574,23 @@ TransactionTableSection & TransactionTable::Impl::add_section( switch (action) { case libdnf5::transaction::TransactionItemAction::INSTALL: - text = "Installing groups"; if (reason == libdnf5::transaction::TransactionItemReason::DEPENDENCY) { - text += " dependencies"; + text = _("Installing groups dependencies:"); + } else { + text = _("Installing groups:"); } break; case libdnf5::transaction::TransactionItemAction::REMOVE: - text = "Removing groups"; + text = _("Removing groups:"); break; case libdnf5::transaction::TransactionItemAction::UPGRADE: - text = "Upgrading groups"; + text = _("Upgrading groups:"); break; default: libdnf_throw_assertion( "Unexpected action in print_transaction_table: {}", libdnf5::utils::to_underlying(action)); } - text += ":"; sections.emplace_back(text, line); current_type = libdnf5::transaction::TransactionItemType::GROUP; @@ -577,20 +611,19 @@ TransactionTableSection & TransactionTable::Impl::add_section( switch (action) { case libdnf5::transaction::TransactionItemAction::INSTALL: - text = "Installing environmental groups"; + text = _("Installing environmental groups:"); break; case libdnf5::transaction::TransactionItemAction::REMOVE: - text = "Removing environmental groups"; + text = _("Removing environmental groups:"); break; case libdnf5::transaction::TransactionItemAction::UPGRADE: - text = "Upgrading environmental groups"; + text = _("Upgrading environmental groups:"); break; default: libdnf_throw_assertion( "Unexpected action in print_transaction_table: {}", libdnf5::utils::to_underlying(action)); } - text += ":"; sections.emplace_back(text, line); current_type = libdnf5::transaction::TransactionItemType::ENVIRONMENT; @@ -611,23 +644,22 @@ TransactionTableSection & TransactionTable::Impl::add_section( switch (action) { case libdnf5::transaction::TransactionItemAction::ENABLE: - text = "Enabling module streams"; + text = _("Enabling module streams:"); break; case libdnf5::transaction::TransactionItemAction::DISABLE: - text = "Disabling modules"; + text = _("Disabling modules:"); break; case libdnf5::transaction::TransactionItemAction::RESET: - text = "Resetting modules"; + text = _("Resetting modules:"); break; case libdnf5::transaction::TransactionItemAction::SWITCH: - text = "Switching module streams"; + text = _("Switching module streams:"); break; default: libdnf_throw_assertion( "Unexpected action in print_transaction_table: {}", libdnf5::utils::to_underlying(action)); } - text += ":"; sections.emplace_back(text, line); current_type = libdnf5::transaction::TransactionItemType::MODULE; @@ -695,7 +727,7 @@ bool print_transaction_table(ITransaction & transaction) { table.print_table(); if (transaction.empty()) { - std::cout << "Nothing to do." << std::endl; + std::cout << _("Nothing to do.") << std::endl; return false; }