Expressions Nix
Une expression Nix est comme n'importe quelle expression de langage de programmation: tout ce qui évalue une valeur ou une fonction. Dans ce cas, une valeur peut également être une liste ou un ensemble. Comme un module Nix (fichier avec extension .nix
) peut contenir n'importe quelle expression Nix, vous vous attendez à ce que le fichier de configuration NixOS ( /etc/nixos/configuration.nix
) contienne une seule expression Nix comme contenu de fichier.
Le fichier de configuration NixOS contient une expression Nix de la forme:
{config, pkgs, ...}: { /* various configuration options */ }
Si vous regardez attentivement, vous pouvez voir que c'est une fonction , car les fonctions suivent le formulaire pattern: form
. Vous pouvez également voir que c'est une fonction qui accepte un ensemble et renvoie un ensemble. Par exemple, si vous avez une fonction f = {x, y}: {a = x + y;}
, vous pouvez l'appeler comme f {x=1; y=2;}
et récupérer un ensemble {a=3;}
.
Cela signifie donc que lorsque vous appelez nixos-rebuild switch
, quelque chose appelle la fonction à l'intérieur du fichier de configuration NixOS avec l'ensemble qui doit contenir les attributs config
et pkgs
.
importations
Dans l'exemple suivant ./hardware-configuration.nix
, la manière simple d'extraire la liste des packages dans un module séparé packages.nix
consiste simplement à extraire l' environment.systemPackages
option et à la mettre ./packages.nix
en imports
option. Votre /etc/nixos/configuration.nix
ressemblerait à:
{ config, ... }:
{
imports =
[ # Include the results of the hardware scan.
./hardware-configuration.nix
# Include the package list.
./packages.nix
];
# SOME STUFF
# SOME STUFF
}
Votre /etc/nixos/packages.nix
ressemblerait à:
{ pkgs, ... }:
{
environment.systemPackages = with pkgs; [ emacs gitFull ];
}
Comment ça marche? Lorsque vous exécutez nixos-rebuild switch
, le processus qui évalue les expressions Nix et décide d'installer des packages et ainsi de suite appelle configuration.nix
avec un ensemble d'attributs, dont certains sont config
et pkgs
.
Elle trouve attribut à l' imports
intérieur de l'ensemble de retour, de sorte qu'il évalue chaque expression Nix dans les modules qui imports
contient les mêmes arguments ( config
, pkgs
, etc.).
Vous devez avoir pkgs
comme argument (ou, techniquement parlant, un attribut d'un ensemble, qui est lui-même un argument) d'une fonction dans packages.nix
, car, du point de vue du langage Nix, le processus peut ou non appeler la fonction avec l'ensemble qui contient pkgs
. Si ce n'est pas le cas, à quel attribut feriez-vous référence lors de l'exécution with pkgs
?
Vous devez également avoir des points de suspension, car la fonction peut être appelée avec d'autres attributs, pas seulement pkgs
.
Pourquoi n'y pkgs
en a- configuration.nix
t- il pas ? Vous pouvez l'avoir, mais si vous n'y faites référence nulle part dans le fichier, vous pouvez l'omettre en toute sécurité, car les points de suspension les incluraient de toute façon.
Mise à jour d'un attribut en appelant une fonction externe
Une autre façon consiste simplement à créer une fonction qui renvoie un ensemble avec un attribut et la valeur de cet attribut que vous mettriez à l'intérieur environment.systemPackages
. Voici votre configuration.nix
:
{ config, pkgs, ... }:
{
imports =
[ # Include the results of the hardware scan.
./hardware-configuration.nix
];
# SOME STUFF
environment.systemPackages = import ./packages.nix pkgs;
# SOME STUFF
}
Votre packages.nix
:
pkgs: with pkgs; [ emacs gitFull ]
import ./packages.nix pkgs
signifie: charger et renvoyer l'expression Nix dans ./packages.nix
et comme c'est une fonction, l'appeler avec un argument pkgs
. with pkgs; [ emacs gitFull ]
est une with-expression , elle apporte la portée de l'expression avant le point-virgule à l'expression après le point-virgule. Sans elle, ce serait [ pkgs.emacs pkgs.gitFull ]
.
imports
n'est qu'une liste, vous pouvez donc y ajouter des éléments de manière conditionnelle, par exempleimports = [ ./foo.nix ./bar.nix ] ++ (if baz then [ ./quux.nix ] else []);