Nix, Direnv, Just, le trio qui simplifie la vie
Rien n’est plus frustrant lorsqu’on travaille sur un projet que de devoir :
- Chercher les outils nécessaires pour travailler sur ce projet (compilation, développement, etc.).
- Gérer les versions des paquets installés en fonction de leur date d’installation.
- Gérer les distributions sur lesquelles ces paquets sont installés (gestionnaire de paquets utilisé).
Pendant la phase de développement d’un projet, maintenir un environnement de développement cohérent qui évolue au fil du temps est assez difficile, en raison notamment des éléments suivants :
- Certains paquets ne sont pas disponibles sur toutes les distributions Windows, MacOS, Linux (Ubuntu, Archlinux, Fedora, Suse, etc.).
- Des versions de paquets peuvent devenir indisponibles suite à l’évolution d’une distribution.
Certains langages de programmation modernes l’ont bien compris, ils disposent de systèmes de gestion de dépendances dotés de fonctionnalités de verrouillage pour assurer la reproductibilité des environnements de développement, notamment :
- Go
- Python
- Ruby
- Rust
- etc …
Ces systèmes permettent de maintenir les mêmes dépendances tout au long de la durée de vie du projet, mais cela ne s’applique qu’aux bibliothèques utilisées et non à tous les outils tiers.
C’est pour cette raison que j’utilise le trio :
- Nix: Permet d’obtenir un système reproductible.
- Direnv: Permet d’exécuter une commande lors de l’entrée dans un répertoire.
- Just: Fournit un gestionnaire de commandes ainsi que l’affichage de l’aide.
Voici un exemple d’utilisation pour le projet de documentation de JSL Devops
Dans un premier temps, vous remarquerez que les outils just
et hugo
ne sont
pas disponibles dans la distribution de l’utilisateur. Cependant, sans
intervention de sa part, vous constaterez qu’ils deviennent disponibles grâce à
Nix
et au fichier flake.nix
.
Installer le paquet direnv
# install direnv
curl -sfL https://direnv.net/install.sh | bash
Configurer le shell pour la prise en compte de direnv
lors d’un nouveau shell.
Ajouter la ligne suivante à la fin du fichier ~/.bashrc
:
eval "$(direnv hook bash)"
Ajouter la ligne suivante à la fin du fichier ~/.zshrc
:
eval "$(direnv hook zsh)"
Ajouter la ligne suivante à la fin du fichier ~/.config/fish/config.fish
:
direnv hook fish | source
Fish supporte 3 modes que vous pouvez définir avec la variable d’environnement
globale direnv_fish_mode
:
set -g direnv_fish_mode eval_on_arrow # Déclenche direnv à l'invite, et à chaque changement de répertoire par flèche (par défaut)
set -g direnv_fish_mode eval_after_arrow # Déclenche direnv à l'invite, et seulement après les changements de répertoire par flèche avant d'exécuter la commande
set -g direnv_fish_mode disable_arrow # Déclenche direnv à l'invite uniquement, il s'agit d'une fonctionnalité similaire au comportement original
sh <(curl -L https://nixos.org/nix/install) --daemon
grep 'experimental-features' /etc/nix/nix.conf || (echo 'experimental-features = nix-command flakes' | sudo tee -a /etc/nix/nix.conf)
sh <(curl -L https://nixos.org/nix/install) --daemon
grep 'experimental-features' /etc/nix/nix.conf || (echo 'experimental-features = nix-command flakes' | sudo tee -a /etc/nix/nix.conf)
sh <(curl -L https://nixos.org/nix/install)
grep 'experimental-features' /etc/nix/nix.conf || (echo 'experimental-features = nix-command flakes' | sudo tee -a /etc/nix/nix.conf)
Une fois nix et direnv installés, lors de votre premier accès au répertoire d’un projet, vous devrez autoriser l’exécution automatique de direnv avec la commande suivante :direnv allow
Vous pouvez égallement lancer le onboarding avec la commande suivantenix develop
L’outil just
sera installé automatiquement avec nix
et flake
, voir la
section suivante.
Pour activer l’onboarding du projet, il suffit de copier les 3 fichiers ci-dessous dans le repertoire racine de votre projet.
projet
├─ .envrc
├─ flake.nix
└─ justfile
Configuration du fichier .envrc
use flake
Configuration du fichier flake.nix
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
flake-utils.url = "github:numtide/flake-utils";
};
outputs = { nixpkgs, flake-utils, ... }:
flake-utils.lib.eachDefaultSystem (system:
let
pkgs = import nixpkgs { inherit system; };
in
{
devShells.default = with pkgs;
mkShell {
name = "Default developpement shell";
packages = [
cocogitto
nixpkgs-fmt
nodePackages.markdownlint-cli
pre-commit
deno
gum
just
];
shellHook = ''
export PROJ="devops.jesuislibre.org"
echo ""
echo "⭐ Welcome to the $PROJ project ⭐"
echo ""
'';
};
});
}
Configuration du fichier justfile
#!/usr/bin/env just -f
# This help
# Help it showed if just is called without arguments
@help:
just -lu | column -s '#' -t | sed 's/[ \t]*$//'
###############################################################################
# pre-commit
###############################################################################
# Setup pre-commit
precommit-install:
#!/usr/bin/env bash
test ! -f .git/hooks/pre-commit && pre-commit install || true
# Update pre-commit
@precommit-update:
pre-commit autoupdate
# precommit check
@precommit-check:
pre-commit run --all-files
###############################################################################
# Tools
###############################################################################
# Update documentation
@doc-update FAKEFILENAME:
./updatedoc.ts
# Lint the project
@lint:
pre-commit run --all-files
# Repl the project
@repl:
nix repl --extra-experimental-features repl-flake .#
# Show installed packages
@packages:
echo $PATH | tr ":" "\n" | grep -E "/nix/store" | sed -e "s/\/nix\/store\/[a-z0-9]\+\-//g" | sed -e "s/\/.*//g"