Quilt es una aplicación utilizada para parchear código, es decir, para modificar el código fuente a través de un «parche», un trozo de código claramente definido que modifica el código original. Quilt no es una herramienta específica de Debian ni de su desarrollo, pero aquí vamos a explicar la forma de usarla en el desarrollo de paquetes debian mediante un sencillo ejemplo con el paquete dnsproxy que estamos poniendo a punto.
¿Quilt?
Los nombres de las aplicaciones están algunas veces muy bien escogidos y este es un ejemplo de ello. Desconocía que quilt es como se denomina en inglés a ese cobertor para la cama hecho a base de retales o parches de múltiples telas:
Origen de la imagen: Wikipedia
Configurar para debian
Seguimos las recomendaciones de Guide for Debian Maintainers: Quilt y hacemos las siguientes modificaciones para poder usar quilt adecuadamente en nuestro desarrollo de paquetes para debian (aunque añadimos antes una línea para que funcione correctamente el auto-completado):
debian@debian:~$ cat >> ~/.bashrc <<EOF _completion_loader quilt alias dquilt="quilt --quiltrc=${HOME}/.quiltrc-dpkg" complete -F _quilt_completion $_quilt_complete_opt dquilt EOF
Y creamos el fichero ~/.quiltrc-dpkg tal como se explica. Para tener definido el alias «dquilt» en esta sesión, simplemente hacemos que se lea el fichero ~/.bashrc:
debian@debian:~$ source ~/.bashrc
Crear un parche para dnsproxy
Si accedemos al directorio d/patches podemos ver que el anterior mantenedor creó dos parches:
debian@debian:~/git/debian/dnsproxy/pkg-dnsproxy/debian/patches$ ls -l total 12 -rw-r--r-- 1 debian debian 365 May 15 10:15 01_fix_missing_prototypes.patch -rw-r--r-- 1 debian debian 626 May 15 10:15 02_fix_wrong_use_of_hyphens_in_manpage.patch -rw-r--r-- 1 debian debian 77 May 15 10:15 series
Vamos a continuación a dar los pasos para añadir un nuevo parche al fichero dnsproxy.c para que cuando ejecutemos el comando «dnsproxy -h» la salida no está marcada como un error (exit(1)), sino como una ejecución correcta (exit(0)):
debian@debian:~/git/debian/dnsproxy/pkg-dnsproxy$ dquilt new 03_set_exit_0_when_help_arg_used.patch Patch 03_set_exit_0_when_help_arg_used.patch is now on top debian@debian:~/git/debian/dnsproxy/pkg-dnsproxy$ dquilt add dnsproxy.c File dnsproxy.c added to patch 03_set_exit_0_when_help_arg_used.patch dquilt new 03_set_exit_0_when_help_arg_used.patch
El fichero dnsproxy.c está añadido al parche, ahora lo editamos e incluímos las modificaciones que consideremos oportunas y añadimos esos cambios al parche con:
debian@debian:~/git/debian/dnsproxy/pkg-dnsproxy$ dquilt refresh Refreshed patch 03_set_exit_0_when_help_arg_used.patch
Por último tenemos que añadir una cabecera al parche conforme a DEP3 (Las DEP o «Debian Enhancement Proposals» son una serie de normas propias de Debian):
debian@debian:~/git/debian/dnsproxy/pkg-dnsproxy$ dquilt header -e --dep3
Y rellenamos los campos correspondientes. Finalmente obtenemos el fichero d/patches/03_set_exit_0_when_help_arg_used.patch con el siguiente contenido:
Description: Add exit 0 when -h argument used When -h argument passed to dnsproxy exit status is set to 1 as the default option. This patch set exit status to 0 when -h argument is used. Author: Alberto Molina Coballes <alb.molina@gmail.com> Last-Update: 2020-05-21 --- This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ --- a/dnsproxy.c +++ b/dnsproxy.c @@ -255,8 +255,15 @@ case 'V': fprintf(stderr, PACKAGE_STRING "\n"); exit(0); - /* FALLTHROUGH */ case 'h': + fprintf(stdout, + "usage: dnsproxy [-c file] [-dhV]\n" \ + "\t-c file Read configuration from file\n" \ + "\t-d Detach and run as a daemon\n" \ + "\t-h This help text\n" \ + "\t-V Show version information\n"); + exit(0); + /* FALLTHROUGH */ default: fprintf(stderr, "usage: dnsproxy [-c file] [-dhV]\n" \
Y también se ha modificado el fichero d/patches/series añadiendo la referencia al parche anterior.
El parche está ahora mismo aplicado a nuestro código, pero esto supone que el fichero dnsproxy.c está modificado en el repositorio git y no es la situación que queremos en general, realmente queremos que el parche se aplique solo antes de construir el paquete, pero que cuando se termine se deshagan las modificaciones en el código fuente. Si queremos que el parche deje de estar aplicado en este momento, podemos hacerlo también con quilt:
debian@debian:~/git/debian/dnsproxy/pkg-dnsproxy$ dquilt pop -a Removing patch 03_set_exit_0_when_help_arg_used.patch Restoring dnsproxy.c No patches applied
Y ya para terminar, vamos a añadir estas modificaciones en un commit que subiremos a salsa después de hacer las comprobaciones oportunas:
debian@debian:~/git/debian/dnsproxy/pkg-dnsproxy$ git status On branch master Your branch is up to date with 'origin/master'. Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: debian/patches/series Untracked files: (use "git add <file>..." to include in what will be committed) .pc/ debian/patches/03_set_exit_0_when_help_arg_used.patch debian@debian:~/git/debian/dnsproxy/pkg-dnsproxy$ git diff diff --git a/debian/patches/series b/debian/patches/series index c61c5e1..f0ff4c9 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -1,2 +1,3 @@ +03_set_exit_0_when_help_arg_used.patch 01_fix_missing_prototypes.patch 02_fix_wrong_use_of_hyphens_in_manpage.patch debian@debian:~/git/debian/dnsproxy/pkg-dnsproxy$ git add debian/patches/series debian@debian:~/git/debian/dnsproxy/pkg-dnsproxy$ git add debian/patches/03_set_exit_0_when_help_arg_used.patch debian@debian:~/git/debian/dnsproxy/pkg-dnsproxy$ git commit -sm "d/patches: Add patch to avoid wrong exit status > > This patch modifies dnsproxy.c to use exit(0) status when -h argument used" [master 8e5d4af] d/patches: Add patch to avoid wrong exit status 2 files changed, 28 insertions(+) create mode 100644 debian/patches/03_set_exit_0_when_help_arg_used.patch