From 0a11bd268ecfaa0bacf012f2ed2ee292700a02aa Mon Sep 17 00:00:00 2001
From: Jaroslav Mracek <jmracek@redhat.com>
Date: Wed, 22 May 2024 11:09:34 +0200
Subject: [PATCH] Limit queries to nevra forms when provided by command

Command `dnf install-n <provide>` does not install only according
to package mame but still search in provides. The patch limits
searrch only to NEVRA forms for install, remove, autoremove,
and repoquery commands.

Resolves partially: https://issues.redhat.com/browse/RHEL-5747

Conflict:NA
Reference:https://github.com/rpm-software-management/dnf/commit/0a11bd268ecfaa0bacf012f2ed2ee292700a02aa
---
 dnf/base.py                   | 14 ++++++++++++--
 dnf/cli/commands/repoquery.py |  5 +++--
 doc/api_base.rst              |  6 +++++-
 doc/command_ref.rst           |  7 +++++--
 4 files changed, 25 insertions(+), 7 deletions(-)

diff --git a/dnf/base.py b/dnf/base.py
index a6b3574686..dac3cefd7a 100644
--- a/dnf/base.py
+++ b/dnf/base.py
@@ -2064,9 +2064,14 @@ def install_specs(self, install, exclude=None, reponame=None, strict=True, forms
     def install(self, pkg_spec, reponame=None, strict=True, forms=None):
         # :api
         """Mark package(s) given by pkg_spec and reponame for installation."""
+        kwargs = {'forms': forms, 'with_src': False}
+        if forms:
+            kwargs['with_nevra'] = True
+            kwargs['with_provides'] = False
+            kwargs['with_filenames'] = False
 
         subj = dnf.subject.Subject(pkg_spec)
-        solution = subj.get_best_solution(self.sack, forms=forms, with_src=False)
+        solution = subj.get_best_solution(self.sack, **kwargs)
 
         if self.conf.multilib_policy == "all" or subj._is_arch_specified(solution):
             q = solution['query']
@@ -2306,8 +2311,13 @@ def autoremove(self, forms=None, pkg_specs=None, grp_specs=None, filenames=None)
     def remove(self, pkg_spec, reponame=None, forms=None):
         # :api
         """Mark the specified package for removal."""
+        kwargs = {'forms': forms}
+        if forms:
+            kwargs['with_nevra'] = True
+            kwargs['with_provides'] = False
+            kwargs['with_filenames'] = False
 
-        matches = dnf.subject.Subject(pkg_spec).get_best_query(self.sack, forms=forms)
+        matches = dnf.subject.Subject(pkg_spec).get_best_query(self.sack, **kwargs)
         installed = [
             pkg for pkg in matches.installed()
             if reponame is None or
diff --git a/dnf/cli/commands/repoquery.py b/dnf/cli/commands/repoquery.py
index 83b52a8abe..41dd688eac 100644
--- a/dnf/cli/commands/repoquery.py
+++ b/dnf/cli/commands/repoquery.py
@@ -461,9 +461,10 @@ def run(self):
         if self.opts.key:
             remote_packages = self._add_add_remote_packages()
 
-            kwark = {}
+            kwark = {'with_provides': False}
             if self.opts.command in self.nevra_forms:
                 kwark["forms"] = [self.nevra_forms[self.opts.command]]
+                kwark['with_filenames'] = False
             pkgs = []
             query_results = q.filter(empty=True)
 
@@ -474,7 +475,7 @@ def run(self):
             for key in self.opts.key:
                 query_results = query_results.union(
                     dnf.subject.Subject(key, ignore_case=True).get_best_query(
-                        self.base.sack, with_provides=False, query=q, **kwark))
+                        self.base.sack, query=q, **kwark))
             q = query_results
 
         if self.opts.recent:
diff --git a/doc/api_base.rst b/doc/api_base.rst
index 389b28ec6f..95d2d57049 100644
--- a/doc/api_base.rst
+++ b/doc/api_base.rst
@@ -280,7 +280,11 @@
   .. method:: install(pkg_spec, reponame=None, strict=True, forms=None)
 
     Mark packages matching `pkg_spec` for installation.
-    `reponame` can be a name of a repository or a list of repository names. If given, the selection of available packages is limited to packages from these repositories. If strict is set to False, the installation ignores packages with dependency solving problems. Parameter `forms` has the same meaning as in :meth:`dnf.subject.Subject.get_best_query`.
+    `reponame` can be a name of a repository or a list of repository names. If given, the selection of available
+    packages is limited to packages from these repositories. If strict is set to False, the installation ignores
+    packages with dependency solving problems. Parameter `forms` is list of pattern forms from `hawkey`_.
+    Leaving the parameter to ``None`` results in using a reasonable default list of forms. When forms is specified,
+    method will not match `pkg_spec` with provides and file provides.
 
   .. method:: package_downgrade(pkg, strict=False)
 
diff --git a/doc/command_ref.rst b/doc/command_ref.rst
index 25431ca1c7..5fba2ebfa5 100644
--- a/doc/command_ref.rst
+++ b/doc/command_ref.rst
@@ -857,7 +857,8 @@ Install Command
     are considered correct, the resulting package is picked simply by lexicographical order.
 
     There are also a few specific install commands ``install-n``, ``install-na`` and
-    ``install-nevra`` that allow the specification of an exact argument in the NEVRA format.
+    ``install-nevra`` that allow the specification of an exact argument in the NEVRA format. As a consequence, <spec>
+    will be not matched with provides and file provides.
 
     See also :ref:`\configuration_files_replacement_policy-label`.
 
@@ -1191,7 +1192,8 @@ Remove Command
     Removes old installonly packages, keeping only latest versions and version of running kernel.
 
     There are also a few specific remove commands ``remove-n``, ``remove-na`` and ``remove-nevra``
-    that allow the specification of an exact argument in the NEVRA format.
+    that allow the specification of an exact argument in the NEVRA format. As a consequence, <spec>
+    will be not matched with provides and file provides.
 
 Remove Examples
 ---------------
@@ -1255,6 +1257,7 @@ Repoquery Command
 
     There are also a few specific repoquery commands ``repoquery-n``, ``repoquery-na`` and ``repoquery-nevra``
     that allow the specification of an exact argument in the NEVRA format (does not affect arguments of options like --whatprovides <arg>, ...).
+    As a consequence, <spec> will be not matched with file provides.
 
 Select Options
 --------------
