Skip to content

Commit

Permalink
repoquery: rework "alldeps" dependency search (RhBug:1534123,1698034)
Browse files Browse the repository at this point in the history
Uses the new feature of filtering by solvables to properly resolve rich
dependencies for packages. The new code now, along with serching for the
arguments as reldeps, also searches for them as NEVRAs and then looks up
the dependencies for the packages it found.

https://bugzilla.redhat.com/show_bug.cgi?id=1534123
https://bugzilla.redhat.com/show_bug.cgi?id=1698034

Closes: #1432
Approved by: j-mracek
  • Loading branch information
Lukáš Hrázký authored and inknos committed May 7, 2020
1 parent be297f8 commit 51e5a0c
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 44 deletions.
2 changes: 1 addition & 1 deletion dnf.spec
@@ -1,5 +1,5 @@
# default dependencies
%global hawkey_version 0.41.0
%global hawkey_version 0.44.0
%global libcomps_version 0.1.8
%global libmodulemd_version 1.4.0
%global rpm_version 4.14.0
Expand Down
93 changes: 50 additions & 43 deletions dnf/cli/commands/repoquery.py
Expand Up @@ -349,54 +349,61 @@ def build_format_fn(self, opts, pkg):
# there don't exist on the dnf Package object.
raise dnf.exceptions.Error(str(e))

def _get_recursive_deps_query(self, query_in, query_select, done=None, recursive=False,
all_dep_types=False):
done = done if done else self.base.sack.query().filterm(empty=True)
t = self.base.sack.query().filterm(empty=True)
set_requires = set()
set_all_deps = set()

for pkg in query_select.run():
pkg_provides = pkg.provides
set_requires.update(pkg_provides)
set_requires.update(pkg.files)
if all_dep_types:
set_all_deps.update(pkg_provides)

t = t.union(query_in.filter(requires=set_requires))
if set_all_deps:
t = t.union(query_in.filter(recommends=set_all_deps))
t = t.union(query_in.filter(enhances=set_all_deps))
t = t.union(query_in.filter(supplements=set_all_deps))
t = t.union(query_in.filter(suggests=set_all_deps))
if recursive:
query_select = t.difference(done)
if query_select:
done = self._get_recursive_deps_query(query_in, query_select, done=t.union(done),
recursive=recursive,
all_dep_types=all_dep_types)
return t.union(done)
def _resolve_nevras(self, nevras, base_query):
resolved_nevras_query = self.base.sack.query().filterm(empty=True)
for nevra in nevras:
resolved_nevras_query = resolved_nevras_query.union(base_query.intersection(
dnf.subject.Subject(nevra).get_best_query(
self.base.sack,
with_provides=False,
with_filenames=False
)
))

return resolved_nevras_query

def _do_recursive_deps(self, query_in, query_select, done=None):
done = done if done else query_select

query_required = query_in.filter(requires=query_select)

query_select = query_required.difference(done)
done = query_required.union(done)

if query_select:
done = self._do_recursive_deps(query_in, query_select, done=done)

return done

def by_all_deps(self, names, query, all_dep_types=False):
defaultquery = self.base.sack.query().filterm(empty=True)
for name in names:
defaultquery = defaultquery.union(query.intersection(
dnf.subject.Subject(name).get_best_query(self.base.sack, with_provides=False,
with_filenames=False)))
requiresquery = query.filter(requires__glob=names)
# in case of arguments being NEVRAs, resolve them to packages
resolved_nevras_query = self._resolve_nevras(names, query)

# filter the arguments directly as reldeps
depquery = query.filter(requires__glob=names)

# filter the resolved NEVRAs as packages
depquery = depquery.union(query.filter(requires=resolved_nevras_query))

if all_dep_types:
requiresquery = requiresquery.union(query.filter(recommends__glob=names))
requiresquery = requiresquery.union(query.filter(enhances__glob=names))
requiresquery = requiresquery.union(query.filter(supplements__glob=names))
requiresquery = requiresquery.union(query.filter(suggests__glob=names))
# TODO this is very inefficient, as it resolves the `names` glob to
# reldeps four more times, which in a reasonably wide glob like
# `dnf repoquery --whatdepends "libdnf*"` can take roughly 50% of
# the total execution time.
depquery = depquery.union(query.filter(recommends__glob=names))
depquery = depquery.union(query.filter(enhances__glob=names))
depquery = depquery.union(query.filter(supplements__glob=names))
depquery = depquery.union(query.filter(suggests__glob=names))

depquery = depquery.union(query.filter(recommends=resolved_nevras_query))
depquery = depquery.union(query.filter(enhances=resolved_nevras_query))
depquery = depquery.union(query.filter(supplements=resolved_nevras_query))
depquery = depquery.union(query.filter(suggests=resolved_nevras_query))

done = requiresquery.union(self._get_recursive_deps_query(query, defaultquery,
all_dep_types=all_dep_types))
if self.opts.recursive:
done = done.union(self._get_recursive_deps_query(query, done,
recursive=self.opts.recursive,
all_dep_types=all_dep_types))
return done
depquery = self._do_recursive_deps(query, depquery)

return depquery

def _get_recursive_providers_query(self, query_in, providers, done=None):
done = done if done else self.base.sack.query().filterm(empty=True)
Expand Down

0 comments on commit 51e5a0c

Please sign in to comment.