[Reproducible-commits] [debbindiff] 01/01: Add support for rpm packages

Reiner Herrmann deki-guest at moszumanska.debian.org
Thu Feb 5 18:26:58 UTC 2015


This is an automated email from the git hooks/post-receive script.

deki-guest pushed a commit to branch master
in repository debbindiff.

commit ed6baf359af53ac7bf8339206f3b2a417ab97f12
Author: Reiner Herrmann <reiner at reiner-h.de>
Date:   Thu Feb 5 19:24:57 2015 +0100

    Add support for rpm packages
---
 debbindiff/comparators/__init__.py |  2 +
 debbindiff/comparators/rpm.py      | 81 ++++++++++++++++++++++++++++++++++++++
 debian/control                     |  2 +
 3 files changed, 85 insertions(+)

diff --git a/debbindiff/comparators/__init__.py b/debbindiff/comparators/__init__.py
index 59fc92b..41f805d 100644
--- a/debbindiff/comparators/__init__.py
+++ b/debbindiff/comparators/__init__.py
@@ -36,6 +36,7 @@ from debbindiff.comparators.gzip import compare_gzip_files
 from debbindiff.comparators.haskell import compare_hi_files
 from debbindiff.comparators.pdf import compare_pdf_files
 from debbindiff.comparators.png import compare_png_files
+from debbindiff.comparators.rpm import compare_rpm_files
 from debbindiff.comparators.text import compare_text_files
 from debbindiff.comparators.tar import compare_tar_files
 from debbindiff.comparators.xz import compare_xz_files
@@ -75,6 +76,7 @@ COMPARATORS = [
     (r'^application/x-tar(;|$)', r'\.tar$', compare_tar_files),
     (r'^application/zip(;|$)', r'\.(zip|jar)$', compare_zip_files),
     (r'^application/(x-debian-package|vnd.debian.binary-package)(;|$)', r'\.u?deb$', compare_deb_files),
+    (r'^application/x-rpm(;|$)', r'\.rpm$', compare_rpm_files),
     (r'^application/x-gzip(;|$)', r'\.gz$', compare_gzip_files),
     (r'^application/x-bzip2(;|$)', r'\.bzip2$', compare_bzip2_files),
     (r'^application/x-executable(;|$)', None, compare_elf_files),
diff --git a/debbindiff/comparators/rpm.py b/debbindiff/comparators/rpm.py
new file mode 100644
index 0000000..3a22b50
--- /dev/null
+++ b/debbindiff/comparators/rpm.py
@@ -0,0 +1,81 @@
+# -*- coding: utf-8 -*-
+#
+# debbindiff: highlight differences between two builds of Debian packages
+#
+# Copyright © 2015 Reiner Herrmann <reiner at reiner-h.de>
+#
+# debbindiff is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# debbindiff is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with debbindiff.  If not, see <http://www.gnu.org/licenses/>.
+
+from __future__ import absolute_import
+import rpm
+import os.path
+import subprocess
+from contextlib import contextmanager
+import debbindiff.comparators
+from debbindiff import logger
+from debbindiff.comparators.utils import binary_fallback, make_temp_directory
+from debbindiff.difference import Difference, get_source
+
+def get_rpm_header(path, ts):
+    header = ''
+    with open(path, 'r') as f:
+        hdr = ts.hdrFromFdno(f)
+        for rpmtag in sorted(rpm.tagnames):
+            if rpmtag not in hdr:
+                continue
+            # header fields can contain binary data
+            try:
+                value = str(hdr[rpmtag]).decode('utf-8')
+            except UnicodeDecodeError:
+                value = str(hdr[rpmtag]).encode('hex_codec')
+            header += "%s: %s\n" % (rpm.tagnames[rpmtag], value)
+
+    return header
+
+
+ at contextmanager
+def extract_rpm_payload(path):
+    cmd = ['rpm2cpio', path]
+    with make_temp_directory() as temp_dir:
+        temp_path = os.path.join(temp_dir, "CONTENTS.cpio")
+        with open(temp_path, 'wb') as temp_file:
+            p = subprocess.Popen(cmd, shell=False,
+                stdout=temp_file, stderr=subprocess.PIPE)
+            p.wait()
+            if p.returncode != 0:
+                logger.error("rpm2cpio exited with error code %d", p.returncode)
+
+            yield temp_path
+
+
+ at binary_fallback
+def compare_rpm_files(path1, path2, source=None):
+    differences = []
+
+    # compare headers
+    ts = rpm.TransactionSet()
+    header1 = get_rpm_header(path1, ts)
+    header2 = get_rpm_header(path2, ts)
+    if header1 != header2:
+        differences.append(Difference(
+            header1.splitlines(1), header2.splitlines(2),
+            path1, path2, source="header"))
+
+    # extract cpio archive
+    with extract_rpm_payload(path1) as archive1:
+        with extract_rpm_payload(path2) as archive2:
+            differences.extend(debbindiff.comparators.compare_files(
+                archive1, archive2, source=get_source(archive1, archive2)))
+
+    return differences
diff --git a/debian/control b/debian/control
index 5f45445..070e6de 100644
--- a/debian/control
+++ b/debian/control
@@ -8,6 +8,7 @@ Build-Depends: debhelper (>= 9),
                python-debian,
                python-docutils,
                python-magic,
+               python-rpm,
                python-setuptools
 Standards-Version: 3.9.6
 X-Python-Version: >= 2.7
@@ -28,6 +29,7 @@ Depends: binutils-multiarch,
          gnupg,
          pdftk,
          poppler-utils,
+         rpm2cpio,
          sng,
          unzip,
          vim,

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/reproducible/debbindiff.git



More information about the Reproducible-commits mailing list