Blame SOURCES/0018-repoquery-fix-rich-deps-matching-by-using-provide-expansion-from-libdn-RhBug-1819172.patch

06f1cc
From bfd04883c44ad31407f0b5a48e06fa597c46d727 Mon Sep 17 00:00:00 2001
06f1cc
From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Hr=C3=A1zk=C3=BD?= <lhrazky@redhat.com>
06f1cc
Date: Fri, 12 Jul 2019 17:14:00 +0200
06f1cc
Subject: [PATCH 1/6] repoquery: move the alldeps/exactdeps check to
06f1cc
 configure()
06f1cc
06f1cc
Moves the check for alldeps/exactdeps switches to the configure() method
06f1cc
along with the other checks.
06f1cc
06f1cc
Raises dnf.cli.CliError instead of dnf.exceptions.Error.
06f1cc
---
06f1cc
 dnf/cli/commands/repoquery.py | 10 ++++++----
06f1cc
 1 file changed, 6 insertions(+), 4 deletions(-)
06f1cc
06f1cc
diff --git a/dnf/cli/commands/repoquery.py b/dnf/cli/commands/repoquery.py
06f1cc
index 7334ddcd90..dc09bf4403 100644
06f1cc
--- a/dnf/cli/commands/repoquery.py
06f1cc
+++ b/dnf/cli/commands/repoquery.py
06f1cc
@@ -303,6 +303,12 @@ def configure(self):
06f1cc
                       "(optionally with '--alldeps', but not with '--exactdeps'), or with "
06f1cc
                       "'--requires <REQ> --resolve'"))
06f1cc
 
06f1cc
+        if self.opts.alldeps or self.opts.exactdeps:
06f1cc
+            if not (self.opts.whatrequires or self.opts.whatdepends):
06f1cc
+                raise dnf.cli.CliError(
06f1cc
+                    _("argument {} requires --whatrequires or --whatdepends option".format(
06f1cc
+                        '--alldeps' if self.opts.alldeps else '--exactdeps')))
06f1cc
+
06f1cc
         if self.opts.srpm:
06f1cc
             self.base.repos.enable_source_repos()
06f1cc
 
06f1cc
@@ -496,10 +502,6 @@ def run(self):
06f1cc
             else:
06f1cc
                 q.filterm(file__glob=self.opts.whatprovides)
06f1cc
         if self.opts.alldeps or self.opts.exactdeps:
06f1cc
-            if not (self.opts.whatrequires or self.opts.whatdepends):
06f1cc
-                raise dnf.exceptions.Error(
06f1cc
-                    _("argument {} requires --whatrequires or --whatdepends option".format(
06f1cc
-                        '--alldeps' if self.opts.alldeps else '--exactdeps')))
06f1cc
             if self.opts.alldeps:
06f1cc
                 q = self.by_all_deps(self.opts.whatrequires, self.opts.whatdepends, q)
06f1cc
             else:
06f1cc
06f1cc
From d9492fef24989085011047dd561fef1dfa1e31d6 Mon Sep 17 00:00:00 2001
06f1cc
From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Hr=C3=A1zk=C3=BD?= <lhrazky@redhat.com>
06f1cc
Date: Fri, 12 Jul 2019 17:22:05 +0200
06f1cc
Subject: [PATCH 2/6] repoquery: fix calling by_all_deps() for --tree
06f1cc
06f1cc
Fixes a bug introduced in bd00c044, where the by_all_deps() arguments
06f1cc
were changed to an array, but in tree_seed() it still passes a single
06f1cc
string.
06f1cc
06f1cc
Untested, I have actually no idea what the code does there, it looks
06f1cc
kind of suspect.
06f1cc
---
06f1cc
 dnf/cli/commands/repoquery.py | 2 +-
06f1cc
 1 file changed, 1 insertion(+), 1 deletion(-)
06f1cc
06f1cc
diff --git a/dnf/cli/commands/repoquery.py b/dnf/cli/commands/repoquery.py
06f1cc
index dc09bf4403..db174b3bba 100644
06f1cc
--- a/dnf/cli/commands/repoquery.py
06f1cc
+++ b/dnf/cli/commands/repoquery.py
06f1cc
@@ -674,7 +674,7 @@ def tree_seed(self, query, aquery, opts, level=-1, usedpkgs=None):
06f1cc
                             ar[querypkg.name + "." + querypkg.arch] = querypkg
06f1cc
                     pkgquery = self.base.sack.query().filterm(pkg=list(ar.values()))
06f1cc
                 else:
06f1cc
-                    pkgquery = self.by_all_deps(pkg.name, None, aquery) if opts.alldeps \
06f1cc
+                    pkgquery = self.by_all_deps((pkg.name, ), None, aquery) if opts.alldeps \
06f1cc
                         else aquery.filter(requires__glob=pkg.name)
06f1cc
                 self.tree_seed(pkgquery, aquery, opts, level + 1, usedpkgs)
06f1cc
 
06f1cc
06f1cc
From f2f31452876b37b54150cba1bf08fc46ecaf72f2 Mon Sep 17 00:00:00 2001
06f1cc
From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Hr=C3=A1zk=C3=BD?= <lhrazky@redhat.com>
06f1cc
Date: Fri, 12 Jul 2019 17:44:38 +0200
06f1cc
Subject: [PATCH 3/6] repoquery: simplify handling of whatrequires and
06f1cc
 whatdepends
06f1cc
06f1cc
Separates whatrequires and whatdepends handling into two separate code
06f1cc
branches, the original was overly complex, confusing and presented
06f1cc
multiple unnecessary corner cases.
06f1cc
06f1cc
The by_all_deps() arguments now also have a much better defined role.
06f1cc
---
06f1cc
 dnf/cli/commands/repoquery.py | 59 +++++++++++++++++------------------
06f1cc
 1 file changed, 29 insertions(+), 30 deletions(-)
06f1cc
06f1cc
diff --git a/dnf/cli/commands/repoquery.py b/dnf/cli/commands/repoquery.py
06f1cc
index db174b3bba..f5e951c9c8 100644
06f1cc
--- a/dnf/cli/commands/repoquery.py
06f1cc
+++ b/dnf/cli/commands/repoquery.py
06f1cc
@@ -350,7 +350,7 @@ def build_format_fn(self, opts, pkg):
06f1cc
             raise dnf.exceptions.Error(str(e))
06f1cc
 
06f1cc
     def _get_recursive_deps_query(self, query_in, query_select, done=None, recursive=False,
06f1cc
-                                  all_deps=False):
06f1cc
+                                  all_dep_types=False):
06f1cc
         done = done if done else self.base.sack.query().filterm(empty=True)
06f1cc
         t = self.base.sack.query().filterm(empty=True)
06f1cc
         set_requires = set()
06f1cc
@@ -360,7 +360,7 @@ def _get_recursive_deps_query(self, query_in, query_select, done=None, recursive
06f1cc
             pkg_provides = pkg.provides
06f1cc
             set_requires.update(pkg_provides)
06f1cc
             set_requires.update(pkg.files)
06f1cc
-            if all_deps:
06f1cc
+            if all_dep_types:
06f1cc
                 set_all_deps.update(pkg_provides)
06f1cc
 
06f1cc
         t = t.union(query_in.filter(requires=set_requires))
06f1cc
@@ -373,29 +373,29 @@ def _get_recursive_deps_query(self, query_in, query_select, done=None, recursive
06f1cc
             query_select = t.difference(done)
06f1cc
             if query_select:
06f1cc
                 done = self._get_recursive_deps_query(query_in, query_select, done=t.union(done),
06f1cc
-                                                      recursive=recursive, all_deps=all_deps)
06f1cc
+                                                      recursive=recursive,
06f1cc
+                                                      all_dep_types=all_dep_types)
06f1cc
         return t.union(done)
06f1cc
 
06f1cc
-    def by_all_deps(self, requires_name, depends_name, query):
06f1cc
-        names = requires_name or depends_name
06f1cc
+    def by_all_deps(self, names, query, all_dep_types=False):
06f1cc
         defaultquery = self.base.sack.query().filterm(empty=True)
06f1cc
         for name in names:
06f1cc
             defaultquery = defaultquery.union(query.intersection(
06f1cc
                 dnf.subject.Subject(name).get_best_query(self.base.sack, with_provides=False,
06f1cc
                                                          with_filenames=False)))
06f1cc
         requiresquery = query.filter(requires__glob=names)
06f1cc
-        if depends_name:
06f1cc
-            requiresquery = requiresquery.union(query.filter(recommends__glob=depends_name))
06f1cc
-            requiresquery = requiresquery.union(query.filter(enhances__glob=depends_name))
06f1cc
-            requiresquery = requiresquery.union(query.filter(supplements__glob=depends_name))
06f1cc
-            requiresquery = requiresquery.union(query.filter(suggests__glob=depends_name))
06f1cc
+        if all_dep_types:
06f1cc
+            requiresquery = requiresquery.union(query.filter(recommends__glob=names))
06f1cc
+            requiresquery = requiresquery.union(query.filter(enhances__glob=names))
06f1cc
+            requiresquery = requiresquery.union(query.filter(supplements__glob=names))
06f1cc
+            requiresquery = requiresquery.union(query.filter(suggests__glob=names))
06f1cc
 
06f1cc
         done = requiresquery.union(self._get_recursive_deps_query(query, defaultquery,
06f1cc
-                                                                  all_deps=depends_name))
06f1cc
+                                                                  all_dep_types=all_dep_types))
06f1cc
         if self.opts.recursive:
06f1cc
             done = done.union(self._get_recursive_deps_query(query, done,
06f1cc
                                                              recursive=self.opts.recursive,
06f1cc
-                                                             all_deps=depends_name))
06f1cc
+                                                             all_dep_types=all_dep_types))
06f1cc
         return done
06f1cc
 
06f1cc
     def _get_recursive_providers_query(self, query_in, providers, done=None):
06f1cc
@@ -501,24 +501,23 @@ def run(self):
06f1cc
                 q = query_for_provide
06f1cc
             else:
06f1cc
                 q.filterm(file__glob=self.opts.whatprovides)
06f1cc
-        if self.opts.alldeps or self.opts.exactdeps:
06f1cc
-            if self.opts.alldeps:
06f1cc
-                q = self.by_all_deps(self.opts.whatrequires, self.opts.whatdepends, q)
06f1cc
+
06f1cc
+        if self.opts.whatrequires:
06f1cc
+            if (self.opts.exactdeps):
06f1cc
+                q.filterm(requires__glob=self.opts.whatrequires)
06f1cc
             else:
06f1cc
-                if self.opts.whatrequires:
06f1cc
-                    q.filterm(requires__glob=self.opts.whatrequires)
06f1cc
-                else:
06f1cc
-                    dependsquery = q.filter(requires__glob=self.opts.whatdepends)
06f1cc
-                    dependsquery = dependsquery.union(
06f1cc
-                        q.filter(recommends__glob=self.opts.whatdepends))
06f1cc
-                    dependsquery = dependsquery.union(
06f1cc
-                        q.filter(enhances__glob=self.opts.whatdepends))
06f1cc
-                    dependsquery = dependsquery.union(
06f1cc
-                        q.filter(supplements__glob=self.opts.whatdepends))
06f1cc
-                    q = dependsquery.union(q.filter(suggests__glob=self.opts.whatdepends))
06f1cc
-
06f1cc
-        elif self.opts.whatrequires or self.opts.whatdepends:
06f1cc
-            q = self.by_all_deps(self.opts.whatrequires, self.opts.whatdepends, q)
06f1cc
+                q = self.by_all_deps(self.opts.whatrequires, q)
06f1cc
+
06f1cc
+        if self.opts.whatdepends:
06f1cc
+            if (self.opts.exactdeps):
06f1cc
+                dependsquery = q.filter(requires__glob=self.opts.whatdepends)
06f1cc
+                dependsquery = dependsquery.union(q.filter(recommends__glob=self.opts.whatdepends))
06f1cc
+                dependsquery = dependsquery.union(q.filter(enhances__glob=self.opts.whatdepends))
06f1cc
+                dependsquery = dependsquery.union(q.filter(supplements__glob=self.opts.whatdepends))
06f1cc
+                q = dependsquery.union(q.filter(suggests__glob=self.opts.whatdepends))
06f1cc
+            else:
06f1cc
+                q = self.by_all_deps(self.opts.whatdepends, q, True)
06f1cc
+
06f1cc
         if self.opts.whatrecommends:
06f1cc
             q.filterm(recommends__glob=self.opts.whatrecommends)
06f1cc
         if self.opts.whatenhances:
06f1cc
@@ -674,7 +673,7 @@ def tree_seed(self, query, aquery, opts, level=-1, usedpkgs=None):
06f1cc
                             ar[querypkg.name + "." + querypkg.arch] = querypkg
06f1cc
                     pkgquery = self.base.sack.query().filterm(pkg=list(ar.values()))
06f1cc
                 else:
06f1cc
-                    pkgquery = self.by_all_deps((pkg.name, ), None, aquery) if opts.alldeps \
06f1cc
+                    pkgquery = self.by_all_deps((pkg.name, ), aquery) if opts.alldeps \
06f1cc
                         else aquery.filter(requires__glob=pkg.name)
06f1cc
                 self.tree_seed(pkgquery, aquery, opts, level + 1, usedpkgs)
06f1cc
 
06f1cc
06f1cc
From a1bdbfa498438c2710aecd607a82face05a1bdfd Mon Sep 17 00:00:00 2001
06f1cc
From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Hr=C3=A1zk=C3=BD?= <lhrazky@redhat.com>
06f1cc
Date: Tue, 9 Jul 2019 17:30:58 +0200
06f1cc
Subject: [PATCH 4/6] repoquery: rework "alldeps" dependency search
06f1cc
 (RhBug:1534123,1698034)
06f1cc
06f1cc
Uses the new feature of filtering by solvables to properly resolve rich
06f1cc
dependencies for packages. The new code now, along with serching for the
06f1cc
arguments as reldeps, also searches for them as NEVRAs and then looks up
06f1cc
the dependencies for the packages it found.
06f1cc
06f1cc
https://bugzilla.redhat.com/show_bug.cgi?id=1534123
06f1cc
https://bugzilla.redhat.com/show_bug.cgi?id=1698034
06f1cc
---
06f1cc
 dnf.spec                      |  2 +-
06f1cc
 dnf/cli/commands/repoquery.py | 93 +++++++++++++++++++----------------
06f1cc
 2 files changed, 51 insertions(+), 44 deletions(-)
06f1cc
06f1cc
diff --git a/dnf.spec b/dnf.spec
06f1cc
index 79e4d27dab..578baccac4 100644
06f1cc
--- a/dnf.spec
06f1cc
+++ b/dnf.spec
06f1cc
@@ -1,5 +1,5 @@
06f1cc
 # default dependencies
06f1cc
-%global hawkey_version 0.41.0
06f1cc
+%global hawkey_version 0.44.0
06f1cc
 %global libcomps_version 0.1.8
06f1cc
 %global libmodulemd_version 1.4.0
06f1cc
 %global rpm_version 4.14.0
06f1cc
diff --git a/dnf/cli/commands/repoquery.py b/dnf/cli/commands/repoquery.py
06f1cc
index f5e951c9c8..d86d32ffcd 100644
06f1cc
--- a/dnf/cli/commands/repoquery.py
06f1cc
+++ b/dnf/cli/commands/repoquery.py
06f1cc
@@ -349,54 +349,61 @@ def build_format_fn(self, opts, pkg):
06f1cc
             # there don't exist on the dnf Package object.
06f1cc
             raise dnf.exceptions.Error(str(e))
06f1cc
 
06f1cc
-    def _get_recursive_deps_query(self, query_in, query_select, done=None, recursive=False,
06f1cc
-                                  all_dep_types=False):
06f1cc
-        done = done if done else self.base.sack.query().filterm(empty=True)
06f1cc
-        t = self.base.sack.query().filterm(empty=True)
06f1cc
-        set_requires = set()
06f1cc
-        set_all_deps = set()
06f1cc
-
06f1cc
-        for pkg in query_select.run():
06f1cc
-            pkg_provides = pkg.provides
06f1cc
-            set_requires.update(pkg_provides)
06f1cc
-            set_requires.update(pkg.files)
06f1cc
-            if all_dep_types:
06f1cc
-                set_all_deps.update(pkg_provides)
06f1cc
-
06f1cc
-        t = t.union(query_in.filter(requires=set_requires))
06f1cc
-        if set_all_deps:
06f1cc
-            t = t.union(query_in.filter(recommends=set_all_deps))
06f1cc
-            t = t.union(query_in.filter(enhances=set_all_deps))
06f1cc
-            t = t.union(query_in.filter(supplements=set_all_deps))
06f1cc
-            t = t.union(query_in.filter(suggests=set_all_deps))
06f1cc
-        if recursive:
06f1cc
-            query_select = t.difference(done)
06f1cc
-            if query_select:
06f1cc
-                done = self._get_recursive_deps_query(query_in, query_select, done=t.union(done),
06f1cc
-                                                      recursive=recursive,
06f1cc
-                                                      all_dep_types=all_dep_types)
06f1cc
-        return t.union(done)
06f1cc
+    def _resolve_nevras(self, nevras, base_query):
06f1cc
+        resolved_nevras_query = self.base.sack.query().filterm(empty=True)
06f1cc
+        for nevra in nevras:
06f1cc
+            resolved_nevras_query = resolved_nevras_query.union(base_query.intersection(
06f1cc
+                dnf.subject.Subject(nevra).get_best_query(
06f1cc
+                    self.base.sack,
06f1cc
+                    with_provides=False,
06f1cc
+                    with_filenames=False
06f1cc
+                )
06f1cc
+            ))
06f1cc
+
06f1cc
+        return resolved_nevras_query
06f1cc
+
06f1cc
+    def _do_recursive_deps(self, query_in, query_select, done=None):
06f1cc
+        done = done if done else query_select
06f1cc
+
06f1cc
+        query_required = query_in.filter(requires=query_select)
06f1cc
+
06f1cc
+        query_select = query_required.difference(done)
06f1cc
+        done = query_required.union(done)
06f1cc
+
06f1cc
+        if query_select:
06f1cc
+            done = self._do_recursive_deps(query_in, query_select, done=done)
06f1cc
+
06f1cc
+        return done
06f1cc
 
06f1cc
     def by_all_deps(self, names, query, all_dep_types=False):
06f1cc
-        defaultquery = self.base.sack.query().filterm(empty=True)
06f1cc
-        for name in names:
06f1cc
-            defaultquery = defaultquery.union(query.intersection(
06f1cc
-                dnf.subject.Subject(name).get_best_query(self.base.sack, with_provides=False,
06f1cc
-                                                         with_filenames=False)))
06f1cc
-        requiresquery = query.filter(requires__glob=names)
06f1cc
+        # in case of arguments being NEVRAs, resolve them to packages
06f1cc
+        resolved_nevras_query = self._resolve_nevras(names, query)
06f1cc
+
06f1cc
+        # filter the arguments directly as reldeps
06f1cc
+        depquery = query.filter(requires__glob=names)
06f1cc
+
06f1cc
+        # filter the resolved NEVRAs as packages
06f1cc
+        depquery = depquery.union(query.filter(requires=resolved_nevras_query))
06f1cc
+
06f1cc
         if all_dep_types:
06f1cc
-            requiresquery = requiresquery.union(query.filter(recommends__glob=names))
06f1cc
-            requiresquery = requiresquery.union(query.filter(enhances__glob=names))
06f1cc
-            requiresquery = requiresquery.union(query.filter(supplements__glob=names))
06f1cc
-            requiresquery = requiresquery.union(query.filter(suggests__glob=names))
06f1cc
+            # TODO this is very inefficient, as it resolves the `names` glob to
06f1cc
+            # reldeps four more times, which in a reasonably wide glob like
06f1cc
+            # `dnf repoquery --whatdepends "libdnf*"` can take roughly 50% of
06f1cc
+            # the total execution time.
06f1cc
+            depquery = depquery.union(query.filter(recommends__glob=names))
06f1cc
+            depquery = depquery.union(query.filter(enhances__glob=names))
06f1cc
+            depquery = depquery.union(query.filter(supplements__glob=names))
06f1cc
+            depquery = depquery.union(query.filter(suggests__glob=names))
06f1cc
+
06f1cc
+            depquery = depquery.union(query.filter(recommends=resolved_nevras_query))
06f1cc
+            depquery = depquery.union(query.filter(enhances=resolved_nevras_query))
06f1cc
+            depquery = depquery.union(query.filter(supplements=resolved_nevras_query))
06f1cc
+            depquery = depquery.union(query.filter(suggests=resolved_nevras_query))
06f1cc
 
06f1cc
-        done = requiresquery.union(self._get_recursive_deps_query(query, defaultquery,
06f1cc
-                                                                  all_dep_types=all_dep_types))
06f1cc
         if self.opts.recursive:
06f1cc
-            done = done.union(self._get_recursive_deps_query(query, done,
06f1cc
-                                                             recursive=self.opts.recursive,
06f1cc
-                                                             all_dep_types=all_dep_types))
06f1cc
-        return done
06f1cc
+            depquery = self._do_recursive_deps(query, depquery)
06f1cc
+
06f1cc
+        return depquery
06f1cc
 
06f1cc
     def _get_recursive_providers_query(self, query_in, providers, done=None):
06f1cc
         done = done if done else self.base.sack.query().filterm(empty=True)
06f1cc
06f1cc
From 60cd14aae7fe3d9ae75d5e5665fc311ef3b04402 Mon Sep 17 00:00:00 2001
06f1cc
From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Hr=C3=A1zk=C3=BD?= <lhrazky@redhat.com>
06f1cc
Date: Fri, 1 Nov 2019 18:33:13 +0100
06f1cc
Subject: [PATCH 5/6] repoquery: resolve NEVRAs to packages for most of --what*
06f1cc
 arguments (RhBug:1534123,1698034)
06f1cc
06f1cc
To properly list the conflicts, suggests, recommends, enhances and
06f1cc
supplements dependencies of packages defined through provides or even
06f1cc
rich dependencies, it is required to resolve them to packages and query
06f1cc
for them, because that's where the dependencies are defined.
06f1cc
06f1cc
https://bugzilla.redhat.com/show_bug.cgi?id=1534123
06f1cc
https://bugzilla.redhat.com/show_bug.cgi?id=1698034
06f1cc
---
06f1cc
 dnf/cli/commands/repoquery.py | 16 +++++++++++-----
06f1cc
 1 file changed, 11 insertions(+), 5 deletions(-)
06f1cc
06f1cc
diff --git a/dnf/cli/commands/repoquery.py b/dnf/cli/commands/repoquery.py
06f1cc
index d86d32ffcd..d0521432be 100644
06f1cc
--- a/dnf/cli/commands/repoquery.py
06f1cc
+++ b/dnf/cli/commands/repoquery.py
06f1cc
@@ -499,7 +499,8 @@ def run(self):
06f1cc
         if self.opts.file:
06f1cc
             q.filterm(file__glob=self.opts.file)
06f1cc
         if self.opts.whatconflicts:
06f1cc
-            q.filterm(conflicts=self.opts.whatconflicts)
06f1cc
+            rels = q.filter(conflicts__glob=self.opts.whatconflicts)
06f1cc
+            q = rels.union(q.filter(conflicts=self._resolve_nevras(self.opts.whatconflicts, q)))
06f1cc
         if self.opts.whatobsoletes:
06f1cc
             q.filterm(obsoletes=self.opts.whatobsoletes)
06f1cc
         if self.opts.whatprovides:
06f1cc
@@ -526,13 +527,18 @@ def run(self):
06f1cc
                 q = self.by_all_deps(self.opts.whatdepends, q, True)
06f1cc
 
06f1cc
         if self.opts.whatrecommends:
06f1cc
-            q.filterm(recommends__glob=self.opts.whatrecommends)
06f1cc
+            rels = q.filter(recommends__glob=self.opts.whatrecommends)
06f1cc
+            q = rels.union(q.filter(recommends=self._resolve_nevras(self.opts.whatrecommends, q)))
06f1cc
         if self.opts.whatenhances:
06f1cc
-            q.filterm(enhances__glob=self.opts.whatenhances)
06f1cc
+            rels = q.filter(enhances__glob=self.opts.whatenhances)
06f1cc
+            q = rels.union(q.filter(enhances=self._resolve_nevras(self.opts.whatenhances, q)))
06f1cc
         if self.opts.whatsupplements:
06f1cc
-            q.filterm(supplements__glob=self.opts.whatsupplements)
06f1cc
+            rels = q.filter(supplements__glob=self.opts.whatsupplements)
06f1cc
+            q = rels.union(q.filter(supplements=self._resolve_nevras(self.opts.whatsupplements, q)))
06f1cc
         if self.opts.whatsuggests:
06f1cc
-            q.filterm(suggests__glob=self.opts.whatsuggests)
06f1cc
+            rels = q.filter(suggests__glob=self.opts.whatsuggests)
06f1cc
+            q = rels.union(q.filter(suggests=self._resolve_nevras(self.opts.whatsuggests, q)))
06f1cc
+
06f1cc
         if self.opts.latest_limit:
06f1cc
             q = q.latest(self.opts.latest_limit)
06f1cc
         # reduce a query to security upgrades if they are specified
06f1cc
06f1cc
From 757f9ad4f26c5a0fee9a6a3620eea94dd6004a73 Mon Sep 17 00:00:00 2001
06f1cc
From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Hr=C3=A1zk=C3=BD?= <lhrazky@redhat.com>
06f1cc
Date: Tue, 14 Jan 2020 16:44:07 +0100
06f1cc
Subject: [PATCH 6/6] [doc] Update documentation for the query filter API
06f1cc
06f1cc
Add the new types of arguments supported for dependency filtering.
06f1cc
---
06f1cc
 doc/api_queries.rst | 11 ++++++++---
06f1cc
 1 file changed, 8 insertions(+), 3 deletions(-)
06f1cc
06f1cc
diff --git a/doc/api_queries.rst b/doc/api_queries.rst
06f1cc
index 5c8804e52a..98907d95a6 100644
06f1cc
--- a/doc/api_queries.rst
06f1cc
+++ b/doc/api_queries.rst
06f1cc
@@ -101,17 +101,20 @@
06f1cc
     release           string         match against packages' releases
06f1cc
     reponame          string         match against packages repositories' names
06f1cc
     version           string         match against packages' versions
06f1cc
-    obsoletes         Query          match packages that obsolete any package from query
06f1cc
     pkg               Query          match against packages in query
06f1cc
     pkg*              list           match against hawkey.Packages in list
06f1cc
     provides          string         match against packages' provides
06f1cc
     provides*         Hawkey.Reldep  match against packages' provides
06f1cc
-    requires          string         match against packages' requirements
06f1cc
-    requires*         Hawkey.Reldep  match against packages' requirements
06f1cc
+    <DEP>             string         match against packages' <DEP>
06f1cc
+    <DEP>*            Hawkey.Reldep  match a reldep against packages' <DEP>
06f1cc
+    <DEP>*            Query          match the result of a query against packages' <DEP>
06f1cc
+    <DEP>*            list(Package)  match the list of hawkey.Packages against packages' <DEP>
06f1cc
     sourcerpm         string         match against packages' source rpm
06f1cc
     upgrades          boolean        see :meth:`upgrades`. Defaults to ``False``.
06f1cc
     ===============   ============== ======================================================
06f1cc
 
06f1cc
+    ``<DEP>`` can be any of: requires, conflicts, obsoletes, enhances, recomments, suggests, supplements
06f1cc
+
06f1cc
     \* The key can also accept a list of values with specified type.
06f1cc
 
06f1cc
     The key name can be supplemented with a relation-specifying suffix, separated by ``__``:
06f1cc
@@ -133,6 +136,8 @@
06f1cc
 
06f1cc
       q = base.sack.query().filter(name__substr="club")
06f1cc
 
06f1cc
+    Note that using packages or queries for dependency filtering performs a more advanced resolution than using a string or a reldep. When a package list or a query is used, rich dependencies are resolved in a more precise way than what is possible when a string or a reldep is used.
06f1cc
+
06f1cc
   .. method:: filterm(\*\*kwargs)
06f1cc
 
06f1cc
     Similar to :meth:`dnf.query.Query.filter` but it modifies the query in place.