Lors d’un précédent billet, j’avais dit qu’on reviendrait sur les templates de chezmoi. Aujourd’hui, nous allons explorer comment utiliser ces templates pour gérer vos versions d’outils avec asdf.

Les data

Chezmoi permet de définir une mini base de données pour stocker ce que vous voulez ! Ces données doivent être définies dans le dossier .chezmoidata/.

Commençons par créer un fichier asdf.yaml dans ce dossier pour stocker les versions de nos outils.

.chezmoidata/asdf.yaml :

asdf:
  version: 0.18.0
  tools:
    - name: age
      version: 1.2.1
      plugin_url:
    - name: bat
      version: 0.25.0
      plugin_url:
    - name: chezmoi
      version: 2.64.0
      plugin_url:
    - name: github-cli
      version: 2.76.2
      plugin_url:
    - name: golang
      version: 1.25.0
      plugin_url:
    - name: hugo
      version: 0.148.2
      plugin_url:
    - name: lazygit
      version: 0.54.2
      plugin_url:
    - name: lsd
      plugin_url: https://github.com/ossareh/asdf-lsd.git
      version: 1.1.5
    - name: neovim
      version: 0.11.3
      plugin_url:
    - name: nodejs
      version: 24.6.0
      plugin_url:
    - name: rclone
      version: 1.70.3
      plugin_url:
    - name: shellcheck
      version: 0.11.0
      plugin_url:
    - name: shfmt
      version: 3.12.0
      plugin_url:
    - name: upx
      version: 5.0.2
      plugin_url:
    - name: yq
      version: 4.47.1
      plugin_url:
    - name: gum
      version: 0.16.2
      plugin_url:
    - name: starship
      version: 1.23.0
      plugin_url:

Les templates

Chezmoi permet d’utiliser des templates pour personnaliser vos fichiers de configuration. Vous pouvez utiliser des variables pour remplacer des valeurs dans vos fichiers.

Les templates chezmoi utilisent le langage de template Go. Plus précisément, ils utilisent la bibliothèque text/template de Go pour le rendu des templates. Cela signifie que vous pouvez utiliser toutes les fonctionnalités de cette bibliothèque, y compris les fonctions, les pipelines et les conditions. Voir la documentation

Ici, nous allons générer le fichier ~/.tool-versions à partir des données définies dans asdf.yaml.

Petit rappel : le fichier commence par un point 👉 on devra donc utiliser dot pour le symboliser. On ajoute un .tmpl pour indiquer qu’il s’agit d’un template.

~/dot_tool-versions.tmpl :

{{ range .asdf.tools -}}
{{ .name }} {{ .version }}
{{ end -}}

Simple, non ?

Explication du template

  • {{ range .asdf.tools -}} crée une boucle pour itérer sur chaque outil défini dans asdf.yaml.
  • {{ .name }} {{ .version }} affiche le nom et la version de chaque outil.
  • {{ end }} termine la boucle.

Les scripts

Là où chezmoi excelle, c’est dans la gestion des scripts. Vous pouvez facilement définir des scripts à exécuter lors de la modification de certains fichiers.

Dans notre cas, chezmoi va bien mettre à jour notre .tool-versions, mais il peut aussi lancer les commandes nécessaires pour qu’asdf installe les outils !

En prime, on peut combiner la notion de templates et de scripts pour automatiser encore plus notre flux de travail.

Créons le fichier run_onchange_dot_tool-versions.sh.tmpl dans le dossier .chezmoiscripts/.

.chezmoiscripts/run_onchange_dot_tool-versions.sh.tmpl :

{{- if eq .chezmoi.os "linux" -}}
#!/bin/bash

# function install_asdf

function install_asdf() {
	base_url="https://github.com/asdf-vm/asdf/releases/download/"
	rm -f asdf-v{{ .asdf.version }}-{{ .chezmoi.os }}-{{ .chezmoi.arch }}.tar.gz*
	wget "${base_url}v{{ .asdf.version }}/asdf-v{{ .asdf.version }}-{{ .chezmoi.os }}-{{ .chezmoi.arch }}.tar.gz"
	tar -xvzf asdf-v{{ .asdf.version }}-{{ .chezmoi.os }}-{{ .chezmoi.arch }}.tar.gz -C ~/.asdf/bin
	# clean up
	rm -f asdf-v{{ .asdf.version }}-{{ .chezmoi.os }}-{{ .chezmoi.arch }}.tar.gz*
	export ASDF_DATA_DIR={{ .chezmoi.config.destDir }}/.asdf
	export PATH="$ASDF_DATA_DIR/shims:$ASDF_DATA_DIR/bin:$PATH"
}

# install asdf
# if ~/.asdf not exist then install asdf
if [ ! -d ~/.asdf ]; then
	mkdir -p ~/.asdf/bin
fi
# if ~/.asdf/bin/asdf not exist or not executable then install asdf
if [ ! -x ~/.asdf/bin/asdf ]; then
	install_asdf
fi
# if asdf version is not the right one then install asdf
if [ "$(~/.asdf/bin/asdf --version | cut -d ' ' -f 3)" != "v{{ .asdf.version }}" ]; then
	install_asdf
fi

{{ range .asdf.tools -}}
# install plugins
# if .plugin_url does not exist then use ""
if [ -z "$(~/.asdf/bin/asdf plugin list | grep {{ .name }})" ]; then
	echo "installing {{.name}} plugin"
	~/.asdf/bin/asdf plugin add {{ .name }} {{ .plugin_url | default "" }}
else
	# if plugin is already installed then update it
	~/.asdf/bin/asdf plugin update {{ .name }}
fi
{{ end -}}

{{ range .asdf.tools -}}
# install tool
# if tool is not installed then install it
echo "installing {{.name}} {{.version}}"
if [ -z "$(~/.asdf/bin/asdf list {{ .name }} | grep {{ .version }})" ]; then
	~/.asdf/bin/asdf install {{ .name }} {{ .version }}
fi
# remove old versions
for mytool in $(asdf list {{ .name }} | grep -v {{ .version }} | sed -e s/\*//); do 
	echo "removing {{ .name }} $mytool"
	asdf uninstall {{ .name }} $mytool; 
done;
{{ end -}}
{{ end -}}

Explication du script

Je ne vais pas tout détailler mais seulement les grandes lignes :

  • Le script commence par vérifier si le système d’exploitation est Linux.
  • Il définit une fonction pour installer asdf.
  • Il s’assure que le dossier nécessaire à l’installation d’asdf est présent.
  • Il regarde si asdf est déjà installé, et si ce n’est pas le cas, il lance l’installation.
  • Pour chaque outil, il contrôle que le plugin est installé et à jour.
  • Pour chaque outil, il s’assure que la version spécifiée dans ~/.tool-versions est installée.
  • Enfin, pour chaque outil, il nettoie les anciennes versions.

Conclusion

Nous avons vu comment utiliser chezmoi pour gérer les versions d’outils avec asdf. En combinant les templates et les scripts, nous pouvons automatiser notre flux de travail et nous assurer que nos outils sont toujours à jour. N’hésitez pas à explorer davantage les fonctionnalités de chezmoi et à les adapter à vos besoins.

Notez que les datas ne peuvent pas être templatisées (pour l’instant en tout cas).

Encore une fois, vous pouvez vous inspirer de mes dotfiles.