Hi all, thanks for making it easy to manipulate Debian packages in Python code. Debian's perl packages in testing have an unusual layout: the perl package has only an upstream changelog, while the changelog.Debian.gz is at /usr/share/doc/perl/changelog.Debian.gz within the perl-base package. Right now, DebFile fails to find the changelog, because it's looking for it at /usr/share/doc/perl-base/changelog.Debian.gz.
To support this configuration without adding a special case for perl-base, I propose checking /usr/share/doc/<source package name>/changelog.Debian.gz before checking the native changelog path. In the future, if any packages are more unusual than this, I think the next step would be to iterate over all of the files in the package looking for /usr/share/doc/*/changelog.Debian.gz, but I didn't want to potentially harm performance, so I didn't go that far. I've attached two patches with cleanups near the code involved, as well as a third patch that implements this suggestion. I've tested the updated code on my system and successfully parsed changelog files out of both perl-base and other packages that implement normal changelog parsing. Cheers, Simon
From 5b47de7a0a8d06dad94681998721e88ccae99895 Mon Sep 17 00:00:00 2001 From: Simon Ruggier <[email protected]> Date: Wed, 14 Jun 2017 14:44:53 -0400 Subject: [PATCH 1/3] Remove trailing whitespace from debfile.py --- lib/debian/debfile.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/debian/debfile.py b/lib/debian/debfile.py index 718159f..6f611a7 100644 --- a/lib/debian/debfile.py +++ b/lib/debian/debfile.py @@ -44,7 +44,7 @@ class DebError(ArError): class DebPart(object): """'Part' of a .deb binary package. - + A .deb package is considered as made of 2 parts: a 'data' part (corresponding to the possibly compressed 'data.tar' archive embedded in a .deb) and a 'control' part (the 'control.tar.gz' archive). Each of @@ -215,7 +215,7 @@ class DebControl(DebPart): def debcontrol(self): """ Return the debian/control as a Deb822 (a Debian-specific dict-like class) object. - + For a string representation of debian/control try .get_content('control') """ -- 2.11.0
From 185a922b5d5bb755c174f49b85d7b80f84561c80 Mon Sep 17 00:00:00 2001 From: Simon Ruggier <[email protected]> Date: Wed, 14 Jun 2017 14:45:09 -0400 Subject: [PATCH 2/3] debfile: Use with statement to open GzipFile object --- lib/debian/debfile.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/debian/debfile.py b/lib/debian/debfile.py index 6f611a7..ff080bb 100644 --- a/lib/debian/debfile.py +++ b/lib/debian/debfile.py @@ -333,9 +333,8 @@ class DebFile(ArFile): for fname in [ CHANGELOG_DEBIAN % self.__pkgname, CHANGELOG_NATIVE % self.__pkgname ]: if self.data.has_file(fname): - gz = gzip.GzipFile(fileobj=self.data.get_file(fname)) - raw_changelog = gz.read() - gz.close() + with gzip.GzipFile(fileobj=self.data.get_file(fname)) as gz: + raw_changelog = gz.read() return Changelog(raw_changelog) return None -- 2.11.0
From 09788135d4ff73e4783f9e3478c3e21393f97196 Mon Sep 17 00:00:00 2001 From: Simon Ruggier <[email protected]> Date: Wed, 14 Jun 2017 15:26:43 -0400 Subject: [PATCH 3/3] Try finding changelog files via the source package name as well --- lib/debian/debfile.py | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/lib/debian/debfile.py b/lib/debian/debfile.py index ff080bb..bd3a94b 100644 --- a/lib/debian/debfile.py +++ b/lib/debian/debfile.py @@ -296,14 +296,20 @@ class DebFile(ArFile): compressed_part_name(CTRL_PART))) self.__parts[DATA_PART] = DebData(self.getmember( compressed_part_name(DATA_PART))) - self.__pkgname = None # updated lazily by __updatePkgName + + # updated lazily by __updatePkgName + self.__pkgname = None + self.__srcpkgname = None f = self.getmember(INFO_PART) self.__version = f.read().strip() f.close() def __updatePkgName(self): - self.__pkgname = self.debcontrol()['package'] + debcontrol = self.debcontrol() + self.__pkgname = debcontrol['package'] + if 'source' in debcontrol: + self.__srcpkgname = self.debcontrol()['source'] version = property(lambda self: self.__version) data = property(lambda self: self.__parts[DATA_PART]) @@ -330,8 +336,15 @@ class DebFile(ArFile): if self.__pkgname is None: self.__updatePkgName() - for fname in [ CHANGELOG_DEBIAN % self.__pkgname, - CHANGELOG_NATIVE % self.__pkgname ]: + fnames = [CHANGELOG_DEBIAN % self.__pkgname] + # Try the source package name as well, if applicable + if self.__srcpkgname: + fnames.append(CHANGELOG_DEBIAN % self.__srcpkgname) + fnames.append(CHANGELOG_NATIVE % self.__pkgname) + if self.__srcpkgname: + fnames.append(CHANGELOG_NATIVE % self.__srcpkgname) + + for fname in fnames: if self.data.has_file(fname): with gzip.GzipFile(fileobj=self.data.get_file(fname)) as gz: raw_changelog = gz.read() -- 2.11.0
-- http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-python-debian-maint
