[SCM] Git repository for devscripts branch, master, updated. v2.11.9-7-g7ebf1f0
James McCoy
jamessan at debian.org
Sat Jun 30 13:57:21 UTC 2012
The following commit has been merged in the master branch:
commit 7ebf1f067d4345e4969d858667e2da0a321b1716
Author: James McCoy <jamessan at debian.org>
Date: Sat Jun 30 09:56:25 2012 -0400
Devscripts/*.pm: Parse dpkg's status file using Dpkg::Control.
Signed-off-by: James McCoy <jamessan at debian.org>
diff --git a/Devscripts/PackageDeps.pm b/Devscripts/PackageDeps.pm
index a02cf2a..5236d7e 100644
--- a/Devscripts/PackageDeps.pm
+++ b/Devscripts/PackageDeps.pm
@@ -20,11 +20,12 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
+package Devscripts::PackageDeps;
use strict;
use Carp;
+use Dpkg::Control;
require 5.006_000;
-package Devscripts::PackageDeps;
# This reads in a package file list, such as /var/lib/dpkg/status,
# and parses it.
@@ -62,27 +63,27 @@ sub parse ($$)
open PACKAGE_FILE, $filename or
croak("Unable to load $filename: $!");
- local $/;
- $/=""; # Split on blank lines
-
+ my $ctrl;
PACKAGE_ENTRY:
- while (<PACKAGE_FILE>) {
- if (/^\s*$/) { next; }
+ while (defined($ctrl = Dpkg::Control->new(type => CTRL_FILE_STATUS))
+ && $ctrl->parse(\*PACKAGE_FILE, $filename)) {
# So we've got a package
- my $pkg;
+ my $pkg = $ctrl->{Package};
my @deps = ();
- chomp;
- s/\n\s+/\376\377/g; # fix continuation lines
- s/\376\377\s*\376\377/\376\377/og;
+ if ($ctrl->{Status} =~ /^\S+\s+\S+\s+(\S+)$/) {
+ my $status = $1;
+ unless ($status eq 'installed' or $status eq 'unpacked') {
+ undef $ctrl;
+ next PACKAGE_ENTRY;
+ }
+ }
- while (/^(\S+):\s*(.*?)\s*$/mg) {
- my ($key, $value) = (lc $1, $2);
- $value =~ s/\376\377/\n /g;
- if ($key eq 'package') { $pkg = $value; }
- elsif ($key =~ /^(pre-)?depends$/) {
- $value =~ s/\(.*?\)//g; # ignore versioning information
+ for my $dep (qw(Depends Pre-Depends)) {
+ if (exists $ctrl->{$dep}) {
+ my $value = $ctrl->{$dep};
+ $value =~ s/\([^)]+\)//g; # ignore versioning information
$value =~ tr/ \t//d; # remove spaces
my @dep_pkgs = split /,/, $value;
foreach my $dep_pkg (@dep_pkgs) {
@@ -91,19 +92,10 @@ sub parse ($$)
else { push @deps, \@dep_pkg_alts; }
}
}
- elsif ($key eq 'status') {
- unless ($value =~ /^\S+\s+\S+\s+(\S+)$/) {
- warn "Unrecognised Status line in $filename:\nStatus: $value\n";
- }
- my $status = $1;
- # Hopefully, the system is in a nice state...
- # Ignore broken packages and removed but not purged packages
- next PACKAGE_ENTRY unless
- $status eq 'installed' or $status eq 'unpacked';
- }
}
$self->{$pkg} = \@deps;
+ undef $ctrl;
}
close PACKAGE_FILE or
croak("Problems encountered reading $filename: $!");
diff --git a/Devscripts/Packages.pm b/Devscripts/Packages.pm
index 66f547f..863ceb3 100644
--- a/Devscripts/Packages.pm
+++ b/Devscripts/Packages.pm
@@ -19,6 +19,7 @@
package Devscripts::Packages;
use Carp;
+use Dpkg::Control;
BEGIN{
use Exporter ();
@@ -183,12 +184,16 @@ sub FilesToPackages (@)
$curfile = shift;
}
elsif (/^(.*): \Q$curfile\E$/) {
- my @pkgs = split /, /, $1;
- if (@pkgs==1) { $packages{$pkgs[0]} = 1; }
+ my @pkgs = split /,\s+/, $1;
+ if (@pkgs == 1 || !grep /:/, @pkgs) {
+ # Only one package, or all Multi-Arch packages
+ map { $packages{$_} = 1 } @pkgs;
+ }
else {
# We've got a file which has been diverted by some package
- # and so is listed in two packages. The *diverting* package
- # is the one with the file that was actually used.
+ # or is Multi-Arch and so is listed in two packages. If it
+ # was diverted, the *diverting* package is the one with the
+ # file that was actually used.
my $found=0;
foreach my $pkg (@pkgs) {
if ($pkg eq $pkgfrom) {
@@ -216,21 +221,20 @@ sub FilesToPackages (@)
sub PackagesMatch ($)
{
- my $package;
my $match=$_[0];
my @matches=();
open STATUS, '/var/lib/dpkg/status'
or croak("Can't read /var/lib/dpkg/status: $!");
- while(<STATUS>) {
- chomp;
- s/\s+$//;
- if (/^Package: (.+)$/) { $package=$1; next; }
- /$match/ or next;
- push @matches, $package if $package;
- # So we only pick up each package at most once
- undef $package;
+ my $ctrl;
+ while (defined($ctrl = Dpkg::Control->new())
+ && $ctrl->parse(\*STATUS, '/var/lib/dpkg/status')) {
+ if ("$ctrl" =~ m/$match/m) {
+ my $package = $ctrl->{Package};
+ push @matches, $package;
+ }
+ undef $ctrl;
}
close STATUS or croak("Problem reading /var/lib/dpkg/status: $!");
@@ -239,24 +243,32 @@ sub PackagesMatch ($)
# Which packages are installed (Package and Source)?
-# This uses internal knowledge about the /var/lib/dpkg/status file
-# for efficiency - it runs 3 times faster than if it didn't use this
-# info.... And calling a shell script is faster still: thanks to
-# Arthur Korn <arthur at korn.ch> for this one ;-)
-# For the correct settings of -B# -A#, keep up-to-date with
-# the dpkg source, defn of fieldinfos[] in lib/parse.c
-# (and should match wnpp-alert.sh)
sub InstalledPackages ($)
{
- my $grep_pattern = $_[0] ? '^\(Package\|Source\):' : '^Package:';
+ my $source = $_[0];
- open (PKG, qq[grep -B2 -A7 'Status: install ok installed' /var/lib/dpkg/status | grep '$grep_pattern' | cut -f2 -d' ' |])
- or croak("Problem opening grep pipe: $!");
+ open STATUS, '/var/lib/dpkg/status'
+ or croak("Can't read /var/lib/dpkg/status: $!");
- my %matches = map { chomp; $_ => 1 } <PKG>;
+ my $ctrl;
+ while (defined($ctrl = Dpkg::Control->new(type => CTRL_FILE_STATUS))
+ && $ctrl->parse(\*STATUS, '/var/lib/dpkg/status')) {
+ if ($ctrl->{Status} !~ /^install\s+ok\s+installed$/) {
+ next;
+ }
+ if ($source) {
+ if (exists $ctrl->{Source}) {
+ $matches{$ctrl->{Source}} = 1;
+ }
+ }
+ if (exists $ctrl->{Package}) {
+ $matches{$ctrl->{Package}} = 1;
+ }
+ undef $ctrl;
+ }
- close PKG or croak("Problem reading grep pipe: $!");
+ close STATUS or croak("Problem reading /var/lib/dpkg/status: $!");
return \%matches;
}
diff --git a/debian/changelog b/debian/changelog
index 456b283..6b1fa13 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -15,6 +15,8 @@ devscripts (2.11.10) UNRELEASED; urgency=low
with the stringified version of a file glob. (Closes: #678193)
* rc-alert: Unset wget's continue option to ensure the bug list is properly
downloaded. (Closes: #677229)
+ * Devscripts/Packages.pm, Devscripts/PackageDeps.pm: Parse dpkg's status
+ file using Dpkg::Control.
-- Benjamin Drung <bdrung at debian.org> Sun, 17 Jun 2012 23:33:41 +0200
--
Git repository for devscripts
More information about the devscripts-devel
mailing list