Author: rra Date: 2008-01-03 01:04:10 +0100 (Thu, 03 Jan 2008) New Revision: 1083
Added: trunk/reporting/lintian.css trunk/reporting/templates/ trunk/reporting/templates/clean.tmpl trunk/reporting/templates/index.tmpl trunk/reporting/templates/maintainer.tmpl trunk/reporting/templates/maintainers.tmpl trunk/reporting/templates/packages.tmpl trunk/reporting/templates/tag.tmpl trunk/reporting/templates/tags.tmpl Modified: trunk/debian/changelog trunk/debian/control trunk/debian/copyright trunk/reporting/html_reports Log: * debian/control: + [RA] Suggest libtext-template-perl, needed for HTML reporting. * reporting/html_reports: + [RA] Rewritten. - Include info, experimental, and overridden tags in the tag pages. - Generate a second report for each maintainer showing all tags. - Correctly handle multiple different maintainer strings with the same e-mail address. - Correctly report the version number of a binary package when it differs from the source package. (Closes: #458036) - Formatting changes (hopefully improvements) to the web pages. - New template-driven system for easier revision of the HTML. * reporting/lintian.css: + [RA] New minimal style sheet for the HTML reports. * reporting/templates/*: + [RA] New Text::Template page templates for the HTML reports. Modified: trunk/debian/changelog =================================================================== --- trunk/debian/changelog 2007-12-18 20:58:27 UTC (rev 1082) +++ trunk/debian/changelog 2008-01-03 00:04:10 UTC (rev 1083) @@ -2,14 +2,32 @@ * checks/control-file{.desc,}: + [RA] Include the package name in stronger-dependency-implies-weaker. + + * debian/control: + + [RA] Suggest libtext-template-perl, needed for HTML reporting. * lib/Dep.pm: + [RA] Allow substvars instead of package names so that dependency checks against the source debian/control file don't treat all substvars as equivalent. Thanks, Julien Cristau. (Closes: #456802) - -- Russ Allbery <[EMAIL PROTECTED]> Tue, 18 Dec 2007 12:58:17 -0800 + * reporting/html_reports: + + [RA] Rewritten. + - Include info, experimental, and overridden tags in the tag pages. + - Generate a second report for each maintainer showing all tags. + - Correctly handle multiple different maintainer strings with the + same e-mail address. + - Correctly report the version number of a binary package when it + differs from the source package. (Closes: #458036) + - Formatting changes (hopefully improvements) to the web pages. + - New template-driven system for easier revision of the HTML. + * reporting/lintian.css: + + [RA] New minimal style sheet for the HTML reports. + * reporting/templates/*: + + [RA] New Text::Template page templates for the HTML reports. + -- Russ Allbery <[EMAIL PROTECTED]> Wed, 02 Jan 2008 16:01:02 -0800 + lintian (1.23.41) unstable; urgency=low The "it would be lovely if there were an actual desktop file standard" Modified: trunk/debian/control =================================================================== --- trunk/debian/control 2007-12-18 20:58:27 UTC (rev 1082) +++ trunk/debian/control 2008-01-03 00:04:10 UTC (rev 1083) @@ -14,7 +14,7 @@ Depends: perl, libdigest-md5-perl | perl (>> 5.8), dpkg-dev (>= 1.13.17), file, binutils, diffstat (>= 1.27-1), man-db (>= 2.3.20-1), gettext (>= 0.16), intltool-debian, libparse-debianchangelog-perl (>= 0.6), liburi-perl -Suggests: binutils-multiarch +Suggests: binutils-multiarch, libtext-template-perl Description: Debian package checker Lintian dissects Debian packages and reports bugs and policy violations. It contains automated checks for many aspects of Debian Modified: trunk/debian/copyright =================================================================== --- trunk/debian/copyright 2007-12-18 20:58:27 UTC (rev 1082) +++ trunk/debian/copyright 2008-01-03 00:04:10 UTC (rev 1083) @@ -30,6 +30,7 @@ Portions Copyright (C) 2004 Jeroen van Wolffelaar Portions Copyright (C) 2005 René van Bevern Portions Copyright (C) 2006 Adeodato Simó +Portions Copyright (C) 2007, 2008 Russ Allbery This program is free software; you may redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -41,8 +42,8 @@ fitness for a particular purpose. See the GNU General Public License for more details. -A copy of the GNU General Public License is available as -/usr/share/common-licenses/GPL in the Debian GNU/Linux distribution +A copy of the GNU General Public License version 2 is available as +/usr/share/common-licenses/GPL-2 in the Debian GNU/Linux distribution or on the World Wide Web at http://www.gnu.org/copyleft/gpl.html. You can also obtain it by writing to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. Modified: trunk/reporting/html_reports =================================================================== --- trunk/reporting/html_reports 2007-12-18 20:58:27 UTC (rev 1082) +++ trunk/reporting/html_reports 2008-01-03 00:04:10 UTC (rev 1083) @@ -3,6 +3,7 @@ # Lintian HTML reporting tool -- Create Lintian web reports # # Copyright (C) 1998 Christian Schwarz and Richard Braakman +# Copyright (C) 2007 Russ Allbery # # This program is free software. It is distributed under the terms of # the GNU General Public License as published by the Free Software @@ -21,643 +22,471 @@ # MA 02110-1301, USA. use strict; +use File::Copy qw(copy); +use Text::Template (); -# Maximum number of identical tags per package: -my $max_tags = 8; +# ------------------------------ +# Global variables and configuration -my $debug = 0; +# Maximum number of identical tags per package to display. Any remaining tags +# will be compressed into a "... reported %d more times" line. +our $MAX_TAGS = 8; -# Read configuration -require './config'; -use vars qw($LINTIAN_ROOT $LINTIAN_ARCHIVEDIR $LINTIAN_DIST $LINTIAN_SECTION - $LINTIAN_ARCH $HTML_TMP_DIR $LINTIAN_LAB - $statistics_file); +# These have no default and must be set in the configuration file. +# FIXME: $statistics_file should be in all caps as well. +our ($LINTIAN_ROOT, $LINTIAN_LAB, $LINTIAN_ARCHIVEDIR, $LINTIAN_DIST, + $LINTIAN_SECTION, $LINTIAN_ARCH, $HTML_TMP_DIR, $statistics_file); -# Read_pkglists needs this +# Read the configuration. +require './config-testing'; + +# The path to the mirror timestamp. +our $LINTIAN_TIMESTAMP + = "$LINTIAN_ARCHIVEDIR/project/trace/ftp-master.debian.org"; + +# FIXME: At least the lab should be a parameter to Read_pkglists rather +# than an environment variable. $ENV{'LINTIAN_LAB'} = $LINTIAN_LAB; $ENV{'LINTIAN_ROOT'} = $LINTIAN_ROOT; -# Import perl libraries -use lib "$ENV{'LINTIAN_ROOT'}/lib"; -use Util; -use Read_taginfo; -my %tag_info = %{read_tag_info('html')}; +# Import Lintian Perl libraries. +use lib "$ENV{LINTIAN_ROOT}/lib"; use Read_pkglists; -use vars qw(%binary_info %source_info %udeb_info %bin_src_ref); # from the above +use Read_taginfo; +use Util; -# These should really not be global. -my $maint = ""; -my $maint_file = ""; +# Global variables from Read_pkglists. Ugh. +# FIXME: Read_pkglists should return this information instead. +our (%binary_info, %source_info, %udeb_info, %bin_src_ref); -# Determine Lintian version -chomp(my $LINTIAN_VERSION = `$LINTIAN_ROOT/frontend/lintian --print-version`); +# Get the tag information from the Lintian *.desc files. +our %tag_info = %{ read_tag_info('html') }; -# Determine timestamp -chomp(my $timestamp = `date -u --rfc-822`); -chomp(my $mirror_timestamp = `cat $LINTIAN_ARCHIVEDIR/project/trace/ftp-master.debian.org`); +# Set the Lintian version, current timestamp, and archive timestamp. +our $LINTIAN_VERSION = `$LINTIAN_ROOT/frontend/lintian --print-version`; +our $timestamp = `date -u --rfc-822`; +our $mirror_timestamp = slurp_entire_file($LINTIAN_TIMESTAMP); +chomp ($LINTIAN_VERSION, $timestamp, $mirror_timestamp); -# Footer for each html page: -my $close_text = <<"EOT_EOT_EOT"; -<HR> -<div style="font-size: smaller"> -<p>Please send all comments about these web pages to -<A HREF="mailto:[EMAIL PROTECTED]">Lintian maintainer</A>.</p> -<p>Page last updated: $timestamp using Lintian $LINTIAN_VERSION</p> -</div> -</BODY></HTML> -EOT_EOT_EOT -# Read configuration file -read_bin_list(); -read_udeb_list(); -# read_src_list(); # not necessary, get_bin_src_ref will run it -get_bin_src_ref(); +# ------------------------------ +# Initialize templates -# Create output directories -mkdir($HTML_TMP_DIR,0777) - or die "cannot create output directory $HTML_TMP_DIR: $!"; -mkdir("$HTML_TMP_DIR/maintainer",0777) - or die "cannot create output directory $HTML_TMP_DIR/maintainer: $!"; +# The path to our templates. +our $TEMPLATES = "$LINTIAN_ROOT/reporting/templates"; -my ($num_errors, $num_warnings, $num_experimental, $num_overridden, $num_info); -$num_errors = $num_warnings = $num_experimental = $num_overridden = $num_info = 0; -my (%by_src, %by_tag); -my %anchor; - -# process input -while (<>) { - chomp; - next unless /^([EWXOI]): (\S+)( \S+)?: (\S+)/; - my ($code, $pkg, $type, $tag) = ($1, $2, $3, $4); - $type = ' binary' unless (defined $type); - my $src; - - if ($code eq 'E') { - $num_errors++; - } elsif ($code eq 'W') { - $num_warnings++; - } elsif ($code eq 'X') { - $num_experimental++; - } elsif ($code eq 'O') { - $num_overridden++; - next; - } elsif ($code eq 'I') { - $num_info++; - next; - } - - if ($type eq ' source') { - $src = $pkg; - unless (exists $source_info{$pkg}) { - print STDERR "error: source package $pkg not listed!\n"; - } - } else { - $src = $bin_src_ref{$pkg}; - unless ($src) { - print STDERR "error: source for package $pkg not found!\n"; - $src = $pkg; - } - } - - if (not exists $source_info{$src}) { - # work around: - $source_info{$src}->{'maintainer'} = - $binary_info{$pkg}->{'maintainer'} || - $udeb_info{$pkg}->{'maintainer'} || '(unknown)'; - $source_info{$src}->{'version'} = $binary_info{$pkg}->{'version'}; - } - - push(@{$by_src{$src}},$_); - push(@{$by_tag{$tag}},$_); +# This only has to be done once, so do it at the start and then reuse the same +# templates throughout. +our %templates; +for my $template (qw/clean index maintainer maintainers packages tag tags/) { + my %options = (TYPE => 'FILE', SOURCE => "$TEMPLATES/$template.tmpl"); + $templates{$template} = Text::Template->new (%options) + or die "cannot load template $template: $Text::Template::ERROR\n"; } -open_qa_list(); -open_maintainer_index(); -my ($src_num_errors, $src_num_warnings); -my ($num_binpkg, $num_udebpkg, $num_maint, $num_srcpkg); +# ------------------------------ +# Main routine -# Build a hash of all maintainers. We use this to generate stub pages for -# maintainers whose packages are all lintian-clean. -my %maintainers; -for my $src (keys %source_info) { - $maintainers{$source_info{$src}{maintainer}} = 1; -} +# Read the package lists. +# +# FIXME: get_bin_src_ref runs read_src_list unconditionally so we can't call +# it directly, which is confusing. +read_bin_list; +read_udeb_list; +get_bin_src_ref; -# Create per-maintainer list -for my $src (sort by_maint keys %by_src) { - my @tags; - my ($lastpkg, $lasttag); - $lastpkg = $lasttag = ""; +# Create output directories. +mkdir($HTML_TMP_DIR, 0777) + or die "cannot create output directory $HTML_TMP_DIR: $!\n"; +mkdir("$HTML_TMP_DIR/full", 0777) + or die "cannot create output directory $HTML_TMP_DIR/full: $!\n"; +mkdir("$HTML_TMP_DIR/maintainer", 0777) + or die "cannot create output directory $HTML_TMP_DIR/maintainer: $!\n"; +mkdir("$HTML_TMP_DIR/tags", 0777) + or die "cannot create output directory $HTML_TMP_DIR/tags: $!\n"; +copy("$LINTIAN_ROOT/reporting/lintian.css", "$HTML_TMP_DIR/lintian.css") + or die "cannot copy lintian.css to $HTML_TMP_DIR: $!\n"; - warn "no maintainer for $src!\n" - unless defined $source_info{$src}{maintainer}; - set_maintainer($source_info{$src}{'maintainer'}); - new_src_package($src, $source_info{$src}{'version'}); - delete $maintainers{$source_info{$src}{maintainer}}; +# This variable will accumulate statistics. For tags: errors, warnings, +# experimental, overridden, and info are the keys holding the count of tags of +# that sort. For packages: binary, udeb, and source are the number of +# packages of each type with Lintian errors or warnings. For maintainers: +# maintainers is the number of maintainers with Lintian errors or warnings. +my %statistics; - for (sort by_tag @{$by_src{$src}}) { - my ($code, $pkg, $type, $tag, $rest) = - /^(\S): (\S+)( \S+)?: (\S+)(.*)/; - $type = ' binary' unless (defined $type); - $rest = quotehtml($rest); +# %by_maint holds a hash of maintainer names to packages and tags. Each +# maintainer is a key. The value is a hash of package names to hashes. Each +# package hash is in turn a hash of versions to an anonymous array of hashes, +# with each hash having keys code, package, type, tag, extra, and xref. xref +# gets the partial URL of the maintainer page for that source package. +# +# In other words, the lintian output line: +# +# W: gnubg source: substvar-source-version-is-deprecated gnubg-data +# +# for gnubg 0.15~20061120-1 maintained by Russ Allbery <[EMAIL PROTECTED]> is +# turned into the following structure: +# +# { 'gnubg' => { +# '0.15~20061120-1' => [ +# { code => 'W', +# package => 'gnubg', +# type => 'source', +# tag => 'substvar-source-version-is-deprecated', +# extra => 'gnubg-data' +# xref => '[EMAIL PROTECTED]' } ] } } +# +# and then stored under the key 'Russ Allbery <[EMAIL PROTECTED]>' +# +# %by_tag is a hash of tag names to an anonymous array of tag information +# hashes just like the inside-most data structure above. +my (%by_maint, %by_tag); - # Create a table of these for the debian-qa folks - $src_num_errors++ if $code eq 'E'; - $src_num_warnings++ if $code eq 'W'; +# We take a lintian log file on either standard input or as the first +# argument. This log file contains all the tags lintian found, plus N: tags +# with informational messages. Ignore all the N: tags and load everything +# else into the hashes we use for all web page generation. +# +# We keep track of a hash from maintainer page URLs to maintainer values so +# that we don't have two maintainers who map to the same page and overwrite +# each other's pages. If we find two maintainers who map to the same URL, +# just assume that the second maintainer is the same as the first (but warn +# about it). +my (%seen, %urlmap, %warned); +while (<>) { + chomp; + next unless /^([EWIXO]): (\S+)(?: (\S+))?: (\S+)(?:\s+(.*))?/; + my ($code, $package, $type, $tag, $extra) = ($1, $2, $3, $4, $5); + $type = 'binary' unless (defined $type); + next unless ($type eq 'source' || $type eq 'binary' || $type eq 'udeb'); - if ($pkg ne $lastpkg and $type eq ' binary') { - $num_binpkg++; - drop_anchor($pkg, ""); - } elsif ($pkg ne $lastpkg and $type eq ' udeb') { - $num_udebpkg++; - drop_anchor($pkg, ""); - } - if ($tag ne $lasttag or $pkg ne $lastpkg) { - output_chunk([EMAIL PROTECTED]) if @tags; - undef @tags; - } - $lastpkg = $pkg if $type ne ' source'; - $lasttag = $tag; - - $tag = make_tagref($tag); - push(@tags,"$code: $pkg$type: $tag$rest\n"); + # Update statistics. + my $key = { + E => 'errors', + W => 'warnings', + I => 'info', + X => 'experimental', + O => 'overridden' + }->{$code}; + $statistics{$key}++; + unless ($seen{"$package $type"}) { + $statistics{"$type-packages"}++; + $seen{"$package $type"} = 1; } - output_chunk([EMAIL PROTECTED]) if @tags; - undef @tags; - - end_src_package($src); -} - -close_maintainer(); -close_maintainer_index(); -close_qa_list(); - -# Now, generate stub pages for every maintainer who has only clean packages. -# Opening the index to /dev/null is such a hack. Code refactoring is -# desperately needed here. -open(I, '>', '/dev/null'); -for my $maintainer (keys %maintainers) { - set_maintainer($maintainer); - print P "<p>All of this maintainer's packages are lintian-clean.</p>\n"; -} -close_maintainer(); -close I; - -# Create tag pages -open_tag_index(); -for my $tag (sort keys %by_tag) { - my $lastpkg = ""; - my $tag_pkgs = 0; - my @tags; - - open_tag_file($tag); - - for (sort @{$by_tag{$tag}}) { - my ($code, $pkg, $type, $tag, $rest) = - /^(\S): (\S+)( \S+)?: (\S+)(.*)/; - $type = "" unless (defined $type); # probably...? - $rest = quotehtml($rest); - - if ($pkg ne $lastpkg) { - if (@tags) { - $tag_pkgs++; - output_chunk([EMAIL PROTECTED]); - undef @tags; - } - - } - $lastpkg = $pkg; - - $pkg = make_anchor($pkg); - push(@tags,"$code: $pkg$type: $tag$rest\n"); + # Determine the source package for this package and warn if there appears + # to be no source package in the archive. Determine the maintainer and + # version. Work around a missing source package by pulling information + # from a binary package or udeb of the same name if there is any. + my ($source, $version, $maintainer); + if ($type eq 'source') { + $source = $package; + if (exists $source_info{$source}) { + $version = $source_info{$source}->{version}; + $maintainer = $source_info{$source}->{maintainer}; + } else { + warn "source package $package not listed!\n"; + } + } else { + $source = $bin_src_ref{$package}; + if ($source and exists $source_info{$source}) { + $maintainer = $source_info{$source}->{maintainer}; + } else { + warn "source for package $package not found!\n"; + $source = $package; + if ($type eq 'binary') { + $maintainer = $binary_info{$package}->{maintainer}; + } elsif ($type eq 'udeb') { + $maintainer = $udeb_info{$package}->{maintainer}; + } + } + if ($type eq 'binary') { + $version = $binary_info{$package}->{version}; + } elsif ($type eq 'udeb') { + $version = $udeb_info{$package}->{version}; + } } + $maintainer ||= '(unknown)'; + $version ||= 'unknown'; - if (@tags) { - $tag_pkgs++; - output_chunk([EMAIL PROTECTED]); - undef @tags; + # Check if we've seen the URL for this maintainer before. + my $url = maintainer_url ($maintainer); + if ($urlmap{$url} && $urlmap{$url} ne $maintainer) { + warn "$maintainer has the same page as $urlmap{$url}\n" + unless ($warned{$maintainer} + || lc ($maintainer) eq lc ($urlmap{$url}) + || $maintainer =~ /[EMAIL PROTECTED](alioth\.)?debian\.org>/); + $warned{$maintainer}++; + $maintainer = $urlmap{$url}; + } else { + $urlmap{$url} = $maintainer; } - close_tag_file($tag); - list_tag($tag, $#{$by_tag{$tag}} + 1, $tag_pkgs); -} -close_tag_index(); + # Update maintainer statistics. + $statistics{maintainers}++ unless defined $by_maint{$maintainer}; -# Create per-package list -my %package_lists; -for my $p (sort keys %anchor) { - my $c = uc substr($p,0,1); - push (@{$package_lists{$c}}, make_anchor($p)); -} + # Sanitize, just out of paranoia. + $source =~ s/[^a-zA-Z0-9.+-]/_/g; + $version =~ s/[^a-zA-Z0-9.+:~-]/_/g; -my (@list1, @list2, @list3, @list4); -for my $c (sort keys %package_lists) { - my $list = join(', ', @{$package_lists{$c}}); - $list = "<H1>$c</H1>\n<BLOCKQUOTE>\n$list</BLOCKQUOTE>\n"; - if ($c le 'F') { - push(@list1, $list); - } elsif ($c le 'L') { - push(@list2, $list); - } elsif ($c le 'R') { - push(@list3, $list); - } elsif ($c le 'Z') { - push(@list4, $list); - } + # Add the tag information to our hashes. Share the data between the + # hashes to save space (which means we can't later do destructive tricks + # with it). + my $info = { + code => html_quote ($code), + package => html_quote ($package), + type => html_quote ($type), + tag => html_quote ($tag), + extra => html_quote ($extra), + xref => maintainer_url ($maintainer) . "#$source" + }; + $by_maint{$maintainer}{$source}{$version} ||= []; + push(@{ $by_maint{$maintainer}{$source}{$version} }, $info); + $by_tag{$tag} ||= []; + push(@{ $by_tag{$tag} }, $info); } -output_packages([EMAIL PROTECTED],'packages_1.html','0-9, A-F'); -output_packages([EMAIL PROTECTED],'packages_2.html','G-L'); -output_packages([EMAIL PROTECTED],'packages_3.html','M-R'); -output_packages([EMAIL PROTECTED],'packages_4.html','S-Z'); - -# Read old statistics file -my $old_stat; -if (-f $statistics_file) { - ($old_stat) = read_dpkg_control($statistics_file); +# Build a hash of all maintainers, not just those with Lintian tags. We use +# this later to generate stub pages for maintainers whose packages are all +# Lintian-clean. +my %clean; +for my $source (keys %source_info) { + $clean{$source_info{$source}->{maintainer}} = 1; } -$old_stat->{'info'} ||= 0; -# Calculate changes -my $delta_num_maint = sprintf "%+d",$num_maint-$old_stat->{'maintainers'}; -my $delta_num_srcpkg = sprintf "%+d",$num_srcpkg-$old_stat->{'source-packages'}; -my $delta_num_binpkg = sprintf "%+d",$num_binpkg-$old_stat->{'binary-packages'}; -my $delta_num_udebpkg = sprintf "%+d",$num_udebpkg-$old_stat->{'udeb-packages'}; -my $delta_num_warnings = sprintf "%+d",$num_warnings-$old_stat->{'warnings'}; -my $delta_num_errors = sprintf "%+d",$num_errors-$old_stat->{'errors'}; -my $delta_num_experimental = sprintf "%+d",$num_experimental-$old_stat->{'experimental'}; -my $delta_num_info = sprintf "%+d",$num_info-$old_stat->{'info'}; -my $delta_num_overridden = sprintf "%+d",$num_overridden-$old_stat->{'overridden'}; +# Now, walk through the tags by source package (sorted by maintainer). Output +# a summary page of errors and warnings for each maintainer, output a full +# page that includes info, experimental, and overriden tags, and assemble the +# maintainer index and the QA package list as we go. +my (%qa, %maintainers, %packages); +for my $maintainer (sort keys %by_maint) { + delete $clean{$maintainer}; -# update statistics file -my $stat; -$stat->{'last-updated'} = $timestamp; -$stat->{'mirror-timestamp'} = $mirror_timestamp; -$stat->{'maintainers'} = $num_maint; -$stat->{'source-packages'} = $num_srcpkg; -$stat->{'binary-packages'} = $num_binpkg; -$stat->{'udeb-packages'} = $num_udebpkg; -$stat->{'warnings'} = $num_warnings; -$stat->{'errors'} = $num_errors; -$stat->{'experimental'} = $num_experimental; -$stat->{'info'} = $num_info; -$stat->{'overridden'} = $num_overridden; -$stat->{'lintian-version'} = $LINTIAN_VERSION; -open(OUT,'>', $statistics_file) - or die "cannot open statistics file $statistics_file for writing: $!"; -for my $k (keys %$stat) { - printf OUT "%s: %s\n",$k,$stat->{$k}; -} -close(OUT); + # For each of this maintainer's packages, add statistical information + # about warnings and errors to the QA list and build the packages hash + # used for the package index. + my ($errors, $warnings) = (0, 0); + for my $source (keys %{ $by_maint{$maintainer} }) { + for my $version (keys %{ $by_maint{$maintainer}{$source} }) { + my $tags = $by_maint{$maintainer}{$source}{$version}; + for my $tag (@$tags) { + $errors++ if $tag->{code} eq 'E'; + $warnings++ if $tag->{code} eq 'W'; + $packages{$tag->{package}} = $tag->{xref}; + } + } + $qa{$source} = [ $errors, $warnings ]; + } -# create index page -open(OUT,'>', "$HTML_TMP_DIR/report-index.html") - or die "cannot open index page $HTML_TMP_DIR/report-index.html for writing: $!"; -print OUT <<"EOT_EOT_EOT"; -<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" - "http://www.w3.org/TR/html4/strict.dtd"> -<html lang="en"> -<head> - <title>Lintian</title> -</head> -<body background="bg.gif"> + # Determine the parts of the maintainer and the file name for the + # maintainer page. + my ($name, $email) = ($maintainer =~ /^(.*) <([^>]+)>/); + $email = 'unknown' unless $email; + my $id = maintainer_url ($maintainer); + my $regular = "maintainer/$id"; + my $full = "full/$id"; -<img align="left" src="logo.gif" alt="Lintian" width=300 height=200> - -<H1>Lintian</H1> - -<p>Lintian dissects <a href="http://www.debian.org/">Debian</a> -<a href="http://packages.debian.org/">packages</a> and reports bugs -and policy violations. It contains automated checks for many aspects -of <a href="http://www.debian.org/doc/debian-policy/">Debian policy</a> -as well as some checks for common errors.</p> - -<p>For more information, see the <a href="manual/index.html">User -Manual</a>.</p> - -<p>Lintian is available in the -<a href="http://packages.debian.org/lintian">lintian package</a>.</p> - -<hr size=1> - -<p>The following Lintian report indices are available:</p> - -<ul> - <li><strong><a href="reports/maintainers.html">Maintainers</a></strong></li> - - <li><strong><a href="reports/tags.html">Tag types</a></strong></li> - - <li><strong>Packages that have names starting with:</strong> - <ul> - <li><a href="reports/packages_1.html">0-9, A-F</a> - <li><a href="reports/packages_2.html">G-L</a> - <li><a href="reports/packages_3.html">M-R</a> - <li><a href="reports/packages_4.html">S-Z</a> - </ul> - </li> -</ul> - -<p>Statistics:</p> - -<blockquote> -<table> -<tr><td>Last updated:</td> <td>$timestamp</td></tr> -<tr><td>Archive timestamp:</td> <td>$mirror_timestamp</td></tr> -<tr><td>Distribution/section/architecture:</td> <td>$LINTIAN_DIST / $LINTIAN_SECTION / $LINTIAN_ARCH</td></tr> -<tr><td>Maintainers listed:</td> <td>$num_maint ($delta_num_maint)</td></tr> -<tr><td>Source packages listed:</td> <td>$num_srcpkg ($delta_num_srcpkg)</td></tr> -<tr><td>Binary packages listed:</td> <td>$num_binpkg ($delta_num_binpkg)</td></tr> -<tr><td>Udeb packages listed:</td> <td>$num_udebpkg ($delta_num_udebpkg)</td></tr> -<tr><td>Warnings:</td> <td>$num_warnings ($delta_num_warnings)</td></tr> -<tr><td>Errors:</td> <td>$num_errors ($delta_num_errors)</td></tr> -<tr><td>Info tags:</td> <td>$num_info ($delta_num_info)</td></tr> -<tr><td>Overridden tags:</td> <td>$num_overridden ($delta_num_overridden)</td></tr> -<tr><td>Lintian version:</td> <td>$LINTIAN_VERSION</td></tr> -</table> -</blockquote> - -<p>(The numbers in parentheses describe the changes since the last Lintian -report, published on $old_stat->{'last-updated'}.)</p> - -$close_text -EOT_EOT_EOT -close(OUT); - -exit 0; - -# ------------------------------- - -sub open_maintainer_index { - open(I, '>', "$HTML_TMP_DIR/maintainers.html") or die "$!"; - print I <<EOH; -<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" - "http://www.w3.org/TR/html4/strict.dtd"> -<html lang="en"> -<head> -<title>Lintian report, sorted by maintainers</title> -<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> -</head> -<body> -<h1>Lintian report, sorted by maintainers</h1> -EOH -; - -} - -sub close_maintainer_index { - print I $close_text; - close(I); -} - -sub list_maintainer { - print I "\n<p><a href=\"$_[0]\">$_[1]</a>\n"; - $num_maint++; -} - -# ------------------------------- - -sub open_tag_index { - open(T, '>', "$HTML_TMP_DIR/tags.html") or die "$!"; - print T <<EOH; -<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" - "http://www.w3.org/TR/html4/strict.dtd"> -<HTML lang="en"> -<HEAD> -<TITLE>Lintian report, sorted by tags</TITLE> -<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> -</HEAD> -<BODY> -<H1>Lintian report, sorted by tags</H1> -EOH -; - -} - -sub close_tag_index { - print T $close_text; - close(T); -} - -sub list_tag { - my ($ts, $ps) = ( "", "" ); - - $ts = 's' if $_[1] != 1; - $ps = 's' if $_[2] != 1; - print T "\n" . make_tagref($_[0]) . " ($_[2] package$ps, $_[1] tag$ts)<P>\n"; -} - -# ------------------------------- - -sub open_maintainer { - return if ($maint_file && $_[0] eq $maint_file); - close_maintainer(); - - $maint_file = $_[0]; - open(P, '>', "$HTML_TMP_DIR/$maint_file") or die "$!"; - - my $t = quotehtml($maint); - - print P <<EOH; -<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" - "http://www.w3.org/TR/html4/strict.dtd"> -<HTML lang="en"> -<HEAD> -<title>Lintian report for $t</title> -<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> -</HEAD> -<body> -<h2>Lintian report for</h2> -<h1>$t</h1> -EOH -; - - list_maintainer($maint_file, $t); -} - -sub set_maintainer { - return if $_[0] eq $maint; - - $maint = $_[0]; - - # The maintainer page should be maintainer/<email>.html where <email> is - # their email address with all characters other than a-z A-Z 0-9 - _ . @ = - # + replaced with _. Don't change this without coordinating with QA. - my ($file) = ($maint =~ /<([^>]+)>/); - if ($file) { - $file =~ tr/[EMAIL PROTECTED]/_/c; - $file = "maintainer/$file.html"; + # Create the regular maintainer page (only errors and warnings) and the + # full maintainer page (all tags, including overrides and info tags). + my %data = ( + email => html_quote ($email), + errors => 1, + id => $id, + maintainer => html_quote ($maintainer), + name => html_quote ($name), + packages => $by_maint{$maintainer}, + timestamp => $timestamp, + version => $LINTIAN_VERSION + ); + my $template; + if ($errors || $warnings) { + $template = $templates{maintainer}; } else { - $file = "maintainer/unsorted.html"; + $template = $templates{clean}; } + output_template ($regular, $template, \%data); + $template = $templates{maintainer}; + $data{errors} = 0; + output_template ($full, $template, \%data); - open_maintainer($file); + # Add this maintainer to the hash of maintainer to URL mappings. + $maintainers{$maintainer} = $id; } -sub drop_anchor { - my ($anch, $text) = @_; - my $key = $anch; +# Write out the maintainer index. +my %data = ( + maintainers => \%maintainers, + timestamp => $timestamp, + version => $LINTIAN_VERSION +); +output_template ('maintainers.html', $templates{maintainers}, \%data); - if (exists $anchor{$key}) { - print P $text; - } else { - $anch =~ tr/-/_/; # dashes don't work correctly in anchors - print P "<a id=\"$anch\" name=\"$anch\">$text</a>"; +# Write out the QA package list. +open (QA, '>', "$HTML_TMP_DIR/qa-list.txt") + or die "cannot create qa-list.txt: $!\n"; +for my $source (sort keys %qa) { + print QA "$source $qa{$source}[0] $qa{$source}[1]\n"; +} +close QA or die "cannot write to qa-list: $!\n"; - $anchor{$key} = "$maint_file#$anch"; - } +# Now, generate stub pages for every maintainer who has only clean packages. +for my $maintainer (keys %clean) { + my ($name, $email) = ($maintainer =~ /^(.*) <([^>]+)>/); + $email = 'unknown' unless $email; + my %data = ( + email => html_quote ($email), + maintainer => html_quote ($maintainer), + name => html_quote ($name), + timestamp => $timestamp, + version => $LINTIAN_VERSION + ); + my $id = maintainer_url ($maintainer); + next if $urlmap{$id}; + output_template ("maintainer/$id", $templates{clean}, \%data); + output_template ("full/$id", $templates{clean}, \%data); } -sub make_anchor { - my $key = shift; - if ($anchor{$key}) { - return "<a href=\"$anchor{$key}\">$key</a>"; +# Create the pages for each tag. Each page shows the extended description for +# the tag and all the packages for which that tag was issued. +for my $tag (sort keys %by_tag) { + my $description; + if ($tag_info{$tag}) { + $description = wrap_paragraphs('HTML', ' ', $tag_info{$tag}); } else { - return $key; + $description = " <p>Can't find description of tag $tag.</p>"; } + my %data = ( + description => $description, + tag => html_quote ($tag), + tags => $by_tag{$tag}, + timestamp => $timestamp, + version => $LINTIAN_VERSION + ); + output_template ("tags/$tag.html", $templates{tag}, \%data); } -sub close_maintainer { - return if not $maint_file; +# Create the general tag index. +%data = ( + tags => \%by_tag, + timestamp => $timestamp, + version => $LINTIAN_VERSION +); +output_template ('tags.html', $templates{tags}, \%data); - print P $close_text; - close(P); - - undef $maint_file; +# Generate the package lists. These are huge, so we break them into four +# separate pages. +# +# FIXME: Does anyone actually use these pages? They're basically unreadable. +my %list; +$list{'0-9, A-F'} = []; +$list{'G-L'} = []; +$list{'M-R'} = []; +$list{'S-Z'} = []; +for my $package (sort keys %packages) { + my $first = uc substr($package, 0, 1); + if ($first le 'F') { push(@{ $list{'0-9, A-F'} }, $package) } + elsif ($first le 'L') { push(@{ $list{'G-L'} }, $package) } + elsif ($first le 'R') { push(@{ $list{'M-R'} }, $package) } + else { push(@{ $list{'S-Z'} }, $package) } } - -# ------------------------------- - -sub new_src_package { - my ($src, $ver) = @_; - - print P "\n<hr> <h2>"; - drop_anchor($src, "Source package: $src ($ver)"); - print P "</h2>\n"; - - $num_srcpkg++; - $src_num_errors = 0; - $src_num_warnings = 0; +%data = ( + packages => \%packages, + timestamp => $timestamp, + version => $LINTIAN_VERSION +); +my $i = 1; +for my $section (sort keys %list) { + $data{section} = $section; + $data{list} = $list{$section}; + output_template ("packages_$i.html", $templates{packages}, \%data); + $i++; } -sub end_src_package { - my ($src) = @_; - - list_qa_entry($src, $src_num_errors, $src_num_warnings); +# Finally, we can start creating the index page. First, read in the old +# statistics file so that we can calculate deltas for all of our statistics. +my $old_statistics; +if (-f $statistics_file) { + ($old_statistics) = read_dpkg_control($statistics_file); } - -# ------------------------------- - -sub open_qa_list { - open(Q, '>', "$HTML_TMP_DIR/qa-list.txt") or die "$!"; +my %delta; +my @attrs = qw(maintainers source-packages binary-packages udeb-packages + errors warnings info experimental overridden); +for my $attr (@attrs) { + my $old = $old_statistics->{$attr} || 0; + $statistics{$attr} ||= 0; + $delta{$attr} = sprintf("%d (%+d)", $statistics{$attr}, + $statistics{$attr} - $old); } -sub close_qa_list { - close(Q); +# Update the statistics file. +open (STATS, '>', $statistics_file) + or die "cannot open $statistics_file for writing: $!\n"; +print STATS "last-updated: $timestamp\n"; +print STATS "mirror-timestamp: $mirror_timestamp\n"; +for my $attr (@attrs) { + print STATS "$attr: $statistics{$attr}\n"; } +print STATS "lintian-version: $LINTIAN_VERSION\n"; +close STATS or die "cannot write to $statistics_file: $!\n"; -sub list_qa_entry { - my ($src, $errs, $warns) = @_; - print Q "$src $errs $warns\n"; -} +# Create the main page. +%data = ( + architecture => $LINTIAN_ARCH, + delta => \%delta, + dist => $LINTIAN_DIST, + mirror => $mirror_timestamp, + previous => $old_statistics->{'last-updated'}, + section => $LINTIAN_SECTION, + timestamp => $timestamp, + version => $LINTIAN_VERSION +); +output_template ('index.html', $templates{index}, \%data); +exit 0; -# ------------------------------- +# ------------------------------ +# Utility functions -sub open_tag_file { - my $tag = shift; - - open(P, '>', "$HTML_TMP_DIR/T$tag.html") or die "$!"; - print P <<EOH; -<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" - "http://www.w3.org/TR/html4/strict.dtd"> -<HTML lang="en"> -<HEAD> -<TITLE>Lintian report for $tag</TITLE> -<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> -</HEAD> -<BODY> -<H2>Lintian report for</H2> -<H1>$tag</H1> -EOH -; - - # print explanation about tag, if available - if ($tag_info{$tag}) { - print P "<blockquote>\n"; - print P wrap_paragraphs('HTML', '',$tag_info{$tag}),"\n"; - print P "</blockquote>\n"; +# Determine the file name for the maintainer page given a maintainer. It +# should be <email>.html where <email> is their email address with all +# characters other than a-z A-Z 0-9 - _ . @ = + replaced with _. Don't change +# this without coordinating with QA. +sub maintainer_url { + my ($maintainer) = @_; + my ($email) = ($maintainer =~ /<([^>]+)>/); + my ($regular, $full); + if ($email) { + my $id = $email; + $id =~ tr/[EMAIL PROTECTED]/_/c; + return "$id.html"; } else { - warn "Can't find info for tag $tag.\n"; + return 'unsorted.html'; } - - print P "<HR>\n"; } -sub close_tag_file { - print P $close_text; - close(P); +# Quote special characters for HTML output. +sub html_quote { + my ($text) = @_; + $text ||= ''; + $text =~ s/&/\&/g; + $text =~ s/</\</g; + $text =~ s/>/\>/g; + return $text; } -sub make_tagref { - return "<a href=\"T$_[0].html\">$_[0]</a>"; +# Given a file name, a template, and a data hash, fill out the template with +# that data hash and output the results to the file. +sub output_template { + my ($file, $template, $data) = @_; + open (OUTPUT, '>', "$HTML_TMP_DIR/$file") + or die "creating $HTML_TMP_DIR/$file falied: $!\n"; + $template->fill_in (OUTPUT => \*OUTPUT, HASH => $data) + or die "filling out $file failed: $Text::Template::ERROR\n"; + close OUTPUT; } -# ------------------------------- - -sub output_chunk { - my ($pbuf) = @_; - - my $count = $#$pbuf+1; - if ($count > $max_tags) { - splice(@$pbuf,$max_tags-1); - push(@$pbuf, sprintf(" ... reported %d more times\n", - $count-($max_tags-1))); - } - - print P "<PRE>\n " . join(' ', @$pbuf) . "</PRE>\n"; -} - -sub output_packages { - my ($l,$f,$r) = @_; - - open(I, '>', "$HTML_TMP_DIR/$f") or die "$!"; - print I <<EOH; -<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" - "http://www.w3.org/TR/html4/strict.dtd"> -<HTML lang="en"> -<HEAD> -<TITLE>Lintian report, sorted by packages ($r)</TITLE> -<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> -</HEAD> -<BODY> -<H1>Lintian report, sorted by packages ($r)</H1> -<a href="packages_1.html">0-9, A-F</a> | -<a href="packages_2.html">G-L</a> | -<a href="packages_3.html">M-R</a> | -<a href="packages_4.html">S-Z</a> -EOH -; - print I @$l; - - print I $close_text; - close(I); -} - -# ------------------------------- - -sub by_maint { - $source_info{$a}->{'maintainer'} cmp $source_info{$b}->{'maintainer'} - || $a cmp $b; -} - -sub by_tag { - substr($a,3) cmp substr($b,3); -} - -sub quotehtml { - $_ = $_[0] . ''; - s/&/\&/g; - s/</\</g; - s/>/\>/g; - return $_; -} +# Local Variables: +# indent-tabs-mode: nil +# cperl-indent-level: 4 +# End: +# vim: syntax=perl sw=4 sts=4 ts=4 et shiftround Added: trunk/reporting/lintian.css =================================================================== --- trunk/reporting/lintian.css (rev 0) +++ trunk/reporting/lintian.css 2008-01-03 00:04:10 UTC (rev 1083) @@ -0,0 +1,9 @@ +/* lintian.css -- Style sheet for lintian.debian.org pages. */ + +h1 { + text-align: center; +} + +div.footer { + font-size: smaller; +} Added: trunk/reporting/templates/clean.tmpl =================================================================== --- trunk/reporting/templates/clean.tmpl (rev 0) +++ trunk/reporting/templates/clean.tmpl 2008-01-03 00:04:10 UTC (rev 1083) @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE html + PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head> + <title>Lintian Report for {$name}</title> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <link rel="stylesheet" href="../lintian.css" type="text/css" /> +</head> + +<body> + <h1>Lintian Report for {$name}</h1> + + <p> + All of the packages maintained by {$maintainer} are Lintian-clean. + </p> + + <p> + Also see their + <a href="http://qa.debian.org/developer.php?login={$email}">QA + overview</a>. + </p> + + <hr /> + <div class="footer"> + <p> + Please send all comments about these web pages to the + <a href="mailto:[EMAIL PROTECTED]">Lintian maintainers</a>.<br /> + Page last updated: {$timestamp} using Lintian {$version} + </p> + </div> +</body> +</html> Added: trunk/reporting/templates/index.tmpl =================================================================== --- trunk/reporting/templates/index.tmpl (rev 0) +++ trunk/reporting/templates/index.tmpl 2008-01-03 00:04:10 UTC (rev 1083) @@ -0,0 +1,90 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE html + PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head> + <title>Lintian</title> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <link rel="stylesheet" href="lintian.css" type="text/css" /> +</head> + +<body background="bg.gif"> + <img align="left" src="logo.gif" alt="Lintian" width="300" height="200"> + + <h1>Lintian</h1> + + <p> + Lintian dissects <a href="http://www.debian.org/">Debian</a> + <a href="http://packages.debian.org/">packages</a> and tries to find + bugs and policy violations. It contains automated checks for many + aspects of <a href="http://www.debian.org/doc/debian-policy/">Debian + policy</a> as well as some checks for common errors. + </p> + + <p> + For more information, see the <a href="manual/index.html">User + Manual</a>. + </p> + + <p> + Lintian is available in the Debian + <a href="http://packages.debian.org/lintian">lintian package</a>. + </p> + + <hr /> + + <p>The following Lintian report indices are available:</p> + + <ul> + <li><strong><a href="reports/maintainers.html">Maintainers</a></strong></li> + <li><strong><a href="reports/tags.html">Tag types</a></strong></li> + <li><strong>Packages that have names starting with:</strong> + <ul> + <li><a href="reports/packages_1.html">0-9, A-F</a></li> + <li><a href="reports/packages_2.html">G-L</a></li> + <li><a href="reports/packages_3.html">M-R</a></li> + <li><a href="reports/packages_4.html">S-Z</a></li> + </ul> + </li> + </ul> + + <dl> + <dt>Statistics:</dt> + <dd> + <table> + <tr><td>Last updated:</td> <td>{$timestamp}</td></tr> + <tr><td>Archive timestamp:</td><td>{$mirror}</td></tr> + <tr><td>Distribution:</td> <td>{$dist}</td></tr> + <tr><td>Section:</td> <td>{$section}</td></tr> + <tr><td>Architecture:</td> <td>{$architecture}</td></tr> + <tr><td>Maintainers:</td> <td>{$delta{maintainers}}</td></tr> + <tr><td>Source packages:</td> <td>{$delta{'source-packages'}}</td></tr> + <tr><td>Binary packages:</td> <td>{$delta{'binary-packages'}}</td></tr> + <tr><td>Udeb packages:</td> <td>{$delta{'udeb-packages'}}</td></tr> + <tr><td>Warnings:</td> <td>{$delta{warnings}}</td></tr> + <tr><td>Errors:</td> <td>{$delta{errors}}</td></tr> + <tr><td>Info tags:</td> <td>{$delta{info}}</td></tr> + <tr><td>Overridden tags:</td> <td>{$delta{overridden}}</td></tr> + <tr><td>Experimental tags:</td><td>{$delta{experimental}}</td></tr> + <tr><td>Lintian version:</td> <td>{$version}</td></tr> + </table> + </dd> + </dl> + + <p> + (The numbers in parentheses describe the changes since the last Lintian + report, published on {$previous}. + </p> + + <hr /> + <div class="footer"> + <p> + Please send all comments about these web pages to the + <a href="mailto:[EMAIL PROTECTED]">Lintian maintainers</a>.<br /> + Page last updated: {$timestamp} using Lintian {$version} + </p> + </div> +</body> +</html> Added: trunk/reporting/templates/maintainer.tmpl =================================================================== --- trunk/reporting/templates/maintainer.tmpl (rev 0) +++ trunk/reporting/templates/maintainer.tmpl 2008-01-03 00:04:10 UTC (rev 1083) @@ -0,0 +1,91 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE html + PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head> + <title>Lintian Report for {$name}</title> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <link rel="stylesheet" href="../lintian.css" type="text/css" /> +</head> + +<body> + <h1>Lintian Report for {$name}</h1> + + <p> + At the time of the last Lintian run, the following possible problems + were found in packages maintained by {$maintainer}, listed by source + package. +{ + if ($errors) { + qq( See also the <a href="../full/$id">full report</a>, including) + . " info and overridden tags."; + } else { + qq( See also the <a href="../maintainer/$id">report showing) + . " only errors and warnings</a>."; + } +} + </p> + + <p> + Also see their + <a href="http://qa.debian.org/developer.php?login={$email}">QA + overview</a>. + </p> + + <dl> +{ + # We get a hash of package names to a hash of versions to a list of + # tags. Create a description list with the package information as the + # title and the tags as the value. + for my $source (sort keys %packages) { + my $anchored; + for my $version (sort keys %{ $packages{$source} }) { + my $tags = $packages{$source}{$version}; + my $last = ''; + for my $info (@$tags) { + if ($errors) { + next unless $info->{code} eq 'E' or $info->{code} eq 'W'; + } + unless ($last) { + if ($anchored) { + $OUT .= qq( <dt>); + } else { + $OUT .= qq( <dt id="$source"><a name="$source">); + } + $OUT .= "<strong>$source ($version)</strong>"; + if ($anchored) { + $OUT .= qq(</dt>\n <dd>\n); + } else { + $OUT .= qq(</a></dt>\n <dd>\n); + $anchored = 1; + } + } + my $id = "$info->{package} $info->{type}"; + my $tag = qq(<a href="../tags/$info->{tag}.html">) + . $info->{tag} . '</a>'; + if ($id ne $last) { + if ($last) { + $OUT .= "</pre>\n\n"; + } + $OUT .= " <pre>\n"; + } + $last = $id; + $OUT .= "$info->{code}: $id: $tag $info->{extra}\n"; + } + $OUT .= "</pre>\n </dd>\n"; + } + } +} </dl> + + <hr /> + <div class="footer"> + <p> + Please send all comments about these web pages to the + <a href="mailto:[EMAIL PROTECTED]">Lintian maintainers</a>.<br /> + Page last updated: {$timestamp} using Lintian {$version} + </p> + </div> +</body> +</html> Added: trunk/reporting/templates/maintainers.tmpl =================================================================== --- trunk/reporting/templates/maintainers.tmpl (rev 0) +++ trunk/reporting/templates/maintainers.tmpl 2008-01-03 00:04:10 UTC (rev 1083) @@ -0,0 +1,66 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE html + PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head> + <title>Lintian Report by Maintainer</title> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <link rel="stylesheet" href="lintian.css" type="text/css" /> +</head> + +<body> + <h1>Lintian Report by Maintainer</h1> + + <p> + Maintainers are listed sorted case-insensitively by package maintainer + string. This is an unsophisticated sort that doesn't take into + account any national collating sequence, only Unicode strings, so + maintainers whose names start with non-ASCII characters will sort at + the end of this page. + </p> + + <p> + Jump to: { join (' ', map { qq(<a href="#$_">$_</a>) } 'A'..'Z') } + </p> + +{ + # Put headings before each new initial letter and add anchors, except + # for non-ASCII initial characters. For those, since we can't be + # assured we'll get combining characters right, just accumulate them + # under a heading of Other. + my $letter = ''; + for my $maintainer (sort { lc ($a) cmp lc ($b) } keys %maintainers) { + my ($url) = $maintainers{$maintainer}; + my $first = uc substr($maintainer, 0, 1); + if ($first lt 'A' || $first gt 'Z') { + $first = 'Other'; + } + if ($first ne $letter) { + unless ($letter) { + $OUT .= " </p>\n\n"; + } + $letter = $first; + if ($letter eq 'Other') { + $OUT .= qq( </p>\n\n <h2>Other</h2>\n\n <p>\n); + } else { + $OUT .= qq( </p>\n\n <h2 id="$letter"><a name="$letter">) + . $letter . "</a></h2>\n\n <p>\n"; + } + } + $OUT .= qq( <a href="maintainer/$url">$maintainer</a>) + . qq{ (<a href="full/$url">full report</a>)<br />\n}; + } +} </p> + + <hr /> + <div class="footer"> + <p> + Please send all comments about these web pages to the + <a href="mailto:[EMAIL PROTECTED]">Lintian maintainers</a>.<br /> + Page last updated: {$timestamp} using Lintian {$version} + </p> + </div> +</body> +</html> Added: trunk/reporting/templates/packages.tmpl =================================================================== --- trunk/reporting/templates/packages.tmpl (rev 0) +++ trunk/reporting/templates/packages.tmpl 2008-01-03 00:04:10 UTC (rev 1083) @@ -0,0 +1,54 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE html + PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head> + <title>Lintian Reports Package Index: {$section}</title> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <link rel="stylesheet" href="lintian.css" type="text/css" /> +</head> + +<body> + <h1>Lintian Reports Package Index: {$section}</h1> + + <p> + This is a list of all source or binary packages that have at least one + lintian tag. This includes all tags, even experimental and info tags + and tags that were overridden. The list is huge, so it's broken into + four separate pages. This page covers package names starting with + {$section}. + </p> + + <p> + <a href="packages_1.html">0-9, A-F</a> + | <a href="packages_2.html">G-L</a> + | <a href="packages_3.html">M-R</a> + | <a href="packages_4.html">S-Z</a> + </p> + +{ + # Put headings before each new initial letter. + my $letter = ''; + for my $package (@list) { + my $first = uc substr($package, 0, 1); + if ($first ne $letter) { + $OUT .= " </p>\n\n" if $letter; + $OUT .= qq( <h2>$first</h2>\n\n <p>\n); + $letter = $first; + } + $OUT .= qq( <a href="full/$packages{$package}">$package</a>\n); + } +} </p> + + <hr /> + <div class="footer"> + <p> + Please send all comments about these web pages to the + <a href="mailto:[EMAIL PROTECTED]">Lintian maintainers</a>.<br /> + Page last updated: {$timestamp} using Lintian {$version} + </p> + </div> +</body> +</html> Added: trunk/reporting/templates/tag.tmpl =================================================================== --- trunk/reporting/templates/tag.tmpl (rev 0) +++ trunk/reporting/templates/tag.tmpl 2008-01-03 00:04:10 UTC (rev 1083) @@ -0,0 +1,59 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE html + PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head> + <title>Lintian Tag {$tag}</title> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <link rel="stylesheet" href="../lintian.css" type="text/css" /> +</head> + +<body> + <h1>Lintian Tag {$tag}</h1> + + <p> + All reports of {$tag} for the archive. The extended description of + this tag is: + </p> + + <blockquote> +{$description} + </blockquote> + + <p> + The package names link to the relevant maintainer page and the + corresponding report for the source package. The links go to the full + maintainer report page, which includes info and experimental tags and + overridden tags, rather than the default page that shows only errors + and warnings. + </p> + +{ + # We get a list of tag data. We create a separate paragraph for each + # package name. + my $last = ''; + for my $info (sort { $a->{package} cmp $b->{package} } @tags) { + my $id = "$info->{package} $info->{type}"; + if ($id ne $last) { + $OUT .= "</pre>\n" if $last; + $OUT .= qq( <pre class="tags">\n); + $last = $id; + } + $id = qq(<a href="../full/$info->{xref}">$id</a>); + $OUT .= "$info->{code}: $id: $info->{tag} $info->{extra}\n"; + } + $OUT .= '</pre>'; +} + + <hr /> + <div class="footer"> + <p> + Please send all comments about these web pages to the + <a href="mailto:[EMAIL PROTECTED]">Lintian maintainers</a>.<br /> + Page last updated: {$timestamp} using Lintian {$version} + </p> + </div> +</body> +</html> Added: trunk/reporting/templates/tags.tmpl =================================================================== --- trunk/reporting/templates/tags.tmpl (rev 0) +++ trunk/reporting/templates/tags.tmpl 2008-01-03 00:04:10 UTC (rev 1083) @@ -0,0 +1,51 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE html + PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head> + <title>Lintian Tags</title> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <link rel="stylesheet" href="lintian.css" type="text/css" /> +</head> + +<body> + <h1>Lintian Tags</h1> + + <p> + This is a list of all tags that occur at least once in the archive + with their frequency counts. This includes all tags, even + experimental and info tags. + </p> + + <p> +{ + for my $tag (sort keys %tags) { + my ($count, $overrides) = (0, 0); + my %seen; + for my $info (@{ $tags{$tag} }) { + if ($info->{code} eq 'O') { + $overrides++; + } else { + $count++; + $seen{$info->{xref}}++; + } + } + my $packages = scalar keys %seen; + $OUT .= qq( <a href="tags/$tag.html">$tag</a>) + . " ($packages packages, $count tags, plus $overrides overrides)" + . "<br />\n"; + } +} </p> + + <hr /> + <div class="footer"> + <p> + Please send all comments about these web pages to the + <a href="mailto:[EMAIL PROTECTED]">Lintian maintainers</a>.<br /> + Page last updated: {$timestamp} using Lintian {$version} + </p> + </div> +</body> +</html> -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]