diff --git a/dnf5/context.cpp b/dnf5/context.cpp index a7a6a4079..5df2fc510 100644 --- a/dnf5/context.cpp +++ b/dnf5/context.cpp @@ -1073,7 +1073,7 @@ std::vector match_specs( bool installed, bool available, bool paths, - bool nevra_for_same_name, + bool only_nevra_for_same_name, const char * file_name_regex) { auto & base = ctx.get_base(); @@ -1127,18 +1127,23 @@ std::vector match_specs( settings.set_with_binaries(false); matched_pkgs_query.resolve_pkg_spec(pattern + '*', settings, true); + std::set package_names; for (const auto & package : matched_pkgs_query) { - auto [it, inserted] = result_set.insert(package.get_name()); - - // Package name was already present - not inserted. There are multiple packages with the same name. - // If requested, removes the name and inserts a full nevra for these packages. - if (nevra_for_same_name && !inserted) { - result_set.erase(it); - libdnf5::rpm::PackageQuery name_query(matched_pkgs_query); - name_query.filter_name({package.get_name()}); - for (const auto & pkg : name_query) { - result_set.insert(pkg.get_full_nevra()); - matched_pkgs_query.remove(pkg); + auto [it, nevra_inserted] = result_set.insert(package.get_full_nevra()); + + // If it is not disabled and there are multiple packages with the same name but different nevras, + // add the name to result_set. + if (!only_nevra_for_same_name && nevra_inserted) { + auto name = package.get_name(); + if (name.length() < pattern.length()) { + // The output must not include a package name shorter than the length of the input patter + // (we don't want to shorten the user-specified input). + continue; + } + auto [it, name_inserted] = package_names.insert(name); + if (!name_inserted) { + // There are multiple packages with different nevra but this name. + result_set.insert(name); } } } diff --git a/dnf5/include/dnf5/context.hpp b/dnf5/include/dnf5/context.hpp index bfa3041e2..6e5237bc7 100644 --- a/dnf5/include/dnf5/context.hpp +++ b/dnf5/include/dnf5/context.hpp @@ -285,8 +285,10 @@ class DNF_API RpmTransCB : public libdnf5::rpm::TransactionCallbacks { DNF_API void run_transaction(libdnf5::rpm::Transaction & transaction); -/// Returns the names of matching packages and paths of matching package file names and directories. -/// If `nevra_for_same_name` is true, it returns a full nevra for packages with the same name. +/// Returns the nevras of matching packages and paths of matching package file names and directories. +/// If `only_nevra_for_same_name` is false, and there are multiple packages with the same name in the output list, +/// and the name is not shorter than the input pattern, the name is added to the output list for those packages +/// in addition to the nevras. /// Only files whose names match `file_name_regex` are returned. /// NOTE: This function is intended to be used only for autocompletion purposes as the argument parser's /// complete hook argument. It does the base setup and repos loading inside. @@ -296,7 +298,7 @@ DNF_API std::vector match_specs( bool installed, bool available, bool paths, - bool nevra_for_same_name, + bool only_nevra_for_same_name, const char * file_name_regex = ".*\\.rpm"); } // namespace dnf5