Wyrażenia Nix
Wyrażenie Nix jest jak każdy ekspresji języka programowania: wszystko, co ma wartość wartości lub funkcji. Wartość w tym przypadku może być również listą lub zestawem. Ponieważ moduł Nix (plik z rozszerzeniem .nix) może zawierać dowolne wyrażenie Nix, można oczekiwać, że plik konfiguracyjny NixOS ( /etc/nixos/configuration.nix) będzie zawierał pojedyncze wyrażenie Nix jako jego zawartość.
Plik konfiguracyjny NixOS zawiera wyrażenie Nix w postaci:
{config, pkgs, ...}: { /* various configuration options */ }
Jeśli przyjrzysz się uważnie, zobaczysz, że jest to funkcja , ponieważ funkcje są zgodne z formą pattern: form. Możesz także zobaczyć, że jest to funkcja, która akceptuje zestaw i zwraca zestaw. Na przykład, jeśli masz funkcję f = {x, y}: {a = x + y;}, możesz ją wywołać jako f {x=1; y=2;}i odzyskać zestaw {a=3;}.
Oznacza to, że kiedy wywołujesz nixos-rebuild switch, coś wywołuje funkcję w pliku konfiguracyjnym NixOS z zestawem, który musi zawierać atrybuty configi pkgs.
import
Zgodnie z przykładem ./hardware-configuration.nixprostego sposobu na wyodrębnienie listy pakietów do oddzielnego modułu packages.nixjest po prostu zgrywanie environment.systemPackagesopcji i umieszczenie jej ./packages.nixw importsopcji. Twój /etc/nixos/configuration.nixwyglądałby jak:
{ config, ... }:
{
imports =
[ # Include the results of the hardware scan.
./hardware-configuration.nix
# Include the package list.
./packages.nix
];
# SOME STUFF
# SOME STUFF
}
Twój /etc/nixos/packages.nixwyglądałby jak:
{ pkgs, ... }:
{
environment.systemPackages = with pkgs; [ emacs gitFull ];
}
Jak to działa? Po uruchomieniu nixos-rebuild switchproces, który ocenia wyrażenia Nix i decyduje się zainstalować pakiety i tak dalej wywołania configuration.nixz zestawem atrybutów, z których niektóre to configi pkgs.
Stwierdzi atrybut importswewnątrz zwróconego zestawu, tak ocenia każde wyrażenie Nix w modułach, które importszawiera z tymi samymi argumentami ( config, pkgsitp).
Musisz mieć pkgsjako argument (lub, technicznie rzecz biorąc, atrybut zestawu, który sam jest argumentem) funkcji w packages.nix, ponieważ z perspektywy języka Nix proces może lub nie może wywoływać funkcję z zestawem, który zawiera pkgs. Jeśli tak się nie stanie, do jakiego atrybutu odnosiłbyś się podczas uruchamiania with pkgs?
Musisz również mieć wielokropek, ponieważ funkcja może być wywoływana z innymi atrybutami, nie tylko pkgs.
Dlaczego nie ma pkgsw configuration.nix? Możesz go mieć, ale jeśli nie odwołujesz się do niego nigdzie w pliku, możesz go bezpiecznie pominąć, ponieważ elipsa i tak je uwzględni.
Aktualizowanie atrybutu przez wywołanie funkcji zewnętrznej
Innym sposobem jest po prostu utworzenie funkcji, która zwraca zestaw z jakimś atrybutem i wartością tego atrybutu, który byś w nim wstawił environment.systemPackages. To jest twój 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
}
Twój packages.nix:
pkgs: with pkgs; [ emacs gitFull ]
import ./packages.nix pkgsoznacza: załaduj i zwróć wyrażenie Nix, ./packages.nixa ponieważ jest to funkcja, wywołaj ją z argumentem pkgs. with pkgs; [ emacs gitFull ]jest wyrażeniem z , przenosi zakres wyrażenia przed średnikiem do wyrażenia po średniku. Bez tego byłoby [ pkgs.emacs pkgs.gitFull ].