Espressioni Nix
Un'espressione Nix è come qualsiasi espressione linguaggio di programmazione: tutto ciò che restituisce un valore o una funzione. Un valore in questo caso può anche essere un elenco o un set. Poiché un modulo Nix (file con estensione .nix
) può contenere qualsiasi espressione Nix, ci si aspetterebbe che il file di configurazione NixOS ( /etc/nixos/configuration.nix
) contenga una singola espressione Nix come contenuto del file.
Il file di configurazione di NixOS contiene un'espressione Nix del modulo:
{config, pkgs, ...}: { /* various configuration options */ }
Se guardi da vicino, puoi vedere che è una funzione , perché le funzioni seguono il modulo pattern: form
. Puoi anche vedere che è una funzione che accetta un set e restituisce un set. Ad esempio, se si dispone di una funzione f = {x, y}: {a = x + y;}
, è possibile chiamarla comef {x=1; y=2;}
e recuperare un set {a=3;}
.
nixos-rebuild switch
Ciò significa che quando chiami , qualcosa chiama la funzione all'interno del file di configurazione NixOS con il set che deve contenere attributi config
epkgs
.
importazioni
Seguendo l'esempio di ./hardware-configuration.nix
, il modo semplice per estrarre l'elenco di pacchetti in un modulo separato packages.nix
è solo quello di estrarre l' environment.systemPackages
opzione e metterla ./packages.nix
in imports
opzione. Il tuo /etc/nixos/configuration.nix
sarebbe simile a:
{ config, ... }:
{
imports =
[ # Include the results of the hardware scan.
./hardware-configuration.nix
# Include the package list.
./packages.nix
];
# SOME STUFF
# SOME STUFF
}
Il tuo /etc/nixos/packages.nix
sarebbe simile a:
{ pkgs, ... }:
{
environment.systemPackages = with pkgs; [ emacs gitFull ];
}
Come funziona? Durante l'esecuzione nixos-rebuild switch
, il processo che valuta le espressioni Nix e decide di installare i pacchetti e così via le chiamate configuration.nix
con un set di attributi, alcuni dei quali sonoconfig
e pkgs
.
Trova l'attributo imports
all'interno del set restituito, quindi valuta ogni espressione Nix nei moduli che imports
contiene con gli stessi argomenti ( config
,pkgs
, ecc).
Devi avere pkgs
come argomento (o, tecnicamente parlando, un attributo di un set, che di per sé è un argomento) di una funzione packages.nix
, perché, dal punto di vista del linguaggio Nix, il processo potrebbe o meno chiamare la funzione con l'insieme che contiene pkgs
. In caso contrario, a quale attributo faresti riferimento durante l'esecuzionewith pkgs
?
È inoltre necessario disporre dei puntini di sospensione, poiché la funzione potrebbe essere chiamata con altri attributi, non solo pkgs
.
Perché non c'è pkgs
inconfiguration.nix
? Puoi averlo, ma se non ti riferisci a nessun punto del file, puoi tranquillamente ometterlo, poiché i puntini di sospensione li includerebbero comunque.
Aggiornamento di un attributo chiamando una funzione esterna
Un altro modo è solo quello di creare una funzione che restituisca un set con qualche attributo e il valore di quell'attributo che inseriresti environment.systemPackages
. Questo è il tuo 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
}
Il tuo packages.nix
:
pkgs: with pkgs; [ emacs gitFull ]
import ./packages.nix pkgs
significa: carica e restituisce l'espressione Nix ./packages.nix
e, poiché è una funzione, chiamala con un argomento pkgs
. with pkgs; [ emacs gitFull ]
è un'espressione con , porta l'ambito dell'espressione prima del punto e virgola all'espressione dopo il punto e virgola. Senza di essa, sarebbe [ pkgs.emacs pkgs.gitFull ]
.