dcavalca / rpms / dnf

Forked from rpms/dnf 2 years ago
Clone

Blame SOURCES/0013-Package-add-a-get-header--method.patch

862ba9
From 38cc67385fb1b36aa0881bc5982bc58d75dac464 Mon Sep 17 00:00:00 2001
862ba9
From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Hr=C3=A1zk=C3=BD?= <lhrazky@redhat.com>
862ba9
Date: Wed, 11 Nov 2020 18:45:11 +0100
862ba9
Subject: [PATCH] Package: add a get_header() method (RhBug:1876606)
862ba9
862ba9
Adds get_header() method to the Package class, which returns the rpm
862ba9
header of an installed package.
862ba9
862ba9
= changelog =
862ba9
msg: Add get_header() method to the Package class
862ba9
type: enhancement
862ba9
resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1876606
862ba9
---
862ba9
 dnf/package.py        | 24 ++++++++++++++++++++++++
862ba9
 tests/test_package.py | 12 ++++++++++++
862ba9
 2 files changed, 36 insertions(+)
862ba9
862ba9
diff --git a/dnf/package.py b/dnf/package.py
862ba9
index baef04fa5b..836e0e4989 100644
862ba9
--- a/dnf/package.py
862ba9
+++ b/dnf/package.py
862ba9
@@ -26,11 +26,13 @@
862ba9
 from dnf.i18n import _
862ba9
 
862ba9
 import binascii
862ba9
+import dnf.exceptions
862ba9
 import dnf.rpm
862ba9
 import dnf.yum.misc
862ba9
 import hawkey
862ba9
 import logging
862ba9
 import os
862ba9
+import rpm
862ba9
 
862ba9
 logger = logging.getLogger("dnf")
862ba9
 
862ba9
@@ -95,6 +97,11 @@ def from_repo(self):
862ba9
 
862ba9
     @property
862ba9
     def _header(self):
862ba9
+        """
862ba9
+        Returns the header of a locally present rpm package file. As opposed to
862ba9
+        self.get_header(), which retrieves the header of an installed package
862ba9
+        from rpmdb.
862ba9
+        """
862ba9
         return dnf.rpm._header(self.localPkg())
862ba9
 
862ba9
     @property
862ba9
@@ -164,6 +171,23 @@ def debugsource_name(self):
862ba9
         src_name = self.source_name if self.source_name is not None else self.name
862ba9
         return src_name + self.DEBUGSOURCE_SUFFIX
862ba9
 
862ba9
+    def get_header(self):
862ba9
+        """
862ba9
+        Returns the rpm header of the package if it is installed. If not
862ba9
+        installed, returns None. The header is not cached, it is retrieved from
862ba9
+        rpmdb on every call. In case of a failure (e.g. when the rpmdb changes
862ba9
+        between loading the data and calling this method), raises an instance
862ba9
+        of PackageNotFoundError.
862ba9
+        """
862ba9
+        if not self._from_system:
862ba9
+            return None
862ba9
+
862ba9
+        try:
862ba9
+            # RPMDBI_PACKAGES stands for the header of the package
862ba9
+            return next(self.base._ts.dbMatch(rpm.RPMDBI_PACKAGES, self.rpmdbid))
862ba9
+        except StopIteration:
862ba9
+            raise dnf.exceptions.PackageNotFoundError("Package not found when attempting to retrieve header", str(self))
862ba9
+
862ba9
     @property
862ba9
     def source_debug_name(self):
862ba9
         # :api
862ba9
diff --git a/tests/test_package.py b/tests/test_package.py
862ba9
index cd4872e631..514e5bf099 100644
862ba9
--- a/tests/test_package.py
862ba9
+++ b/tests/test_package.py
862ba9
@@ -68,6 +68,18 @@ def fn_getter():
862ba9
             with self.assertRaises(IOError):
862ba9
                 pkg._header
862ba9
 
862ba9
+    # rpm.hdr() is not easy to construct with custom data, we just return a string
862ba9
+    # instead, as we don't actually need an instance of rpm.hdr for the test
862ba9
+    @mock.patch("rpm.TransactionSet.dbMatch", lambda self, a, b: iter(["package_header_test_data"]))
862ba9
+    def test_get_header(self):
862ba9
+        pkg = self.sack.query().installed().filter(name="pepper")[0]
862ba9
+        header = pkg.get_header()
862ba9
+        self.assertEqual(header, "package_header_test_data")
862ba9
+
862ba9
+        pkg = self.sack.query().available().filter(name="pepper")[0]
862ba9
+        header = pkg.get_header()
862ba9
+        self.assertEqual(header, None)
862ba9
+
862ba9
     @mock.patch("dnf.package.Package.rpmdbid", long(3))
862ba9
     def test_idx(self):
862ba9
         """ pkg.idx is an int. """