Nothing is more frustrating when you're working on a project than having to : - Find the tools you need to work on the project (compilation, development, etc.). - Manage the versions of installed packages according to their installation date. - Manage the distributions on which these packages are installed (package manager used).
During the development phase of a project, maintaining a coherent development environment that evolves over time is quite difficult, mainly because of the following factors:
Some modern programming languages are well aware of this, and have dependency management systems with locking functions to ensure the reproducibility of development environments, such as :
These systems make it possible to maintain the same dependencies throughout the life of the project, but this only applies to the libraries used and not to all the third-party tools.
This is why I use the :
Here is an example of use for the JSL Devops
Firstly, you will notice that the just and hugo are not available in the user's distribution. However, without any intervention from the user, you will notice that they become available thanks to Nix and the file flake.nix file.
Install the direnv package
# install direnv
curl -sfL https://direnv.net/install.sh | bash
Configure the shell to take into account direnv when a new shell is created. ### Shells
Add the following line to the end of the file ~/.bashrc :
eval "$(direnv hook bash)"
Add the following line to the end of the file ~/.zshrc :
eval "$(direnv hook zsh)"
Add the following line to the end of the file ~/.config/fish/config.fish :
direnv hook fish | source
Fish supports 3 modes that you can define with the global environment variable 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)
Once nix and direnv have been installed, the first time you access a project directory you will need to authorise automatic execution of direnv with the following command: direnv allow
You can also launch onboarding with the following command nix develop
The tool just tool tool will be installed automatically with nix and flakesee the next section.
To activate project onboarding, simply copy the 3 files below into your project's root directory.
projet
├─ .envrc
├─ flake.nix
└─ justfile
Configuration of the .envrc file
use flake
File configuration 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 of the 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"