[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Source Dependencies, a real solution



This is a full blown implementation (not to be confused with a hack).
It enables dpkg-source to recognize _versioned_ dependencies using the
same syntax as regular dependencies. It does this in the course of
'dpkg-source -x'. I have also added a -d option for doing nothing but
checking the dependencies in the .dsc file (does not extract the
source). Using the -d option only requires the .dsc (source and diff
are not required).

This still uses a 'Source-Depends' field from the general control file
section.

Sample output using a modifed control file in dpkg:

[root@marcus(9:39pm)-/<1>src/dpkg]%more *.dsc
Source: dpkg
Version: 1.4.1
Binary: dpkg, dpkg-dev
Maintainer: Ian Jackson and others <dpkg-maint@chiark.greenend.org.uk>
Architecture: any
Standards-Version: 2.1.0.0
Source-Depends: libc6-dev (>> 2.2.300), unknown-dev, libncurses4-dev
Files:
 c8e9ba78c23ad18f67f085942363d7bd 456447 dpkg_1.4.1.tar.gz
[root@marcus(9:41pm)-/<1>src/dpkg]%./dpkg-source -x dpkg_1.4.1.dsc
dpkg-source: checking source dependencies...
dpkg-source: warning: libc6-dev (2.0.105-1.2) is not >> 2.2.300
dpkg-source: warning: missing source dependencies: unknown-dev
dpkg-source: extracting dpkg in dpkg-1.4.1
[root@marcus(9:41pm)-/<1>src/dpkg]%

As you can see it checks all fields, first for missing packages, then
for version compatibility. The program uses dpkg-perl for checking
package install status, and `dpkg --compare-versions' for version
compares.

dpkg-gencontrol was also modified in order to not give a warning for
the new field, it does not do anything with the info.

NOTE: This diff also includes a patch for the problem with lines
removed in the diff that start with '--' that I posted yesterday since
it was also a patch to dpkg-source.

enjoy,
  Ben

--
-----    -- - -------- --------- ----  -------  -----  - - ---   --------
Ben Collins <b.m.collins@larc.nasa.gov>                  Debian GNU/Linux
UnixGroup Admin - Jordan Systems Inc.                 bcollins@debian.org
------ -- ----- - - -------   ------- -- The Choice of the GNU Generation
diff -ur dpkg-1.4.1/debian/changelog dpkg-1.4.1.1/debian/changelog
--- dpkg-1.4.1/debian/changelog	Sun Nov  1 12:34:32 1998
+++ dpkg-1.4.1.1/debian/changelog	Wed Jan 13 17:26:54 1999
@@ -1,3 +1,13 @@
+dpkg (1.4.1.1) unstable; urgency=low
+
+  * Non-release patch
+  * Modified dpkg-source to recoginize Source-Depends field in general
+    control file section. Works like regular depends including optional
+    versioning with dpkg --compare-versions. The package and version
+    lookups use dpkg-perl (dpkg-dev now depends on dpkg-perl)
+
+ -- Ben Collins <bcollins@debian.org>  Wed, 13 Jan 1999 17:19:37 -0500
+
 dpkg (1.4.1) unstable; urgency=low
 
   * Maintainer release by IWJ.
diff -ur dpkg-1.4.1/scripts/controllib.pl dpkg-1.4.1.1/scripts/controllib.pl
--- dpkg-1.4.1/scripts/controllib.pl	Sun Nov  1 11:36:14 1998
+++ dpkg-1.4.1.1/scripts/controllib.pl	Wed Jan 13 12:05:09 1999
@@ -1,7 +1,8 @@
 
 $parsechangelog= 'dpkg-parsechangelog';
 
-grep($capit{lc $_}=$_, qw(Pre-Depends Standards-Version Installed-Size));
+grep($capit{lc $_}=$_, qw(Pre-Depends Standards-Version Installed-Size
+	Source-Depends));
 
 $substvar{'Format'}= 1.5;
 $substvar{'Newline'}= "\n";
diff -ur dpkg-1.4.1/scripts/dpkg-gencontrol.pl dpkg-1.4.1.1/scripts/dpkg-gencontrol.pl
--- dpkg-1.4.1/scripts/dpkg-gencontrol.pl	Sun Nov  1 11:07:41 1998
+++ dpkg-1.4.1.1/scripts/dpkg-gencontrol.pl	Wed Jan 13 21:03:51 1999
@@ -1,7 +1,7 @@
 #!/usr/bin/perl
 
 $dpkglibdir= ".";
-$version= '1.3.0'; # This line modified by Makefile
+$version= '1.3.1'; # This line modified by Makefile
 
 $controlfile= 'debian/control';
 $changelogfile= 'debian/changelog';
@@ -125,6 +125,7 @@
             $f{$_}= $v;
         } elsif (m/^Section$|^Priority$/) {
             $spvalue{$_}= $v;
+        } elsif (m/^Source-Depends$/) {
         } elsif (m/^Architecture$/) {
             if ($v eq 'all') {
                 $f{$_}= $v;
diff -ur dpkg-1.4.1/scripts/dpkg-source.pl dpkg-1.4.1.1/scripts/dpkg-source.pl
--- dpkg-1.4.1/scripts/dpkg-source.pl	Sun Nov  1 11:07:46 1998
+++ dpkg-1.4.1.1/scripts/dpkg-source.pl	Wed Jan 13 22:26:15 1999
@@ -1,7 +1,7 @@
 #! /usr/bin/perl
 
 my $dpkglibdir = ".";
-my $version = "1.3.0"; # This line modified by Makefile
+my $version = "1.3.2"; # This line modified by Makefile
 
 my @filesinarchive;
 my %dirincluded;
@@ -18,6 +18,8 @@
 push (@INC, $dpkglibdir);
 require 'controllib.pl';
 
+use Dpkg::Package::List;
+                     
 sub usageversion {
     print STDERR
 "Debian GNU/Linux dpkg-source $version.  Copyright (C) 1996
@@ -26,6 +28,7 @@
 There is NO warranty.
 
 Usage:  dpkg-source -x <filename>.dsc
+        dpkg-source -d <filename>.dsc
         dpkg-source -b <directory> [<orig-directory>|<orig-targz>|\'\']
 Build options:   -c<controlfile>     get control info from this file
                  -l<changelogfile>   get per-version info from this file
@@ -51,7 +54,8 @@
 
 $i = 100;
 grep ($fieldimps {$_} = $i--,
-      qw (Source Version Binary Maintainer Architecture Standards-Version));
+      qw (Source Version Binary Maintainer Architecture Standards-Version
+	Source-Depends));
 
 while (@ARGV && $ARGV[0] =~ m/^-/) {
     $_=shift(@ARGV);
@@ -59,6 +63,8 @@
         &setopmode('build');
     } elsif (m/^-x$/) {
         &setopmode('extract');
+    } elsif (m/^-d$/) {
+        &setopmode('depends');
     } elsif (m/^-s([akpursnAKPUR])$/) {
         $sourcestyle= $1;
     } elsif (m/^-c/) {
@@ -111,7 +117,8 @@
         if (s/^C //) {
 #print STDERR "G key >$_< value >$v<\n";
             if (m/^Source$/) { &setsourcepackage; }
-            elsif (m/^Standards-Version$|^Maintainer$/) { $f{$_}= $v; }
+            elsif (m/^Standards-Version$|^Maintainer$|^Source-Depends$/) {
+		$f{$_}= $v; }
             elsif (s/^X[BC]*S[BC]*-//i) { $f{$_}= $v; }
             elsif (m/^(Section|Priority|Files)$/ || m/^X[BC]+-/i) { }
             else { &unknown('general section of control info file'); }
@@ -455,7 +462,7 @@
     $sourcestyle =~ m/[pun]/ ||
         &usageerr("source handling style -s$sourcestyle not allowed with -b");
 
-    @ARGV==1 || &usageerr("-x needs exactly one argument, the .dsc");
+    @ARGV==1 || &usageerr("-x and -d need exactly one argument, the .dsc");
     $dsc= shift(@ARGV);
     $dsc= "./$dsc" unless $dsc =~ m:^/:;
     $dscdir= $dsc; $dscdir= "./$dscdir" unless $dsc =~ m,^/|^\./,;
@@ -496,6 +503,12 @@
         &setfile(\$difffile) if $file =~ m/\.diff\.gz$/;
     }
 
+    $sourcedepends= $fi{'S Source-Depends'};
+    if ($sourcedepends ne "") {
+	&check_source_deps($sourcedepends)
+    }
+    if ($opmode eq "depends") { exit (0); }
+
     $newdirectory= $sourcepackage.'-'.$baseversion;
     $expectprefix= $newdirectory; $expectprefix.= '.orig' if length($difffile);
     
@@ -511,7 +524,23 @@
         $/="\n";
         while (<GZIP>) {
             s/\n$// || &error("diff is missing trailing newline");
-            if (/^--- /) {
+           if (/^\@\@ .* \@\@$/) {
+               @patch_args = split(' ', $_);
+               ($dump, $after_lines) = split(',', $patch_args[2]);
+               if ($after_lines eq "") { $after_lines = $dump; }
+               ($dump, $before_lines) = split(',', $patch_args[1]);
+               while ($after_lines > 0 || $before_lines > 0) {
+                   $_= <GZIP>; s/\n$// ||
+                       &error("diff finishes in middle of file patch (line $.)");
+                   if (/^\+/) { $after_lines--; }
+                   elsif (/^-/) { $before_lines--; }
+                   elsif (/^ /) { $after_lines--; $before_lines--; }
+                   elsif (/^@/) {
+                       &error("premature finish to file patch (line $.)");
+                   } elsif (/^\\ No newline at end of file$/) { }
+                   else { &error ("diff contains unknown line \`$_'"); }
+               }
+           } elsif (/^--- /) {
                 $fn= $';
                 substr($fn,0,length($expectprefix)+1) eq "$expectprefix/" ||
                     &error("diff patches file ($fn) not in expected subdirectory");
@@ -530,6 +559,7 @@
                 $filepatched{$fn}++ && &error("diff patches file $fn twice");
             } elsif (/^\\ No newline at end of file$/) {
             } elsif (/^[-+ \@]/) {
+		&error ("patch lines out of place (line $.)");
 	    } else {
                 &error ("diff contains unknown line \`$_'");
             }
@@ -660,6 +690,52 @@
                             $fn,$newmode,$mode));
     }
     exit(0);
+}
+
+sub check_source_deps {
+	my ($sourcedepends) = @_;
+	print "$progname: checking source dependencies...\n";
+	$statuslist = new Dpkg::Package::List('filename' => '/var/lib/dpkg/status');
+	my %pkgs = map {$_->{'package'} => $_} @{$statuslist->packages()};
+
+	for $check (split(/,/, $sourcedepends)) {
+	    $check =~ s/^\s*|\s*$//g;
+	    ($tmppkg, $operator, $tmpversion) = split(/ /, $check);
+	    if ($pkgs{$tmppkg}{'status'} !~ /ok installed/) {
+		push (@missing, $tmppkg);
+	    } elsif ($tmpversion ne "") {
+		$operator =~ s/^\s*|\s*$//g;
+		$operator =~ s/[\(\)]//g;
+		$tmpversion =~ s/^\s*|\s*$//g;
+		$tmpversion =~ s/[\(\)]//g;
+		$operator2 = &convert_op($operator);
+		if ($operator2 ne "unknown") {
+		    if (system ("dpkg", "--compare-versions",
+			"$pkgs{$tmppkg}{'version'}", "$operator2", "$tmpversion")) {
+			&warn("$tmppkg ($pkgs{$tmppkg}{'version'}) is not $operator $tmpversion");
+		    }
+		}
+	    }
+	}
+	if (@missing) {
+	    $longlist = join(', ', @missing);
+	    &warn("missing source dependencies: $longlist");
+	}
+}
+
+sub convert_op {
+    my ($op) = @_;
+    if ($op eq "<") { return "lt"; }
+    elsif ($op eq "<=") { return "le"; }
+    elsif ($op eq "<<") { return "lt"; }
+    elsif ($op eq "=")  { return "eq"; }
+    elsif ($op eq "!=") { return "ne"; }
+    elsif ($op eq ">=") { return "ge"; }
+    elsif ($op eq ">>") { return "gt"; }
+    else {
+	&warn("unknown source depends operator \"$op\"");
+	return "unknown";
+    }
 }
 
 sub checkstats {

Attachment: pgpd2dQQpQ6IR.pgp
Description: PGP signature


Reply to: