Control: tags + patch Hi!
On Tue, 2013-07-30 at 21:57:59 +0200, Guillem Jover wrote: > Package: alien > Version: 8.88 > Severity: minor > The Alien/Package/Deb.pm file has fallback code to be used whenever > dpkg-deb is not available, but this code using ar does not support any > other data.tar member beside data.tar.gz, as described in deb(5). The > missing ones are: > > data.tar > data.tar.xz > data.tar.bz2 > data.tar.lzma (deprecated) > > You might want to add support for those, but if no one else has asked > for it before, I'm not sure how much that code is being used? Ok, here's a patch implementing the above, plus support for the new control.tar and control.tar.xz. Some comments about the patch itself. I've used List::Utils, but I'm not sure if you are fine with that. I've also only cached the ar member list to avoid repetitive «ar -t» calls, but didn't bother caching the control.tar member name or the compressor used. I also refactored the $datamember_cmd setting, but I could move it into another patch or revert that part. I've tested it using the test binaries from the t-deb-format test in <git://git.debian.org/git/dpkg/pkg-tests.git>, to generate them you could use «make -C t-deb-format test-case». Although some are valid and others are bogus. I've only tested converting from deb to rpm, but I think that should be enough. To make sure I was testing the fallback code I've changed the have_dpkg_deb() call, attached too. Thanks, Guillem
From c8083476ce6206e50af10a5690d780e91b1e488d Mon Sep 17 00:00:00 2001 From: Guillem Jover <guil...@debian.org> Date: Fri, 9 May 2014 07:41:26 +0200 Subject: [PATCH] Update deb support in fallback code Add support for control.tar, control.tar.xz, data.tar, data.tar.xz, data.tar.bz2 (deprecated) and data.tar.lzma (deprecated), so that the fallback code is in line with current dpkg-deb. The deprecated members are supported because there might be such binary packages laying around. --- Alien/Package/Deb.pm | 88 +++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 81 insertions(+), 7 deletions(-) diff --git a/Alien/Package/Deb.pm b/Alien/Package/Deb.pm index f431ab6..4ad968d 100644 --- a/Alien/Package/Deb.pm +++ b/Alien/Package/Deb.pm @@ -9,6 +9,7 @@ Alien::Package::Deb - an object that represents a deb package package Alien::Package::Deb; use strict; use base qw(Alien::Package); +use List::Util qw(first); =head1 DESCRIPTION @@ -23,6 +24,10 @@ Alien::Package. Set to a true value if dpkg-deb is available. +=item deb_member_list + +Set to the list of member names in the deb package. + =item dirtrans After the build stage, set to a hash reference of the directories we moved @@ -117,6 +122,26 @@ sub test { } } +=item get_deb_member_list + +Helper method. Pass it the name of the deb and it will return the list of +ar members. + +=cut + +sub get_deb_member_list { + my $this=shift; + my $file=$this->filename; + my $members=$this->deb_member_list; + + unless (defined $members) { + $members = [ map { chomp; $_ } $this->runpipe(1, "ar -t '$file'") ]; + $this->deb_member_list($members); + } + + return @{$members}; +} + =item getcontrolfile Helper method. Pass it the name of a control file, and it will pull it out @@ -142,11 +167,58 @@ sub getcontrolfile { " tar xf - './$file' &&". " cat '$file'; cd /; rm -rf /tmp/tar_out.$$)"; } - my $getcontrol = "ar -p '$file' control.tar.gz | gzip -dc | ".tar_out($controlfile)." 2>/dev/null"; + my $controlcomp; + my $controlmember = first { /^control\.tar/ } + $this->get_deb_member_list; + if (! defined $controlmember) { + die 'Cannot find control member!'; + } elsif ($controlmember eq 'control.tar.gz') { + $controlcomp = 'gzip -dc'; + } elsif ($controlmember eq 'control.tar.xz') { + $controlcomp = 'xz -dc'; + } elsif ($controlmember eq 'control.tar') { + $controlcomp = 'cat'; + } else { + die 'Unknown control member!'; + } + my $getcontrol = "ar -p '$file' $controlmember | $controlcomp | ".tar_out($controlfile)." 2>/dev/null"; return $this->runpipe(1, $getcontrol); } } +=item get_datamember_cmd + +Helper method. Pass it the name of the deb and it will return the raw +command needed to extract the data.tar member. + +=cut + +sub get_datamember_cmd { + my $this=shift; + my $file=$this->filename; + + my $datacomp; + my $datamember = first { /^data\.tar/ } + $this->get_deb_member_list; + if (! defined $datamember) { + die 'Cannot find data member!'; + } elsif ($datamember eq 'data.tar.gz') { + $datacomp = 'gzip -dc'; + } elsif ($datamember eq 'data.tar.bz2') { + $datacomp = 'bzip2 -dc'; + } elsif ($datamember eq 'data.tar.xz') { + $datacomp = 'xz -dc'; + } elsif ($datamember eq 'data.tar.lzma') { + $datacomp = 'xz -dc'; + } elsif ($datamember eq 'data.tar') { + $datacomp = 'cat'; + } else { + die 'Unknown data member!'; + } + + return "ar -p '$file' $datamember | $datacomp"; +} + =item scan Implement the scan method to read a deb file. @@ -209,15 +281,15 @@ sub scan { # Read in the list of all files. # Note that tar doesn't supply a leading '/', so we have to add that. - my @filelist; + my $datamember_cmd; if ($this->have_dpkg_deb) { - @filelist=map { chomp; s:\./::; "/$_" } - $this->runpipe(0, "dpkg-deb --fsys-tarfile '$file' | tar tf -"); + $datamember_cmd = "dpkg-deb --fsys-tarfile '$file'"; } else { - @filelist=map { chomp; s:\./::; "/$_" } - $this->runpipe(0, "ar -p '$file' data.tar.gz | gzip -dc | tar tf -"); + $datamember_cmd = $this->get_datamember_cmd($file); } + my @filelist=map { chomp; s:\./::; "/$_" } + $this->runpipe(0, "$datamember_cmd | tar tf -"); $this->filelist(\@filelist); # Read in the scripts, if any. @@ -244,7 +316,9 @@ sub unpack { or die "Unpacking of '$file' failed: $!"; } else { - $this->do("ar -p $file data.tar.gz | gzip -dc | (cd ".$this->unpacked_tree."; tar xpf -)") + my $datamember_cmd = $this->get_datamember_cmd($file); + + $this->do("$datamember_cmd | (cd ".$this->unpacked_tree."; tar xpf -)") or die "Unpacking of '$file' failed: $!"; } -- 2.0.0.rc2.303.gcfa251b
diff --git a/Alien/Package/Deb.pm b/Alien/Package/Deb.pm index 4ad968d..9c7927c 100644 --- a/Alien/Package/Deb.pm +++ b/Alien/Package/Deb.pm @@ -66,7 +66,7 @@ sub init { my $this=shift; $this->SUPER::init(@_); - $this->have_dpkg_deb($this->_inpath('dpkg-deb')); + $this->have_dpkg_deb(''); } =item checkfile