Skip to content

Commit

Permalink
versionlock: Fix wildcards handling in add command
Browse files Browse the repository at this point in the history
There’s a bug in how the `dnf5 versionlock add <spec>` command handles
package specifications when the `spec` contains a wildcard and matches
multiple package names with the same version (EVR). In such cases, only
the first package is considered, while the rest are quietly skipped.
For example there are three packages matching 'aws-checksums*' pattern,
but only one is actually locked:

❯ dnf repoquery 'aws-checksums*'
Repositories loaded.
aws-checksums-0:0.2.2-1.fc40.i686
aws-checksums-0:0.2.2-1.fc40.x86_64
aws-checksums-devel-0:0.2.2-1.fc40.i686
aws-checksums-devel-0:0.2.2-1.fc40.x86_64
aws-checksums-libs-0:0.2.2-1.fc40.i686
aws-checksums-libs-0:0.2.2-1.fc40.x86_64

❯ dnf versionlock add 'aws-checksums*'
Repositories loaded.
Adding versionlock on "aws-checksums = 0.2.2-1.fc40".

With this patch, each group of packages with the same name is handled
separately, ensuring that all the packages are correctly locked:

❯ dnf5 versionlock add 'aws-checksums*'
Repositories loaded.
Adding versionlock on "aws-checksums = 0.2.2-1.fc40".
Adding versionlock on "aws-checksums-devel = 0.2.2-1.fc40".
Adding versionlock on "aws-checksums-libs = 0.2.2-1.fc40".

For: #1895
  • Loading branch information
m-blaha authored and kontura committed Jan 20, 2025
1 parent 8ede807 commit fe32348
Showing 1 changed file with 27 additions and 17 deletions.
44 changes: 27 additions & 17 deletions dnf5/commands/versionlock/versionlock_add.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,25 +106,35 @@ void VersionlockAddCommand::run() {
std::cerr << libdnf5::utils::sformat(_("No package found for \"{}\"."), spec) << std::endl;
continue;
}
libdnf5::rpm::PackageQuery installed_query(query);
installed_query.filter_installed();
if (!installed_query.empty()) {
// if spec is installed, add only installed version
query = installed_query;
}

std::unordered_set<std::string> versions{};
// The spec can resolve to multiple package names. Handle each name in
// the query separately.
std::set<std::string> package_names;
for (const auto & pkg : query) {
auto evr = pkg.get_evr();
if (versions.contains(evr)) {
continue;
package_names.emplace(pkg.get_name());
}
for (const auto & name : package_names) {
libdnf5::rpm::PackageQuery name_query(query);
name_query.filter_name(name);
libdnf5::rpm::PackageQuery installed_query(name_query);
installed_query.filter_installed();
if (!installed_query.empty()) {
// if spec is installed, add only installed version
name_query = installed_query;
}
versions.emplace(evr);
if (lock_version(vl_config, pkg, comment)) {
std::cout << libdnf5::utils::sformat(_("Adding versionlock on \"{0} = {1}\"."), pkg.get_name(), evr)
<< std::endl;
} else {
std::cerr << libdnf5::utils::sformat(_("Package \"{}\" is already locked."), spec) << std::endl;

std::unordered_set<std::string> versions{};
for (const auto & pkg : name_query) {
auto evr = pkg.get_evr();
if (versions.contains(evr)) {
continue;
}
versions.emplace(evr);
if (lock_version(vl_config, pkg, comment)) {
std::cout << libdnf5::utils::sformat(_("Adding versionlock on \"{0} = {1}\"."), pkg.get_name(), evr)
<< std::endl;
} else {
std::cerr << libdnf5::utils::sformat(_("Package \"{}\" is already locked."), spec) << std::endl;
}
}
}
}
Expand Down

0 comments on commit fe32348

Please sign in to comment.