dcavalca / rpms / dnf

Forked from rpms/dnf 2 years ago
Clone

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

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