Manejando Dotfiles Sin Estilo


El omnisciente algoritmo de YouTube me ha recomendado el vídeo Manage Your Dotfiles With Style! sobre la utilización de GNU Stow para gestionar la ordenación y despliegue de dotfiles. Stow es una de las herramientas más populares para llevar a cabo este tipo de tareas pero nunca la he usado porque me parece absolutamente innecesaria. Es un abuso espurio de un software que está pensado para instalar paquetes en sus propios árboles de directorios que, mediante enlaces simbólicos aparentan estar instalados en el árbol común. De hecho, el uso que se hace de Stow es tan simple que se puede emular con un oneliner de Bash que he programado para la ocasión

for i in $(find -type f); do ln -sf "$(realpath "$i")" ~/"${i#??}"; done

Aunque el código es bastante deficiente ya que no debería emplearse find en un bucle for y la expansión de variables es un bashismo intolerable, no me apetecía usar xargs ni extender un comando que funciona con menos de 80 caracteres. Así podríamos desplegar los dotfiles sin necesidad de instalar stow que, por lo general, no viene incluido por defecto en ningún sistema operativo.

De todas formas, no me parece la mejor forma de abordar el problema. Hace más de cuatro años que se me ocurrió una solución superior, si bien nunca la he publicado porque es demasiado manual y carente de ingenio, pero ahora voy a explicarla para establecer una comparación con Stow. Mi alternativa se basa en un script dotfiles.sh que crea enlaces simbólicos. A diferencia de Stow, las direcciones de estos no se basan en la jerarquía de los archivos sino que están codificadas a mano. Aunque suena bastante tedioso, solo hay que añadir una linea cada vez que creemos un nuevo dotfile. El resultado concreto es el siguiente

#!/bin/sh

ln -sf ~/dotfiles/alias ~/.bash_aliases
ln -sf ~/dotfiles/bash ~/.bashrc
ln -sf ~/dotfiles/getmail ~/.getmail/getmailrc
ln -sf ~/dotfiles/i3 ~/.config/i3/config
ln -sf ~/dotfiles/sublime ~/.config/sublime-text-3/Packages/User/Preferences.sublime-settings
ln -sf ~/dotfiles/xmodmap ~/.Xmodmap
ln -sf ~/dotfiles/xresources ~/.Xresources
ln -sf ~/dotfiles/zathura ~/.config/zathura/zathurarc
ln -sf ~/dotfiles/irssi ~/.irssi/config
ln -sf ~/dotfiles/git ~/.gitconfig
ln -sf ~/dotfiles/dunst ~/.config/dunst/dunstrc
ln -sf ~/dotfiles/newsboat ~/.newsboat/config

Si leemos con atención se verán las que considero ventajas de este método. No hay que crear una falsa jerarquía de archivos, pudiendo almacenarlos todos en la misma carpeta para mejorar el orden y permite renombrar los dotfiles como queramos ya que su denominación obligatoria se pospone hasta la creación de los symlinks. Concretamente, mi script se ejecuta sobre la siguiente lista de archivos

~/dotfiles
├── alias
├── bash
├── dunst
├── getmail
├── git
├── i3
├── irssi
├── newsboat
├── sublime
├── xmodmap
├── xresources
└── zathura

En contraposición a esta simplicidad, podemos generar la estructura que Stow exigiría a los mismos dotfiles para funcionar.

~/dotfiles
├── .bash_aliases
├── .bashrc
├── .config
│   ├── dunst
│   │   └── dunstrc
│   ├── i3
│   │   └── config
│   ├── sublime-text-3
│   │   └── Packages
│   │       └── User
│   │           └── Preferences.sublime-settings
│   └── zathura
│       └── zathurarc
├── .getmail
│   └── getmailrc
├── .gitconfig
├── .irssi
│   └── config
├── .newsboat
│   └── config
├── .Xmodmap
└── .Xresources

Las diferencias son más que evidentes, pero la elección de una forma u otra para administrar nuestros archivos de configuración es muy subjetiva y en el fondo va a estar regida por preferencias personales.