\documentclass{beamer}

\mode<presentation>
{
  \usetheme{Boadilla} % Darmstadt / Singapore / Frankfurt / Goettingen / Madrid / Warsaw
  % or ...

  \usecolortheme{seahorse}
  \usecolortheme{rose}

  \setbeamercovered{transparent}
  % or whatever (possibly just delete it)
}


\usepackage[english]{babel}
\usepackage[latin1]{inputenc}
\usepackage{listings}

\usepackage{times}
\usepackage[T1]{fontenc}
% Or whatever. Note that the encoding and the font should match. If T1
% does not look nice, try deleting the line with the fontenc.


\title %[] (optional, use only with long paper titles)
{Lintian}

\subtitle
{Internals and Thoughts about further Development}

\author %[] (optional, use only with lots of authors)
{Frank Lichtenheld <djpig@debian.org>}

\institute[Debian] % (optional, but mostly needed)
{Debian Project}

\date[Debian QA Meeting 2005]
{09/11/2005 / Debian QA Meeting 2005}

\subject{Talks}
% This is only inserted into the PDF information catalog. Can be left
% out. 

\pgfdeclareimage[height=1cm]{debian-logo}{officiallogo}
\logo{\pgfuseimage{debian-logo}}

% Delete this, if you do not want the table of contents to pop up at
% the beginning of each subsection:
\AtBeginSubsection[]
{
  \begin{frame}<beamer>
    \frametitle{Outline}
    \tableofcontents[currentsection,currentsubsection]
  \end{frame}
}


\begin{document}

\begin{frame}
  \titlepage
\end{frame}

\begin{frame}
  \frametitle{Outline}
  \tableofcontents
  % You might wish to add the option [pausesections]
\end{frame}


\section{Internals}

\subsection{History}

\begin{frame}
  \frametitle{History of Lintian development}

  \begin{itemize}
  \item Development started 1998 by Christian Schwarz and Richard
    Braakman
  \item General design unchanged since then
  \item A lot of people have contributed since then and the
    maintainership changed several times
    \begin{itemize}
    \item 1999 to Darren Benham
    \item 2000 to Sean 'Shaleh' Perry
    \item 2002 to Josip Rodin
    \item 2004 to \textit{Debian Lintian Maintainers} (Jeroen van Wolffelaar,
      Frank Lichtenheld, Marc 'HE' Brockschmidt)
    \end{itemize}
    (People that have contributed significantly without ever assuming
    maintainership include Joey Hess, Colin Watson, and Denis Barbier).
  \end{itemize}

  \begin{itemize}
  \item Currently maintained in a private subversion repository on
    Jeroen's server, but we plan to move that to Alioth.
  \item If you want to have an account, you can request one at
    \url{http://svn.wolffelaar.nl/}
  \end{itemize}

\end{frame}

\subsection{Workflow}

\begin{frame}
  \frametitle{Overview over Lintian's workflow}

  \begin{itemize}
  \item \texttt{lintian} -- Frontend
    \begin{enumerate}
    \item \texttt{unpack/} -- Scripts to unpack packages to certain degrees
    \item \texttt{collection/} -- Scripts to collect files and meta
    data from the unpacked packages
    \item \texttt{checks/} -- Modules to search for errors with the
    collected information
    \item \texttt{lintian-info} -- Script to postprocess the output of
    the checks
    \end{enumerate}
  \end{itemize}

\end{frame}

\begin{frame}
  \frametitle{Unpacking}

  \begin{description}
  \item[binary packages]\mbox{}\\
    \begin{description}
    \item[Level 1] unpacks the \texttt{control.tar} from the package
      and generates an index of the files in the \texttt{data.tar}
    \item[Level 2] unpacks the \texttt{data.tar}
    \end{description}
  \item[source packages]\mbox{}\\
    \begin{description}
      \item[Level 1] extracts information from the \texttt{.dsc}
      \item[Level 2] unpacks the source package
    \end{description}
  \end{description}

\end{frame}

\begin{frame}[fragile]
  \frametitle{Data Collection}

  Scripts (mostly Perl, one Shell). Each script has a corresponding
  description file (\texttt{\textit{scriptname}.desc}):
  \begin{exampleblock}{collection/objdump-info.desc}\small
  \begin{verbatim}
Collector-Script: objdump-info
Author: Christian Schwarz <schwarz@debian.org>
Info: This script runs `objdump' over all binaries
 and object files of a binary package.
Type: binary, udeb
Unpack-Level: 2
Output: objdump-info
Order: 2
Needs-Info: file-info
  \end{verbatim}
  \end{exampleblock}
\end{frame}

\begin{frame}[fragile]
  \frametitle{Checking}

  Also formerly scripts but we converted them to Perl modules that are
  directly included instead if run with \texttt{exec}. They also have
  a description file:

  \begin{exampleblock}{checks/etcfiles.desc}\footnotesize
  \begin{verbatim}
Check-Script: etcfiles
Author: Sean 'Shaleh' Perry <shaleh@debian.org>
Abbrev: etc
Standards-Version: 3.5.0.0
Type: binary
Needs-Info: etcfiles
Unpack-Level: 1

Tag: file-in-etc-not-marked-as-conffile
Type: error
Ref: policy 10.7
Info: Files in <tt>/etc</tt> must be marked conffiles if they
 are included in a package.  Otherwise they should be created
 by maintainer scripts.
  \end{verbatim}
  \end{exampleblock}

\end{frame}

\lstset{language=Perl, numbers=left, numberstyle=\tiny,
  stepnumber=2, numbersep=5pt}

\begin{frame}[fragile]
  \frametitle{A simple checking script}

  {\scriptsize
  \begin{lstlisting}
# [copyright stuff]
package Lintian::control_file;
use Util; use Tags;

sub run {
my $pkg = shift;
my $type = shift;
# Check that each field is only used once:
my $seen_fields = {};
open (CONTROL, "debfiles/control") or fail "Couldn't read control: $!";
while (<CONTROL>) {
        #Reset seen_fields if we enter a new section:
        $seen_fields = {} if /^$/;
        if (/^(\S+):/) {
                my $field = lc ($1);
                if ($seen_fields->{$field}) {
                        tag "debian-control-with-duplicate-fields",
                            "$field: $$seen_fields{$field}, $.";
                }
                $seen_fields->{$field} = $.; 
        }
}
1;
  \end{lstlisting}
  }
\end{frame}


\begin{frame}
  \frametitle{\texttt{lintian-info} (Postprocessing)}

  \begin{itemize}
    \item Reads the \texttt{Info:} fields from the check description
      files
    \item strips out HTML tags and expands some special entities
    \item wraps the text to the screen width
  \end{itemize}
\end{frame}

\section{Further Development}

\subsection{Code quality, Refactoring}

\begin{frame}
  \frametitle{Code quality, Refactoring}

  \begin{itemize}
  \item A lot of code could be rewritten in a much cleaner and shorter
    way due to the new Perl features of the last seven years
    (e.g. the whole \texttt{fork-and-exec} stuff)
  \item By converting more of the scripts to Perl modules we can
    make the whole process more flexible (and probably faster by
    saving quite some forks and maybe even file reads).
  \item By moving more code from the frontend to separate Perl modules
    we can make the frontend code more maintainable.
  \end{itemize}
\end{frame}

\subsection{Backend, Data Storage and Managment}

\begin{frame}
  \frametitle{Backend, Data Storage and Managment}

  \begin{itemize}
  \item The current lab code is \textit{teh suck}.
  \item The lab should cache more things, like the result of the last
    run (lintian.debian.org uses a single log file for that right now
    which is a really ugly hack) and probably even some of the results
    of the collection scripts
  \item Lintian tries to use information from the source package while
    processing the binary package but the implementation for that
    is a hack too
  \end{itemize}
\end{frame}

\subsection{User Interaction and Reporting}

\begin{frame}
  \frametitle{User Interaction and Reporting}

  \begin{itemize}
  \item The current system is not very accurate and mixes
    information about severity and quality of the check
    (e.g. we downgraded some errors to warnings because they produced
    too many false positives)
  \item The plan is to introduce two dimensions "Severity"
    and "Significance" where each of them has 3-4 possible values
  \item There will be one human-readable output format that will
    just add a qualifier to the severity value (e.g. \texttt{E?}
    or \texttt{E!} instead of just \texttt{E})) and one
    machine-readable output with numerical values (don't know which
    format to use yet, tough, colon-separated? XML? RFC822?)
  \end{itemize}
\end{frame}

\subsection{Integration with other tools}

\begin{frame}
  \frametitle{Integration with other tools}

  \begin{itemize}
  \item We probably should have better unpacking scripts that can
    handle things like a unpacked source package or even an installed
    package. The latter would also open the possibility for a set of
    new checks that can't be done on the package file itself
  \item Currently many maintainers run a lot of tools to test their
    packages (lintian, linda, debdiff, piuparts, etc.). It would
    be certainly useful to have some kind of integration between
    these tools, even if it would be only a frontend to run them
    all on a given package in a senseful way. But also things like
    running lintian on the installed package within piuparts sound
    interesting
  \end{itemize}
\end{frame}

\section{Helping with Lintian}

\begin{frame}
  \frametitle{How to help making lintian better}

  \begin{itemize}
  \item Provide complete patches (let's fix a bug to demonstrate what
    that means, \#324944 looks simple enough)
  \item If you can't provide patches, provide an algorithm (and invest
    some thoughts how good it avoids false positives)
  \item Subscribe to \url{debian-lint-maint@lists.debian.org} and
    contribute to discussions and development
  \end{itemize}
\end{frame}

\begin{frame}[fragile]
  \frametitle{Bug \#324944}

  \begin{small}
  \begin{verbatim}
From: Otavio Salvador <otavio@debian.org>
To: Debian Bug Tracking System <submit@bugs.debian.org>
Subject: lintian: False positive to extra license file
Date: Wed, 24 Aug 2005 21:26:47 -0300

Package: lintian
Version: 1.23.11
Severity: minor

  W: gnome-icon-theme-gartoon binary: extra-license-file \
     usr/share/[...]/gnome-mime-text-x-copying.svg

[...]
  \end{verbatim}
  \end{small}
\end{frame}

\begin{frame}[fragile]
  \frametitle{Let's search the code}

  \begin{verbatim}
lintian/trunk$ grep extra-license-file checks/*
checks/files:   tag "extra-license-file", "$file";
checks/files.desc:Tag: extra-license-file
lintian/trunk$ grep extra-license-file testset/tags.*
lintian/trunk$
  \end{verbatim}
\end{frame}

\begin{frame}[fragile]
  \frametitle{Found it}

  {\scriptsize
  \begin{lstlisting}
# ---------------- license files
if ($file =~ m,(copying|licen[cs]e)(\.[^/]+)?$,i
    # ignore some common extensions; there was at least one file
    # named "license.el".  These are probably license-displaying
    # code, not license files.
    # Another exception is made for .html and .php because preserving
    # working links is more important than saving some bytes, and
    # because a package had a HTML form for licenses called like that.
    # Another exception is made for various picture formats since
    # those are likely to just be simply pictures.
    and not $file =~ m/\.(el|c|h|py|cc|pl|pm|html|php|xpm|png)$/
    and not defined $link) {
    tag "extra-license-file", "$file";
}
  \end{lstlisting}
  }
\end{frame}

\begin{frame}[fragile]
  \frametitle{Changed it}

  {\scriptsize
  \begin{lstlisting}
# ---------------- license files
if ($file =~ m,(copying|licen[cs]e)(\.[^/]+)?$,i
    # ignore some common extensions; there was at least one file
    # named "license.el".  These are probably license-displaying
    # code, not license files.
    # Another exception is made for .html and .php because preserving
    # working links is more important than saving some bytes, and
    # because a package had a HTML form for licenses called like that.
    # Another exception is made for various picture formats since
    # those are likely to just be simply pictures.
    and not $file =~ m/\.(el|c|h|py|cc|pl|pm|html|php|xpm|png|jpe?g|gif|svg)$/
    and not defined $link) {
    tag "extra-license-file", "$file";
}
  \end{lstlisting}
%  }
%  {\small
  Changelog entry:
  \begin{verbatim}
  * debian/files:
    + [FL] Add some formats to the exception list for
      extra-license-file (jpe?g, gif and svg)
      (Closes: #324944)
  \end{verbatim}
  }
\end{frame}

\begin{frame}[fragile]
  \frametitle{Add a testset}

  In \texttt{testset/filenames/debian/rules} we add:
  {\scriptsize
  \begin{verbatim}
	install -d debian/tmp/usr/share/pixmaps
	install -d debian/tmp/usr/share/pixmaps/foo
	touch debian/tmp/usr/share/pixmaps/license.jpeg
	touch debian/tmp/usr/share/pixmaps/licence.jpg
	touch debian/tmp/usr/share/pixmaps/copying.xpm
	touch debian/tmp/usr/share/pixmaps/foo/COPYING.svg
	touch debian/tmp/usr/share/pixmaps/foo/copying.png
	touch debian/tmp/usr/share/pixmaps/license.txt
	touch debian/tmp/usr/share/pixmaps/license.foo
	touch debian/tmp/usr/share/pixmaps/COPYING
  \end{verbatim}
  }
\end{frame}

\begin{frame}[fragile]
  \frametitle{Add a testset 2}

  Let's run the testset:
  {\scriptsize
  \begin{verbatim}
lintian/trunk$ ./debian/rules runtests onlyrun=filenames
.... running tests ....
[ -d debian/tests ] || mkdir debian/tests
LINTIAN_ROOT="" /usr/bin/perl testset/runtests -k testset \
  debian/tests filenames
Checking for missing info tags ... done.
Running static lab test ... create ...  renew ...  remove ... rmdir ...done.
Running test on filenames 12-0.1: copying... building... testing... FAILED:
--- testset/tags.filenames      2005-09-09 07:12:43.000000000 +0200
+++ debian/tests/tags.filenames 2005-09-09 08:03:58.073754528 +0200
@@ -38,6 +38,9 @@
 W: filenames: binary-without-manpage testxbin
 W: filenames: binary-without-manpage testxbin2
 W: filenames: cvsignore-file-in-package files/.cvsignore
+W: filenames: extra-license-file usr/share/pixmaps/COPYING
+W: filenames: extra-license-file usr/share/pixmaps/license.foo
+W: filenames: extra-license-file usr/share/pixmaps/license.txt
 W: filenames: file-in-unusual-dir files/ .tif
 W: filenames: file-in-unusual-dir files/".tif
 W: filenames: file-in-unusual-dir files/'\\
Checking whether all tags are tested and tags have description ...
done.
touch runtests
  \end{verbatim}
  }
\end{frame}

\begin{frame}[fragile]
  \frametitle{Add a testset 3}

  In \texttt{testset/tags.filenames} we add the expected results
  {\scriptsize
  \begin{verbatim}
[...]
W: filenames: binary-without-manpage testxbin
W: filenames: binary-without-manpage testxbin2
W: filenames: cvsignore-file-in-package files/.cvsignore
W: filenames: extra-license-file usr/share/pixmaps/COPYING
W: filenames: extra-license-file usr/share/pixmaps/license.foo
W: filenames: extra-license-file usr/share/pixmaps/license.txt
W: filenames: file-in-unusual-dir files/ .tif
W: filenames: file-in-unusual-dir files/".tif
W: filenames: file-in-unusual-dir files/'\\
[...]
  \end{verbatim}
  }
\end{frame}

\begin{frame}[fragile]
  \frametitle{Add a testset 4}

  Now it works...
  {\scriptsize
  \begin{verbatim}
lintian/trunk$ ./debian/rules runtests onlyrun=filenames
.... running tests ....
[ -d debian/tests ] || mkdir debian/tests
LINTIAN_ROOT="" /usr/bin/perl testset/runtests -k testset \
  debian/tests filenames
Checking for missing info tags ... done.
Running static lab test ... create ...  renew ...  remove ... rmdir ...done.
Running test on filenames 12-0.1: copying... building... testing... done.
Checking whether all tags are tested and tags have description ...
done.
touch runtests
  \end{verbatim}
  }
\end{frame}


\end{document}



