Package: devscripts
Version: 2.9.21
Severity: wishlist

Hi, 

I have written a new script that I think would be good for inclusion in
devscripts.

I'm not sure about the name, and perhaps it should be folded in to
debdiff itself, but this felt more natural.

It is a wrapper around debdiff that runs it for all binary packages
built from a source package, comparing the most recent version to the
previous. 

It attempts to get as much information as possible from files. It can be
run from an unpacked source dir, in which it read debian/control and
debian/changelog to get the packages and versions. The alternative is to
run it with a .changes file as an argument, in which case the old
version must be provided, as it is not in the file.

It first build a list of packages, and then downloads the packages it
needs using aptitude, then compares each in turn. If you already have
the binary packages on your system you can poit it to their location to
save that step.

I think it is worth including as it works out versions an packages from
the information that is already there. It also downloads any packages
that it needs, saving another manual step.

I use it after a pbuilder run, so I do

  $ pdebuild
  $ checkdiffs --new-dir /path/to/pbuilder/result/dir

making it very easy to use debdiff, and so try and eliminate mistakes
like files going missing between versions.

Please consider including it,

Thanks,

James
diff -Nru devscripts-2.9.21/checkdiffs.1 devscripts-2.9.22/checkdiffs.1
--- devscripts-2.9.21/checkdiffs.1      1970-01-01 01:00:00.000000000 +0100
+++ devscripts-2.9.22/checkdiffs.1      2006-09-23 17:25:19.000000000 +0100
@@ -0,0 +1,38 @@
+.TH USCAN 1 "Debian Utilities" "DEBIAN" \" -*- nroff -*-
+.SH NAME
+checkdiffs \- run debdiff for all binary packages built from the same source
+.SH SYNOPSIS
+\fBcheckdiffs\fR [\fI--new-dir path\fR] [\fI--old-dir path\fR] 
+           [\fI--old-version version\fR] [\fI--new-version version\fR]
+           [ .changes ]
+.SH DESCRIPTION
+\fBcheckdiffs\fR runs debdiff for each binary package built from a source 
+package, comparing the current version to the previous. It can either work
+from an unpacked source directory or from a .changes file. If a .changes file
+is used the --old-version option must be used, as the .changes file doesn't 
+contain this information.
+.PP
+If the directory options aren't given then aptitude will be used to retrieve
+the versions of the packages that are required.
+.SH OPTIONS
+.TP
+.B \-\-new\-version version
+The version number to use for the newer version to compare.
+.TP
+.B \-\-old\-version version
+The version number to use for the old version of the packages to compare.
+.TP
+.B \-\-new\-dir
+The directory where the .debs for the new versions of the package are. All the 
+required .debs should be in the root of this directory.
+.TP
+.B \-\-old\-dir
+Same as \-\-new\-dir but for the old versions of the packages.
+
+.SH SEE ALSO
+.BR aptitude (8),
+.BR debdiff (1),
+.SH AUTHOR
+Both checkdiffs and this manpage were written by James Westby. They are both
+(C) 2006 James Westby <[EMAIL PROTECTED]>, and are licensed under the
+GPL v2 or later.
diff -Nru devscripts-2.9.21/checkdiffs.pl devscripts-2.9.22/checkdiffs.pl
--- devscripts-2.9.21/checkdiffs.pl     1970-01-01 01:00:00.000000000 +0100
+++ devscripts-2.9.22/checkdiffs.pl     2006-09-23 17:15:51.000000000 +0100
@@ -0,0 +1,359 @@
+#!/usr/bin/perl -w
+# 
+# Copyright (C) 2006 James Westby <[EMAIL PROTECTED]>
+#
+# This program 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 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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 this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+use strict;
+
+use File::Temp qw/ tempdir /;
+use Getopt::Long;
+use Cwd;
+
+#====================================
+
+sub usage() {
+  
+  print <<ENDUSAGE
+  Usage: $0 [ --new-dir dir ] [ --old-dir dir ] 
+            [ --old-version version ] [ --new-version version ] [ .changes ]
+    where the dirs are directories containing the necessary debs
+           if only one or neither of the paths are given then the
+           script will use aptitude to download the required debs. 
+    You can specify the versions to compare using the --new-version and 
+    --old-version arguments. The default is to compare the most recent revision
+    with the previous.
+    you can either run from within an unpacked source directory, or pass the
+    .changes file as an argument. If the .changes file is used the 
+    --old-version argument must be used.
+ENDUSAGE
+} 
+
+sub temp_dir() {
+
+  my $temp_dir = tempdir( "checkdiffs.XXXXXXXX" , DIR => File::Spec->tmpdir());
+  die "Could not create temp dir" unless $temp_dir;
+  return $temp_dir;
+
+}
+
+sub test_dir() {
+
+  if (! -r "debian/control") {
+    print STDERR "No debian/control, cannot find packages.\n";
+    exit 1;
+  }
+
+}
+
+sub get_packages_changelog() {
+
+  open(CONTROL, '<', "debian/control");
+
+  my $package;
+  my (@archdep, @archindep);
+
+  while(<CONTROL>) {
+
+    my $line = $_;
+
+    chomp $line;
+
+    if ( $line =~ m/Package: (.*)/ ) {
+      close CONTROL if $package;
+      die "Unable to parse debian/control" if $package;
+      $package = $1;
+    }
+
+    if ( $line =~ m/Architecture: (.*)/ ) {
+      if ( $1 =~ m/all/ ) {
+        push (@archindep, $package);
+      } else {
+        push (@archdep, $package);
+      }
+      undef $package;  
+    }
+
+  }
+
+  close CONTROL;
+  
+  return ([EMAIL PROTECTED], [EMAIL PROTECTED]);
+}
+
+sub get_packages_changes($) {
+  my $changes = shift;
+
+  open(CHANGE, '<', $changes);
+
+  my (@archdep, @archindep);
+
+  while(<CHANGE>) {
+    
+    if (/^ [0-9a-f]+ [0-9]+ [a-z]+ [a-z]+ ([-a-z_0-9~.:+]+)$/) {
+      my $deb = $1;
+
+      if ($deb =~ /^([^_]+)_[-0-9a-z.:~+]+_([a-z0-9]+)\.deb$/) {
+        my $package = $1;
+        my $arch = $2;
+        if ($arch eq "all") {
+          push @archindep, $package;
+        } else {
+          push @archdep, $package;
+        }
+      }
+    }
+  }
+  close CHANGE;
+
+  return ([EMAIL PROTECTED], [EMAIL PROTECTED]);
+}
+
+sub get_versions_changelog() {
+
+  if ( ! -r "debian/changelog" ) {
+    print STDERR "No debian/changelog, cannot get versions.\n";
+    exit 1;
+  }
+
+  open(CHANGE, '<', "debian/changelog");
+
+  my ($new, $old);
+
+  while (<CHANGE>) {
+    
+    my $line = $_;
+
+    if ($line =~ m/.*\((.*)\).*;.*=.*/) {
+      my $rel = $1;
+      if ( ! defined $new ) {
+        $new = $rel;
+      } else {
+        $old = $rel;
+        last;
+      }
+    }
+    
+  }
+
+  close(CHANGE);
+
+  if (! defined $new || ! defined $old) {
+    die "Unable to parse versions from debian/changelog, maybe this is a new 
package."
+  }
+  
+  return ($new, $old);
+}
+
+sub get_versions_changes($) {
+
+  my $changes = shift;
+
+  my $version;
+
+  open(CHANGE, '<', $changes);
+
+  while (<CHANGE>) {
+
+    if (/^Version: (.*)$/) {
+      $version = $1;
+    }
+
+  }
+
+  close CHANGE;
+
+  return $version;
+
+}
+
+sub get_arch() {
+
+  open (ARCH, "dpkg-architecture -qDEB_BUILD_ARCH |");
+
+  my $arch = <ARCH>;
+
+  close ARCH;
+
+  chomp $arch;
+
+  return $arch;
+  
+}
+
+sub deb_name {
+
+  my $package = shift;
+  my $version = shift;
+  my $arch = shift;
+
+  return $package."_".$version."_".$arch.".deb";
+
+}
+
+sub download_packages {
+
+  my $packages = shift;
+  my $version = shift;
+  my $dir = shift;
+
+  chdir $dir;
+
+  my $all = "";
+  foreach my $p (@$packages) {
+    $all .= $p."=$version ";
+  }
+  
+  system("aptitude download $all");
+}
+
+sub process_packages {
+
+  my $packages = shift;
+  my $arch = shift;
+  my $oldver = shift;
+  my $newver = shift;
+  my $olddir = shift;
+  my $newdir = shift;
+
+  foreach my $package (@$packages) { 
+    my $olddeb = deb_name($package, $oldver, $arch);
+    my $newdeb = deb_name($package, $newver, $arch);
+
+    my $error = 0;
+
+    foreach my $deb ( "$olddir/$olddeb", "$newdir/$newdeb" ) {
+
+      if ( ! -f "$deb" ) {
+        print STDERR "$deb does not exist, either there was a problem, or an 
assumption failed (maybe it is a new package) ".`pwd`."\n";
+        $error = 1;
+      }
+    }
+
+    last if $error;
+
+    print "Differences in $package between $oldver and $newver\n";
+
+    system("debdiff $olddir/$olddeb $newdir/$newdeb");
+    
+  }
+}
+
+#==================================================
+
+my $olddir;
+my $newdir;
+my $oldver;
+my $newver;
+my $help;
+
+my $result = GetOptions ("help"  => \$help, 
+                         "old-version=s" => \$oldver,
+                         "new-version=s" => \$newver,
+                         "old-dir=s" => \$olddir,
+                         "new-dir=s" => \$newdir);
+
+if ( $help ) {
+  usage;
+  exit;
+}
+
+my $changes = shift;
+
+if (defined $changes) {
+  if ( ! -f $changes ) {
+    print STDERR "$changes doesn't exist.\n";
+    exit 1;
+  }
+  if (! defined $oldver) {
+    print STDERR ",changes file given, but --old-version not provided.\n";
+    exit 1;
+  }
+}
+
+foreach my $dir ( $olddir, $newdir ) {
+  if ( $dir && ! -d $dir ) {
+     print STDERR "$dir is not a directory\n";
+     exit 1;
+  }
+  if ( $dir && $dir !~ /^\// ) {
+    $dir = cwd."/".$dir;
+  }
+}
+
+my ($archdep, $archindep);
+my @allpackages;
+
+my ($tempnew, $tempold);
+
+if (! defined $changes) {
+
+  test_dir();
+
+  ($archdep, $archindep) = get_packages_changelog();
+
+  if ( ! defined $newver || ! defined $oldver ) {
+
+    ($tempnew, $tempold) = get_versions_changelog();
+
+  }
+
+} else {
+
+  ($archdep, $archindep) = get_packages_changes($changes);
+
+  if ( ! defined $newver ) {
+
+    $tempnew = get_versions_changes($changes);
+
+  }
+
+}
+
+if ( ! defined $newver ) {
+  $newver = $tempnew;
+}
+
+if ( ! defined $oldver ) {
+  $oldver = $tempold;
+}
+
[EMAIL PROTECTED] = (@$archdep, @$archindep);
+
+my $arch = get_arch();
+
+my $tmpdir;
+
+if ( ! defined $olddir || ! defined $newdir ) {
+  $tmpdir = temp_dir();
+}
+
+if ( ! defined $olddir ) {
+  download_packages([EMAIL PROTECTED], $oldver, $tmpdir);
+  $olddir = $tmpdir;
+} 
+
+if ( ! defined $newdir ) {
+  download_packages([EMAIL PROTECTED], $newver, $tmpdir);
+  $newdir = $tmpdir;
+}
+
+process_packages($archdep, $arch, $oldver, $newver, $olddir, $newdir);
+process_packages($archindep, "all", $oldver, $newver, $olddir, $newdir);
+
+system("rm -rf $tmpdir") if (defined $tmpdir && -d $tmpdir);
+
+exit 0
+
diff -Nru devscripts-2.9.21/debian/changelog devscripts-2.9.22/debian/changelog
--- devscripts-2.9.21/debian/changelog  2006-08-29 11:35:12.000000000 +0100
+++ devscripts-2.9.22/debian/changelog  2006-09-23 17:31:45.000000000 +0100
@@ -1,3 +1,10 @@
+devscripts (2.9.22) unstable; urgency=low
+
+  * Add checkdiffs script for automating debdiff somewhat. Contributed by
+    James Wesbty <[EMAIL PROTECTED]>.
+
+ -- James Westby <[EMAIL PROTECTED]>  Sat, 23 Sep 2006 17:31:06 +0100
+
 devscripts (2.9.21) unstable; urgency=low
 
   * bts: reportspam/spamreport can now take multiple bug numbers
diff -Nru devscripts-2.9.21/debian/control devscripts-2.9.22/debian/control
--- devscripts-2.9.21/debian/control    2006-08-29 11:34:48.000000000 +0100
+++ devscripts-2.9.22/debian/control    2006-09-23 17:28:46.000000000 +0100
@@ -11,7 +11,7 @@
 Conflicts: debmake (<< 3.5), dupload (<< 2.1), suidmanager (<< 0.51)
 Depends: dpkg-dev, debianutils (>= 2.0), perl (>= 5.8), sed (>= 2.95), 
${shlibs:Depends}, ${misc:Depends}
 Recommends: fakeroot
-Suggests: devscripts-el, at, build-essential, cvs-buildpackage, cvs | 
subversion | tla | bazaar, debian-keyring, dupload (>=2.1) | dput, gnupg (>= 
1.0.7), gnuplot, libdigest-md5-perl, libtimedate-perl, libwww-perl, lintian | 
linda, mailx | mailutils, mutt, patch, patchutils, ssh, strace, wdiff, wget, 
www-browser
+Suggests: devscripts-el, at, build-essential, cvs-buildpackage, cvs | 
subversion | tla | bazaar, debian-keyring, dupload (>=2.1) | dput, gnupg (>= 
1.0.7), gnuplot, libdigest-md5-perl, libtimedate-perl, libwww-perl, lintian | 
linda, mailx | mailutils, mutt, patch, patchutils, ssh, strace, wdiff, wget, 
www-browser, aptitude
 Description: Scripts to make the life of a Debian Package maintainer easier
  Contains the following scripts, dependencies/recommendations shown in
  brackets afterwards:
@@ -22,6 +22,8 @@
       libwww-perl, mailx | mailutils]
   - checkbashisms: check whether a /bin/sh script contains any common
       bash-specific contructs
+  - checkdiffs: run debdiff for all binary packages created from a source 
+      package, comparing the latest version to the previous.
   - cvs-debi, cvs-debc: to call debi and debc from the CVS working directory
       after running cvs-debuild or cvs-buildpackage [cvs-buildpackage]
   - cvs-debrelease: to call debrelease from the CVS working directory
diff -Nru devscripts-2.9.21/Makefile devscripts-2.9.22/Makefile
--- devscripts-2.9.21/Makefile  2006-03-31 18:27:59.000000000 +0100
+++ devscripts-2.9.22/Makefile  2006-09-23 17:29:27.000000000 +0100
@@ -1,7 +1,7 @@
 # Simplified Makefile for devscripts
 
-PL_FILES = bts.pl checkbashisms.pl cvs-debuild.pl dd-list.pl debchange.pl \
-       debcommit.pl debdiff.pl debi.pl debpkg.pl debuild.pl dget.pl \
+PL_FILES = bts.pl checkbashisms.pl checkdiffs.pl cvs-debuild.pl dd-list.pl \
+       debchange.pl debcommit.pl debdiff.pl debi.pl debpkg.pl debuild.pl 
dget.pl \
        dpkg-depcheck.pl dscverify.pl grep-excuses.pl mass-bug.pl \
        plotchangelog.pl rc-alert.pl rmadison.pl svnpath.pl
 
diff -Nru devscripts-2.9.21/README devscripts-2.9.22/README
--- devscripts-2.9.21/README    2006-03-31 18:27:59.000000000 +0100
+++ devscripts-2.9.22/README    2006-09-23 17:26:39.000000000 +0100
@@ -30,6 +30,9 @@
 - checkbashisms: checks whether a /bin/sh script uses any common
   bash-specific features
 
+- checkdiffs: run debdiff for all binary packages created from a source
+  package, comparing the latest version to the previous.
+
 - cvs-debi, cvs-debc [cvs-buildpackage]: wrappers around debi and debc
   respectively (see below) which allow them to be called from the CVS
   working directory.

Reply via email to