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

[SCM] Debian package checker branch, master, updated. 2.5.2-63-g6c2cbf2



The following commit has been merged in the master branch:
commit 6c2cbf29d3cf16674bb5f24b64c80e0456e02bce
Author: Niels Thykier <niels@thykier.net>
Date:   Sat Jul 30 11:02:07 2011 +0200

    Collect comments from override files
    
    With --show-overrides, lintian will now show related comments to
    overridden tags.

diff --git a/debian/changelog b/debian/changelog
index 559ee44..07fe7bb 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -107,8 +107,13 @@ lintian (2.5.3) UNRELEASED; urgency=low
     + [JW,NT] Replace use of fail with croak.  (Closes: #637741)
   * lib/Lintian/Profile.pm:
     + [NT] Reject profiles containing an unknown field.
+  * lib/Lintian/Tag/Override.pm:
+    + [NT] New file.
   * lib/Lintian/Tags.pm:
     + [NT] Track which tags had overrides that have been dropped.
+    + [NT,RG] Collect override comments and print the comments
+      above the overridden tag (with --show-overrides).  Thanks
+      to Carl Fürstenberg for the report.  (Closes: #474590)
   * lib/Text_utils.pm:
     + [NT] Close <p>-tags in dtml_to_html since the output is used
       in xhtml (xml), where all tags must be closed properly.
diff --git a/doc/lintian.xml b/doc/lintian.xml
index 1c6ced4..d6243cc 100644
--- a/doc/lintian.xml
+++ b/doc/lintian.xml
@@ -523,22 +523,24 @@ $
         and stores it in the laboratory. The files currently installed
         on the system are not used in current Lintian versions.
       </para>
-      <para>
-        The format of the overrides file is simple, it consists of one override per
-        line (and may contain empty lines and comments, starting with a <literal>#</literal>, on others):
-        <literal>[[<replaceable>&lt;package&gt;</replaceable>][ <replaceable>&lt;archlist&gt;</replaceable>][ <replaceable>&lt;type&gt;</replaceable>]: ]<replaceable>&lt;lintian-tag&gt;</replaceable>[
-          [*]<replaceable>&lt;lintian-info&gt;</replaceable>[*]]</literal>.  <replaceable>&lt;package&gt;</replaceable> is the package name;
-        <replaceable>&lt;archlist&gt;</replaceable> is an architecture list
-        in the same format as for the Build-Depends field (except architecture wildcards are not supported);
-        <replaceable>&lt;type&gt;</replaceable> is one of <literal>binary</literal>, <literal>udeb</literal> and
-        <literal>source</literal>,
-        and <replaceable>&lt;lintian-info&gt;</replaceable> is all
-        additional information provided by Lintian except for the
-        tag. What's inside brackets is optional and may be omitted if
-        you want to match it all.  An example file for a binary
-        package would look like:
-      </para>
-      <screen>
+      <sect2 label="2.4.1" id="section-2.4.1">
+        <title>Format of override files</title>
+        <para>
+          The format of the overrides file is simple, it consists of one override per
+          line (and may contain empty lines and comments, starting with a <literal>#</literal>, on others):
+          <literal>[[<replaceable>&lt;package&gt;</replaceable>][ <replaceable>&lt;archlist&gt;</replaceable>][ <replaceable>&lt;type&gt;</replaceable>]: ]<replaceable>&lt;lintian-tag&gt;</replaceable>[
+            [*]<replaceable>&lt;lintian-info&gt;</replaceable>[*]]</literal>.  <replaceable>&lt;package&gt;</replaceable> is the package name;
+          <replaceable>&lt;archlist&gt;</replaceable> is an architecture list
+          in the same format as for the Build-Depends field (except architecture wildcards are not supported);
+          <replaceable>&lt;type&gt;</replaceable> is one of <literal>binary</literal>, <literal>udeb</literal> and
+          <literal>source</literal>,
+          and <replaceable>&lt;lintian-info&gt;</replaceable> is all
+          additional information provided by Lintian except for the
+          tag. What's inside brackets is optional and may be omitted if
+          you want to match it all.  An example file for a binary
+          package would look like:
+        </para>
+        <screen>
 /usr/share/lintian/overrides/foo, where foo is the name of your package
 
 # We use a non-standard dir permission to only allow the webserver to look
@@ -546,29 +548,67 @@ $
 foo binary: non-standard-dir-perm
 foo binary: FSSTND-dir-in-usr /usr/man/man1/foo.1.gz
 </screen>
-      <para>An example file for a source package would look like:</para>
-      <screen>
+        <para>An example file for a source package would look like:</para>
+        <screen>
 debian/source.lintian-overrides in your base source directory
 foo source: debian-files-list-in-source
 # Upstream distributes it like this, repacking would be overkill though, so
 # tell lintian to not complain:
 foo source: configure-generated-file-in-source config.cache
 </screen>
-      <para>
-        Many tags can occur more than once (e.g. if the same error is
-        found in more than one file). You can override a tag either
-        completely by specifying its name (first line in the examples)
-        or only one occurrence of it by specifying the additional
-        info, too (second line in the examples).  If you add an
-        asterisk (<literal>*</literal>) in the additional info, this
-        will match arbitrary strings similar to the shell wildcard.
-      </para>
-      <para>
-        The first wildcard support appeared in Lintian 2.0.0, which
-        only allowed the wildcards in the very beginning or end.
-        Version 2.5.0~rc4 extended this to allow wildcards any where
-        in the additional info.
-      </para>
+        <para>
+          Many tags can occur more than once (e.g. if the same error is
+          found in more than one file). You can override a tag either
+          completely by specifying its name (first line in the examples)
+          or only one occurrence of it by specifying the additional
+          info, too (second line in the examples).  If you add an
+          asterisk (<literal>*</literal>) in the additional info, this
+          will match arbitrary strings similar to the shell wildcard.
+        </para>
+        <para>
+          The first wildcard support appeared in Lintian 2.0.0, which
+          only allowed the wildcards in the very beginning or end.
+          Version 2.5.0~rc4 extended this to allow wildcards any where
+          in the additional info.
+        </para>
+      </sect2>
+      <sect2 label="2.4.2" id="section-2.4.2">
+        <title>Documenting overrides</title>
+        <para>
+          To assist reviewers, Lintian will extract the comments from
+          the overrides file and display the related comments next to
+          the overridden tags.
+        </para>
+        <para>
+          Comments directly above an override will be shown next to all
+          tags it overrides.  If an override for the same tags appears
+          on the very next line, it will inherit the comment from the
+          override above it.
+        </para>
+        <screen>
+# This comment will be shown above all tags overriden by the following
+# two overrides, (because they apply to the same tag and there is no
+# empty line between them)
+foo source: some-tag extact match
+foo source: some-tag wildcard * match
+# This override has its own comment, and it is not shared with the
+# override below (because there is an empty line inbetween them).
+foo source: some-tag another exact match
+
+foo source: some-tag override without a comment
+</screen>
+        <para>
+          Empty lines can be used to disassociate a comment from an
+          override following it.  This can also be used to make a general
+          comment about the overrides that will not be displayed.
+        </para>
+        <screen>
+# This is a general comment not connected to any override, since there
+# is one (or more) empty lines after it.
+
+foo source: another-tag without any comments
+</screen>
+      </sect2>
     </sect1>
     <sect1 label="2.5" id="section-2.5">
       <title>Vendor Profiles</title>
diff --git a/lib/Lintian/Tag/Override.pm b/lib/Lintian/Tag/Override.pm
new file mode 100644
index 0000000..698a496
--- /dev/null
+++ b/lib/Lintian/Tag/Override.pm
@@ -0,0 +1,184 @@
+# -*- perl -*-
+# Lintian::Tag::Override -- Interface to Lintian overrides
+
+# Copyright (C) 2011 Niels Thykier
+#
+# 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, see <http://www.gnu.org/licenses/>.
+
+package Lintian::Tag::Override;
+
+use strict;
+use warnings;
+
+use base qw(Class::Accessor);
+
+=head1 NAME
+
+Lintian::Tag::Override -- Representation of an Lintian Override
+
+=head1 SYNOPSIS
+
+ use Lintian::Tag::Override;
+ 
+ my $data = {
+    'comments' => ['some', 'multi-line', 'comments']
+ };
+ my $override = Lintian::Tag::Override->new('unused-override', $data);
+ my $comments = $override->comments;
+ if ($override->overrides("some extra") ) {
+     # do something
+ }
+
+=head1 DESCRIPTION
+
+Represents and encalsulates a Lintian Override.
+
+=head1 METHODS
+
+=over 4
+
+=item Lintian::Tag::Override->new($tag, $data)
+
+Creates a new override for $tag.  $data should be a hashref with the
+following fields.
+
+=over 4
+
+=item arch
+
+Architectures this override applies too (not really used).
+
+=item comments
+
+A list of comments (each item is a separate line)
+
+=item extra
+
+The extra part of the override.  If it contains a "*" is will
+considered a pattern.
+
+=back
+
+=cut
+
+sub new {
+    my ($type, $tag, $data) = @_;
+    $data = {} unless defined $data;
+    my $self = {
+        'arch'     => $data->{'arch'},
+        'comments' => $data->{'comments'},
+        'extra'    => $data->{'extra'}//'',
+        'tag'      => $tag,
+    };
+    $self->{'arch'} = 'any' unless $self->{'arch'};
+    bless $self, $type;
+    $self->_init();
+    return $self;
+}
+
+=item $override->tag
+
+Returns the name of the tag.
+
+=item $override->arch
+
+Returns the architecture this tag applies to.
+
+=item $override->comments
+
+Returns a list of lines that makes up the comments for this override.
+
+Do not modify the contents of this list.
+
+=item $override->extra
+
+Returns the extra of this tag (or the empty string, if there is no
+extra).
+
+=item $override->is_pattern
+
+Returns a truth value if the extra is a pattern.
+
+=cut
+
+Lintian::Tag::Override->mk_ro_accessors (qw(tag arch comments extra is_pattern));
+
+=item $override->overrides($extra)
+
+Returns a truth value if this override applies to this extra.
+
+=cut
+
+sub overrides {
+    my ($self, $textra) = @_;
+    my $extra = $self->{'extra'}//'';
+    # No extra => applies to all tags
+    return 1 unless $extra;
+    return 1 if $extra eq $textra;
+    if ($self->{'is_pattern'}) {
+        my $pat = $self->{'pattern'};
+        if ($textra =~ m/^$pat\z/){
+            return 1;
+        }
+    }
+    return 0;
+}
+
+# Internal initialization method
+sub _init  {
+    my ($self) = @_;
+    my $extra = $self->{'extra'};
+    if ($extra && $extra =~ m/\*/o) {
+        # It is a pattern, pre-compute it
+        my $pattern = $extra;
+        my $end = ''; # Trailing "match anything" (if any)
+        my $pat = ''; # The rest of the pattern
+        # Split does not help us if $pattern ends with *
+        # so we deal with that now
+        if ($pattern =~ s/\Q*\E+\z//o){
+            $end = '.*';
+        }
+        # Are there any * left (after the above)?
+        if ($pattern =~ m/\Q*\E/o) {
+            # this works even if $text starts with a *, since
+            # that is split as '', <text>
+            my @pargs = split(m/\Q*\E++/o, $pattern);
+            $pat = join('.*', map { quotemeta($_) } @pargs);
+        } else {
+            $pat = $pattern;
+        }
+        $self->{'is_pattern'} = 1;
+        $self->{'pattern'} = qr/$pat$end/;
+    } else {
+        $self->{'is_pattern'} = 0;
+    }
+}
+
+=back
+
+=head1 AUTHOR
+
+Originally written by Niels Thykier <niels@thykier.net> for Lintian.
+
+=head1 SEE ALSO
+
+lintian(1)
+
+L<Lintain::Tags>
+
+=cut
+
+1;
+
+
diff --git a/lib/Lintian/Tags.pm b/lib/Lintian/Tags.pm
index 57e3184..e6a6af9 100644
--- a/lib/Lintian/Tags.pm
+++ b/lib/Lintian/Tags.pm
@@ -24,6 +24,7 @@ use warnings;
 
 use Lintian::Output;
 use Lintian::Tag::Info;
+use Lintian::Tag::Override;
 use Util qw(fail);
 
 use base 'Exporter';
@@ -191,39 +192,26 @@ called first or if an attempt is made to issue an unknown tag.
 # overrides for the current file.  This may require checking for matches
 # against override data with wildcards.  Returns undef if the tag is not
 # overridden or the override if the tag is.
+#
+# The override will be returned as a list ref where the first element is the
+# name of the tag and the second is the "extra" for the override (if any).
 sub _check_overrides {
     my ($self, $tag, $extra) = @_;
-    my $overrides = $self->{info}{$self->{current}}{overrides}{$tag};
+    my $overrides = $self->{info}{$self->{current}}{'overrides-data'}{$tag};
+    my $stats = $self->{info}{$self->{current}}{overrides}{$tag};
     return unless $overrides;
     if (exists $overrides->{''}) {
-        $overrides->{''}++;
-        return $tag;
+        $stats->{''}++;
+        return [$tag, ''];
     } elsif ($extra ne '' and exists $overrides->{$extra}) {
-        $overrides->{$extra}++;
-        return "$tag $extra";
+        $stats->{$extra}++;
+        return [$tag, $extra];
     } elsif ($extra ne '') {
         for (sort keys %$overrides) {
-            my $pattern = $_;
-            my $end = '';
-            my $pat = '';
-            next unless $pattern =~ m/\Q*\E/o;
-            # Split does not help us if $text ends with *
-            # so we deal with that now
-            if ($pattern =~ s/\Q*\E+\z//o){
-                $end = '.*';
-            }
-            # Are there any * left (after the above)?
-            if ($pattern =~ m/\Q*\E/o) {
-                # this works even if $text starts with a *, since
-                # that is split as '', <text>
-                my @pargs = split(m/\Q*\E++/o, $pattern);
-                $pat = join('.*', map { quotemeta($_) } @pargs);
-            } else {
-                $pat = $pattern;
-            }
-            if ($extra =~ m/^$pat$end\z/) {
-                $overrides->{$_}++;
-                return "$tag $_";
+            my $override = $overrides->{$_};
+            if ($override->is_pattern && $override->overrides($extra)){
+                $stats->{$_}++;
+                return [$tag, $override->extra];
             }
         }
     }
@@ -272,7 +260,21 @@ sub tag {
     return if (defined($overridden) and not $self->{show_overrides});
     return unless $self->displayed($tag);
     my $file = $self->{info}{$self->{current}};
-    $Lintian::Output::GLOBAL->print_tag($file, $info, $extra, $overridden);
+    my $ovout;
+    if ($overridden) {
+        my $overrides = $self->{info}{$self->{current}}{'overrides-data'}{$tag}{$overridden->[1]};
+        my $comments = $overrides->comments;
+        if ($comments && @$comments) {
+            $Lintian::Output::GLOBAL->msg(@$comments);
+        }
+        # We have to use undef, "$tag" or "$tag $extra" due to the Lintian::Output API
+        if ($overridden->[1]) {
+            $ovout = join(' ', @$overridden);
+        } else {
+            $ovout = $overridden->[0];
+        }
+    }
+    $Lintian::Output::GLOBAL->print_tag($file, $info, $extra, $ovout);
 }
 
 =back
@@ -502,12 +504,13 @@ sub file_start {
         die "duplicate of file $file added to Lintian::Tags object";
     }
     $self->{info}{$file} = {
-        file      => $file,
-        package   => $pkg,
-        version   => $version,
-        arch      => $arch,
-        type      => $type,
-        overrides => {},
+        file              => $file,
+        package           => $pkg,
+        version           => $version,
+        arch              => $arch,
+        type              => $type,
+        overrides         => {},
+        'overrides-data'  => {},
     };
     $self->{statistics}{$file} = {
         types     => {},
@@ -543,13 +546,27 @@ sub file_overrides {
         die 'no current file when adding overrides';
     }
     my $info = $self->{info}{$self->{current}};
+    my $comments = [];
+    my $last_over = undef;
     open(my $file, '<', $overrides)
         or fail("cannot open override file $overrides: $!");
     local $_;
     while (<$file>) {
         s/^\s+//;
         s/\s+$//;
-        next if /^(?:\#|\z)/;
+        if ($_ eq '') {
+            # Throw away comments, as they are not attached to a tag
+            # also throw away the option of "carrying over" the last
+            # comment
+            $comments = [];
+            $last_over = undef;
+            next;
+        }
+        if (/^#/o){
+            s/^# ?//o;
+            push @$comments, $_;
+            next;
+        }
         s/\s+/ /go;
         my $override = $_;
         # The override looks like the following:
@@ -563,6 +580,9 @@ sub file_overrides {
             # Valid - so far at least
             my ($archlist, $tagdata) = ($1, $2);
             my ($tag, $extra) = split(m/ /o, $tagdata, 2);
+            my $tagover;
+            my $com;
+            my $data;
             if ($archlist) {
                 # parse and figure
                 my (@archs) = split(m/\s++/o, $archlist);
@@ -587,8 +607,26 @@ sub file_overrides {
                 $self->{ignored_overrides}{$tag}++;
                 next;
             }
+
+            if ($last_over && $last_over->tag eq $tag && !scalar @$comments) {
+                # There are no new comments, no "empty line" in between and
+                # this tag is the same as the last, so we "carry over" the
+                # comment from the previous override (if any).
+                #
+                # Since L::T::Override is (supposed to be) immutable, the new
+                # override can share the reference with the previous one.
+                $comments = $last_over->comments;
+            }
             $extra = '' unless defined $extra;
+            $data =  {
+                'extra' => $extra,
+                'comments' => $comments,
+            };
+            $comments = [];
+            $tagover = Lintian::Tag::Override->new($tag, $data);
+            $info->{'overrides-data'}{$tag}{$extra} = $tagover;
             $info->{overrides}{$tag}{$extra} = 0;
+            $last_over = $tagover;
         } else {
             tag('malformed-override', $_);
         }
diff --git a/man/lintian.pod.in b/man/lintian.pod.in
index b63b362..69c754c 100644
--- a/man/lintian.pod.in
+++ b/man/lintian.pod.in
@@ -297,7 +297,10 @@ profiles.
 
 =item B<--show-overrides>
 
-Output tags that have been overridden.
+Output tags that have been overridden.  The related override comments
+will also be printed (unless --quiet is used).  Please refer to the
+Lintian User Manual for the documentation on how lintian relates
+comments to a given override.
 
 This option overrides the B<show-overrides> variable in the
 configuration file.
diff --git a/t/scripts/pod-coverage.t b/t/scripts/pod-coverage.t
index b0bb132..34298d6 100755
--- a/t/scripts/pod-coverage.t
+++ b/t/scripts/pod-coverage.t
@@ -29,6 +29,7 @@ our %MODULES =
      'Lintian::Relation::Version'  => [ qr/^compare$/ ],
      'Lintian::Tags'               => [],
      'Lintian::Tag::Info'          => [],
+     'Lintian::Tag::Override'      => [],
     );
 # TODO:
 #		Lintian::Collect::Binary
diff --git a/t/tests/overrides/debian/debian/manpages b/t/tests/overrides-shown/debian/debian/manpages
similarity index 100%
copy from t/tests/overrides/debian/debian/manpages
copy to t/tests/overrides-shown/debian/debian/manpages
diff --git a/t/tests/overrides/debian/debian/overrides.lintian-overrides b/t/tests/overrides-shown/debian/debian/overrides-shown.lintian-overrides
similarity index 76%
copy from t/tests/overrides/debian/debian/overrides.lintian-overrides
copy to t/tests/overrides-shown/debian/debian/overrides-shown.lintian-overrides
index 854c581..06165a4 100644
--- a/t/tests/overrides/debian/debian/overrides.lintian-overrides
+++ b/t/tests/overrides-shown/debian/debian/overrides-shown.lintian-overrides
@@ -1,3 +1,7 @@
+# This comment will not appear in the output, also the last
+# tag should not have a comment due to the empty line between
+# it and the one before it.
+
 # override without extra information
 manpage-has-bad-whatis-entry
 # Architecture specific override - which is retarded considering
@@ -6,8 +10,9 @@ manpage-has-bad-whatis-entry
 [!i386]: hyphen-used-as-minus-sign usr/share/man/man1/foo.1.gz:6
 # exact extra information
 hyphen-used-as-minus-sign usr/share/man/man1/foo.1.gz:4
-# wildcards
+# These are wildcard overrides
 hyphen-used-as-minus-sign usr/share/man/man1/foo.1.gz:2*
 hyphen-used-as-minus-sign */foo.1.gz:5
 hyphen-used-as-minus-sign */foo.1.gz:3*
+
 hyphen-used-as-minus-sign usr/share/man/man1/foo.1.gz * more occurrences not shown
diff --git a/t/tests/overrides/debian/foo.1 b/t/tests/overrides-shown/debian/foo.1
similarity index 100%
copy from t/tests/overrides/debian/foo.1
copy to t/tests/overrides-shown/debian/foo.1
diff --git a/t/tests/overrides-shown/desc b/t/tests/overrides-shown/desc
new file mode 100644
index 0000000..aa73544
--- /dev/null
+++ b/t/tests/overrides-shown/desc
@@ -0,0 +1,6 @@
+Testname: overrides-shown
+Sequence: 1500
+Version: 1.0
+Options: --show-overrides -I -E
+Sort: no
+Description: Test override handling
diff --git a/t/tests/overrides-shown/tags b/t/tests/overrides-shown/tags
new file mode 100644
index 0000000..6cf70c0
--- /dev/null
+++ b/t/tests/overrides-shown/tags
@@ -0,0 +1,21 @@
+N: override without extra information
+O: overrides-shown: manpage-has-bad-whatis-entry usr/share/man/man1/foo.1.gz
+N: exact extra information
+O: overrides-shown: hyphen-used-as-minus-sign usr/share/man/man1/foo.1.gz:4
+N: These are wildcard overrides
+O: overrides-shown: hyphen-used-as-minus-sign usr/share/man/man1/foo.1.gz:5
+N: Architecture specific override - which is retarded considering
+N: it is an arch: all package we are testing >.>
+O: overrides-shown: hyphen-used-as-minus-sign usr/share/man/man1/foo.1.gz:6
+I: overrides-shown: hyphen-used-as-minus-sign usr/share/man/man1/foo.1.gz:12
+I: overrides-shown: hyphen-used-as-minus-sign usr/share/man/man1/foo.1.gz:13
+I: overrides-shown: hyphen-used-as-minus-sign usr/share/man/man1/foo.1.gz:14
+N: These are wildcard overrides
+O: overrides-shown: hyphen-used-as-minus-sign usr/share/man/man1/foo.1.gz:21
+N: These are wildcard overrides
+O: overrides-shown: hyphen-used-as-minus-sign usr/share/man/man1/foo.1.gz:22
+N: These are wildcard overrides
+O: overrides-shown: hyphen-used-as-minus-sign usr/share/man/man1/foo.1.gz:23
+N: These are wildcard overrides
+O: overrides-shown: hyphen-used-as-minus-sign usr/share/man/man1/foo.1.gz:30
+O: overrides-shown: hyphen-used-as-minus-sign usr/share/man/man1/foo.1.gz 2 more occurrences not shown

-- 
Debian package checker


Reply to: