Skip to content

Commit

Permalink
Repoquery: Add --what* and --exactdeps options
Browse files Browse the repository at this point in the history
  • Loading branch information
kontura committed Nov 16, 2022
1 parent f94d86e commit fbf0ddd
Show file tree
Hide file tree
Showing 2 changed files with 224 additions and 0 deletions.
212 changes: 212 additions & 0 deletions dnf5/commands/repoquery/repoquery.cpp
Expand Up @@ -101,6 +101,84 @@ void RepoqueryCommand::set_argument_parser() {

info->add_conflict_argument(*nevra);

whatdepends = std::make_unique<libdnf::cli::session::StringListOption>(
*this,
"whatdepends",
'\0',
"Limit the resulting set only to packages that require, enhance, recommend, suggest or supplement any of "
"<capabilities>.",
"CAPABILITY,...",
",");
whatconflicts = std::make_unique<libdnf::cli::session::StringListOption>(
*this,
"whatconflicts",
'\0',
"Limit the resulting set only to packages that conflict with any of <capabilities>.",
"CAPABILITY,...",
",");
whatprovides = std::make_unique<libdnf::cli::session::StringListOption>(
*this,
"whatprovides",
'\0',
"Limit the resulting set only to packages that provide any of <capabilities>.",
"CAPABILITY,...",
",");
whatrequires = std::make_unique<libdnf::cli::session::StringListOption>(
*this,
"whatrequires",
'\0',
"Limit the resulting set only to packages that require any of <capabilities>. Use --whatdepends if you want to "
"list all depending packages.",
"CAPABILITY,...",
",");
whatobsoletes = std::make_unique<libdnf::cli::session::StringListOption>(
*this,
"whatobsoletes",
'\0',
"Limit the resulting set only to packages that obsolete any of <capabilities>.",
"CAPABILITY,...",
",");
whatrecommends = std::make_unique<libdnf::cli::session::StringListOption>(
*this,
"whatrecommends",
'\0',
"Limit the resulting set only to packages that recommend any of <capabilities>. Use --whatdepends if you want "
"to list all depending packages.",
"CAPABILITY,...",
",");
whatenhances = std::make_unique<libdnf::cli::session::StringListOption>(
*this,
"whatenhances",
'\0',
"Limit the resulting set only to packages that enhance any of <capabilities>. Use --whatdepends if you want to "
"list all depending packages.",
"CAPABILITY,...",
",");
whatsupplements = std::make_unique<libdnf::cli::session::StringListOption>(
*this,
"whatsupplements",
'\0',
"Limit the resulting set only to packages that supplement any of <capabilities>. Use --whatdepends if you "
"want to list all depending packages.",
"CAPABILITY,...",
",");
whatsuggests = std::make_unique<libdnf::cli::session::StringListOption>(
*this,
"whatsuggests",
'\0',
"Limit the resulting set only to packages that suggest any of <capabilities>. Use --whatdepends if you want to "
"list all depending packages.",
"CAPABILITY,...",
",");

exactdeps = std::make_unique<libdnf::cli::session::BoolOption>(
*this,
"exactdeps",
'\0',
"This option is stackable with --whatrequires or --whatdepends only. Limit the resulting set only to packages "
"that require <capability> specified by –whatrequires.",
false);

advisory_name = std::make_unique<AdvisoryOption>(*this);
advisory_security = std::make_unique<SecurityOption>(*this);
advisory_bugfix = std::make_unique<BugfixOption>(*this);
Expand Down Expand Up @@ -141,6 +219,22 @@ void RepoqueryCommand::load_additional_packages() {
}
}

// In case of input being nevras -> resolve them to packages
static libdnf::rpm::PackageQuery resolve_nevras_to_packges(
libdnf::Base & base, std::vector<std::string> nevra_globs, libdnf::rpm::PackageQuery base_query) {
auto resolved_nevras_query = libdnf::rpm::PackageQuery(base, libdnf::sack::ExcludeFlags::APPLY_EXCLUDES, true);
auto settings = libdnf::ResolveSpecSettings();
settings.with_provides = false;
settings.with_filenames = false;
for (auto nevra : nevra_globs) {
auto tmp_query = base_query;
tmp_query.resolve_pkg_spec(nevra, settings, true);
resolved_nevras_query |= tmp_query;
}

return resolved_nevras_query;
}

void RepoqueryCommand::run() {
auto & ctx = get_context();

Expand All @@ -161,6 +255,124 @@ void RepoqueryCommand::run() {
full_package_query.filter_advisories(advisories.value(), libdnf::sack::QueryCmp::GTE);
}

if (!whatdepends->get_value().empty()) {
auto matched_reldeps = libdnf::rpm::ReldepList(ctx.base);
for (const auto & reldep_glob : whatdepends->get_value()) {
matched_reldeps.add_reldep_with_glob(reldep_glob);
}

// Filter requires by reldeps
auto dependsquery = full_package_query;
dependsquery.filter_requires(matched_reldeps, libdnf::sack::QueryCmp::EQ);

// Filter weak deps via reldeps
auto recommends_reldep_query = full_package_query;
recommends_reldep_query.filter_recommends(matched_reldeps, libdnf::sack::QueryCmp::EQ);
dependsquery |= recommends_reldep_query;
auto enhances_reldep_query = full_package_query;
enhances_reldep_query.filter_enhances(matched_reldeps, libdnf::sack::QueryCmp::EQ);
dependsquery |= enhances_reldep_query;
auto supplements_reldep_query = full_package_query;
supplements_reldep_query.filter_supplements(matched_reldeps, libdnf::sack::QueryCmp::EQ);
dependsquery |= supplements_reldep_query;
auto suggests_reldep_query = full_package_query;
suggests_reldep_query.filter_suggests(matched_reldeps, libdnf::sack::QueryCmp::EQ);
dependsquery |= suggests_reldep_query;

if (!exactdeps->get_value()) {
auto pkgs_from_resolved_nevras =
resolve_nevras_to_packges(ctx.base, whatdepends->get_value(), full_package_query);

// Filter requires by packages from resolved nevras
auto what_requires_resolved_nevras = full_package_query;
what_requires_resolved_nevras.filter_requires(pkgs_from_resolved_nevras);
dependsquery |= what_requires_resolved_nevras;

// Filter weak deps by packages from resolved nevras
auto recommends_pkg_query = full_package_query;
recommends_pkg_query.filter_recommends(pkgs_from_resolved_nevras, libdnf::sack::QueryCmp::EQ);
dependsquery |= recommends_pkg_query;
auto enhances_pkg_query = full_package_query;
enhances_pkg_query.filter_enhances(pkgs_from_resolved_nevras, libdnf::sack::QueryCmp::EQ);
dependsquery |= enhances_pkg_query;
auto supplements_pkg_query = full_package_query;
supplements_pkg_query.filter_supplements(pkgs_from_resolved_nevras, libdnf::sack::QueryCmp::EQ);
dependsquery |= supplements_pkg_query;
auto suggests_pkg_query = full_package_query;
suggests_pkg_query.filter_suggests(pkgs_from_resolved_nevras, libdnf::sack::QueryCmp::EQ);
dependsquery |= suggests_pkg_query;
}
//TODO(amatej): add recurisve option call

full_package_query = dependsquery;
}
if (!whatprovides->get_value().empty()) {
auto provides_query = full_package_query;
provides_query.filter_provides(whatprovides->get_value(), libdnf::sack::QueryCmp::GLOB);
if (!provides_query.empty()) {
full_package_query = provides_query;
} else {
// If provides query doesn't match anything try matching files
full_package_query.filter_file(whatprovides->get_value(), libdnf::sack::QueryCmp::GLOB);
}
}
if (!whatrequires->get_value().empty()) {
if (exactdeps->get_value()) {
full_package_query.filter_requires(whatrequires->get_value(), libdnf::sack::QueryCmp::GLOB);
} else {
auto requires_resolved = full_package_query;
requires_resolved.filter_requires(
resolve_nevras_to_packges(ctx.base, whatrequires->get_value(), full_package_query));

full_package_query.filter_requires(whatrequires->get_value(), libdnf::sack::QueryCmp::GLOB);
full_package_query |= requires_resolved;
//TODO(amatej): add recurisve option call
}
}
if (!whatobsoletes->get_value().empty()) {
full_package_query.filter_obsoletes(whatobsoletes->get_value(), libdnf::sack::QueryCmp::GLOB);
}
if (!whatconflicts->get_value().empty()) {
auto conflicts_resolved = full_package_query;
conflicts_resolved.filter_conflicts(
resolve_nevras_to_packges(ctx.base, whatconflicts->get_value(), full_package_query));

full_package_query.filter_conflicts(whatconflicts->get_value(), libdnf::sack::QueryCmp::GLOB);
full_package_query |= conflicts_resolved;
}
if (!whatrecommends->get_value().empty()) {
auto recommends_resolved = full_package_query;
recommends_resolved.filter_recommends(
resolve_nevras_to_packges(ctx.base, whatrecommends->get_value(), full_package_query));

full_package_query.filter_recommends(whatrecommends->get_value(), libdnf::sack::QueryCmp::GLOB);
full_package_query |= recommends_resolved;
}
if (!whatenhances->get_value().empty()) {
auto enhances_resolved = full_package_query;
enhances_resolved.filter_enhances(
resolve_nevras_to_packges(ctx.base, whatenhances->get_value(), full_package_query));

full_package_query.filter_enhances(whatenhances->get_value(), libdnf::sack::QueryCmp::GLOB);
full_package_query |= enhances_resolved;
}
if (!whatsupplements->get_value().empty()) {
auto supplements_resolved = full_package_query;
supplements_resolved.filter_supplements(
resolve_nevras_to_packges(ctx.base, whatsupplements->get_value(), full_package_query));

full_package_query.filter_supplements(whatsupplements->get_value(), libdnf::sack::QueryCmp::GLOB);
full_package_query |= supplements_resolved;
}
if (!whatsuggests->get_value().empty()) {
auto suggests_resolved = full_package_query;
suggests_resolved.filter_suggests(
resolve_nevras_to_packges(ctx.base, whatsuggests->get_value(), full_package_query));

full_package_query.filter_suggests(whatsuggests->get_value(), libdnf::sack::QueryCmp::GLOB);
full_package_query |= suggests_resolved;
}

if (pkg_specs.empty() && pkg_file_paths.empty()) {
result_pset |= full_package_query;
} else {
Expand Down
12 changes: 12 additions & 0 deletions dnf5/commands/repoquery/repoquery.hpp
Expand Up @@ -51,6 +51,18 @@ class RepoqueryCommand : public Command {
std::vector<std::string> pkg_file_paths;
std::vector<libdnf::rpm::Package> cmdline_packages;

std::unique_ptr<libdnf::cli::session::StringListOption> whatdepends{nullptr};
std::unique_ptr<libdnf::cli::session::StringListOption> whatconflicts{nullptr};
std::unique_ptr<libdnf::cli::session::StringListOption> whatenhances{nullptr};
std::unique_ptr<libdnf::cli::session::StringListOption> whatobsoletes{nullptr};
std::unique_ptr<libdnf::cli::session::StringListOption> whatprovides{nullptr};
std::unique_ptr<libdnf::cli::session::StringListOption> whatrecommends{nullptr};
std::unique_ptr<libdnf::cli::session::StringListOption> whatrequires{nullptr};
std::unique_ptr<libdnf::cli::session::StringListOption> whatsuggests{nullptr};
std::unique_ptr<libdnf::cli::session::StringListOption> whatsupplements{nullptr};

std::unique_ptr<libdnf::cli::session::BoolOption> exactdeps{nullptr};

std::unique_ptr<AdvisoryOption> advisory_name{nullptr};
std::unique_ptr<SecurityOption> advisory_security{nullptr};
std::unique_ptr<BugfixOption> advisory_bugfix{nullptr};
Expand Down

0 comments on commit fbf0ddd

Please sign in to comment.