Нікс-вирази
Вираз 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 ]є з-виразом , він приводить область виразу перед крапкою з комою до виразу після крапки з комою. Без нього було б [ pkgs.emacs pkgs.gitFull ].