Creative Commons License
Excepto donde se indique otra cosa, todo el contenido de este lugar está bajo una licencia de Creative Commons.
Taquiones > debian > Mensajes de Lintian

Mensajes de Lintian

Introducción

Lintian es el programa que utilizo para verificar si los paquetes Debian que construyo son correctos o no.

Tras varios meses de uso me doy cuenta de que las advertencias y errores se repiten y me veo una y otra vez consultando qué quieren decir exactamente y cómo eliminarlos. Mi memoria no da para más, y menos en casos como éste en los que una vez que lo he arreglado no vuelven a repetirse. Por esa razón voy a escribir aquí una breve nota sobre cada uno de los que me aparezcan, a modo de referencia, y su aplicación en paquetes que contienen código Perl si se da el caso.

En su página, el programa lintian dispone de una clasificación muy instructiva sobre sus advertencias:

En el primer caso se incluye una lista de los paquetes que contienen errores del mismo tipo, mientras que en el segundo una lista de sus paquetes y los errores correspondientes.

Un pequeño truco que puede utilizarse para automatizar enlaces a estas páginas es que la estructura de las mismas es bastante predecible y viene a ser algo como:

http://lintian.debian.org/reports/T%s.html

donde podemos sustituir %s por el nombre del aviso, con los guiones de separación que nos muestra lintian, y tenemos la dirección real de la página:

http://lintian.debian.org/reports/Tancient-standards-version.html

En dicha página además de aparecer la descripción del error ó advertencia, tendremos acceso a una lista de paquetes en los que dicha situación se da.

La otra manera de obtener esta información, ya que he visto que no todos los mensajes aparecen en la página, es utilizar un programa llamado lintian-info incluído en el paquete.

$ lintian-info --tags ancient-standards-version
N: ancient-standards-version
N:
N:   The source package refers to a `Standards-Version' older than one
N:   year. Please update your package to latest policy and set this control
N:   field appropriately.
N:
N:   If the package is already compliant with the current standards, you
N:   don't have to re-upload the package just to adjust the
N:   Standards-Version control field. However, please remember to update
N:   this field next time you upload the package.
N:

Advertencias

native-package-with-dash-version

Los paquetes nativos deberían crearse únicamente si el software que contienen ha sido concebido especificamente para convertirse en un paquete Debian. En este caso el número de versión de dicho paquete no debería contener un valor en el número de versión Debian.

Estos paquetes se crean a veces por accidente, ya que en la mayor parte de los casos la razón es la localización del archivo tar con los fuentes originales. Puesto que el programa dpkg-source busca este archivo en el directorio superior, como ../paquete-version.orig.tar.gz, si no lo encuentra, no lo considera como tal.

Y al respecto sobre el tema de crear ó no paquetes nativos, hay varias discusiones útiles en la red:

source-contains-svn-control-dir

El fuente del paquete contiene un directorio .svn. Es bastante común incluirlo accidentalmente, ya que los directorios con este nombre son de uso interno de subversion y no pertenecen al paquete.

Cuando se empaquete un programa obtenido de una versión bajo control de --subversion-- es preferible usar una exportación limpia (usando export) en lugar de una copia de trabajo (usando checkout).

En el caso de que una versión procedente del desarrollador principal (upstream release) contenga directorios .svn debe ser considerado un error y enviado como tal a dicho desarrollador, dado que puede llegar a duplicar el tamaño del archivo tar innecesariamente.

Perl

Reconozco que este aviso es algo que no me importa ignorar puesto que el archivo tar lo tengo muy controlado, pero he encontrado una solución cuando se utiliza Module::Build.

  1. Creamos una distribución limpia utilizando la opción distdir, la cual copia todos los archivos del manifiesto del paquete en un directorio llamado nombredeladistribucion_-_version_ (como Taquiones-Admin-0.9), borrándolo si previamente existe.
  2. Si en la distribución hemos incluído los archivos del directorio debian/ nos movemos al nuevo directorio.
  3. Ejecutamos debuild con las opciones adecuadas (en mi caso suelen ser -uc -us porque no quiero firmar por el momento).

Siendo ésto un buen ejercicio para comprobar si nuestro paquete instalaría sin más que bajarse el paquete en el que viene; en algunos casos me ha ayudado mucho a comprender que estaba dejándome cosas fuera y otras dadas por hechas cuando no era así.

Al final he llegado a incluir la siguiente estrofa en el archivo make de rigor:

deb: Build
    perl Build distdir
    cd Taquiones-Admin*; debuild -uc -us

Cambiando el nombre del directorio según el paquete correspondiente. Si se desea hacerlo de una forma más automática en esta página he descrito una forma.

manpage-has-bad-whatis-entry

Cada una de las páginas de manual debe comenzar con una sección NAME que indique el nombre y una breve descripción de la misma, separados por un guión \-.

Estas secciónes son analizadas por mandb y la información extraída es almacenada en una base de datos y será utilizada por los programas apropos y whatis (ambos en el mismo paquete), por lo que es necesario que estén en un formato normalizado. Esta advertencia aparece cuando se encuentra con una página con un formato que no ha podido reconocer.

mandb utiliza el mismo algoritmo que lexgrog para analizar páginas, y según la documentación de éste, el formato correcto en el conjunto tradicional de macros es:

.SH NAME
nombre \- descripción breve

y en el caso de que existan varios nombres

.SH NAME
nombre1 \- descripción breve 1
.br
nombre2 \- descripción breve 2

aunque puede sustituírse .br por .PP ó cualquier otra macro que comience un párrafo.

Perl

En el caso de los paquetes en Perl, las páginas de manual se crean en muchas ocasiones automáticamente para todos los archivos fuente, siendo la mayor parte de ellas referencias de librerías ó meramente código sin documentar, y que no corresponden con ninguna página como tal.

Gunnar Wolf lo explica bastante bien a raíz de una consulta en la lista de Debian y Perl.

En estos casos existen varias soluciones según el sistema de construcción que se emplee:

  • --perl-mm--: se deben incluir las claves MAN1PODS y MAN3PDOS en los datos que definen al paquete, de manera que sólo lo que allí pongamos se procese. Si se desea suprimir cualquier creación de manuales ambas variables deben contener hashes vacíos y no valores nulos ó escalares.

    MAN3PODS => {},
    
  • --perl-mb--: se debe usar el parámetro pod_files en la creación del objeto, aunque está pensando para situaciones extrañas, donde los fuentes no están situados en los lugares acordados, tales como un módulo Foo::Bar cuyo fuente exista únicamente en ./Bar.pm.

    pod_files   =>  {   'Bar.pm'   =>  'lib/Foo/Bar.pod' },
    

Por otra parte, es bastante común que algunos analizadores de documentación POD no entiendan bien la misma, e ignoren la sección creada ó la cambien de alguna forma.

Por ejemplo, en mis módulos tengo lo siguiente:

__EOF__
=head1 NAME

Nombre - Descripción breve

=head1 SYNOPSIS

de tal manera que la primera sección, NAME, es ignorada por completo y se pasa a la siguiente. Lo arreglo añadiendo algo de ruido al comienzo:

__EOF__
=cut

=head1 NAME

Nombre - Descripción breve

y tanto lintian como yo estamos la mar de contentos.

manpage-has-errors-from-man

La página de manual indicada provoca errores ó advertencias del propio ejecutable man.

Son de varios tipos:

  • cannot adjust ó can't break indican problemas con el relleno de párrafos, normalmente relacionados con la longitud de las líneas.

  • can't find numbered character generalmente significa que se ha encontrado algún caracter especial tipo latin1 ó similar en la entrada, y se avisa de que estos caracteres no aparecerán en la salida.

script-not-executable

Esta advertencia aparece cuando alguno de los archivos del paquete contiene la secuencia que lo marca como ejecutable a través de un intérprete (shebang), pero no tiene permisos de ejecución, ni está en los directorios habituales de programas.

Este debate al respecto puede aclarar los motivos de que exista esta advertencia.

El mejor modo de resolverlo, descartando eliminar el shebang, es incluírlo en el archivo overrides del paquete.

old-fsf-address-in-copyright-file

El archivo con la declaración de los derechos de copia (/usr/share/doc/PACKAGE/copyright) contiene una referencia a la antigua dirección de la --fsf--. Es necesario actualizarla a

Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
MA 02110-1301, USA.

y la advertencia desaparece.

Es normal que, si se incluye en este archivo el texto completo de alguna licencia que aparece bajo /usr/share/common-licenses, Lintian pueda encontrar la dirección antigua y emita, además, un error referente a contener el texto completo de la licencia.

copyright-lists-upstream-authors-with-dh make-boilerplate

En este caso Lintian cree que no se ha trabajado lo suficiente en el archivo debian/copyright puesto que ha encontrado una pequeña trampa sintáctica en el mismo.

Los programas de ayuda en la creación de paquetes Debian como dh_make utilizan plantillas para crear los archivos de control del paquete. En el caso de debian/copyright la trampa está en la frase Upstream Author(s), que debe cambiarse a Upstream Author en el caso de que el autor principal sea único, ó reemplazarse por Upstream Authors en el caso de que sean varios.

binary-without-manpage

Según la sección 12.1 de la normativa Debian todos los programas que residan en alguno de estos directorios /usr/bin, /usr/sbin, /bin, /sbin ó /usr/games deben tener una página de manual que los describa.

Se recuerda también que, aunque el programa man tiene la capacidad de comprobar si una página corresponde a varios programas, mirando la sección NAME, cada uno de los programas debería tener la suya propia, aunque se trate de un enlace simbólico al mismo archivo, dado que existen varios lectores de páginas de manual que no tienen esa posibilidad.

debian-copyright-file-uses-obsolete-national-encoding

La normativa Debian exige ahora que el archivo que declara los derechos de copia (debian/copyright) contenga texto en formato UTF-8 válido.

Aconsejan emplear la herramienta iconv (en el paquete libc6) para convertir los ficheros en formato obsoleto por el nuevo:

$ iconv -f ISO-8859-1 -t UTF-8 debian/copyright > debian/copyright.new
$ mv debian/copyright.new debian/copyright

En el ejemplo el juego de caracteres del archivo es ISO-8859-1 y es algo que puede determinarse con:

$ file debian/copyright
debian/copyright: ISO-8859 English text

y se puede verificar que tras la conversión queda como

$ file debian/copyright
debian/copyright: UTF-8 Unicode English text

out-of-date-standards-version

La advertencia aparece cuando el paquete fuente referencia una versión de los estándares que está desactualizada, comparada con la normativa actual.

Se indica también que esta advertencia puede ignorarse perfectamente, pero que sería bueno que se actualizase a la versión en curso. Ahora bien, obtener dicha versión de forma automática es muy difícil, puesto que está incluída en el fuente del programa que verifica dicha condición. Un vistazo al archivo /usr/share/lintian/checks/standards-version revela que se almacenan en variables locales de un paquete especial, y que no existe un interfaz definido que nos permita recuperarlos limpiamente.

Las opciones que tenemos son dos: invocar a lintian desde el directorio del paquete, de esta forma:

$ lintian -C standards-version ../mypackage.dsc
W: mypackage source: out-of-date-standards-version 3.7.2 (current is 3.7.3)

o crearnos un programa Perl sencillo que extraiga las versiones del fuente y las imprima.

copyright-without-copyright-notice

Este aviso aparece cuando en el archivo de derechos de copia (debian/copyright) el aviso de quién exactamente posee dichos derechos no está en un formato adecuado.

Dicho formato consiste en una línea donde se aparezca la palabra Copyright, la abreviatura Copr. ó el carácter Unicode de una letra C encerrada en un círculo, seguido del año y el nombre del tenedor de los derechos.

Lo siguiente es un texto real en uno de mis paquetes que provocó esta advertencia:

The upstream author is: "Víctor Moral" <victor@taquiones.net>.

This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; either version 2 or later of the License.

y que tuve que cambiar por

The upstream author is: "Víctor Moral" <victor@taquiones.net>.

Copyright 2008 Víctor Moral

This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; either version 2 or later of the License.

description-synopsis-might-not-be-phrased-properly

La sinópsis de un paquete es la primera línea de la descripción (campo Description), y no es necesario que sea una sentencia completa; la normativa recomienda que se utilice una frase descriptiva.

Lintian avisa de ésto cuando se encuentra un punto al final de la misma como en:

Description: Module::Build extension for develop Ikiwiki plugins.
 The goal of this module is build and install IkiWiki plugins in Perl,
 subclassing the Module::Build and adding some extra funcionalites to it.
 .

La sección 3.4.1 de la normativa de Debian especifica que la sinopsis debe ser tan descriptiva como sea posible en menos de 80 caracteres y que no debe continuarse en el resto de la descripción, ya que deben ser dos entes informativos independientes, siempre desde el punto de vista del usuario.

debhelper-but-no-misc-depends

El paquete fuente emplea debhelper pero no usa la variable ${misc:Depends} en los correspondientes paquetes binarios citados en el archivo de control.

¿ Por qué puede ser necesario ésto ? Porque el paquete puede hacer uso de útiles debhelper que fabriquen dependencias concretas para el nuestro, y mantenerlas es una tarea tediosa y, además, dependiente por completo de cómo funciona debhelper en sí, algo que tal vez cambie en el futuro.

Ejemplos son los programas dh_installdebconf que arrastra una dependencia del paquete debconf, y dh_installxfonts que crea una dependencia de una versión concreta de xutils.

Errores

nested-examples-directory

Este error aparece cuando en el paquete se encuentra un directorio de ejemplos dentro de otro:

usr/share/doc/PAQUETE/examples/examples

y es debido a que el archivo de reglas debian/rules llama a dh_installexamples de esta forma:

binary-indep: build install
    ...
    dh_installexamples examples

lo que se traduce en la siguiente instrucción:

install -d debian/libmodule-build-pm-filter-perl/usr/share/doc/libmodule-build-pm-filter-perl/examples
cp -a examples/ debian/libmodule-build-pm-filter-perl/usr/share/doc/libmodule-build-pm-filter-perl/examples

y, efectivamente, el directorio se copia al completo.

La solución pasa por cambiar la llamada al instalador de esta forma:

binary-indep: build install
    ...
    dh_installexamples examples/*

y como no indicamos un directorio sino su contenido (exceptuando aquellos archivos ocultos que el shell no va a expandir) no crearemos un segundo directorio con el mismo nombre.

copyright-file-contains-full-gpl-license

Anteriormente conocida como copyright-file-is-gpl.

El archivo de los derechos de copia (debian/copyright) del paquete está incluyendo innecesariamente el texto completo de la licencia GPL.

Para arreglarlo se debería incluír únicamente una referencia al archivo /usr/share/common-licenses/GPL.

Nota: actualmente conviene tener en cuenta que este archivo, en un sistema Debian enlaza a la versión 3 de la GPL, por lo que es necesario asegurarse de que la licencia haga referencia a la versión 2 ó posteriores ó sólo a la versión 2.

La diferencia es grande.

Más detalles en la Normativa Debian, sección 12.5.

manpage-not-compressed-with-gzip

Las páginas de manual deben estar comprimidas al máximo mediante el programa gzip, y para ello lo idóneo es utilizar lo siguiente

gzip -9 pagina_fuente

Aunque no aclara demasiado a este respecto se recomienda echar un vistazo a la sección 12.1 de la normativa Debian.

En mi caso este error aparece cuando cometo errores en el archivo make correspondiente:

hwreport.1.gz:  hwreport.sgml
    docbook-to-man $< > $@
    gzip -9 $@

es decir, le estoy indicando que convierta a formato nroff la página en formato SGML y que lo grabe directamente sobre el nombre final que debe tener hwreport.1.gz por lo que la llamada a gzip lo ignora.

Para corregirlo basta con añadir:

hwreport.1.gz:  hwreport.1

hwreport.1: hwreport.sgml
    docbook-to-man $< > $@
    gzip -9 $@

package-installs-packlist

Aquellos paquete que se han construído utilizando --perl-mm-- tendrán un archivo llamado .packlist que contiene la lista de los archivos que componen la distribución. En Debian estos archivos son inútiles y, en algunos casos, tienen el inconveniente añadido de crear un directorio dependiente de la arquitectura en lo que se supone es un paquete independiente de ella.

Para eliminarlos por las bravas se puede usar lo siguiente en el archivo de reglas de construcción debian/rules:

find debian/<pkg> -type f -name .packlist | xargs rm -f

sustituyendo <pkg> por el nombre del paquete, como es obvio.

Otra opción más recomendable es modificar el comportamiento de la herramienta de construcción del paquete en Perl, según el caso:

  • ExtUtils::MakeMaker: Sin solución concreta hasta el momento (y mira que he buscado).
  • Module::Build: Usando el parámetro create_packlist con un valor falso en la construcción del objeto se inhibe la creación de este archivo.

Por ejemplo, en la correspondiente sección del archivo debian/rules se puede añadir lo siguiente:

install: build install-stamp
install-stamp:
    dh_testdir
    dh_testroot
    dh_clean -k

    # Add commands to install the package into debian/$PACKAGE_NAME here
    $(PERL) Build test
    $(PERL) Build install create_packlist=0 destdir=$(TMP)

    touch install-stamp

missing-build-dependency

Este error se debe a que se no se ha especificado una dependencia constructiva de otro paquete, pero se hace uso de él en el archivo de reglas (debian/rules).

Lintian no toma en cuenta las dependencias transitivas, incluso si el paquete depende para su construcción de otro que a su vez declara dicha dependencia desaparecida. Es necesario, pues, añadir una dependencia específica sobre él.

Un caso concreto lo he encontrado en uno de mis paquetes, el cual para construirse necesitaba de:

ikiwiki-plugin-syntax   ->  libmodule-build-perl
                        ->  ...

(entre otros), pero que se amplió con un módulo intermedio como en:

ikiwiki-plugin-syntax   ->  libmodule-build-ikiwiki-perl    ->  libmodule-build-perl
                        ->  ...

y éste error apareció en cuanto eliminé las referencias a libmodule-build-perl en el campo Build-Depends, asumiendo que libmodule-build-ikiwiki-perl ya las incluía en su propio campo. Pues no, según Lintian si el paquete es utilizado directamente en la construcción se recomienda encarecidamente añadir una dependencia sobre él, siempre que pertenezca a una categoría no esencial (non-essential y non-build-essential).

Se sugiere, además, echarle un vistazo a la sección 4.2 de la normativa Debian