# Copyright (C) 2019 Felix Lechner # # 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 https://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 Test::Lintian::Output::Universal; =head1 NAME Test::Lintian::Output::Universal -- routines to process universal hints =head1 SYNOPSIS use Test::Lintian::Output::Universal qw(get_tag_names); my $filepath = "path to a universal hint file"; my @tags = get_tag_names($filepath); =head1 DESCRIPTION Helper routines to deal with universal hints and hint files. This is an abstract format that has the minimum information found in all Lintian output formats. =cut use v5.20; use warnings; use utf8; use Exporter qw(import); BEGIN { our @EXPORT_OK = qw( get_tag_names order package_name package_type tag_name parse_line universal_string ); } use Carp; use Const::Fast; use List::SomeUtils qw(uniq); use List::Util qw(all); use Path::Tiny; use Unicode::UTF8 qw(encode_utf8); const my $SPACE => q{ }; const my $COLON => q{:}; const my $LPARENS => q{(}; const my $RPARENS => q{)}; =head1 FUNCTIONS =over 4 =item get_tag_names(PATH) Gets all the tag names mentioned in universal hint file located at PATH. =cut sub get_tag_names { my ($path) = @_; my @lines = path($path)->lines_utf8({ chomp => 1 }); my @names = map { tag_name($_) } @lines; return uniq @names; } =item order =cut sub order { my ($line) = @_; return package_type($line) . $line; } =item package_name =cut sub package_name { my ($line) = @_; my ($package, undef, undef, undef) = parse_line($line); return $package; } =item package_type =cut sub package_type { my ($line) = @_; my (undef, $type, undef, undef) = parse_line($line); return $type; } =item tag_name =cut sub tag_name { my ($line) = @_; my (undef, undef, $name, undef) = parse_line($line); return $name; } =item parse_line =cut sub parse_line { my ($line) = @_; my ($package, $type, $name, $details) = $line =~ qr/^(\S+)\s+\(([^)]+)\):\s+(\S+)(?:\s+(.*))?$/; croak encode_utf8("Cannot parse line $line") unless all { length } ($package, $type, $name); return ($package, $type, $name, $details); } =item universal_string =cut sub universal_string { my ($package, $type, $name, $details) = @_; croak encode_utf8('Need a package name') unless length $package; croak encode_utf8('Need a package type') unless length $type; croak encode_utf8('Need a tag name') unless length $name; my $line = $package. $SPACE. $LPARENS. $type. $RPARENS. $COLON. $SPACE. $name; $line .= $SPACE . $details if length $details; return $line; } =back =head1 AUTHOR Originally written by Felix Lechner for Lintian. =head1 SEE ALSO lintian(1) =cut 1; # Local Variables: # indent-tabs-mode: nil # cperl-indent-level: 4 # End: # vim: syntax=perl sw=4 sts=4 sr et