Subject: [PATCH] Add support for checking multiple, comma-separated, sections

From: Raphael Geissert <[email-masked]>
Date: Sun, 22 Feb 2009 17:11:38 -0600

---
 man/lintian.1          |    5 +-
 reporting/html_reports |    2 +-
 unpack/list-binpkg     |  159 +++++++++++++++++++++++----------------------
 unpack/list-srcpkg     |  164 ++++++++++++++++++++++++-----------------------
 unpack/list-udebpkg    |  167 +++++++++++++++++++++++++-----------------------
 5 files changed, 256 insertions(+), 241 deletions(-)

diff --git a/man/lintian.1 b/man/lintian.1
index 49bb48e..4b4e791 100644
--- a/man/lintian.1
+++ b/man/lintian.1
@@ -287,13 +287,14 @@ environment variable and the configuration file entry of the same
 name.
 
 .TP
-.BR \-\-section " release"
+.BR \-\-section " release[,release[,...]]"
 When scanning for packages in the distdir, select only packages from
-section
+section(s)
 .IR section
 (e.g. main). This option overrides the
 .B LINTIAN_SECTION
 environment variable and the configuration file entry of the same name.
+Multiple sections can be specified by separating them with a comma.
 
 .TP
 .BR \-\-arch " arch"
diff --git a/reporting/html_reports b/reporting/html_reports
index 7c67d24..a0928c3 100755
--- a/reporting/html_reports
+++ b/reporting/html_reports
@@ -517,7 +517,7 @@ close STATS or die "cannot write to $statistics_file: $!\n";
     dist         => $LINTIAN_DIST,
     mirror       => $mirror_timestamp,
     previous     => $old_statistics->{'last-updated'},
-    section      => $LINTIAN_SECTION,
+    section      => join(', ', glob("{$LINTIAN_SECTION}")),
 );
 output_template ('index.html', $templates{index}, \%data);
 exit 0;
diff --git a/unpack/list-binpkg b/unpack/list-binpkg
index 9b84789..10e47c5 100755
--- a/unpack/list-binpkg
+++ b/unpack/list-binpkg
@@ -85,96 +85,101 @@ open(OUT, '>', $output_file)
 print OUT "$BINLIST_FORMAT\n";
 
 # parse Packages file to get list of packages
-my $packages = "$LINTIAN_ARCHIVEDIR/dists/$LINTIAN_DIST/$LINTIAN_SECTION/".
-               "binary-$LINTIAN_ARCH/Packages";
-if (-e $packages) {
-	print "N: Parsing $packages ...\n" if $verbose;
-	open(IN, '<', $packages) or fail("cannot open Packages file $packages: $!");
-} elsif (-e "$packages.gz") {
-	print "N: Parsing $packages.gz ...\n" if $verbose;
-	open (IN, '-|', 'gzip', '-dc', "$packages.gz")
-	    or fail("cannot open Packages file $packages.gz: $!");
-} else {
-	fail("No packages file $packages");
-}
+my @packages = glob("$LINTIAN_ARCHIVEDIR/dists/$LINTIAN_DIST/{$LINTIAN_SECTION}/".
+               "binary-$LINTIAN_ARCH/Packages");
 
-my $line;
 my %packages;
 my $total = 0;
 
-while (!eof(IN)) {
-    do { $line = <IN> } until ($line =~ m/^Architecture: (.*)$/m);
-    my $arch = $1;
-    do { $line = <IN> } until ($line =~ m/^Filename: (.*)$/m);
-    my $deb_file = $1;
-    do { $line = <IN> } until ($line =~ m/^\s*$/m);
-
-    my @stat;
-    # get timestamp...
-    unless (@stat = stat "$LINTIAN_ARCHIVEDIR/$deb_file") {
-	print "E: general: cannot stat $LINTIAN_ARCHIVEDIR/$deb_file\n";
-	next;
-    }
-    my $timestamp = $stat[9];
-    my ($status, $pkg, $data);
-
-    # was package already included in last list?
-    if (exists $pkgfile{$deb_file}) {
-	# yes!
-	$pkg = $pkgfile{$deb_file};
-	$data = $binary_info{$pkg};
-
-	# file changed since last run?
-	if ($timestamp == $data->{'timestamp'}) {
-	    # no.
-	    $status = 'unchanged';
-	} else {
-	    $status = 'changed';
-	    delete $binary_info{$pkg};
-	}
+foreach my $packages (@packages) {
+    if (-e $packages) {
+	    print "N: Parsing $packages ...\n" if $verbose;
+	    open(IN, '<', $packages) or fail("cannot open Packages file $packages: $!");
+    } elsif (-e "$packages.gz") {
+	    print "N: Parsing $packages.gz ...\n" if $verbose;
+	    open (IN, '-|', 'gzip', '-dc', "$packages.gz")
+		or fail("cannot open Packages file $packages.gz: $!");
     } else {
-	# new package, get info
-	$status = 'new';
+	    fail("No packages file $packages");
     }
 
-    if (($status eq 'new') or ($status eq 'changed')) {
-	$data = &safe_get_deb_info($deb_file);
-	next if not defined $data;
-	$pkg = $data->{'package'};
-    }
+    my $line;
 
-    # check for duplicates
-    if (exists $packages{$pkg}) {
-	print "E: general: duplicate-binary-package $pkg\n";
-	next;
-    }
+    while (!eof(IN)) {
+	do { $line = <IN> } until ($line =~ m/^Architecture: (.*)$/m);
+	my $arch = $1;
+	do { $line = <IN> } until ($line =~ m/^Filename: (.*)$/m);
+	my $deb_file = $1;
+	do { $line = <IN> } until ($line =~ m/^\s*$/m);
 
-    unless (exists $data->{'source-version'}) {
-	if ($data->{'source'} =~ /^([-+\.\w]+)\s+\((.+)\)$/) {
-	    $data->{'source'} = $1;
-	    $data->{'source-version'} = $2;
+	my @stat;
+	# get timestamp...
+	unless (@stat = stat "$LINTIAN_ARCHIVEDIR/$deb_file") {
+	    print "E: general: cannot stat $LINTIAN_ARCHIVEDIR/$deb_file\n";
+	    next;
+	}
+	my $timestamp = $stat[9];
+	my ($status, $pkg, $data);
+
+	# was package already included in last list?
+	if (exists $pkgfile{$deb_file}) {
+	    # yes!
+	    $pkg = $pkgfile{$deb_file};
+	    $data = $binary_info{$pkg};
+
+	    # file changed since last run?
+	    if ($timestamp == $data->{'timestamp'}) {
+		# no.
+		$status = 'unchanged';
+	    } else {
+		$status = 'changed';
+		delete $binary_info{$pkg};
+	    }
 	} else {
-	    $data->{'source-version'} = $data->{'version'};
+	    # new package, get info
+	    $status = 'new';
 	}
-    }
 
-    # write entry to output file
-    print OUT join(';',
-		   $pkg,
-		   $data->{'version'},
-		   $data->{'source'},
-		   $data->{'source-version'},
-		   $deb_file,
-		   $timestamp,
-		   ),"\n";
-    printf "N: Listed %s binary package %s %s\n",$status,$pkg,$data->{'version'} if $verbose;
-
-    # remove record from hash
-    delete $binary_info{$pkg} if $status eq 'unchanged';
-    $packages{$pkg} = 1;
-    $total++;
+	if (($status eq 'new') or ($status eq 'changed')) {
+	    $data = &safe_get_deb_info($deb_file);
+	    next if not defined $data;
+	    $pkg = $data->{'package'};
+	}
+
+	# check for duplicates
+	if (exists $packages{$pkg}) {
+	    print "E: general: duplicate-binary-package $pkg\n";
+	    next;
+	}
+
+	unless (exists $data->{'source-version'}) {
+	    if ($data->{'source'} =~ /^([-+\.\w]+)\s+\((.+)\)$/) {
+		$data->{'source'} = $1;
+		$data->{'source-version'} = $2;
+	    } else {
+		$data->{'source-version'} = $data->{'version'};
+	    }
+	}
+
+	# write entry to output file
+	print OUT join(';',
+		       $pkg,
+		       $data->{'version'},
+		       $data->{'source'},
+		       $data->{'source-version'},
+		       $deb_file,
+		       $timestamp,
+		       ),"\n";
+	printf "N: Listed %s binary package %s %s\n",$status,$pkg,$data->{'version'} if $verbose;
+
+	# remove record from hash
+	delete $binary_info{$pkg} if $status eq 'unchanged';
+	$packages{$pkg} = 1;
+	$total++;
+    }
+    close(IN) or fail("cannot close input pipe: $!");
 }
-close(IN) or fail("cannot close input pipe: $!");
+
 close(OUT) or fail("cannot close output pipe: $!");
 
 if ($verbose) {
diff --git a/unpack/list-srcpkg b/unpack/list-srcpkg
index 9564f69..a1416e4 100755
--- a/unpack/list-srcpkg
+++ b/unpack/list-srcpkg
@@ -82,101 +82,105 @@ open(OUT, '>', $output_file) or fail("cannot open list file $output_file for wri
 print OUT "$SRCLIST_FORMAT\n";
 
 # parse Sources.gz to get list of packages
-my $sources = "$LINTIAN_ARCHIVEDIR/dists/$LINTIAN_DIST/$LINTIAN_SECTION/source/Sources.gz";
-print "N: Parsing $sources ...\n" if $verbose;
-open(IN, '-|', 'zcat', $sources) or fail("Cannot open input pipe from zcat $sources: $!");
+my @sources = glob("$LINTIAN_ARCHIVEDIR/dists/$LINTIAN_DIST/{$LINTIAN_SECTION}/source/Sources.gz");
 
-my $line;
 my %packages;
 my $total = 0;
 
-while (!eof(IN)) {
-  do { $line = <IN> } until ($line =~ m/^Directory: (.*)$/m);
-  my $pkg_dir = $1;
-  do { $line = <IN> } until ($line =~ m/^ [0-9a-f]{32} [0-9]+ (.+\.dsc)$/m);
-  my $dsc_file = "$pkg_dir/$1";
-  do { $line = <IN> } until ($line =~ m/^\s*$/m);
-
-  my @stat;
-  # get timestamp...
-  unless (@stat = stat "$LINTIAN_ARCHIVEDIR/$dsc_file") {
-    warn "E: general: cannot stat file $LINTIAN_ARCHIVEDIR/$dsc_file: $!\n";
-    next;
-  }
-  my $timestamp = $stat[9];
+foreach my $sources (@sources) {
+  print "N: Parsing $sources ...\n" if $verbose;
+  open(IN, '-|', 'zcat', $sources) or fail("Cannot open input pipe from zcat $sources: $!");
 
-  my ($status,$pkg,$data);
+  my $line;
 
-  # was package already included in last list?
-  if (exists $pkgfile{$dsc_file}) {
-    # yes!
-    $pkg = $pkgfile{$dsc_file};
-    $data = $source_info{$pkg};
+  while (!eof(IN)) {
+    do { $line = <IN> } until ($line =~ m/^Directory: (.*)$/m);
+    my $pkg_dir = $1;
+    do { $line = <IN> } until ($line =~ m/^ [0-9a-f]{32} [0-9]+ (.+\.dsc)$/m);
+    my $dsc_file = "$pkg_dir/$1";
+    do { $line = <IN> } until ($line =~ m/^\s*$/m);
 
-    # file changed since last run?
-    if ($timestamp == $data->{'timestamp'}) {
-      # no.
-      $status = 'unchanged';
+    my @stat;
+    # get timestamp...
+    unless (@stat = stat "$LINTIAN_ARCHIVEDIR/$dsc_file") {
+      warn "E: general: cannot stat file $LINTIAN_ARCHIVEDIR/$dsc_file: $!\n";
+      next;
+    }
+    my $timestamp = $stat[9];
+
+    my ($status,$pkg,$data);
+
+    # was package already included in last list?
+    if (exists $pkgfile{$dsc_file}) {
+      # yes!
+      $pkg = $pkgfile{$dsc_file};
+      $data = $source_info{$pkg};
+
+      # file changed since last run?
+      if ($timestamp == $data->{'timestamp'}) {
+        # no.
+        $status = 'unchanged';
+      } else {
+        $status = 'changed';
+        delete $source_info{$pkg};
+      }
     } else {
-      $status = 'changed';
-      delete $source_info{$pkg};
+      # new package, get info
+      $status = 'new';
     }
-  } else {
-    # new package, get info
-    $status = 'new';
-  }
 
-  if (($status eq 'new') or ($status eq 'changed')) {
-    # use eval when calling get_dsc_info, since we don't want to `die' just
-    # because of a single broken package
-    eval { $data = get_dsc_info("$LINTIAN_ARCHIVEDIR/$dsc_file"); };
-    if ($@) {
-      # error!
-      print STDERR "$@\n";
-      print "E: general: bad-source-package $dsc_file\n";
-      next;
+    if (($status eq 'new') or ($status eq 'changed')) {
+      # use eval when calling get_dsc_info, since we don't want to `die' just
+      # because of a single broken package
+      eval { $data = get_dsc_info("$LINTIAN_ARCHIVEDIR/$dsc_file"); };
+      if ($@) {
+        # error!
+        print STDERR "$@\n";
+        print "E: general: bad-source-package $dsc_file\n";
+        next;
+      }
+      my @f = ();
+      for my $fs (split(/\n/,$data->{'files'})) {
+        next if $fs =~ /^\s*$/o;
+        my @t = split(/\s+/o,$fs);
+        push(@f,$t[2]);
+      }
+      $data->{'files'} = join(',',@f);
+      $data->{'standards-version'} ||= "";
+      $pkg = $data->{'source'};
     }
-    my @f = (); 
-    for my $fs (split(/\n/,$data->{'files'})) {
-      next if $fs =~ /^\s*$/o;
-      my @t = split(/\s+/o,$fs);
-      push(@f,$t[2]);
-    }
-    $data->{'files'} = join(',',@f);
-    $data->{'standards-version'} ||= "";
-    $pkg = $data->{'source'};
-  }
 
-  # check for duplicates
-  if (exists $packages{$pkg}) {
-    print "E: general: duplicate-source-package $pkg\n";
-    next;
-  }
+    # check for duplicates
+    if (exists $packages{$pkg}) {
+      print "E: general: duplicate-source-package $pkg\n";
+      next;
+    }
 
-  # write entry to output file
-  for (qw/version maintainer uploaders architecture standards-version binary files/) {
-    $data->{$_} =~ tr/;\n/_ / if $data->{$_};
+    # write entry to output file
+    for (qw/version maintainer uploaders architecture standards-version binary files/) {
+      $data->{$_} =~ tr/;\n/_ / if $data->{$_};
+    }
+    print OUT join(';',
+                  $pkg,
+                  $data->{'version'},
+                  $data->{'maintainer'},
+                  $data->{'uploaders'} || '',
+                  $data->{'architecture'},
+                  $data->{'standards-version'},
+                  $data->{'binary'},
+                  $data->{'files'},
+                  $dsc_file,
+                  $timestamp,
+                  ),"\n";
+    printf "N: Listed %s source package %s %s\n",$status,$pkg,$data->{'version'} if $verbose;
+
+    # remove record from hash
+    delete $source_info{$pkg} if $status eq 'unchanged';
+    $packages{$pkg} = 1;
+    $total++;
   }
-  print OUT join(';',
-		 $pkg,
-		 $data->{'version'},
-		 $data->{'maintainer'},
-                 $data->{'uploaders'} || '',
-                 $data->{'architecture'},
-                 $data->{'standards-version'},
-                 $data->{'binary'},
-                 $data->{'files'},
-                 $dsc_file,
-		 $timestamp,
-		 ),"\n";
-  printf "N: Listed %s source package %s %s\n",$status,$pkg,$data->{'version'} if $verbose;
-
-  # remove record from hash
-  delete $source_info{$pkg} if $status eq 'unchanged';
-  $packages{$pkg} = 1;
-  $total++;
+  close(IN) or fail("cannot close input pipe: $!");
 }
-close(IN) or fail("cannot close input pipe: $!");
 close(OUT) or fail("cannot close output pipe: $!");
 
 if ($verbose) {
diff --git a/unpack/list-udebpkg b/unpack/list-udebpkg
index 42c99fe..992822f 100755
--- a/unpack/list-udebpkg
+++ b/unpack/list-udebpkg
@@ -86,96 +86,101 @@ open(OUT, '>', $output_file)
 print OUT "$UDEBLIST_FORMAT\n";
 
 # parse Packages file to get list of packages
-my $packages = "$LINTIAN_ARCHIVEDIR/dists/$LINTIAN_DIST/$LINTIAN_SECTION/".
-               "debian-installer/binary-$LINTIAN_ARCH/Packages";
-if (-e $packages) {
-    print "N: Parsing $packages ...\n" if $verbose;
-    open(IN, '<', $packages) or fail("cannot open Packages file $packages: $!");
-} elsif (-e "$packages.gz") {
-    print "N: Parsing $packages.gz ...\n" if $verbose;
-    open(IN, '-|', 'gzip', '-dc', "$packages.gz")
-        or fail("cannot open Packages file $packages.gz: $!");
-} else {
-    fail("No packages file $packages");
-}
+my @packages = glob("$LINTIAN_ARCHIVEDIR/dists/$LINTIAN_DIST/{$LINTIAN_SECTION}/".
+               "debian-installer/binary-$LINTIAN_ARCH/Packages");
 
-my $line;
 my %packages;
 my $total = 0;
 
-while (!eof(IN)) {
-    do { $line = <IN> } until ($line =~ m/^Architecture: (.*)$/m);
-    my $arch = $1;
-    do { $line = <IN> } until ($line =~ m/^Filename: (.*)$/m);
-    my $deb_file = $1;
-    do { $line = <IN> } until ($line =~ m/^\s*$/m);
-
-    my @stat;
-    # get timestamp...
-    unless (@stat = stat "$LINTIAN_ARCHIVEDIR/$deb_file") {
-	print "E: general: cannot stat $LINTIAN_ARCHIVEDIR/$deb_file\n";
-	next;
-    }
-    my $timestamp = $stat[9];
-    my ($status, $pkg, $data);
-
-    # was package already included in last list?
-    if (exists $pkgfile{$deb_file}) {
-	# yes!
-	$pkg = $pkgfile{$deb_file};
-	$data = $udeb_info{$pkg};
-
-	# file changed since last run?
-	if ($timestamp == $data->{'timestamp'}) {
-	    # no.
-	    $status = 'unchanged';
-	} else {
-	    $status = 'changed';
-	    delete $udeb_info{$pkg};
-	}
+foreach my $packages (@packages) {
+    if (-e $packages) {
+        print "N: Parsing $packages ...\n" if $verbose;
+        open(IN, '<', $packages) or fail("cannot open Packages file $packages: $!");
+    } elsif (-e "$packages.gz") {
+        print "N: Parsing $packages.gz ...\n" if $verbose;
+         open(IN, '-|', 'gzip', '-dc', "$packages.gz")
+            or fail("cannot open Packages file $packages.gz: $!");
     } else {
-	# new package, get info
-	$status = 'new';
-    }
-
-    if (($status eq 'new') or ($status eq 'changed')) {
-	$data = &safe_get_deb_info($deb_file);
-	next if not defined $data;
-	$pkg = $data->{'package'};
+        warn("No packages file $packages, skipping");
+        next;
     }
 
-    # check for duplicates
-    if (exists $packages{$pkg}) {
-	print "E: general: duplicate-udeb-package $pkg\n";
-	next;
+    my $line;
+
+    while (!eof(IN)) {
+        do { $line = <IN> } until ($line =~ m/^Architecture: (.*)$/m);
+        my $arch = $1;
+        do { $line = <IN> } until ($line =~ m/^Filename: (.*)$/m);
+        my $deb_file = $1;
+        do { $line = <IN> } until ($line =~ m/^\s*$/m);
+
+        my @stat;
+        # get timestamp...
+        unless (@stat = stat "$LINTIAN_ARCHIVEDIR/$deb_file") {
+	    print "E: general: cannot stat $LINTIAN_ARCHIVEDIR/$deb_file\n";
+	    next;
+        }
+        my $timestamp = $stat[9];
+        my ($status, $pkg, $data);
+
+        # was package already included in last list?
+        if (exists $pkgfile{$deb_file}) {
+	    # yes!
+	    $pkg = $pkgfile{$deb_file};
+	    $data = $udeb_info{$pkg};
+
+	    # file changed since last run?
+	    if ($timestamp == $data->{'timestamp'}) {
+	        # no.
+	        $status = 'unchanged';
+	    } else {
+	        $status = 'changed';
+	        delete $udeb_info{$pkg};
+	    }
+        } else {
+	    # new package, get info
+	    $status = 'new';
+        }
+
+        if (($status eq 'new') or ($status eq 'changed')) {
+	    $data = &safe_get_deb_info($deb_file);
+	    next if not defined $data;
+	    $pkg = $data->{'package'};
+        }
+
+        # check for duplicates
+        if (exists $packages{$pkg}) {
+	    print "E: general: duplicate-udeb-package $pkg\n";
+	    next;
+        }
+
+         unless (exists $data->{'source-version'}) {
+	    if ($data->{'source'} =~ /^([-+\.\w]+)\s+\((.+)\)$/) {
+	        $data->{'source'} = $1;
+	        $data->{'source-version'} = $2;
+	    } else {
+	        $data->{'source-version'} = $data->{'version'};
+	    }
+        }
+
+        # write entry to output file
+        print OUT join(';',
+		       $pkg,
+		       $data->{'version'},
+		       $data->{'source'},
+		       $data->{'source-version'},
+		       $deb_file,
+		       $timestamp,
+		       ),"\n";
+        printf "N: Listed %s udeb package %s %s\n",$status,$pkg,$data->{'version'} if $verbose;
+
+        # remove record from hash
+        delete $udeb_info{$pkg} if $status eq 'unchanged';
+        $packages{$pkg} = 1;
+        $total++;
     }
-
-    unless (exists $data->{'source-version'}) {
-	if ($data->{'source'} =~ /^([-+\.\w]+)\s+\((.+)\)$/) {
-	    $data->{'source'} = $1;
-	    $data->{'source-version'} = $2;
-	} else {
-	    $data->{'source-version'} = $data->{'version'};
-	}
-    }
-
-    # write entry to output file
-    print OUT join(';',
-		   $pkg,
-		   $data->{'version'},
-		   $data->{'source'},
-		   $data->{'source-version'},
-		   $deb_file,
-		   $timestamp,
-		   ),"\n";
-    printf "N: Listed %s udeb package %s %s\n",$status,$pkg,$data->{'version'} if $verbose;
-
-    # remove record from hash
-    delete $udeb_info{$pkg} if $status eq 'unchanged';
-    $packages{$pkg} = 1;
-    $total++;
+    close(IN) or fail("cannot close input pipe: $!");
 }
-close(IN) or fail("cannot close input pipe: $!");
 close(OUT) or fail("cannot close output pipe: $!");
 
 if ($verbose) {