Skip to content

Commit

Permalink
For packages, always offer nevra in bash completion
Browse files Browse the repository at this point in the history
Originally, for packages, the name was offered in bash completion.
In the case of multiple packages with the same name, there was an option
to offer navra instead of a name for those packages.

Now, bash completion always offers nevra for packages. In the case
of multiple packages with different nevras but the same name, there is
an option to offer a name in addition to nevras for those packages.

For example, a user wants to install the package "xyz". The package
is available in multiple versions. Bash completion will offer
the nevras of all versions plus just the name. Usually the user
does not install a specific nevra, but the name and the solver selects
the version.
  • Loading branch information
jrohel committed Jan 3, 2025
1 parent 8751434 commit c1b1fae
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 15 deletions.
29 changes: 17 additions & 12 deletions dnf5/context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1073,7 +1073,7 @@ std::vector<std::string> 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();

Expand Down Expand Up @@ -1127,18 +1127,23 @@ std::vector<std::string> match_specs(
settings.set_with_binaries(false);
matched_pkgs_query.resolve_pkg_spec(pattern + '*', settings, true);

std::set<std::string> 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);
}
}
}
Expand Down
8 changes: 5 additions & 3 deletions dnf5/include/dnf5/context.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -296,7 +298,7 @@ DNF_API std::vector<std::string> 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
Expand Down

0 comments on commit c1b1fae

Please sign in to comment.