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

[lintian] 03/09: c/appstream-metadata: Added checks for AppStream metadata



This is an automated email from the git hooks/post-receive script.

nthykier pushed a commit to branch master
in repository lintian.

commit 7556f21baed835084cc5ff6f532104db598151a2
Author: Petter Reinholdtsen <pere@hungry.com>
Date:   Sun Oct 23 23:41:47 2016 +0200

    c/appstream-metadata: Added checks for AppStream metadata
    
    This will do some basic validation of AppStream metadata and compare
    the metadata to udev rules.
    
    Signed-off-by: Niels Thykier <niels@thykier.net>
---
 checks/appstream-metadata.desc |  38 ++++++++
 checks/appstream-metadata.pm   | 215 +++++++++++++++++++++++++++++++++++++++++
 t/scripts/pod-spelling.t       |   2 +-
 3 files changed, 254 insertions(+), 1 deletion(-)

diff --git a/checks/appstream-metadata.desc b/checks/appstream-metadata.desc
new file mode 100644
index 0000000..84673cd
--- /dev/null
+++ b/checks/appstream-metadata.desc
@@ -0,0 +1,38 @@
+Check-Script: appstream-metadata
+Author: Petter Reinholdtsen <pere@hungry.com>
+Type: binary
+Needs-Info: unpacked
+Info: This script checks the AppStream metadata files for problems.
+
+Tag: appstream-metadata-in-legacy-location
+Severity: minor
+Certainty: certain
+Ref: https://wiki.debian.org/AppStream/Guidelines
+Info: AppStream metadata file was found in /usr/share/appdata/.  The
+ AppStream XML files should be placed in /usr/share/metainfo/.
+
+Tag: appstream-metadata-legacy-format
+Severity: important
+Certainty: certain
+Ref: https://wiki.debian.org/AppStream/Guidelines
+Info: AppStream metadata with obsolete <application> root node found.
+ This indicate a legacy format.  The metadata should follow the format
+ outlined at https://www.freedesktop.org/software/appstream/docs/chap-Metadata.html#sect-Metadata-GenericComponent .
+ It is possible to validate the format using 'appstreamcli validate'.
+
+Tag: appstream-metadata-missing-modalias-provide
+Severity: normal
+Certainty: certain
+Ref: https://wiki.debian.org/AppStream/Guidelines
+Info: This package contain a udev rule for providing device access to
+ the console user (using the uaccess udev TAG) or to members of the
+ plugdev file group without announcing the hardware support using
+ AppStream.
+
+Tag: appstream-metadata-malformed-modalias-provide
+Severity: normal
+Certainty: certain
+Ref: https://wiki.debian.org/AppStream/Guidelines
+Info: The modalias matching rule in the AppStream metadata file is
+ malformed.  Hexadecimal numbers in vendor and product IDs must be
+ upper case.
diff --git a/checks/appstream-metadata.pm b/checks/appstream-metadata.pm
new file mode 100644
index 0000000..af65354
--- /dev/null
+++ b/checks/appstream-metadata.pm
@@ -0,0 +1,215 @@
+# appstream-metadata -- lintian check script -*- perl -*-
+
+# Copyright © 2016 Petter Reinholdtsen
+#
+# 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, you can find it on the World Wide
+# Web at http://www.gnu.org/copyleft/gpl.html, or write to the Free
+# Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+# MA 02110-1301, USA.
+
+package Lintian::appstream_metadata;
+
+# For .desktop files, the lintian check would be really easy: Check if
+# .desktop file is there, check if matching file exists in
+# /usr/share/metainfo, if not throw a warning. Maybe while we're at it
+# also check for legacy locations (stuff in /usr/share/appdata) and
+# legacy data (metainfo files starting with `<application>`).
+#
+# For modaliases, maybe udev rules could give some hints.
+# Check modalias values to ensure hex numbers are using capital A-F.
+
+use strict;
+use warnings;
+
+use XML::Simple qw(:strict);
+use File::Basename qw(basename);
+
+use Lintian::Tags qw(tag);
+
+sub run {
+    my ($pkg, $type, $info, $proc, $group) = @_;
+
+    my %desktopfiles;
+    my %metainfo;
+    my @udevrules;
+    my $found_modalias = 0;
+    my $modaliases = [];
+    if (defined(my $dir = $info->index_resolved_path('usr/share/applications/'))) {
+        for my $file ($dir->children('breadth-first')) {
+            $desktopfiles{$file} = 1 if ($file->is_file);
+        }
+    }
+    if (defined(my $dir = $info->index_resolved_path('usr/share/metainfo/'))) {
+        for my $file ($dir->children) {
+            if ($file->is_file) {
+                $metainfo{$file} = 1;
+                $found_modalias |= check_modalias($info, $file, $modaliases);
+            }
+        }
+    }
+    if (defined(my $dir = $info->index_resolved_path('usr/share/appdata/'))) {
+        for my $file ($dir->children('breadth-first')) {
+            if ($file->is_file) {
+                tag('appstream-metadata-in-legacy-location', $file);
+                $found_modalias |= check_modalias($info, $file, $modaliases);
+            }
+        }
+    }
+    if (defined(my $dir = $info->index_resolved_path('lib/udev/rules.d/'))) {
+        for my $file ($dir->children('breadth-first')) {
+            push(@udevrules, $file) if ($file->is_file);
+        }
+    }
+
+    for my $udevrule (@udevrules) {
+        if (check_udev_rules($udevrule, \&provides_user_device, $modaliases)
+            && !$found_modalias) {
+            tag('appstream-metadata-missing-modalias-provide', $udevrule);
+        }
+    }
+    return;
+}
+
+=head1 NAME
+
+check_modalias
+
+=head1 DESCRIPTION
+
+Check if a AppStream XML file contain a provides->modalias block and
+check its content.
+
+=cut
+sub check_modalias {
+    my ($info, $metadatafile, $modaliases) = @_;
+#    my $metadatafile = $info->index_resolved_path($metadatapath);
+    if (! $metadatafile->is_open_ok()) {
+        # FIXME report this as an error
+        return;
+    }
+    my $xml = XMLin($metadatafile->fs_path(),
+                    ForceArray => [ 'provides', 'modalias' ],
+                    KeepRoot => 1,
+                    KeyAttr => [],
+        );
+    if (exists $xml->{'application'}) {
+        tag('appstream-metadata-legacy-format', $metadatafile);
+        return 0;
+    }
+    if (exists $xml->{'component'}
+        && exists $xml->{'component'}->{'provides'}
+        && exists $xml->{'component'}->{'provides'}[0]->{'modalias'}) {
+        for (@{$xml->{'component'}->{'provides'}[0]->{'modalias'}}) {
+            push(@{$modaliases}, $_);
+            if (m/^usb:v[0-9a-f]{4}p[0-9a-f]{4}d/i
+                && ! m/^usb:v[0-9A-F]{4}p[0-9A-F]{4}d/) {
+                tag('appstream-metadata-malformed-modalias-provide',
+                    $metadatafile,
+                    "include non-valid hex digit in USB matching rule '$_'"
+                    );
+            }
+        }
+        return 1;
+    }
+    return 0;
+}
+
+=head1 NAME
+
+provides_user_device
+
+=head1 DESCRIPTION
+
+Check if a udev rule file contain rules for plugdev or uaccess.
+
+=cut
+sub provides_user_device {
+    my ($udevrulefile, $linenum, $rule, $data) = @_;
+    my $retval = 0;
+    if (
+        m/plugdev/
+        || m/uaccess/
+        || m/MODE=\"0666\"/
+        ) {
+        $retval = 1;
+    }
+    if ($rule =~ m/SUBSYSTEM=="usb"/) {
+        my ($vmatch, $pmatch);
+        if ($rule =~ m/ATTR\{idVendor\}=="([0-9a-fA-F]{4})"/) {
+            $vmatch = "v" . uc($1);
+        }
+        if ($rule =~ m/ATTR\{idProduct\}=="([0-9a-fA-F]{4})"/) {
+            $pmatch = "p" . uc($1);
+        }
+        if (defined $vmatch && defined $pmatch) {
+            my $match = "usb:${vmatch}${pmatch}d";
+            my $foundmatch;
+            for my $aliasmatch (@{$data}) {
+                if (0 == index($aliasmatch, $match)) {
+                    $foundmatch = 1;
+                }
+            }
+            if (! $foundmatch) {
+                tag('appstream-metadata-missing-modalias-provide',
+                    $udevrulefile, "match rule $match*");
+            }
+        }
+    }
+    return $retval;
+}
+
+=head1 NAME
+
+check_udev_rules
+
+=head1 DESCRIPTION
+
+Extract all udev rules from a rule file and pass them on one by one to
+the callback function.
+
+This is a copy of a function in udev.pm.
+
+=cut
+sub check_udev_rules {
+    my ($file, $check, $data) = @_;
+
+    my $fd = $file->open();
+    my $linenum = 0;
+    my $cont;
+    my $retval = 0;
+    while (<$fd>) {
+        chomp;
+        $linenum++;
+        if (defined $cont) {
+            $_ = $cont . $_;
+            $cont = undef;
+        }
+        if (/^(.*)\\$/) {
+            $cont = $1;
+            next;
+        }
+        next if /^#.*/; # Skip comments
+        $retval |= $check->($file, $linenum, $_, $data);
+    }
+    close($fd);
+    return $retval;
+}
+
+1;
+
+# Local Variables:
+# indent-tabs-mode: nil
+# cperl-indent-level: 4
+# End:
+# vim: syntax=perl sw=4 sts=4 sr et
diff --git a/t/scripts/pod-spelling.t b/t/scripts/pod-spelling.t
index 6973488..a5b07db 100755
--- a/t/scripts/pod-spelling.t
+++ b/t/scripts/pod-spelling.t
@@ -121,7 +121,7 @@ hashrefs namespace subdir SIGPIPE SIG blocknumber blocksub readwindow
 REMOVESLASH STAMPFILE TAGNAME TCODE TESTDATA BLOCKSIZE jN
 POSIX t1c2pfb init runtime txt executability writability
 INHANDLE OUTHANDLES UTC timestamp faux tagname READMEs Testname
-debhelper dh buildpackage uaccess udev
+debhelper dh buildpackage uaccess udev AppStream plugdev
 
 __END__
 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/lintian/lintian.git


Reply to: