diff options
Diffstat (limited to '')
-rwxr-xr-x | reporting/checkout-release | 29 | ||||
-rw-r--r-- | reporting/config.yaml | 72 | ||||
-rw-r--r-- | reporting/graphs/statistics.gpi | 38 | ||||
-rw-r--r-- | reporting/graphs/tags.gpi | 35 | ||||
-rw-r--r-- | reporting/images/ico.png | bin | 0 -> 230 bytes | |||
-rw-r--r-- | reporting/images/l.png | bin | 0 -> 669 bytes | |||
-rw-r--r-- | reporting/images/logo-small.png | bin | 0 -> 2830 bytes | |||
-rw-r--r-- | reporting/templates/clean.tmpl | 19 | ||||
-rw-r--r-- | reporting/templates/foot.tmpl | 20 | ||||
-rw-r--r-- | reporting/templates/head.tmpl | 26 | ||||
-rw-r--r-- | reporting/templates/index.tmpl | 128 | ||||
-rw-r--r-- | reporting/templates/lintian.css.tmpl | 447 | ||||
-rw-r--r-- | reporting/templates/maintainer.tmpl | 196 | ||||
-rw-r--r-- | reporting/templates/maintainers.tmpl | 57 | ||||
-rw-r--r-- | reporting/templates/packages.tmpl | 35 | ||||
-rw-r--r-- | reporting/templates/tag-not-seen.tmpl | 16 | ||||
-rw-r--r-- | reporting/templates/tag.tmpl | 102 | ||||
-rw-r--r-- | reporting/templates/tags-all.tmpl | 28 | ||||
-rw-r--r-- | reporting/templates/tags-severity.tmpl | 37 | ||||
-rw-r--r-- | reporting/templates/tags.tmpl | 34 |
20 files changed, 1319 insertions, 0 deletions
diff --git a/reporting/checkout-release b/reporting/checkout-release new file mode 100755 index 0000000..000f363 --- /dev/null +++ b/reporting/checkout-release @@ -0,0 +1,29 @@ +#!/bin/sh +# Copyright (C) 2008 Frank Lichtenheld <djpig@debian.org>, if at all copyrightable +# Copyright (C) 2009 Russ Allbery <rra@debian.org> + +# Helper script for updating lintian.debian.org to the latest lintian release +# Call with the release number as only argument, e.g. +# +# $ cd /org/lintian.debian.org && ./root/reporting/checkout-release 1.25.0 + +set -e + +if [ $# -ne 1 ]; then + echo "Usage: checkout-release <version-number>" + exit 2 +fi +release=$1 + +set -x + +cd root +git fetch +git merge "$release" +perl -i -pe "s/(LINTIAN_VERSION = )\S+/$1\"$release\";/" root/frontend/lintian +debian/rules build + +# Local Variables: +# indent-tabs-mode: nil +# End: +# vim: syntax=sh sw=4 sts=4 sr et diff --git a/reporting/config.yaml b/reporting/config.yaml new file mode 100644 index 0000000..e3f0ecd --- /dev/null +++ b/reporting/config.yaml @@ -0,0 +1,72 @@ +## Used to define some reused variables +defaults: + architectures: &ARCH + - i386 + - amd64 + components: &COMP + - main + - contrib + - non-free + +## List of archives to process +archives: + ## A name given to the archive + debian: + ## Name of the tracefile to use to determine how up to date + ## the archive is. + tracefile: ftp-master.debian.org + ## Where the archive is placed on the file system + base-dir: /srv/mirrors/debian + ## Architectures to process + architectures: *ARCH + ## Which components to process + components: *COMP + ## Which suites/distributions to process + distributions: + - unstable + - experimental + debian-debug: + tracefile: ftp-master.debian.org + base-dir: /srv/mirrors/debian-debug + architectures: *ARCH + components: *COMP + distributions: + - unstable-debug + - experimental-debug + +storage: +## Path to the log files + log-dir: /srv/lintian.debian.org/logs +## Path to a directory to hold temporary data used by lintian. +## Used as TMPDIR for lintian and will also hold temporary labs +## - Can be /var/tmp or /tmp as long as they have space enough +## - Can be cleaned automatically. Either on boot or via a +## "delete anything older than X days"-mechanism + scratch-space: /srv/lintian.debian.org/scratch +## Path to a directory to hold cached data like which packages +## have been processed. +## - Can be in /var/cache +## - Can be deleted to reset / restart processing from scratch + state-cache: /srv/lintian.debian.org/harness-state +## Where to store latest completed report / static website + reports-dir: /srv/lintian.debian.org/reports-directory/www +## Directory to use for compiling new reports +## FIXME: This should just be a tmpdir + reports-work-dir: /srv/lintian.debian.org/reports-directory/www.tmp +## Where to store collected data / historical data (used for +## generating graphs etc.) + historical-data-dir: /srv/lintian.debian.org/history + +lintian: +## Extra options to pass to lintian (not all options can be +## passed via this. E.g. --cfg is ignored). +# extra-options: ['--jobs', '2'] + +## All of these variables will be available for templates to consume +## via "$config_vars{VAR}" +template-variables: + LINTIAN_SOURCE: https://salsa.debian.org/git/lintian/lintian.git + +## Source packages to not process +blacklist: +- gcc-8-cross-ports # #890873 diff --git a/reporting/graphs/statistics.gpi b/reporting/graphs/statistics.gpi new file mode 100644 index 0000000..7e59a21 --- /dev/null +++ b/reporting/graphs/statistics.gpi @@ -0,0 +1,38 @@ +# set terminal png truecolor small size 600,300 +set terminal svg size 640,375 font "Sans,11" + +set style line 10 linetype 1 linecolor rgb "#FF6700" lw 1.5 +set style line 11 linetype 1 linecolor rgb "#FFEB44" lw 1.5 +set style line 12 linetype 1 linecolor rgb "#C7EA3C" lw 1.5 +set style line 13 linetype 1 linecolor rgb "#E7F6AC" lw 1.5 +set style line 14 linetype 1 linecolor rgb "#EE99EE" lw 1.5 +set style line 15 linetype 1 linecolor rgb "#CCCCCC" lw 1.5 + +set key outside + +set xdata time +set timefmt "%s" +set format x "%b/%y" + +set size 1.0,0.80 +set origin 0.0,0.05 + +set nomxtics +set xtics nomirror scale 0.5,0 rotate by 55 offset -3.2,-2.7 +set ytics nomirror scale 0.5,0 +set offsets 0,0,500,0 + +load "common.gpi" + +set xrange [ date_min : date_max ] +set yrange [ 0 : ] + +set output sprintf("%s/statistics.svg", graph_dir) +plot sprintf("%s/statistics.dat", history_dir) \ + u 1:7 w l ls 10 t 'Errors', \ + '' u 1:8 w l ls 11 t 'Warnings', \ + '' u 1:9 w l ls 12 t 'Info', \ + '' u 1:11 w l ls 13 t 'Pedantic', \ + '' u 1:10 w l ls 14 t 'Experimental', \ + '' u 1:12 w l ls 15 t 'Overridden' + diff --git a/reporting/graphs/tags.gpi b/reporting/graphs/tags.gpi new file mode 100644 index 0000000..16ef73c --- /dev/null +++ b/reporting/graphs/tags.gpi @@ -0,0 +1,35 @@ +tag=sprintf("%s", ARG1) +# set terminal png truecolor small size 600,300 +set terminal svg size 640,375 font "Sans,11" + +set style fill solid 0.25 + +set style line 20 linetype 1 linecolor rgb "#1A77C9" +set style line 21 linetype 1 linecolor rgb "#83CDBE" +set style line 22 linetype 1 linecolor rgb "#BBBBBB" + +set key outside + +set xdata time +set timefmt "%s" +set format x "%b/%y" + +set size 1.0,0.80 +set origin 0.0,0.05 + +set nomxtics +set xtics nomirror scale 0.5,0 rotate by 55 offset -3.2,-2.7 +set ytics nomirror scale 0.5,0 +set offsets 0,0,1,0 + +load "common.gpi" + +set xrange [ date_min : date_max ] +set yrange [ 0 : ] + +set output sprintf("%s/tags/%s.svg", graph_dir, tag) +plot sprintf("%s/tags/%s.dat", history_dir, tag) \ + u 1:2 w filledcurve x1 ls 20 t sprintf("Tag %s emitted", tag), \ + '' u 1:4 w filledcurve x1 ls 21 t sprintf("Packages which emitted %s", tag), \ + '' u 1:3 w filledcurve x1 ls 22 t sprintf("Tag %s overridden", tag) + diff --git a/reporting/images/ico.png b/reporting/images/ico.png Binary files differnew file mode 100644 index 0000000..e78bd5b --- /dev/null +++ b/reporting/images/ico.png diff --git a/reporting/images/l.png b/reporting/images/l.png Binary files differnew file mode 100644 index 0000000..0473ba2 --- /dev/null +++ b/reporting/images/l.png diff --git a/reporting/images/logo-small.png b/reporting/images/logo-small.png Binary files differnew file mode 100644 index 0000000..59bf0c7 --- /dev/null +++ b/reporting/images/logo-small.png diff --git a/reporting/templates/clean.tmpl b/reporting/templates/clean.tmpl new file mode 100644 index 0000000..5ae636a --- /dev/null +++ b/reporting/templates/clean.tmpl @@ -0,0 +1,19 @@ +{ head("Lintian Report for $name", 1) } + <h1>{$name}</h1> + + <p> + All of the packages maintained by {$maintainer} are Lintian-clean. +{ + if (!$clean) { + qq( But also see the <a href="${path_prefix}full/$id">full report</a>) + . " which includes info, experimental and overridden tags"; + } +} + </p> + + <p> + Also see their + <a href="https://qa.debian.org/developer.php?login={$email}">QA + overview</a>. + </p> +{ foot() } diff --git a/reporting/templates/foot.tmpl b/reporting/templates/foot.tmpl new file mode 100644 index 0000000..ddc7dc1 --- /dev/null +++ b/reporting/templates/foot.tmpl @@ -0,0 +1,20 @@ +</main> + +<hr/> + +<footer> + <p> + Comments about these web pages? Please use + <a href="https://packages.debian.org/sid/reportbug">reportbug</a> + to report a bug against the lintian package. + </p> + <p> + The source code to Lintian is available under the GNU GPL version 2, + or (at your option) any later version. It can be downloaded from + <a href="{$config_vars{LINTIAN_SOURCE}}">{$config_vars{LINTIAN_SOURCE}}</a>. + </p> + <p>Page last updated: {$timestamp} using Lintian {$version}.</p> +</footer> + +</body> +</html> diff --git a/reporting/templates/head.tmpl b/reporting/templates/head.tmpl new file mode 100644 index 0000000..4001950 --- /dev/null +++ b/reporting/templates/head.tmpl @@ -0,0 +1,26 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <title>{$page_title}</title> + <meta charset="utf-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <link rel="stylesheet" href="{resource_path('lintian.css')}" type="text/css" integrity="{resource_integrity('lintian.css')}" crossorigin="anonymous" /> + <link rel="icon" href="{resource_path('ico.png')}" type="image/png" integrity="{resource_integrity('ico.png')}" crossorigin="anonymous" /> +</head> + +<body> + +<header> + <p><a href="{$path_prefix}index.html">Lintian Reports</a></p> + <nav> + <ul id="nav"> + <li><a href="{$path_prefix}maintainers.html">Maintainers</a></li> + <li><a href="{$path_prefix}tags.html">Emitted Tags</a></li> + <li><a href="{$path_prefix}tags-all.html">All Tags</a></li> + <li><a href="{$path_prefix}packages_1.html">Packages</a></li> + </ul> + </nav> + <div class="clear"></div> +</header> + +<main> diff --git a/reporting/templates/index.tmpl b/reporting/templates/index.tmpl new file mode 100644 index 0000000..0889624 --- /dev/null +++ b/reporting/templates/index.tmpl @@ -0,0 +1,128 @@ +{ head("Lintian") } + <div id="front"> + <div id="info"> + <p> + Lintian dissects <a href="https://www.debian.org/">Debian</a> + <a href="https://packages.debian.org/">packages</a> and tries to find + bugs and policy violations. It contains automated checks for many + aspects of <a href="https://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="{$path_prefix}manual/index.html">User + Manual</a>. + </p> + + <p> + Auto-generated documentation of the Lintian Perl Library API can + be found <a href="{$path_prefix}library-api/index.html">here</a>. + </p> + + + <p> + Lintian is available in the Debian + <a href="https://packages.debian.org/lintian">lintian package</a>. + </p> + </div> <!-- info --> + <div class="clear"></div> + </div> <!-- front --> + + <nav id="index"> + <h2>Indices and links</h2> + + <ul> + <li><a href="{$path_prefix}maintainers.html">Index of Lintian reports per package maintainers</a></li> + <li><a href="{$path_prefix}tags.html">List of emitted tags sorted alphabetically</a></li> + <li><a href="{$path_prefix}tags-severity.html">List of emitted tags grouped by severity</a></li> + <li><a href="{$path_prefix}tags-all.html">List of all tags sorted alphabetically</a></li> + <li>Lists of packages that have names starting with: + <ul> + <li><a href="{$path_prefix}packages_1.html">0-9, A-F</a></li> + <li><a href="{$path_prefix}packages_2.html">G-L</a></li> + <li><a href="{$path_prefix}packages_3.html">M-R</a></li> + <li><a href="{$path_prefix}packages_4.html">S-Z</a></li> + </ul> + </li> + <li>Download the lintian output for off-line processing: <a href="{resource_path('lintian.log.gz')}">lintian.log.gz</a></li> + </ul> + </nav> <!-- index --> + + <div id="archives"> + <h2>Archives</h2> + <p>The following archives are processed by Lintian:</p> + <table> + <tr><th>Archive name</th><th>Attribute</th><th>Attribute value</th></tr> +{ + for my $archive_info (@archives) { + my $name = $archive_info->{'name'}; + my $archs = join(' ', @{$archive_info->{'architectures'}}); + my $distributions = join(' ', @{$archive_info->{'distributions'}}); + my $components = join(' ', @{$archive_info->{'components'}}); + my $timestamp = $archive_info->{'timestamp'}; + $OUT .= qq{ <tr><td rowspan="4">${name}</td><td>Architectures</td><td>$archs</td></tr>\n}; + $OUT .= qq{ <tr><td>Distributions/Suites</td><td>$distributions</td></tr>\n}; + $OUT .= qq{ <tr><td>Components</td><td>$components</td></tr>\n}; + $OUT .= qq{ <tr><td>Mirror timestamp</td><td>$timestamp</td></tr>\n}; + } +} + </table> + </div> + + <div id="stats"> + <h2>Statistics</h2> + <table> + <tr><td>Last updated:</td> <td>{$timestamp}</td></tr> + <tr><td>Maintainers:</td> <td>{$delta{maintainers}}</td></tr> + <tr><td>Package groups:</td> <td>{$delta{'groups-known'}}</td></tr> + <tr><td>Rescheduled groups:</td> <td>{$delta{'groups-backlog'}}</td></tr> + <tr><td>Groups with processing errors:</td> <td>{$delta{'groups-with-errors'}}</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>μdeb packages:</td> <td>{$delta{'udeb-packages'}}</td></tr> + <tr> + <td><span class="type-E">E</span> Errors:</td> + <td>{$delta{errors}}</td> + </tr> + <tr> + <td><span class="type-W">W</span> Warnings:</td> + <td>{$delta{warnings}}</td> + </tr> + <tr> + <td><span class="type-I">I</span> Info tags:</td> + <td>{$delta{info}}</td> + </tr> + <tr> + <td><span class="type-P">P</span> Pedantic tags:</td> + <td>{$delta{pedantic}}</td> + </tr> + <tr> + <td><span class="type-O">O</span> Overridden tags:</td> + <td>{$delta{overridden}}</td> + </tr> + <tr> + <td><span class="type-X">X</span> Experimental tags:</td> + <td>{$delta{experimental}}</td> + </tr> + <tr><td>Lintian version:</td> <td>{$version}</td></tr> + </table> + + <p> + (The numbers in parentheses describe the changes since the last Lintian + report, published on {$previous}.) + </p> + +{ + if ($graphs) { + my $graph_link = resource_path('statistics.svg'); + $OUT .= qq( <p>\n); + $OUT .= qq( Evolution of Lintian tags over the past\n); + $OUT .= qq( $graphs_days days:</p>\n); + $OUT .= qq( <div class="graph"><a href="${graph_link}"><img class="graph"\n); + $OUT .= qq( src="${graph_link}" alt="The beforementioned graph of Lintian\n); + $OUT .= qq( tags" /></a></div>\n); + } +} + + </div> <!-- stats --> +{ foot() } diff --git a/reporting/templates/lintian.css.tmpl b/reporting/templates/lintian.css.tmpl new file mode 100644 index 0000000..cc3e8a3 --- /dev/null +++ b/reporting/templates/lintian.css.tmpl @@ -0,0 +1,447 @@ +{{{ + # NOTE - in this file, perl code must be within three braces rather than + # the usual single brace. This was done because a single brace is rather + # common in .css-files. NB: The braces cannot be escaped - see "DELIMITERS" + # in Text::Template. + # + # To refer to a resource, use: + # {{{resource_path('basename.png')}}} + # NB: The path will be relative to the .css file. Usually something like + # "../resources/<checksum>.png" + # + # To refer to a file name relative to the .css file, use: + # {{{$path_prefix}}}path/from/HTML_ROOT +}}}/* lintian.css -- Style sheet for lintian.debian.org pages. */ + +/* + # Table of Contents: + # + # 1. General styles (links, lists, titles, tables...) + # 2. Header + # 3. Navigation + # 4. Main content + # 5. Footer + # 6. Other + */ + +/* + # Order: + # + # example { + # display + # position + # width + # height + # margin + # padding + # background + # color + # font + # text + # line-height + # border + # } + */ + + +/* + * 1. General styles + */ + +body { + margin: 0; + padding: 0; + color: #222; + background-color: white; + font-family: sans-serif; +} + +h1, h2 { + font-family: "Junicode", "FreeSerif", serif; +} + +h2 { + margin-bottom: 14px; + padding-bottom: 6px; + border-bottom: 2px solid #AAA; +} + +h3 { + margin: 5px 0 5px 10px; + color: #444; + font-size: 1.0em; +} + +p { + line-height: 1.4em; +} + +a { + color: #3252B2; +} + +ul { + margin: 0; +} + +li { + color: #333; +} + +hr { + display: none; +} + +/* + * 2. Header title + */ + +header { + display: block; /* HTML5 compat */ + margin: 0 0 28px 0; + padding: 5px 20px; + background: #F3F3F3 url("{{{resource_path('logo-small.png')}}}") no-repeat right; + border-bottom: 1px solid #AAA; +} + +header p { + float: left; + margin: 5px 0; + color: #444; + font-size: 1.0em; + font-family: sans-serif; + font-weight: bold; +} + +header p a { + color: #444; + text-decoration: none; +} + + +/* + * 3. Navigation bar + */ + +#nav { + float: right; + margin: 5px 55px 5px 0; + padding: 0; +} + +#nav li { + display: inline; + margin-left: 5px; +} + +#nav a { + padding: 3px 5px; + color: #333; + font-size: 0.9em; + text-decoration: none; +} + +#nav a:hover { + background-color: #FBFBFB; + border-bottom: 2px solid #D70751; +} + + +/* + * 4. Main content + */ + +main { + display: block; + margin: 0 25px; + font-size: 0.9em; + line-height: 1.4em; +} + +img.graph { + width: 95%; + max-width: 640px; +} + +/* Front page */ + +#logo { + text-align: center; +} + +#index h2, #stats h2, #archives h2 { + margin: 1.4em 0 0.4em 0; + border: none; +} + +#info { + margin: 25px 0; + padding: 20px; + background: #EFF4F8 url("{{{resource_path('l.png')}}}") no-repeat left; + border: 1px solid #DFE4E8; +} + +#info p { + margin-left: 130px; +} + +/* For smaller devices, we leave out the "icon" - it is fairly wide with + * little added value. + */ +@media (max-width: 700px) { + + #info { + margin: 25px 0; + padding: 20px; + background: #EFF4F8; + border: 1px solid #DFE4E8; + } + + #info p { + margin-left: 5%; + } +} + +#stats table, #archives table { + border-collapse: collapse; +} + +#stats table tr td, #archives table tr td { + padding: 3px 5px; + background-color: #FDFDFD; + border: 1px solid #CCC; +} + +#stats td span, #archives td span { + margin: 0 3px 0 0; + padding: 1px 3px; + font-family: monospace; +} + +#stats div.graph { + text-align: left; +} + +/* Maintainer reports */ + +#summary { + font-size: 0.9em; +} + +#summary p { + margin-top: 5px; + font-size: 0.95em; +} + +#summary ul { + padding-left: 20px; +} + +ul.report { + padding-left: 20px; + padding-bottom: 1em; +} + +div.graph { + text-align: center; +} + +ul.tag { + padding-bottom: 1em; +} + +ul.report li { + padding-left: 5px; + padding-bottom: 6px; + list-style: none; +} + +ul.tag li { + list-style: square; +} + +li span { + margin: 0 3px 0 0; + padding: 1px 3px; + font-family: monospace; +} + +h1 span { + padding: 1px 5px; + font-family: monospace; + font-size: 0.85em; + font-weight: normal; +} + +ul.extra { + margin-bottom: 0; + padding-bottom: 0; +} + +ul.report li ul.extra li { + padding-left: 0; + padding-bottom: 1px; + color: #444; + list-style: square; +} + +div.source-header { + width: 100%; + margin: 1.4em 0 14px 0; + padding-bottom: 6px; + border-bottom: 2px solid #AAA; +} + +div.source-header p, div.source-header h2 { + display: inline; + border: none; +} + +.info-links { + margin-top: 0; +} + +.info-links:before { + content: "– "; +} + +/* Tag type */ + +h2.tag { + margin: 5px 0; + padding: 0; + color: #444; + font-family: sans-serif; + font-size: 1.0em; + font-weight: normal; + border: none; +} + +h2.tag a { + font-weight: bold; +} + +h2.tag span.type-O { + margin: 0 3px 0 0; + padding: 2px 4px; + color: #555; + background: #EEE; + font-family: monospace; + font-size: 1.1em; + font-weight: bold; + border: 1px solid #DDD; +} + +br.tag { + padding-bottom: 1em; +} + + +/* E/W/I colors */ + +span.type-I { + color: #111; + background-color: #C7EA3C; +} + +span.type-W { + color: #111; + background-color: #FFEB44; +} + +span.type-E { + color: #111; + background-color: #FF6700; +} + +span.type-X { + color: #111; + background-color: #EE99EE; +} + +span.type-O { + color: #111; + background-color: #DDD; +} + +span.type-P { + color: #111; + background-color: #C7EA3C; +} + +span.type-C { + color: #111; + background-color: blue; +} + +li.type-O { + color: #444; +} + +b.processing-error { + color: #FF6700; +} + +blockquote { + padding: 6px 16px; + background-color: #EEE; + border: 1px solid #DDD; +} + +blockquote.type-I { + background-color: #DFA; + border: 1px solid #C7EA3C; +} + +blockquote.type-W { + background-color: #FFD; + border: 1px solid #FFEB44; +} + +blockquote.type-E { + background-color: #FE9; + border: 1px solid #FF6700; +} + +blockquote.type-X { + background-color: #FECCFE; + border: 1px solid #DE66DE; +} + +blockquote.type-P { + background-color: #DFA; + border: 1px solid #C7EA3C; +} + +blockquote.type-C { + background-color: #DFA; + border: 1px solid #C7EA3C; +} + + +/* + * 5. Footer + */ + +footer { + display: block; /* HTML5 compat */ + margin: 20px 20px; + padding: 10px 0 0 0; + font-size: 0.85em; + border-top: 1px solid #AAA; +} + +footer p { + margin: 0; + padding: 0; +} + + +/* + * 6. Other + */ + +div.clear { + clear: both; +} + diff --git a/reporting/templates/maintainer.tmpl b/reporting/templates/maintainer.tmpl new file mode 100644 index 0000000..e5e9353 --- /dev/null +++ b/reporting/templates/maintainer.tmpl @@ -0,0 +1,196 @@ +{ head("Lintian Report for $name") } + <h1>{$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="${path_prefix}full/$id">full report</a>, including) + . " info, experimental and overridden tags."; + } else { + qq( See also the <a href="${path_prefix}maintainer/$id">report showing) + . " only errors and warnings</a>."; + } +} + Also see their + <a href="https://qa.debian.org/developer.php?login={$email}">QA + overview</a>. + </p> + +{ + # Show the summary only if the number of packages is within a certain + # range. + my $num_packages = keys(%packages) + keys(%uploads); + if ($num_packages) { + $OUT .= qq( <nav id="summary">\n <ul>\n); + foreach my $source (sort(keys(%packages), keys(%uploads))) { + # Only display a link for the package if either we're + # displaying the full report, or the package has error + # or warning tags + my @interesting = (); + my $versions = $packages{$source} || $uploads{$source}; + + if (!$errors) { + # Full report, so include the package + @interesting = sort by_version keys %$versions; + @interesting = map { + [$_, $versions->{$_}[0]{pkg_info}{anchor}] + } @interesting; + } else { + for my $version (sort by_version keys %$versions) { + my $tags = $versions->{$version}; + for my $tag (@$tags) { + if (($tag->{code} eq 'E') or ($tag->{code} eq 'W')) { + push(@interesting, [$version, $tag->{pkg_info}{anchor}]); + last; + } + } + } + } + + if (@interesting) { + foreach my $vdata (@interesting) { + my ($version, $anchor) = @{$vdata}; + $OUT .= q{ } . + qq(<li><a href="#${anchor}">$source ($version)</a></li>\n); + } + } + } + $OUT .= " </ul>\n </nav>\n"; + } +} + <div class="clear"></div> + +{ + # We get a hash of package names to a hash of versions to a list of tags. + # Create a list with the package information as the title and the tags as + # the value. + for my $source (sort (keys (%packages), keys (%uploads))) { + my ($data, $upload); + my $first_version = 1; + if ($packages{$source}) { + $data = $packages{$source}; + } else { + $data = $uploads{$source}; + $upload = 1; + } + for my $version (sort by_version keys %$data) { + my @tags = @{$data->{$version}}; + my @error_tags = grep { $_->{code} eq 'E' or $_->{code} eq 'W' } @tags; + my $first = 1; + my $binary = ''; + my $tag = ''; + my $firstcomponent = ''; + # Tracks whether we have opened an "<ul>"-list for the tag "extra". + # We only do this if the tags have "extra" info to avoid an empty + # "<ul></ul>" (which is forbidden by XHTML 1.0 strict). + my $has_extra = 0; + + if ($errors) { + @tags = @error_tags; + next if not @error_tags; + } + + for my $info (@tags) { + my $pkg_info = $info->{pkg_info}; + my $is_binary = ($pkg_info->{type} eq "binary" or $pkg_info->{type} eq "udeb"); + my $new_binary = $pkg_info->{package} ne $binary if $is_binary; + my $tag_info = $info->{tag_info}; + my $next_tag = $tag_info->name; + + my $component = ($pkg_info->{component} eq 'main') ? '' : "; $pkg_info->{component}"; + $firstcomponent = $pkg_info->{component} unless $firstcomponent; + if ($first) { + my $state = $pkg_info->{'state_data'}; + my $anchor = $pkg_info->{'anchor'}; + my $status = 'up-to-date'; + my $last_processed_by = $state->{'last-processed-by'} // 'N/A'; + $status = '<i>outdated</i>' if (exists($state->{'out-of-date'})); + $status = '<b class="processing-error">incomplete report; an error occurred during the last check</b>' + if exists($state->{'last-error-by'}) and $state->{'last-error-by'}; + $OUT .= qq( <div class="source-header">\n); + $OUT .= qq( <h2 id="$pkg_info->{anchor}">); + $OUT .= "$source ($version$component)"; + $OUT .= " [Uploader]" if $upload; + if ($first_version) { + # Unversioned #<pkg> references just go to the first version. + $first_version = 0; + $OUT .= qq( <a href="#${source}" id="${source}">§</a>) + } + $OUT .= "</h2>\n"; + $OUT .= qq( <p class="info-links">\n); + $OUT .= qq( <a href="https://packages.debian.org/src:$source">Info</a>\n); + $OUT .= qq( <a href="https://tracker.debian.org/$source">Package Tracker</a>\n); + $OUT .= qq( <a href="https://bugs.debian.org/src:$source">Bugs</a>\n); + $OUT .= qq( <a href="https://sources.debian.org/src/$source/$version">Source</a>\n); + if ($errors) { + $OUT .= qq( <a href="${path_prefix}full/$id#$anchor">Full report</a>\n); + } elsif (@error_tags) { + $OUT .= qq( <a href="${path_prefix}maintainer/$id#$anchor">Short report</a>\n); + } + $OUT .= qq[ (${status}, last processed by Lintian/$last_processed_by)]; + $OUT .= qq( </p>\n </div>\n); + $OUT .= qq( <ul class="report">\n) unless $is_binary; + } + + my $bin_version = ''; + unless ($pkg_info->{version} eq $version + and $pkg_info->{component} eq $firstcomponent) { + $bin_version = " ($pkg_info->{version}; $pkg_info->{component})"; + } + + if ($tag ne $next_tag or $new_binary) { + # Close the '<ul class="extra">' HTML tag if it is open + $OUT .= "</ul>\n" if $has_extra; + # Reset has_extra; if the tag has an "extra", we will check + # for it later. + $has_extra = 0; + if ($new_binary) { + $OUT .= " </li>\n </ul>\n" unless $first; + $OUT .= qq( <h3>$pkg_info->{package}$bin_version</h3>\n); + $OUT .= qq( <ul class="report">\n); + } + } + + my $class = ''; + # No HTML quote needed; severity is from a fixed + # whitelist of known safe words. + my $severity = $tag_info->effective_severity; + $class = qq( title="$severity"); + + # Display tag name only once. + if ($tag ne $next_tag or $new_binary) { + my $q_next_tag = html_quote($next_tag); + $OUT .= " </li>\n" unless $first or $new_binary; + $OUT .= " <li$class>\n"; + $OUT .= qq( <span class="type-$info->{code}">); + $OUT .= "$info->{code}</span> "; + $OUT .= qq(<a href="${path_prefix}tags/${q_next_tag}.html">); + $OUT .= "${q_next_tag}</a>\n"; + } + + if ($info->{extra}) { + if (not $has_extra) { + # Open a list for the "extra" info. + $has_extra = 1; + $OUT .= qq( <ul class="extra">); + } + $OUT .= "<li>$info->{extra}"; + my @archs = sort keys %{ $info->{archs} }; + $OUT .= " <tt>[" . join(', ', @archs) . "]</tt>" if @archs > 1; + $OUT .= "</li>"; + } + + $first = 0; + $binary = $pkg_info->{package} if $is_binary; + $tag = $next_tag; + } + # Close the "extra" info-list (if present) and the current setup + $OUT .= "</ul>\n" if $has_extra; + $OUT .= " </li>\n </ul>\n"; + } + } +} +{ foot() } diff --git a/reporting/templates/maintainers.tmpl b/reporting/templates/maintainers.tmpl new file mode 100644 index 0000000..58a9626 --- /dev/null +++ b/reporting/templates/maintainers.tmpl @@ -0,0 +1,57 @@ +{ head("Lintian Reports by Maintainer") } + <h1>Maintainers</h1> + + <p> + Maintainers are listed sorted case-insensitively by package maintainer + string. This is an unsophisticated sort that does not 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', 'Other')) } +{ + # !!NB!! We are deliberately leaving out the closing "</p>" here. + # It will be added by the loop below, which can (due to this) + # unconditionally emit a "</p>" at the start of each new letter. + + # 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 = ''; + my @order = sort { + my $la = lc($a); + my $lb = lc($b); + # Ensure non-ASCII characters get push to the back + if ($la lt 'a' and $lb ge 'a') { + 1; + } elsif ($la ge 'a' and $lb lt 'a') { + -1; + } else { + $la cmp $lb; + } + } keys(%maintainers); + for my $key (@order) { + my $maint_data = $maintainers{$key}; + my $url = $maint_data->{url}; + my $maintainer = $maint_data->{name}; + my $first = uc substr($key, 0, 1); + if ($first lt 'A' || $first gt 'Z') { + $first = 'Other'; + } + if ($first ne $letter) { + $letter = $first; + if ($letter eq 'Other') { + $OUT .= qq( </p>\n\n <h2 id="Other">Other</h2>\n\n <p>\n); + } else { + $OUT .= qq( </p>\n\n <h2 id="$letter"><a id="$letter">) + . $letter . "</a></h2>\n\n <p>\n"; + } + } + $OUT .= qq( <a href="${path_prefix}maintainer/$url">$maintainer</a>) + . qq{ (<a href="${path_prefix}full/$url">full report</a>)<br />\n}; + } +} </p> +{ foot() } diff --git a/reporting/templates/packages.tmpl b/reporting/templates/packages.tmpl new file mode 100644 index 0000000..352f6b1 --- /dev/null +++ b/reporting/templates/packages.tmpl @@ -0,0 +1,35 @@ +{ head("Lintian Package Index: $section") } + <h1>Package Index: {$section}</h1> + + <p> + This is a list of all source 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="{$path_prefix}packages_1.html">0-9, A-F</a> + | <a href="{$path_prefix}packages_2.html">G-L</a> + | <a href="{$path_prefix}packages_3.html">M-R</a> + | <a href="{$path_prefix}packages_4.html">S-Z</a> + </p> + +{ + # ' # hi, emacs + # 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; + } + foreach my $version (sort by_version keys %{ $sources{$package} }) { + $OUT .= qq( <a href="${path_prefix}full/$sources{$package}{$version}">$package ($version)</a>\n); + } + } +} </p> +{ foot() } diff --git a/reporting/templates/tag-not-seen.tmpl b/reporting/templates/tag-not-seen.tmpl new file mode 100644 index 0000000..2e3c8a9 --- /dev/null +++ b/reporting/templates/tag-not-seen.tmpl @@ -0,0 +1,16 @@ +{ head("Lintian Tag: $tag") } + <h1><span class="type-{$code}">{$code}</span> {$tag}</h1> + + <p> + All reports of {$tag} for the archive. The extended description of this + tag is: + </p> + + <blockquote class="type-{$code}"> +{$description} + </blockquote> + + <p> + This tag has not been emitted in any package tested by Lintian. + </p> +{ foot() } diff --git a/reporting/templates/tag.tmpl b/reporting/templates/tag.tmpl new file mode 100644 index 0000000..d7c7271 --- /dev/null +++ b/reporting/templates/tag.tmpl @@ -0,0 +1,102 @@ +{ # No my/our in front of $q_tag or it will leave scope too soon! + $q_tag = html_quote($tag); + head("Lintian Tag: ${q_tag}") } + <h1><span class="type-{$code}">{$code}</span> {${q_tag}}</h1> + +{ if ($statistics{total} <= $shown_count) { + $OUT .= qq( + <p> + All reports of ${tag} for the archive. The extended description of this + tag is: + </p> +); + } else { + my $log_link = resource_path('lintian.log.gz'); + $OUT .= qq( + <p> + A subset of the reports of ${tag} for the archive. Unfortunately the full + list is too long, so only ${shown_count} instances are listed on this page. + At most ${tag_limit_per_package} tags are shown per package. + <a href="${log_link}">If you need the full list of tags, + please download the lintian.log.gz file and extract the data you need.</a> + </p> + <p> + The extended description of this tag is: + </p> + ); + } +} + + <blockquote class="type-{$code}"> +{$description} + </blockquote> + +{ + if ($graphs) { + my $graph_link = resource_path("${tag}.svg"); + $OUT .= qq( <p>\n); + $OUT .= qq( Evolution of the ${q_tag} Lintian tag over the past\n); + $OUT .= qq( $graphs_days days:</p>\n); + $OUT .= qq( <div class="graph"><a href="${graph_link}"><img class="graph"\n); + $OUT .= qq( src="${graph_link}" alt="The beforementioned graph for the ${q_tag} tag"\n); + $OUT .= qq( /></a></div>\n); + } + $OUT .= qq(<p>Emitted (non-overridden): $statistics{count}, ); + $OUT .= qq(overridden: $statistics{overrides}, ); + $OUT .= qq(total: $statistics{total}</p>); +} + + <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, $last_pi, $tag, $has_nonoverridden); + for my $info (sort { $a->{pkg_info}{package} cmp $b->{pkg_info}{package} } @tags) { + my $pkg_info = $info->{pkg_info}; + if (!$last + or "$pkg_info->{package} $pkg_info->{type} $pkg_info->{version}" ne "$last_pi->{package} $last_pi->{type} $last_pi->{version}") { + if ($last) { + my $overridden = $has_nonoverridden ? '' : qq{ <span class="type-O">overridden</span>}; + $OUT .= qq( <h2 class="tag"><a href="${path_prefix}full/$last->{pkg_info}{xref}">); + $OUT .= "$last_pi->{package} $last_pi->{version}</a> ($last_pi->{type}) (<em>$last_pi->{maintainer}</em>)$overridden</em></h2>\n"; + if ($tag) { + $OUT .= qq( <ul class="tag">\n); + $OUT .= $tag; + $OUT .= "</ul>\n"; + } else { + $OUT .= qq(<br class="tag" />\n); + } + } + $last = $info; + $last_pi = $pkg_info; + $tag = ''; + $has_nonoverridden = 0; + } + $has_nonoverridden = 1 if $info->{code} ne 'O'; + if ($info->{extra}) { + $tag .= qq{ <li class="type-$info->{code}">}; + $tag .= qq{<span class="type-O">O</span> } if $info->{code} eq 'O'; + $tag .= $info->{extra}; + my @archs = sort keys %{ $info->{archs} }; + $tag .= " <tt>[" . join(', ', @archs) . "]</tt>" if @archs > 1; + $tag .= "</li>"; + } + } + my $overridden = $has_nonoverridden ? '' : qq{ <span class="type-O">overridden</span>}; + $OUT .= qq( <h2 class="tag"><a href="${path_prefix}full/$last->{pkg_info}{xref}">); + $OUT .= "$last_pi->{package} $last_pi->{version}</a> ($last_pi->{type}) (<em>$last_pi->{maintainer}</em>)$overridden</h2>\n"; + if ($tag) { + $OUT .= qq( <ul class="tag">\n); + $OUT .= $tag; + $OUT .= "</ul>\n"; + } else { + $OUT .= qq(<br class="tag" />\n); + } +} +{ foot() } diff --git a/reporting/templates/tags-all.tmpl b/reporting/templates/tags-all.tmpl new file mode 100644 index 0000000..eb592c3 --- /dev/null +++ b/reporting/templates/tags-all.tmpl @@ -0,0 +1,28 @@ +{ head("Lintian Tags") } + <h1>Tags</h1> + + <p> + This is a list of all tags known to Lintian even the ones + not emitted. + </p> + + <ul> +{ + for my $tag (sort $profile->known_tags) { + my $text; + my $q_tag = html_quote($tag); + if ($stats{$tag}) { + my $packages = $stats{$tag}{'packages'}; + my $count = $stats{$tag}{'count'}; + my $overrides = $stats{$tag}{'overrides'}; + $text = "$packages packages, $count tags" + . ($overrides > 0 ? ", plus $overrides overrides" : ""); + } else { + $text = 'Not emitted'; + } + $OUT .= qq( <li><a href="${path_prefix}tags/${q_tag}.html">${q_tag}</a>) + . " ($text)" + . "</li>\n"; + } +} </ul> +{ foot() } diff --git a/reporting/templates/tags-severity.tmpl b/reporting/templates/tags-severity.tmpl new file mode 100644 index 0000000..164cb40 --- /dev/null +++ b/reporting/templates/tags-severity.tmpl @@ -0,0 +1,37 @@ +{ head("Lintian Tags") } + <h1>Tags</h1> + + <p> + This is a list of all tags that occur at least once in the archive + sorted by severity. This includes all tags, even experimental and + info tags. + </p> + +{ + my @tags = sort keys %tags; + for my $severity (qw/error warning info pedantic classification/) { + my $heading = 0; + for my $tag (@tags) { + my ($first) = @{ $tags{$tag} }; + my $tag_info = $first->{tag_info}; + next unless $tag_info->effective_severity eq $severity; + unless ($heading) { + $OUT .= " <h2>Severity: $severity,"; + $OUT .= " <ul>\n"; + $heading = 1; + } + my $packages = $stats{$tag}{'packages'}; + my $count = $stats{$tag}{'count'}; + my $overrides = $stats{$tag}{'overrides'}; + my $q_tag = html_quote($tag); + $OUT .= qq( <li><a href="${path_prefix}tags/${q_tag}.html">${q_tag}</a>) + . " ($packages packages, $count tags" + . ($overrides > 0 ? ", plus $overrides overrides" : "") + . ")</li>\n"; + } + if ($heading) { + $OUT .= " </ul>\n\n"; + } + } +} +{ foot() } diff --git a/reporting/templates/tags.tmpl b/reporting/templates/tags.tmpl new file mode 100644 index 0000000..3654af7 --- /dev/null +++ b/reporting/templates/tags.tmpl @@ -0,0 +1,34 @@ +{ head("Lintian Tags") } + <h1>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> + + <ul> +{ + for my $tag (sort keys %stats) { + my $q_tag = html_quote($tag); + my $packages = $stats{$tag}{'packages'}; + my $count = $stats{$tag}{'count'}; + my $packages_str = $packages != 1 ? + "$packages packages" : + "$packages package"; + my $count_str = $count != 1 ? "$count tags" : "$count tag"; + my $overrides = $stats{$tag}{'overrides'}; + my $overrides_str = ''; + if ($overrides) { + if ($overrides == 1) { + $overrides_str = ", plus $overrides override"; + } else { + $overrides_str = ", plus $overrides overrides"; + } + } + $OUT .= qq( <li><a href="${path_prefix}tags/${q_tag}.html">${q_tag}</a>) + . " ($packages_str, ${count_str}${overrides_str}" + . ")</li>\n"; + } +} </ul> +{ foot() } |