3.3. Writing your own Lintian checks

This section describes how to write and deploy your own Lintian checks. Lintian will load checks from the following directories (in order):

Existing checks can be shadowed by placing a check with the same name in a directory appearing earlier in the list. This also holds for the checks provided by Lintian itself.

Checks in Lintian consist of a description file (.desc) and a Perl module implementing the actual check (.pm). The names of these checks must consist entirely of the lower case characters ([a-z]), digits ([0-9]), underscore (_), dash (-), period (.) and forward slashes (/).

The check name must be a valid Perl unique module name after the following transformations. All periods and dashes are replaced with underscores. All forward slashes are replaced with two colons (::).

Check names without a forward slash (e.g. "fields") and names starting with either "lintian/" or "coll/" are reserved for the Lintian core. Vendors are recommended to use their vendor name before the first slash (e.g. "ubuntu/fields").

3.3.1. Check description file

The check description file is written in the same syntax as Debian control files as described in the Debian Policy Manual ยง5.1. Check description files allow comments as described in the Policy Manual.

The check description file has two paragraph types. The first is the check description itself and must be the first paragraph. The rest of the descriptions describe tags, one tag per paragraph. Check description paragraph

The fields in the check description paragraph are:

Check-Script (simple, mandatory)

Name of the check. This is used to determine the package name of the Perl module implementing the check.

Type (simple, mandatory)

Comma separated list of package types for which this check should be run. Allowed values in the list are "binary" (.deb files), "changes" (.changes files), "source" (.dsc files) and "udeb" (.udeb files).

Needs-Info (simple, optional)

Comma separated list of collections required for the check to be run. Common values here include "unpacked", "index" and "file-info".

Info (multiline, optional)

A short description of what the check is for.

Author (simple, optional)

Name and email of the person, who created (or implemented etc.) the check.

Abbrev (simple, optional)

Alternative or abbreviated name of the check. These can be used with certain command line options as an alternative name for the check. Tag description paragraph

The fields in the tag description paragraph are:

Tag (simple, mandatory)

Name of the tag. It must consist entirely of the lower or/and upper case characters ([a-zA-Z]), digits ([0-9]), underscore (_), dash (-) and period (.). The tag name should be at most 68 characters long.

Severity (simple, mandatory)

Determines the default value for how "severe" the tag is. The value must be one of "serious", "important", "normal", "minor", "wishlist" and "pedantic". The effective severity and the value of the Certainty field of a tag determine the "one-letter" code (of non-experimental tags).

Certainty (simple, mandatory)

How accurate the tag is (believed to be). The value must be one of "certain", "possible", "wild-guess". The effective severity and the value of the Certainty field of a tag determine the "one-letter" code (of non-experimental tags).

Info (multiline, mandatory)

The description of the tag, which can be seen by using lintian-info (etc.). The HTML tags "<tt>" and "<i>" may be used in the description.

The symbols &, < and > must be escaped as &amp;, &lt; and &gt; (respectively).

Indented lines are considered "pre-formatted" and will not be line wrapped. These lines are still subject to the allowed HTML tags and above mentioned escape sequences.

Ref (simple, optional)

A comma separated list of references. It can be used to refer to extra documentation. It is primarily used for manual references, HTTP links or Debian bug references.

If a reference contains a space, it is taken as a manual reference (e.g. "policy 4.14"). These references are recorded in the "output/manual-references" data file.

Other references include manpages ("lintian(1)"), ftp or http(s) links ("https://lintian.debian.org"), file references ("/usr/share/doc/lintian/changelog.gz") or Debian bug numbers prefixed with a hash ("#651816").

Unknown references are (silently) ignored.

Experimental (simple, optional)

Whether or not the tag is considered "experimental". Recognised values are "no" (default) and "yes". Experimental tags always use "X" as their "one-letter" code.

3.3.2. Check Perl module file

This section describes the requirements for the Perl module implementing a given check.

The Perl package name of the check must be identical to the check name (as defined by the "Check-Script" field in the description file) with the following transformations:

As an example, the check name contrib/hallo-world will result in the Perl package name Lintian::contrib::hallo_world. API of the "run" sub

The Perl module must implement the sub called run in that Perl package. This sub will be run once for each package to be checked with 5 arguments. These are (in order):

  • The package name.

  • The package type being checked in this run. This string is one of "binary" (.deb), "changes" (.changes), "source" (.dsc) or "udeb" (.udeb).

  • An instance of API Lintian::Collect. Its exact type depends on the type being processed and is one of Lintian::Collect::Binary (.deb or .udeb), Lintian::Collect::Changes (.changes) or Lintian::Collect::Source (.dsc).

  • An instance of Lintian::Processable that represents the package being processed.

  • An instance of Lintian::ProcessableGroup that represents the other processables in the given group. An instance of the Lintian::Collect::Group is available via its "info" method.

Further arguments may be added in the future after the above mentioned ones. Implementations should therefore ignore extra arguments beyond the ones they know of.

If the run sub returns "normally", the check was run successfully. Implementations should ensure the return value is undefined.

If the run sub invokes a trappable error (e.g. "die"), no further checks are done on the package and Lintian will (eventually) exit with 2 to its caller. The check may still be run on other packages.

The run sub may emit tags by invoking the sub "tag" from Lintian::Tags (it can be imported). The first argument is the name of the tag to emit. Any extra arguments will be used as the "tag extra" (or diagnostics). Example:

use Lintian::Tags qw(tag);
sub run {
    tag 'my-tag', 'hallo world';

would emit the tag "my-tag" with the extra note "hallo world" like this:

I: package: my-tag hallo world