From 7ac700ebfd5cd524a1096f0f7f8b432e97473b2d Mon Sep 17 00:00:00 2001 From: long-walk Date: Sun, 21 Jan 2024 22:37:36 +0100 Subject: [PATCH 01/10] single line transaction list --- .../libdnf5-cli/output/transaction_table.hpp | 89 +++++++++++++------ 1 file changed, 61 insertions(+), 28 deletions(-) diff --git a/include/libdnf5-cli/output/transaction_table.hpp b/include/libdnf5-cli/output/transaction_table.hpp index fb19715a2..282219dfa 100644 --- a/include/libdnf5-cli/output/transaction_table.hpp +++ b/include/libdnf5-cli/output/transaction_table.hpp @@ -30,6 +30,7 @@ along with libdnf. If not, see . #include #include #include +#include #include #include @@ -429,7 +430,7 @@ bool print_transaction_table(Transaction & transaction) { struct libscols_table * tb = scols_new_table(); - auto column = scols_table_new_column(tb, "Package", 0.3, SCOLS_FL_TREE); + auto column = scols_table_new_column(tb, "Package", 0.2, SCOLS_FL_TREE); auto header = scols_column_get_header(column); scols_cell_set_color(header, "bold"); @@ -437,7 +438,7 @@ bool print_transaction_table(Transaction & transaction) { header = scols_column_get_header(column); scols_cell_set_color(header, "bold"); - column = scols_table_new_column(tb, "Version", 0.3, SCOLS_FL_TRUNC); + column = scols_table_new_column(tb, "Version", 0.2, SCOLS_FL_TRUNC); header = scols_column_get_header(column); scols_cell_set_color(header, "bold"); @@ -445,7 +446,7 @@ bool print_transaction_table(Transaction & transaction) { header = scols_column_get_header(column); scols_cell_set_color(header, "bold"); - column = scols_table_new_column(tb, "Size", 9, SCOLS_FL_RIGHT); + column = scols_table_new_column(tb, "Size", 0.1, SCOLS_FL_RIGHT); header = scols_column_get_header(column); scols_cell_set_color(header, "bold"); @@ -507,41 +508,73 @@ bool print_transaction_table(Transaction & transaction) { scols_cell_set_color(scols_line_get_cell(ln_reason, COL_NAME), replaced_color); } for (auto & replaced : tspkg.get_replaces()) { + // highlight arch change + if (tspkg.get_package().get_arch() != replaced.get_arch()) { + auto cl_arch = scols_line_get_cell(ln, COL_ARCH); + scols_cell_set_color(cl_arch, "brown"); + scols_cell_set_data(cl_arch, (pkg.get_arch() + " <- " + replaced.get_arch()).c_str()); + } + // highlight incoming packages with epoch/version change if (tspkg.get_package().get_epoch() != replaced.get_epoch() || tspkg.get_package().get_version() != replaced.get_version()) { - auto cl_evr = scols_line_get_cell(ln, COL_EVR); - scols_cell_set_color(cl_evr, "bold"); + scols_cell_set_color(scols_line_get_cell(ln, COL_EVR), "bold"); } - struct libscols_line * ln_replaced = scols_table_new_line(tb, ln); - // TODO(jmracek) Translate it - std::string name("replacing "); - name.append(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()); - scols_line_set_data(ln_replaced, COL_REPO, replaced.get_from_repo_id().c_str()); - - auto replaced_size = static_cast(replaced.get_install_size()); - scols_line_set_data( - ln_replaced, COL_SIZE, libdnf5::cli::utils::units::format_size_aligned(replaced_size).c_str()); - auto replaced_color = action_color(libdnf5::transaction::TransactionItemAction::REPLACED); - auto obsoleted_color = "brown"; + // highlight repo changed + if (pkg.get_repo_id() != replaced.get_from_repo_id()) { + scols_cell_set_color(scols_line_get_cell(ln, COL_REPO), "magenta"); + scols_line_set_data(ln, COL_REPO, (pkg.get_repo_id() + " <- " + replaced.get_from_repo_id()).c_str()); + } - scols_cell_set_color(scols_line_get_cell(ln_replaced, COL_EVR), replaced_color); - if (pkg.get_arch() == replaced.get_arch()) { - scols_cell_set_color(scols_line_get_cell(ln_replaced, COL_ARCH), replaced_color); - } else { - scols_cell_set_color(scols_line_get_cell(ln_replaced, COL_ARCH), obsoleted_color); + // highlight size changed >10% + double long difference = + abs((double long)100 - ((double long)100 / (double long)pkg.get_install_size() * + (double long)replaced.get_install_size())); + if (difference > 10) { + scols_cell_set_color(scols_line_get_cell(ln, COL_SIZE), "red"); + auto replaced_size = static_cast(replaced.get_install_size()); + scols_line_set_data( + ln, + COL_SIZE, + (libdnf5::cli::utils::units::format_size_aligned(tspkg_size) + " <- " + + libdnf5::cli::utils::units::format_size_aligned(replaced_size)) + .c_str()); } + if (pkg.get_name() == replaced.get_name()) { - scols_cell_set_color(scols_line_get_cell(ln_replaced, COL_NAME), replaced_color); + auto cl_evr = scols_line_get_cell(ln, COL_EVR); + scols_cell_set_data(cl_evr, fmt::format("{:20s} <- {}", pkg.get_evr(), replaced.get_evr()).c_str()); } else { - scols_cell_set_color(scols_line_get_cell(ln_replaced, COL_NAME), obsoleted_color); + struct libscols_line * ln_replaced = scols_table_new_line(tb, ln); + // TODO(jmracek) Translate it + std::string name("replacing "); + name.append(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()); + scols_line_set_data(ln_replaced, COL_REPO, replaced.get_from_repo_id().c_str()); + + auto replaced_size = static_cast(replaced.get_install_size()); + scols_line_set_data( + ln_replaced, COL_SIZE, libdnf5::cli::utils::units::format_size_aligned(replaced_size).c_str()); + auto replaced_color = action_color(libdnf5::transaction::TransactionItemAction::REPLACED); + auto obsoleted_color = "brown"; + + scols_cell_set_color(scols_line_get_cell(ln_replaced, COL_EVR), replaced_color); + if (pkg.get_arch() == replaced.get_arch()) { + scols_cell_set_color(scols_line_get_cell(ln_replaced, COL_ARCH), replaced_color); + } else { + scols_cell_set_color(scols_line_get_cell(ln_replaced, COL_ARCH), obsoleted_color); + } + if (pkg.get_name() == replaced.get_name()) { + scols_cell_set_color(scols_line_get_cell(ln_replaced, COL_NAME), replaced_color); + } else { + scols_cell_set_color(scols_line_get_cell(ln_replaced, COL_NAME), obsoleted_color); + } + scols_cell_set_color(scols_line_get_cell(ln_replaced, COL_REPO), replaced_color); + scols_cell_set_color(scols_line_get_cell(ln_replaced, COL_SIZE), replaced_color); } - scols_cell_set_color(scols_line_get_cell(ln_replaced, COL_REPO), replaced_color); - scols_cell_set_color(scols_line_get_cell(ln_replaced, COL_SIZE), replaced_color); } } From 03eddfd1445c5e810be96559ee05f6592389de02 Mon Sep 17 00:00:00 2001 From: long-walk Date: Mon, 22 Jan 2024 18:05:28 +0100 Subject: [PATCH 02/10] remove unused if --- include/libdnf5-cli/output/transaction_table.hpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/include/libdnf5-cli/output/transaction_table.hpp b/include/libdnf5-cli/output/transaction_table.hpp index 282219dfa..941adc988 100644 --- a/include/libdnf5-cli/output/transaction_table.hpp +++ b/include/libdnf5-cli/output/transaction_table.hpp @@ -567,11 +567,7 @@ bool print_transaction_table(Transaction & transaction) { } else { scols_cell_set_color(scols_line_get_cell(ln_replaced, COL_ARCH), obsoleted_color); } - if (pkg.get_name() == replaced.get_name()) { - scols_cell_set_color(scols_line_get_cell(ln_replaced, COL_NAME), replaced_color); - } else { - scols_cell_set_color(scols_line_get_cell(ln_replaced, COL_NAME), obsoleted_color); - } + scols_cell_set_color(scols_line_get_cell(ln_replaced, COL_NAME), obsoleted_color); scols_cell_set_color(scols_line_get_cell(ln_replaced, COL_REPO), replaced_color); scols_cell_set_color(scols_line_get_cell(ln_replaced, COL_SIZE), replaced_color); } From 9025a648136abbf4e328bb48bc71dbcce59d96e6 Mon Sep 17 00:00:00 2001 From: long-walk Date: Sun, 4 Feb 2024 02:39:42 +0100 Subject: [PATCH 03/10] Version highlight only for major/minor version --- .../libdnf5-cli/output/transaction_table.hpp | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/include/libdnf5-cli/output/transaction_table.hpp b/include/libdnf5-cli/output/transaction_table.hpp index 02bd9d1b5..8d5af7496 100644 --- a/include/libdnf5-cli/output/transaction_table.hpp +++ b/include/libdnf5-cli/output/transaction_table.hpp @@ -548,15 +548,6 @@ bool print_transaction_table(Transaction & transaction) { } } - // highlight incoming packages with epoch/version change - if (tspkg.get_package().get_epoch() != replaced.get_epoch() || - tspkg.get_package().get_version() != replaced.get_version()) { - scols_cell_set_color(scols_line_get_cell(ln, COL_EVR), "lightblue"); - if (termwidth < single_line_min) { - scols_cell_set_color(scols_line_get_cell(ln_pre, COL_EVR), "lightblue"); - } - } - // print SIZE, filter changes on small package, bigger pakages need 10% of size change double long difference = abs((double long)100 - ((double long)100 / (double long)pkg.get_install_size() * @@ -587,6 +578,18 @@ bool print_transaction_table(Transaction & transaction) { } } + // highlight incoming packages with epoch, major/minor version change + std::string tmpver = tspkg.get_package().get_version(); + std::string tmprepver = replaced.get_version(); + std::string version = tmpver.substr(0, tmpver.find_first_of(".-", tmpver.find('.') + 1)); + std::string rep_version = tmprepver.substr(0, tmprepver.find_first_of(".-", tmprepver.find('.') + 1)); + if (tspkg.get_package().get_epoch() != replaced.get_epoch() || version != rep_version) { + scols_cell_set_color(scols_line_get_cell(ln, COL_EVR), "lightblue"); + if (termwidth < single_line_min) { + scols_cell_set_color(scols_line_get_cell(ln_pre, COL_EVR), "lightblue"); + } + } + // print Version if (pkg.get_name() == replaced.get_name()) { if (termwidth < single_line_min) { From e5e66283ed6dd356020099b67f629f3e68b1b8e6 Mon Sep 17 00:00:00 2001 From: long-walk <56696022+long-walk@users.noreply.github.com> Date: Sun, 11 Feb 2024 03:03:21 +0100 Subject: [PATCH 04/10] fix var inizialization --- include/libdnf5-cli/output/transaction_table.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/libdnf5-cli/output/transaction_table.hpp b/include/libdnf5-cli/output/transaction_table.hpp index 8d5af7496..679ec3195 100644 --- a/include/libdnf5-cli/output/transaction_table.hpp +++ b/include/libdnf5-cli/output/transaction_table.hpp @@ -513,7 +513,7 @@ bool print_transaction_table(Transaction & transaction) { scols_cell_set_color(scols_line_get_cell(ln_reason, COL_NAME), replaced_color); } - struct libscols_line * ln_pre; + struct libscols_line * ln_pre = nullptr; for (auto & replaced : tspkg.get_replaces()) { if (pkg.get_name() == replaced.get_name() && termwidth < single_line_min) { ln_pre = scols_table_new_line(tb, ln); From 246b0a67de339d8a528d76d9db821bfc49d858e1 Mon Sep 17 00:00:00 2001 From: long-walk Date: Sun, 11 Feb 2024 18:03:26 +0100 Subject: [PATCH 05/10] fix reinstall show the same version twice --- include/libdnf5-cli/output/transaction_table.hpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/include/libdnf5-cli/output/transaction_table.hpp b/include/libdnf5-cli/output/transaction_table.hpp index 679ec3195..2041a4ba7 100644 --- a/include/libdnf5-cli/output/transaction_table.hpp +++ b/include/libdnf5-cli/output/transaction_table.hpp @@ -592,13 +592,15 @@ bool print_transaction_table(Transaction & transaction) { // print Version if (pkg.get_name() == replaced.get_name()) { - if (termwidth < single_line_min) { - scols_line_set_data(ln, COL_EVR, pkg.get_evr().c_str()); - scols_line_set_data(ln_pre, COL_EVR, replaced.get_evr().c_str()); - } else { - auto cl_evr = scols_line_get_cell(ln, COL_EVR); - scols_cell_set_data( - cl_evr, fmt::format("{:20s}{}{}", pkg.get_evr(), arrow, replaced.get_evr()).c_str()); + if (pkg.get_evr() != replaced.get_evr()) { + if (termwidth < single_line_min) { + scols_line_set_data(ln, COL_EVR, pkg.get_evr().c_str()); + scols_line_set_data(ln_pre, COL_EVR, replaced.get_evr().c_str()); + } else { + auto cl_evr = scols_line_get_cell(ln, COL_EVR); + scols_cell_set_data( + cl_evr, fmt::format("{:20s}{}{}", pkg.get_evr(), arrow, replaced.get_evr()).c_str()); + } } } else { // print replacing versions struct libscols_line * ln_replaced = scols_table_new_line(tb, ln); From 4075c6760e2b5f41ad6f4cd2bc6d751f6d134e74 Mon Sep 17 00:00:00 2001 From: Thomas Date: Wed, 21 Feb 2024 20:40:09 +0100 Subject: [PATCH 06/10] optimize size calculation --- include/libdnf5-cli/output/transaction_table.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/libdnf5-cli/output/transaction_table.hpp b/include/libdnf5-cli/output/transaction_table.hpp index 2041a4ba7..d7edd4b93 100644 --- a/include/libdnf5-cli/output/transaction_table.hpp +++ b/include/libdnf5-cli/output/transaction_table.hpp @@ -554,10 +554,10 @@ bool print_transaction_table(Transaction & transaction) { (double long)replaced.get_install_size())); unsigned long small = (pkg.get_install_size() < replaced.get_install_size()) ? pkg.get_install_size() : replaced.get_install_size(); - unsigned long test = (unsigned long)pow((double)small / 5000, 2); + unsigned long test = 1000 - (small / 200); unsigned long index = 10; - if (test < 990) { - index = 1000 - test; + if (test > 10) { + index = test; } if (difference > index) { scols_cell_set_color(scols_line_get_cell(ln, COL_SIZE), "red"); From 3e336a02592189d6e560dc72c49601db950600b1 Mon Sep 17 00:00:00 2001 From: Thomas Date: Sun, 25 Feb 2024 01:33:23 +0100 Subject: [PATCH 07/10] fix crash --- include/libdnf5-cli/output/transaction_table.hpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/include/libdnf5-cli/output/transaction_table.hpp b/include/libdnf5-cli/output/transaction_table.hpp index 622ac4e5a..37c833a0e 100644 --- a/include/libdnf5-cli/output/transaction_table.hpp +++ b/include/libdnf5-cli/output/transaction_table.hpp @@ -512,7 +512,7 @@ SmartcolsTableWrapper create_transaction_table(Transaction & transaction, Transa } // print ARCH if (tspkg.get_package().get_arch() != replaced.get_arch()) { - if (termwidth < single_line_min) { + if (ln_pre != nullptr) { auto cl_arch = scols_line_get_cell(ln, COL_ARCH); scols_cell_set_color(cl_arch, "brown"); scols_cell_set_data(cl_arch, pkg.get_arch().c_str()); @@ -528,7 +528,7 @@ SmartcolsTableWrapper create_transaction_table(Transaction & transaction, Transa // print REPO if (pkg.get_repo_id() != replaced.get_from_repo_id()) { - if (termwidth < single_line_min) { + if (ln_pre != nullptr) { scols_cell_set_color(scols_line_get_cell(ln, COL_REPO), "magenta"); scols_line_set_data(ln, COL_REPO, pkg.get_repo_id().c_str()); scols_cell_set_color(scols_line_get_cell(ln_pre, COL_REPO), "magenta"); @@ -554,7 +554,7 @@ SmartcolsTableWrapper create_transaction_table(Transaction & transaction, Transa if (difference > index) { scols_cell_set_color(scols_line_get_cell(ln, COL_SIZE), "red"); auto replaced_size = static_cast(replaced.get_install_size()); - if (termwidth < single_line_min) { + if (ln_pre != nullptr) { scols_cell_set_color(scols_line_get_cell(ln_pre, COL_SIZE), "red"); scols_line_set_data( ln, COL_SIZE, libdnf5::cli::utils::units::format_size_aligned(tspkg_size).c_str()); @@ -577,7 +577,7 @@ SmartcolsTableWrapper create_transaction_table(Transaction & transaction, Transa std::string rep_version = tmprepver.substr(0, tmprepver.find_first_of(".-", tmprepver.find('.') + 1)); if (tspkg.get_package().get_epoch() != replaced.get_epoch() || version != rep_version) { scols_cell_set_color(scols_line_get_cell(ln, COL_EVR), "lightblue"); - if (termwidth < single_line_min) { + if (ln_pre != nullptr) { scols_cell_set_color(scols_line_get_cell(ln_pre, COL_EVR), "lightblue"); } } @@ -585,7 +585,7 @@ SmartcolsTableWrapper create_transaction_table(Transaction & transaction, Transa // print Version if (pkg.get_name() == replaced.get_name()) { if (pkg.get_evr() != replaced.get_evr()) { - if (termwidth < single_line_min) { + if (ln_pre != nullptr) { scols_line_set_data(ln, COL_EVR, pkg.get_evr().c_str()); scols_line_set_data(ln_pre, COL_EVR, replaced.get_evr().c_str()); } else { From 07c0960390f4d2af92f9255ef7a0c77f973b601b Mon Sep 17 00:00:00 2001 From: Thomas Date: Mon, 22 Apr 2024 19:29:04 +0200 Subject: [PATCH 08/10] adjust for .cpp changes --- libdnf5-cli/output/transaction_table.cpp | 734 +++++++++++++++++++++++ 1 file changed, 734 insertions(+) create mode 100644 libdnf5-cli/output/transaction_table.cpp diff --git a/libdnf5-cli/output/transaction_table.cpp b/libdnf5-cli/output/transaction_table.cpp new file mode 100644 index 000000000..30b57397e --- /dev/null +++ b/libdnf5-cli/output/transaction_table.cpp @@ -0,0 +1,734 @@ +/* +Copyright Contributors to the libdnf project. + +This file is part of libdnf: https://github.com/rpm-software-management/libdnf/ + +Libdnf is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 2.1 of the License, or +(at your option) any later version. + +Libdnf is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with libdnf. If not, see . +*/ + +#include "libdnf5-cli/output/transaction_table.hpp" + +#include "smartcols_table_wrapper.hpp" + +#include "libdnf5-cli/output/interfaces/comps.hpp" +#include "libdnf5-cli/output/interfaces/package.hpp" +#include "libdnf5-cli/tty.hpp" +#include "libdnf5-cli/utils/units.hpp" + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace libdnf5::cli::output { + +namespace { + +enum { COL_NAME, COL_ARCH, COL_EVR, COL_REPO, COL_SIZE }; + +const char * action_color(libdnf5::transaction::TransactionItemAction action) { + switch (action) { + case libdnf5::transaction::TransactionItemAction::INSTALL: + case libdnf5::transaction::TransactionItemAction::UPGRADE: + case libdnf5::transaction::TransactionItemAction::REINSTALL: + case libdnf5::transaction::TransactionItemAction::REASON_CHANGE: + case libdnf5::transaction::TransactionItemAction::ENABLE: + case libdnf5::transaction::TransactionItemAction::SWITCH: + return "green"; + case libdnf5::transaction::TransactionItemAction::DOWNGRADE: + case libdnf5::transaction::TransactionItemAction::RESET: + return "magenta"; + case libdnf5::transaction::TransactionItemAction::REMOVE: + case libdnf5::transaction::TransactionItemAction::DISABLE: + return "red"; + case libdnf5::transaction::TransactionItemAction::REPLACED: + return "halfbright"; + } + + libdnf_throw_assertion("Unexpected action in print_transaction_table: {}", libdnf5::utils::to_underlying(action)); +} + + +class ActionHeaderPrinter { +public: + ActionHeaderPrinter(SmartcolsTableWrapper & table) : table(table) {} + + struct libscols_line * print(const ITransactionPackage & tspkg) { + if (!current_action || *current_action != tspkg.get_action() || + ((*current_action == libdnf5::transaction::TransactionItemAction::INSTALL || + *current_action == libdnf5::transaction::TransactionItemAction::REMOVE) && + *current_reason != tspkg.get_reason())) { + auto reason = tspkg.get_reason(); + auto action = tspkg.get_action(); + current_header_line = scols_table_new_line(*table, NULL); + std::string text; + + switch (action) { + case libdnf5::transaction::TransactionItemAction::INSTALL: + text = "Installing"; + if (reason == libdnf5::transaction::TransactionItemReason::DEPENDENCY) { + text += " dependencies"; + } else if (reason == libdnf5::transaction::TransactionItemReason::WEAK_DEPENDENCY) { + text += " weak dependencies"; + } else if (reason == libdnf5::transaction::TransactionItemReason::GROUP) { + text += " group/module packages"; + } + break; + case libdnf5::transaction::TransactionItemAction::UPGRADE: + text = "Upgrading"; + break; + case libdnf5::transaction::TransactionItemAction::DOWNGRADE: + text = "Downgrading"; + break; + case libdnf5::transaction::TransactionItemAction::REINSTALL: + text = "Reinstalling"; + break; + case libdnf5::transaction::TransactionItemAction::REMOVE: + text = "Removing"; + if (reason == libdnf5::transaction::TransactionItemReason::DEPENDENCY) { + text += " dependent packages"; + } else if (reason == libdnf5::transaction::TransactionItemReason::CLEAN) { + text += " unused dependencies"; + } + break; + case libdnf5::transaction::TransactionItemAction::REASON_CHANGE: + text = "Changing reason"; + break; + case libdnf5::transaction::TransactionItemAction::REPLACED: + case libdnf5::transaction::TransactionItemAction::ENABLE: + case libdnf5::transaction::TransactionItemAction::DISABLE: + case libdnf5::transaction::TransactionItemAction::RESET: + case libdnf5::transaction::TransactionItemAction::SWITCH: + libdnf_throw_assertion( + "Unexpected action in print_transaction_table: {}", libdnf5::utils::to_underlying(action)); + } + + text += ":"; + + scols_line_set_data(current_header_line, COL_NAME, text.c_str()); + + current_action = action; + current_reason = reason; + } + + return current_header_line; + } + +private: + SmartcolsTableWrapper & table; + struct libscols_line * current_header_line = nullptr; + std::optional current_action; + std::optional current_reason; +}; + + +class ActionHeaderPrinterEnvironment { +public: + ActionHeaderPrinterEnvironment(SmartcolsTableWrapper & table) : table(table) {} + + struct libscols_line * print(const ITransactionEnvironment & tsgrp) { + if (!current_action || *current_action != tsgrp.get_action() || !current_reason || + *current_reason != tsgrp.get_reason()) { + auto reason = tsgrp.get_reason(); + auto action = tsgrp.get_action(); + current_header_line = scols_table_new_line(*table, NULL); + std::string text; + + switch (action) { + case libdnf5::transaction::TransactionItemAction::INSTALL: + text = "Installing environmental groups"; + break; + case libdnf5::transaction::TransactionItemAction::REMOVE: + text = "Removing environmental groups"; + break; + case libdnf5::transaction::TransactionItemAction::UPGRADE: + text = "Upgrading environmental groups"; + break; + default: + libdnf_throw_assertion( + "Unexpected action in print_transaction_table: {}", libdnf5::utils::to_underlying(action)); + } + + text += ":"; + + scols_line_set_data(current_header_line, COL_NAME, text.c_str()); + + current_action = action; + current_reason = reason; + } + + return current_header_line; + } + +private: + SmartcolsTableWrapper & table; + struct libscols_line * current_header_line = nullptr; + std::optional current_action; + std::optional current_reason; +}; + + +class ActionHeaderPrinterGroup { +public: + ActionHeaderPrinterGroup(SmartcolsTableWrapper & table) : table(table) {} + + struct libscols_line * print(const ITransactionGroup & tsgrp) { + if (!current_action || *current_action != tsgrp.get_action() || !current_reason || + *current_reason != tsgrp.get_reason()) { + auto reason = tsgrp.get_reason(); + auto action = tsgrp.get_action(); + current_header_line = scols_table_new_line(*table, NULL); + std::string text; + + switch (action) { + case libdnf5::transaction::TransactionItemAction::INSTALL: + text = "Installing groups"; + if (reason == libdnf5::transaction::TransactionItemReason::DEPENDENCY) { + text += " dependencies"; + } + break; + case libdnf5::transaction::TransactionItemAction::REMOVE: + text = "Removing groups"; + break; + case libdnf5::transaction::TransactionItemAction::UPGRADE: + text = "Upgrading groups"; + break; + default: + libdnf_throw_assertion( + "Unexpected action in print_transaction_table: {}", libdnf5::utils::to_underlying(action)); + } + + text += ":"; + + scols_line_set_data(current_header_line, COL_NAME, text.c_str()); + + current_action = action; + current_reason = reason; + } + + return current_header_line; + } + +private: + SmartcolsTableWrapper & table; + struct libscols_line * current_header_line = nullptr; + std::optional current_action; + std::optional current_reason; +}; + + +class ActionHeaderPrinterModule { +public: + ActionHeaderPrinterModule(SmartcolsTableWrapper & table) : table(table) {} + + struct libscols_line * print(const ITransactionModule & tsmodule) { + if (!current_action || *current_action != tsmodule.get_action() || !current_reason || + *current_reason != tsmodule.get_reason()) { + auto reason = tsmodule.get_reason(); + auto action = tsmodule.get_action(); + current_header_line = scols_table_new_line(*table, NULL); + std::string text; + + switch (action) { + case libdnf5::transaction::TransactionItemAction::ENABLE: + text = "Enabling module streams"; + break; + case libdnf5::transaction::TransactionItemAction::DISABLE: + text = "Disabling modules"; + break; + case libdnf5::transaction::TransactionItemAction::RESET: + text = "Resetting modules"; + break; + case libdnf5::transaction::TransactionItemAction::SWITCH: + text = "Switching module streams"; + break; + default: + libdnf_throw_assertion( + "Unexpected action in print_transaction_table: {}", libdnf5::utils::to_underlying(action)); + } + + text += ":"; + + scols_line_set_data(current_header_line, COL_NAME, text.c_str()); + + current_action = action; + current_reason = reason; + } + + return current_header_line; + } + +private: + SmartcolsTableWrapper & table; + struct libscols_line * current_header_line = nullptr; + std::optional current_action; + std::optional current_reason; +}; + + +class TransactionSummary { +public: + void add(const libdnf5::transaction::TransactionItemAction & action) { + switch (action) { + case libdnf5::transaction::TransactionItemAction::INSTALL: + installs++; + break; + case libdnf5::transaction::TransactionItemAction::UPGRADE: + upgrades++; + break; + case libdnf5::transaction::TransactionItemAction::DOWNGRADE: + downgrades++; + break; + case libdnf5::transaction::TransactionItemAction::REINSTALL: + reinstalls++; + break; + case libdnf5::transaction::TransactionItemAction::REMOVE: + removes++; + break; + case libdnf5::transaction::TransactionItemAction::REPLACED: + replaced++; + break; + case libdnf5::transaction::TransactionItemAction::REASON_CHANGE: + reason_changes++; + break; + case libdnf5::transaction::TransactionItemAction::ENABLE: + case libdnf5::transaction::TransactionItemAction::DISABLE: + case libdnf5::transaction::TransactionItemAction::RESET: + case libdnf5::transaction::TransactionItemAction::SWITCH: + // Only package change counts are reported. + break; + } + } + + void print(std::FILE * fd = stdout) const { + std::fputs("\nTransaction Summary:\n", fd); + if (installs != 0) { + std::fputs(fmt::format(" {:15} {:4} packages\n", "Installing:", installs).c_str(), fd); + } + if (reinstalls != 0) { + std::fputs(fmt::format(" {:15} {:4} packages\n", "Reinstalling:", reinstalls).c_str(), fd); + } + if (upgrades != 0) { + std::fputs(fmt::format(" {:15} {:4} packages\n", "Upgrading:", upgrades).c_str(), fd); + } + if (replaced != 0) { + std::fputs(fmt::format(" {:15} {:4} packages\n", "Replacing:", replaced).c_str(), fd); + } + if (removes != 0) { + std::fputs(fmt::format(" {:15} {:4} packages\n", "Removing:", removes).c_str(), fd); + } + if (downgrades != 0) { + std::fputs(fmt::format(" {:15} {:4} packages\n", "Downgrading:", downgrades).c_str(), fd); + } + if (reason_changes != 0) { + std::fputs(fmt::format(" {:15} {:4} packages\n", "Changing reason:", reason_changes).c_str(), fd); + } + std::fputc('\n', fd); + } + +private: + int installs = 0; + int reinstalls = 0; + int upgrades = 0; + int downgrades = 0; + int removes = 0; + int replaced = 0; + int reason_changes = 0; +}; + + +bool transaction_package_cmp( + const std::unique_ptr & tspkg1, const std::unique_ptr & tspkg2) { + if (tspkg1->get_action() != tspkg2->get_action()) { + return tspkg1->get_action() > tspkg2->get_action(); + } + + // INSTALL and REMOVE actions are divided (printed) into groups according to the reason. + auto current_action = tspkg1->get_action(); + if ((current_action == libdnf5::transaction::TransactionItemAction::INSTALL || + current_action == libdnf5::transaction::TransactionItemAction::REMOVE) && + tspkg1->get_reason() != tspkg2->get_reason()) { + return tspkg1->get_reason() > tspkg2->get_reason(); + } + + return libdnf5::rpm::cmp_naevr(*tspkg1->get_package(), *tspkg2->get_package()); +} + + +bool transaction_group_cmp( + const std::unique_ptr & tsgrp1, const std::unique_ptr & tsgrp2) { + if (tsgrp1->get_action() != tsgrp2->get_action()) { + return tsgrp1->get_action() > tsgrp2->get_action(); + } + + if (tsgrp1->get_reason() != tsgrp2->get_reason()) { + return tsgrp1->get_reason() > tsgrp2->get_reason(); + } + + return tsgrp1->get_group()->get_groupid() > tsgrp2->get_group()->get_groupid(); +} + +} // namespace + + +class TransactionTable::Impl { +public: + Impl(ITransaction & transaction); + +private: + friend class TransactionTable; + TransactionSummary ts_summary; + SmartcolsTableWrapper tb; +}; + + +TransactionTable::Impl::Impl(ITransaction & transaction) { + //SmartcolsTableWrapper create_transaction_table(ITransaction & transaction, TransactionSummary & ts_summary) { + // SmartcolsTableWrapper tb; + + auto termwidth = (int)scols_table_get_termwidth(*tb); + + auto column = scols_table_new_column(*tb, "Package", 0.2, SCOLS_FL_TREE); + auto header = scols_column_get_header(column); + scols_cell_set_color(header, "lightblue"); + + column = scols_table_new_column(*tb, "Arch", 6, 0); + header = scols_column_get_header(column); + scols_cell_set_color(header, "lightblue"); + + column = scols_table_new_column(*tb, "Version", 0.2, SCOLS_FL_TRUNC); + header = scols_column_get_header(column); + scols_cell_set_color(header, "lightblue"); + + column = scols_table_new_column(*tb, "Repository", 0.1, SCOLS_FL_TRUNC); + header = scols_column_get_header(column); + scols_cell_set_color(header, "lightblue"); + + column = scols_table_new_column(*tb, "Size", 0.1, SCOLS_FL_RIGHT); + header = scols_column_get_header(column); + scols_cell_set_color(header, "lightblue"); + + scols_table_enable_maxout(*tb, 1); + scols_table_enable_colors(*tb, libdnf5::cli::tty::is_interactive()); + + // TODO(dmach): use colors from config + // TODO(dmach): highlight version changes (rebases) + // TODO(dmach): consider reordering so the major changes (installs, obsoletes, removals) are at the bottom next to the confirmation question + // TODO(jrohel): Print relations with obsoleted packages + + auto tspkgs = transaction.get_transaction_packages(); + std::sort(tspkgs.begin(), tspkgs.end(), transaction_package_cmp); + auto tsgrps = transaction.get_transaction_groups(); + std::sort(tsgrps.begin(), tsgrps.end(), transaction_group_cmp); + + struct libscols_line * header_ln = nullptr; + ActionHeaderPrinter action_header_printer(tb); + int single_line_min = 130; + std::string arrow = " <- "; + if (termwidth < single_line_min) { + scols_column_set_whint(scols_table_get_column(*tb, COL_NAME), 0.4); // priorizize pakage name over versions + } + for (auto & tspkg : tspkgs) { + // TODO(lukash) handle OBSOLETED correctly through the transaction table output + if (tspkg->get_action() == libdnf5::transaction::TransactionItemAction::REPLACED) { + ts_summary.add(tspkg->get_action()); + continue; + } + + auto pkg = tspkg->get_package(); + + header_ln = action_header_printer.print(*tspkg); + + struct libscols_line * ln = scols_table_new_line(*tb, header_ln); + scols_line_set_data(ln, COL_NAME, pkg->get_name().c_str()); + scols_line_set_data(ln, COL_ARCH, pkg->get_arch().c_str()); + scols_line_set_data(ln, COL_EVR, pkg->get_evr().c_str()); + if (tspkg->get_action() == libdnf5::transaction::TransactionItemAction::REMOVE) { + scols_line_set_data(ln, COL_REPO, pkg->get_from_repo_id().c_str()); + } else { + scols_line_set_data(ln, COL_REPO, pkg->get_repo_id().c_str()); + } + auto tspkg_size = static_cast(pkg->get_install_size()); + scols_line_set_data(ln, COL_SIZE, libdnf5::cli::utils::units::format_size_aligned(tspkg_size).c_str()); + auto ce = scols_line_get_cell(ln, COL_NAME); + scols_cell_set_color(ce, action_color(tspkg->get_action())); + + ts_summary.add(tspkg->get_action()); + 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( + "{} -> {}", + 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()); + scols_cell_set_color(scols_line_get_cell(ln_reason, COL_NAME), replaced_color); + } + + struct libscols_line * ln_pre = nullptr; + for (auto & replaced : tspkg->get_replaces()) { + if (pkg->get_name() == replaced->get_name() && termwidth < single_line_min) { + ln_pre = scols_table_new_line(*tb, ln); + } + // print ARCH + if (tspkg->get_package()->get_arch() != replaced->get_arch()) { + if (ln_pre != nullptr) { + auto cl_arch = scols_line_get_cell(ln, COL_ARCH); + scols_cell_set_color(cl_arch, "brown"); + scols_cell_set_data(cl_arch, pkg->get_arch().c_str()); + auto cl_prearch = scols_line_get_cell(ln_pre, COL_ARCH); + scols_cell_set_color(cl_prearch, "brown"); + scols_cell_set_data(cl_prearch, replaced->get_arch().c_str()); + } else { + auto cl_arch = scols_line_get_cell(ln, COL_ARCH); + scols_cell_set_color(cl_arch, "brown"); + scols_cell_set_data(cl_arch, (pkg->get_arch() + arrow + replaced->get_arch()).c_str()); + } + } + + // print REPO + if (pkg->get_repo_id() != replaced->get_from_repo_id()) { + if (ln_pre != nullptr) { + scols_cell_set_color(scols_line_get_cell(ln, COL_REPO), "magenta"); + scols_line_set_data(ln, COL_REPO, pkg->get_repo_id().c_str()); + scols_cell_set_color(scols_line_get_cell(ln_pre, COL_REPO), "magenta"); + scols_line_set_data(ln_pre, COL_REPO, replaced->get_from_repo_id().c_str()); + } else { + scols_cell_set_color(scols_line_get_cell(ln, COL_REPO), "magenta"); + scols_line_set_data( + ln, COL_REPO, (pkg->get_repo_id() + arrow + replaced->get_from_repo_id()).c_str()); + } + } + + // print SIZE, filter changes on small package, bigger pakages need 10% of size change + double long difference = + abs((double long)100 - ((double long)100 / (double long)pkg->get_install_size() * + (double long)replaced->get_install_size())); + unsigned long small = (pkg->get_install_size() < replaced->get_install_size()) + ? pkg->get_install_size() + : replaced->get_install_size(); + unsigned long test = 1000 - (small / 200); + unsigned long index = 10; + if (test > 10) { + index = test; + } + if (difference > index) { + scols_cell_set_color(scols_line_get_cell(ln, COL_SIZE), "red"); + auto replaced_size = static_cast(replaced->get_install_size()); + if (ln_pre != nullptr) { + scols_cell_set_color(scols_line_get_cell(ln_pre, COL_SIZE), "red"); + scols_line_set_data( + ln, COL_SIZE, libdnf5::cli::utils::units::format_size_aligned(tspkg_size).c_str()); + scols_line_set_data( + ln_pre, COL_SIZE, libdnf5::cli::utils::units::format_size_aligned(replaced_size).c_str()); + } else { + scols_line_set_data( + ln, + COL_SIZE, + (libdnf5::cli::utils::units::format_size_aligned(tspkg_size) + arrow + + libdnf5::cli::utils::units::format_size_aligned(replaced_size)) + .c_str()); + } + } + + // highlight incoming packages with epoch, major/minor version change + std::string tmpver = tspkg->get_package()->get_version(); + std::string tmprepver = replaced->get_version(); + std::string version = tmpver.substr(0, tmpver.find_first_of(".-", tmpver.find('.') + 1)); + std::string rep_version = tmprepver.substr(0, tmprepver.find_first_of(".-", tmprepver.find('.') + 1)); + if (tspkg->get_package()->get_epoch() != replaced->get_epoch() || version != rep_version) { + scols_cell_set_color(scols_line_get_cell(ln, COL_EVR), "lightblue"); + if (ln_pre != nullptr) { + scols_cell_set_color(scols_line_get_cell(ln_pre, COL_EVR), "lightblue"); + } + } + + // print Version + if (pkg->get_name() == replaced->get_name()) { + if (pkg->get_evr() != replaced->get_evr()) { + if (ln_pre != nullptr) { + scols_line_set_data(ln, COL_EVR, pkg->get_evr().c_str()); + scols_line_set_data(ln_pre, COL_EVR, replaced->get_evr().c_str()); + } else { + auto cl_evr = scols_line_get_cell(ln, COL_EVR); + scols_cell_set_data( + cl_evr, fmt::format("{:20s}{}{}", pkg->get_evr(), arrow, replaced->get_evr()).c_str()); + } + } + } else { // print replacing versions + struct libscols_line * ln_replaced = scols_table_new_line(*tb, ln); + // TODO(jmracek) Translate it + std::string name(" replacing "); + name.append(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()); + scols_line_set_data(ln_replaced, COL_REPO, replaced->get_from_repo_id().c_str()); + + auto replaced_size = static_cast(replaced->get_install_size()); + scols_line_set_data( + ln_replaced, COL_SIZE, libdnf5::cli::utils::units::format_size_aligned(replaced_size).c_str()); + auto replaced_color = action_color(libdnf5::transaction::TransactionItemAction::REPLACED); + auto obsoleted_color = "brown"; + + scols_cell_set_color(scols_line_get_cell(ln_replaced, COL_EVR), replaced_color); + if (pkg->get_arch() == replaced->get_arch()) { + scols_cell_set_color(scols_line_get_cell(ln_replaced, COL_ARCH), replaced_color); + } else { + scols_cell_set_color(scols_line_get_cell(ln_replaced, COL_ARCH), obsoleted_color); + } + scols_cell_set_color(scols_line_get_cell(ln_replaced, COL_NAME), obsoleted_color); + scols_cell_set_color(scols_line_get_cell(ln_replaced, COL_REPO), replaced_color); + scols_cell_set_color(scols_line_get_cell(ln_replaced, COL_SIZE), replaced_color); + } + } + } + + ActionHeaderPrinterGroup action_header_printer_group(tb); + for (auto & tsgrp : tsgrps) { + auto grp = tsgrp->get_group(); + + header_ln = action_header_printer_group.print(*tsgrp); + + 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, ""); + } else { + scols_line_set_data(ln, COL_NAME, grp_name.c_str()); + } + auto ce = scols_line_get_cell(ln, COL_NAME); + scols_cell_set_color(ce, action_color(tsgrp->get_action())); + } + + ActionHeaderPrinterEnvironment action_header_printer_environment(tb); + for (auto & tsenv : transaction.get_transaction_environments()) { + auto env = tsenv->get_environment(); + + header_ln = action_header_printer_environment.print(*tsenv); + + 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, ""); + } else { + scols_line_set_data(ln, COL_NAME, env_name.c_str()); + } + auto ce = scols_line_get_cell(ln, COL_NAME); + scols_cell_set_color(ce, action_color(tsenv->get_action())); + } + + ActionHeaderPrinterModule action_header_printer_module(tb); + for (auto & tsmodule : transaction.get_transaction_modules()) { + header_ln = action_header_printer_module.print(*tsmodule); + + struct libscols_line * ln = scols_table_new_line(*tb, header_ln); + scols_line_set_data(ln, COL_NAME, tsmodule->get_module_name().c_str()); + scols_cell_set_color(scols_line_get_cell(ln, COL_NAME), action_color(tsmodule->get_action())); + + const auto & replaces = tsmodule->get_replaces(); + // TODO(pkratoch): When implementing module obsoletes, it might be necessary to change the condition to report obsoletes differently + 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()); + } 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); + 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); + scols_cell_set_color(scols_line_get_cell(ln_replaced, COL_NAME), replaced_color); + scols_cell_set_color(scols_line_get_cell(ln_replaced, COL_EVR), replaced_color); + } + } + } +} + + +TransactionTable::TransactionTable(ITransaction & transaction) : p_impl(new Impl(transaction)) {} + +TransactionTable::~TransactionTable() = default; + +TransactionTable::TransactionTable(TransactionTable && src) = default; + +TransactionTable & TransactionTable::operator=(TransactionTable && src) = default; + + +void TransactionTable::print_table() { + scols_print_table(*p_impl->tb); +} + + +void TransactionTable::print_summary() const { + p_impl->ts_summary.print(scols_table_get_stream(*p_impl->tb)); +} + + +void TransactionTable::set_colors_enabled(bool enable) { + scols_table_enable_colors(*p_impl->tb, enable); +} + + +void TransactionTable::set_term_width(std::size_t width) { + scols_table_set_termwidth(*p_impl->tb, width); +} + + +void TransactionTable::set_output_stream(FILE * fd) { + scols_table_set_stream(*p_impl->tb, fd); +} + + +/// Prints all transaction problems +void print_resolve_logs(const ITransaction & transaction, std::ostream & stream) { + const std::vector logs = transaction.get_resolve_logs_as_strings(); + for (const auto & log : logs) { + stream << log << std::endl; + } + if (logs.size() > 0) { + stream << std::endl; + } +} + + +bool print_transaction_table(ITransaction & transaction) { + // even correctly resolved transaction can contain some warnings / hints / infos + // in resolve logs (e.g. the package user wanted to install is already installed). + // Present them to the user. + print_resolve_logs(transaction); + + if (transaction.empty()) { + std::cout << "Nothing to do." << std::endl; + return false; + } + + TransactionTable table(transaction); + table.print_table(); + table.print_summary(); + + return true; +} + +} // namespace libdnf5::cli::output From 3623b15c7ad2940af2124025a4601565252053f4 Mon Sep 17 00:00:00 2001 From: Thomas Date: Thu, 16 May 2024 17:54:50 +0200 Subject: [PATCH 09/10] fix non-intended replacing line --- libdnf5-cli/output/transaction_table.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libdnf5-cli/output/transaction_table.cpp b/libdnf5-cli/output/transaction_table.cpp index b0df0a5b8..88a40a855 100644 --- a/libdnf5-cli/output/transaction_table.cpp +++ b/libdnf5-cli/output/transaction_table.cpp @@ -415,7 +415,7 @@ TransactionTable::Impl::Impl(ITransaction & transaction) { } else { // print replacing versions struct libscols_line * ln_replaced = scols_table_new_line(*tb, ln); // TODO(jmracek) Translate it - std::string name(" replacing "); + std::string name(" replacing "); name.append(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()); From 144a9671196050251b18baf82557100326618928 Mon Sep 17 00:00:00 2001 From: Thomas Date: Fri, 17 May 2024 20:34:53 +0200 Subject: [PATCH 10/10] improvment output --- libdnf5-cli/output/transaction_table.cpp | 25 ++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/libdnf5-cli/output/transaction_table.cpp b/libdnf5-cli/output/transaction_table.cpp index 88a40a855..502c90b1f 100644 --- a/libdnf5-cli/output/transaction_table.cpp +++ b/libdnf5-cli/output/transaction_table.cpp @@ -227,7 +227,12 @@ TransactionTable::Impl::Impl(ITransaction & transaction) { scols_table_enable_noheadings(*tb, 1); struct libscols_line * header_ln = scols_table_new_line(*tb, NULL); + int single_line_min = 130; auto termwidth = (int)scols_table_get_termwidth(*tb); + int scols_fl = SCOLS_FL_WRAP; + if (termwidth < single_line_min) { + scols_fl = SCOLS_FL_TRUNC; + } auto column = scols_table_new_column(*tb, "Package", 0.2, 0); auto header = scols_column_get_header(column); @@ -241,13 +246,13 @@ TransactionTable::Impl::Impl(ITransaction & transaction) { scols_cell_set_data(cell, scols_cell_get_data(header)); scols_cell_set_color(cell, PKG_HIGHLIGHT_COLOR); - column = scols_table_new_column(*tb, "Version", 0.1, SCOLS_FL_TRUNC); + column = scols_table_new_column(*tb, "Version", 0.1, scols_fl); 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, PKG_HIGHLIGHT_COLOR); - column = scols_table_new_column(*tb, "Repository", 0.1, SCOLS_FL_TRUNC); + column = scols_table_new_column(*tb, "Repository", 0.1, scols_fl); 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)); @@ -275,10 +280,9 @@ TransactionTable::Impl::Impl(ITransaction & transaction) { auto tsgrps = transaction.get_transaction_groups(); std::sort(tsgrps.begin(), tsgrps.end(), transaction_group_cmp); - int single_line_min = 130; - std::string arrow = " <- "; + //std::string arrow = " <- "; if (termwidth < single_line_min) { - scols_column_set_whint(scols_table_get_column(*tb, COL_NAME), 0.4); // priorizize pakage name over versions + scols_column_set_whint(scols_table_get_column(*tb, COL_NAME), 0.35); // priorizize pakage name over versions } for (const auto & tspkg : tspkgs) { // TODO(lukash) handle OBSOLETED correctly through the transaction table output @@ -339,7 +343,7 @@ TransactionTable::Impl::Impl(ITransaction & transaction) { } else { auto cl_arch = scols_line_get_cell(ln, COL_ARCH); scols_cell_set_color(cl_arch, "brown"); - scols_cell_set_data(cl_arch, (pkg->get_arch() + arrow + replaced->get_arch()).c_str()); + scols_cell_set_data(cl_arch, (pkg->get_arch() + " (" + replaced->get_arch() + ")").c_str()); } } @@ -353,7 +357,7 @@ TransactionTable::Impl::Impl(ITransaction & transaction) { } else { scols_cell_set_color(scols_line_get_cell(ln, COL_REPO), "magenta"); scols_line_set_data( - ln, COL_REPO, (pkg->get_repo_id() + arrow + replaced->get_from_repo_id()).c_str()); + ln, COL_REPO, (pkg->get_repo_id() + " (" + replaced->get_from_repo_id() + ")").c_str()); } } @@ -382,8 +386,8 @@ TransactionTable::Impl::Impl(ITransaction & transaction) { scols_line_set_data( ln, COL_SIZE, - (libdnf5::cli::utils::units::format_size_aligned(tspkg_size) + arrow + - libdnf5::cli::utils::units::format_size_aligned(replaced_size)) + (libdnf5::cli::utils::units::format_size_aligned(tspkg_size) + " (" + + libdnf5::cli::utils::units::format_size_aligned(replaced_size) + ")") .c_str()); } } @@ -409,7 +413,8 @@ TransactionTable::Impl::Impl(ITransaction & transaction) { } else { auto cl_evr = scols_line_get_cell(ln, COL_EVR); scols_cell_set_data( - cl_evr, fmt::format("{:20s}{}{}", pkg->get_evr(), arrow, replaced->get_evr()).c_str()); + cl_evr, + fmt::format("{:20s}{}{}{}", pkg->get_evr(), " (", replaced->get_evr(), ")").c_str()); } } } else { // print replacing versions