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

[SCM] Debian package checker branch, master, updated. 2.5.8-20-g26b32db



The following commit has been merged in the master branch:
commit 26b32db14fab7164822d2652b768f4b39123b2e9
Author: Niels Thykier <niels@thykier.net>
Date:   Wed Jun 13 17:46:16 2012 +0200

    lintian: Guess .changes from d/changelog if possible
    
    When not given any packages to process, auto-process a .changes based
    on d/changelog if it exists.
    
    Signed-off-by: Niels Thykier <niels@thykier.net>

diff --git a/debian/changelog b/debian/changelog
index 59ad0c0..f8325b4 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -50,6 +50,10 @@ lintian (2.5.9) UNRELEASED; urgency=low
     + [NT] Remove assumption that $ENV{HOME} is set/defined.  If
       $ENV{HOME} is not sent, user specific profiles will simply
       be ignored.
+  * frontend/lintian:
+    + [NT] Attempt to automatically determine what to process, if
+      no packages are given and debian/changelog exists.  Thanks
+      to Gilles Filippini for the suggestion.  (Closes: #676799)
 
   * lib/Lintian/Collect/Package.pm:
     + [NT] sorted_index now returns a list rather than a list ref.
diff --git a/frontend/lintian b/frontend/lintian
index 7cd55b0..446092c 100755
--- a/frontend/lintian
+++ b/frontend/lintian
@@ -591,7 +591,17 @@ $action = 'check' unless $action;
 
 # check for arguments
 if ($action =~ /^(?:check|unpack|remove)$/ and $#ARGV == -1 and not $check_everything and not $packages_file and not $opt{'packages-from-file'}) {
-    syntax();
+    my $ok = 0;
+    if ($action eq 'check' or $action eq 'unpack') {
+        # If debian/changelog exists, assume an implied "../<source>_<version>_<arch>.changes"
+        # (or "../<source>_<version>_source.changes").
+        if ( -f 'debian/changelog' ) {
+            my $file = _find_changes();
+            push @ARGV, $file;
+            $ok = 1;
+        }
+    }
+    syntax() unless $ok;
 }
 
 die "Cannot use profile together with --ftp-master-rejects.\n" if $opt{'LINTIAN_PROFILE'} and $ftpmaster_tags;
@@ -1644,6 +1654,98 @@ sub _clear_group_cache {
     undef %group_cache;
 }
 
+sub _find_changes {
+    require Parse::DebianChangelog;
+    my $dch = Parse::DebianChangelog->init ( { infile => 'debian/changelog', quiet => 1 } );
+    my $data = $dch->data;
+    my $last = $data ? $data->[0] : undef;
+    my ($source, $version, $arch);
+    my $changes;
+    my @archs;
+    my @dirs;
+    if (not $last) {
+        my @errors = $dch->get_parse_errors;
+        if (@errors) {
+            print STDERR "Cannot parse debian/changelog due to errors:\n";
+            for my $error (@errors) {
+                print STDERR "$error->[2] (line $error->[1])\n";
+            }
+        } else {
+            print STDERR "debian/changelog does not have any data?\n";
+        }
+        exit 2;
+    }
+    $version = $last->Version;
+    $source = $last->Source;
+    if (not defined $version or not defined $source) {
+        $version//='<N/A>';
+        $source//='<N/A>';
+        print STDERR "Cannot determine source and version from debian/changelog:\n";
+        print STDERR "Source: $source\n";
+        print STDERR "Version: $source\n";
+        exit 2;
+    }
+    # remove the epoch
+    $version =~ s/^\d+://;
+    if (exists $ENV{'DEB_BUILD_ARCH'}) {
+        my $barch = $ENV{'DEB_BUILD_ARCH'};
+        push @archs, $barch;
+        $changes = "../${source}_${version}_${barch}.changes";
+        return $changes if -f $changes;
+    }
+    if (exists $ENV{'DEB_HOST_ARCH'}) {
+        $arch = $ENV{'DEB_HOST_ARCH'};
+    } else {
+        chomp ( $arch = `dpkg --print-architecture` );
+    }
+    if ($arch ne ($ENV{'DEB_BUILD_ARCH'}//'')) {
+        push @archs, $arch;
+        $changes = "../${source}_${version}_${arch}.changes";
+        return $changes if -f $changes;
+    }
+    if (system ('dpkg', '--assert-multi-arch') == 0) {
+        # Maybe cross-built for something dpkg knows about...
+        open my $foreign, '-|', 'dpkg', '--print-foreign-architectures'
+            or die "dpkg --print-foreign-architectures: $!\n";
+        while ( my $line = <$foreign> ) {
+            chomp $line;
+            # Skip already attempted architectures (e.g. via DEB_BUILD_ARCH)
+            next if grep { $_ eq $line } @archs;
+            $changes = "../${source}_${version}_${line}.changes";
+            if ( -f $changes ) {
+                # Consume the entire input, even if we don't need it.
+                1 for <$foreign>;
+                close $foreign;
+                return $changes;
+            }
+            push @archs, $line;
+        }
+        close $foreign;
+    }
+    foreach my $a (qw(multi source)) {
+        $changes = "../${source}_${version}_${a}.changes";
+        return $changes if -f $changes;
+        push @archs, $a;
+    }
+    foreach my $dir ('../build-area', '/var/cache/pbuilder/result') {
+        next unless -d $dir;
+        foreach my $a (@archs) {
+            $changes = "$dir/${source}_${version}_${a}.changes";
+            return $changes if -f $changes;
+        }
+        push @dirs, $dir;
+    }
+    print STDERR "Cannot find changes file for ${source}/${version}, tried:\n";
+    foreach my $a (@archs) {
+        print STDERR "  ../${source}_${version}_${a}.changes\n";
+    }
+    if (@dirs) {
+        print STDERR " Also tried the following dirs:\n";
+        print STDERR '  ' , join ("\n  ", @dirs), "\n";
+    }
+    exit 0;
+}
+
 sub _guess_version {
     require File::Basename;
     require Cwd;
diff --git a/man/lintian.pod.in b/man/lintian.pod.in
index 030ee6b..994ae55 100644
--- a/man/lintian.pod.in
+++ b/man/lintian.pod.in
@@ -46,6 +46,14 @@ If you specify a I<.changes> file, Lintian will process all packages
 listed in that file.  This is convenient when checking a new package
 before uploading it.
 
+If you specify packages to be checked or use one of the options
+B<--all>, B<--packages-from-file> or B<--packages-file>, the packages
+requested will be processed.  Otherwise, if I<debian/changelog>
+exists, it is parsed to determine the name of the .changes file to
+look for in the parent directory (when using the actions B<--check> or
+B<--unpack>).  See L</CHECKING LAST BUILD> for more information.
+
+
 =head1 OPTIONS
 
 Actions of the lintian command: (Only one action can be specified per invocation)
@@ -681,10 +689,75 @@ group.  The I<package> and I<version> part will be used to look up one
 or more source packages.  The binaries, udebs and changes files for
 each matching source package will also be activated.
 
+=head1 CHECKING LAST BUILD
+
+When run in an unpacked package dir (with no package selection
+arguments), Lintian will use I<debian/changelog> to determine the
+source and version of the package.  Lintian will then attempt to find
+a matching I<.changes> file for this source and version combination.
+
+Lintian will (in order) search the following directories:
+
+=over 4
+
+=item ..
+
+Used by dpkg-buildpackage(1).
+
+=item ../build-area
+
+Used by svn-buildpackage(1).
+
+=item /var/cache/pbuilder/result
+
+Used by pbuilder(1) and cowbuilder(1).
+
+=back
+
+In each directory, Lintian will attempt to find a I<.changes> file
+using the following values as architectecture (in order):
+
+=over 4
+
+=item I<$DEB_BUILD_ARCH>
+
+The environment variable DEB_BUILD_ARCH.
+
+=item I<$DEB_HOST_ARCH> (or I<dpkg --print-architecture>)
+
+The environment variable DEB_HOST_ARCH (if not set, "dpkg
+--print-architecture" will be used instead)
+
+=item I<dpkg --print-foreign-architectures>
+
+If dpkg(1) appears to support multi-arch, then any architecture listed
+by "dpkg --print-foreign-architectures" will be used (in the order
+returned by dpkg).
+
+=item I<multi>
+
+Pseudo architecture used by mergechanges(1).
+
+=item I<source>
+
+Used for "source only" builds (e.g. dpkg-buildpackage -S).
+
+=back
+
+If a I<.changes> file matches any combination above exists, Lintian
+will process the first match as if you had passed it per command line.
+If no I<.changes> file can be found, Lintian will print a list of attempted
+locations on STDERR and exit 0.
+
 =head1 EXAMPLES
 
 =over 4
 
+=item B<$ lintian foo.changes>
+
+Check the changes file itself and any (binary, udeb or source) package
+listed in it.
+
 =item B<$ lintian foo.deb>
 
 Check binary package foo given by foo.deb.
@@ -721,6 +794,12 @@ Unpack all packages named foo in the Lintian laboratory.
 
 Remove all packages named foo from the Lintian laboratory.
 
+=item B<$ lintian>
+
+Assuming I<debian/changelog> exists, look for a changes file for the
+source in the parent dir.  Otherwise, print usage information and
+exit.
+
 =back
 
 =head1 BUGS

-- 
Debian package checker


Reply to: