Никс выражения
Выражение Nix , как любое выражение языка программирования: все , что имеет значение значения или функции. Значением в этом случае также может быть список или набор. Поскольку модуль Nix (файл с расширением .nix
) может содержать любое выражение Nix, можно ожидать, что файл конфигурации NixOS ( /etc/nixos/configuration.nix
) будет содержать одно выражение Nix в качестве содержимого файла.
Файл конфигурации NixOS содержит выражение Nix в форме:
{config, pkgs, ...}: { /* various configuration options */ }
Если вы посмотрите внимательно, вы увидите, что это функция , потому что функции следуют за формой pattern: form
. Вы также можете увидеть, что это функция, которая принимает набор и возвращает набор. Например, если у вас есть функция f = {x, y}: {a = x + y;}
, вы можете вызвать ее как f {x=1; y=2;}
и вернуть набор {a=3;}
.
Это означает, что когда вы вызываете nixos-rebuild switch
, что-то вызывает функцию внутри файла конфигурации NixOS с набором, который должен содержать атрибуты config
и pkgs
.
импорт
Следуя примеру ./hardware-configuration.nix
, простой способ извлечь список пакетов в отдельный модуль packages.nix
просто разорвать environment.systemPackages
вариант и положить ./packages.nix
в imports
опции. Ваш /etc/nixos/configuration.nix
будет выглядеть так:
{ config, ... }:
{
imports =
[ # Include the results of the hardware scan.
./hardware-configuration.nix
# Include the package list.
./packages.nix
];
# SOME STUFF
# SOME STUFF
}
Ваш /etc/nixos/packages.nix
будет выглядеть так:
{ pkgs, ... }:
{
environment.systemPackages = with pkgs; [ emacs gitFull ];
}
Как это работает? При запуске nixos-rebuild switch
процесс, который оценивает выражения Nix и решает установить пакеты и т. Д., Вызывает configuration.nix
с набором атрибутов, некоторые из которых являются config
и pkgs
.
Он находит атрибут imports
в возвращаемом наборе, поэтому он оценивает каждое выражение Nix в модулях, imports
содержащих одинаковые аргументы ( config
, pkgs
и т. Д.).
Вы должны иметь pkgs
в качестве аргумента (или, технически говоря, атрибут набора, который сам является аргументом) функции packages.nix
, потому что с точки зрения языка Nix процесс может вызывать или не вызывать функцию с набором, который содержит pkgs
. Если это не так, на какой атрибут вы бы ссылались при запуске with pkgs
?
Вы также должны иметь многоточие, потому что функция может быть вызвана с другими атрибутами, а не только pkgs
.
Почему не pkgs
в configuration.nix
? Вы можете иметь это, но если вы не обращаетесь к нему где-либо в файле, вы можете спокойно его пропустить, поскольку многоточие будет включать их в любом случае.
Обновление атрибута путем вызова внешней функции
Другой способ - просто создать функцию, которая возвращает набор с некоторым атрибутом и значением этого атрибута, которое вы бы поместили внутрь environment.systemPackages
. Это ваше 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
}
Ваш packages.nix
:
pkgs: with pkgs; [ emacs gitFull ]
import ./packages.nix pkgs
означает: загрузить и вернуть выражение Nix, ./packages.nix
и, поскольку оно является функцией, вызвать его с аргументом pkgs
. with pkgs; [ emacs gitFull ]
является выражением with , оно переносит область выражения перед точкой с запятой в выражение после точки с запятой. Без этого было бы [ pkgs.emacs pkgs.gitFull ]
.