Design goals
&pkglint; should be simple to use. It should be consistent
and predictable in what it does. The diagnostics should be
understandable. The number of false positive and false negative
diagnostics should be minimal.
Simple to use
Requirement: Using &pkglint; should
not require any knowledge about obscure command line options or
hidden features.
Calling &pkglint; without options gives a useful amount of
warnings. No further knowledge is needed. Users that are
accustomed to GNU software will quickly find the
--help command line option, which gives a
quite verbose description of the available options. Users that
know the GNU compilers will easily remember the
-W class of options, especially
-Wall. Other than with the GNU compilers, the
latter option enables really all warnings
that are intended to be user-visible.
The command line options come in two flavors: short and
long options. The long options are meant to be used when
explaining them to others, while the short options are meant to
be used when invoking &pkglint; in an interactive shell.
Consistent and predictable
Requirement: &pkglint; should behave
such that the user quickly gets an impression about what
&pkglint; does. This impression should be persistent, that is,
the output format for diagnostics should be stable over time,
and diagnostic messages should not be changed without
reason.
There are only two cases of what the output of
&pkglint; is. One is a single line containing the text
looks fine.
, the other is a list of diagnostics,
followed by a summary on the number of diagnostics.
If no warnings are printed, the single line looks
fine.
gives a little motivation to the user. This
message is one of the few things that have been kept in
&pkglint; since it has been adopted from FreeBSD. It just makes
pkglint a more friendly tool. :)
All error and warning messages are formatted by a single
procedure, PkgLint::Logging::log_message. This
way, all messages are formatted the same way, which allows easy
recognition by human users as well as other tools. There are two
different formats available, the traditional one and the gcc-like
one. In both formats, each diagnostic occupies exactly one line. Up
to the year 2005, some of the longer messages used to take more than
one line, but this behavior has been removed.
The default format is the traditional one. It consists of the
severity, in upper-case letters, followed by the filename, the line
number and finally the message text. It allows easy recognition of
the severity of the messages. Even if errors and warnings are
intermixed in the output, the filenames start almost in the same
column.
The gcc-like output format consists of the filename, the line
numbers, the severity and finally the message text. It has been
added to make it easier to integrate the &pkglint; diagnostics into
various text editors, for example Emacs. Since in this format the
filename is the first word, it can be easily seen which warning
originates in which file.
There are some other procedures that affect the output, but
they have to be enabled explicitly.
Understandable diagnostics
Requirement: The diagnostics are
intended to help the user in writing better package definitions.
They should use an unambiguous, clear language and point
directly to the problem. If possible, they should include a hint
on how the problem can be fixed properly.
Few false diagnostics
Requirement: The number of
false positives, that is diagnostics
where no problem actually exists, should be minimal. On the
other hand, &pkglint; should detect as many problems as
possible. If it fails to detect a problem, this is called a
false negative.
Currently, there are very few false positives. The way
&pkglint; parses the files is already close to the way
make and sh parse them, so
the structure of the files is modelled quite well.
Since &pkglint; is also very strict in what it accepts,
many problems can already be detected. But since the pkgsrc
developers are quite creative when it comes to solving problems,
&pkglint; cannot detect everything. After all, the language used
to define packages is turing-complete, so it cannot be decided
in every case whether a package is valid or not. Luckily, most
packages are quite simple.