Введение в опции Denix
Опции Denix представляют собой обёртку для lib.mkOption
. Это означает, что любую опцию Denix можно создать, используя стандартный lib.mkOption
, и использование опций Denix является необязательным.
Зачем использовать опции Denix?
Использование lib.mkOption
может быть громоздким, и каждый раз писать что-то вроде:
nix
lib.mkOption {type = lib.types.listOf lib.types.str; default = [];}
- неудобно, особенно когда опции в вашей конфигурации используются повсеместно. Вместо этого можно написать более лаконично:
nix
delib.listOfOption delib.str []
Таким образом, вместо создания опции через указание всех параметров, можно использовать функции Denix для более читабельного и аккуратного кода.
Принцип работы
Функции, связанные с опциями, делятся на четыре основных типа:
Создание опции с типом N
*Option <default>
- например,strOption "foo"
.*OfOption <secondType> <default>
- например,listOfOption str ["foo" "bar"]
.*ToOption <secondType> <default>
- например,lambdaToOption int (x: 123)
.
Добавление к типам опции X тип N
allow* <option>
- например,allowStr ...
.allow*Of <secondType> <option>
- например,allowListOf str ...
.allow*To <secondType> <option>
- например,allowLambdaTo int ...
.
Прямое изменение attribute set опции
noDefault <option>
- удаляет атрибутdefault
из опции. Используется редко, так как редко бывают опции без значения по умолчанию.noNullDefault <option>
- удаляет атрибутdefault
из опции, если его значение равноnull
. Используется для логики значений по умолчанию, где допускается их отсутствие.readOnly <option>
- добавляет атрибутreadOnly
со значениемtrue
.apply <option> <apply>
- добавляет атрибутapply
с переданным значением.description <option> <description>
- добавляет атрибутdescription
с переданным значением.
Генерация конкретной опции/опций
singleEnableOption <default> { name, ... }
- создаёт attribute set с помощью выраженияdelib.setAttrByStrPath "${name}.enable" (boolOption default)
. Обычно это используется вdelib.module :: options
, с её передаваемыми аргументами, поэтому достаточно написать:
nix
options = delib.singleEnableOption <default>;
singleCascadeEnableOption { parent, ... }
- создаёт attribute set с помощьюsingleEnableOption
выше, но используетparent.enable
для<default>
. Пример:
nix
# если имя (name) текущего модуля это "programs.category.example",
# то он будет включен по умолчанию если "programs.category" включен.
# будет ошибка, если "programs.category.enable" не существует.
options = delib.singleCascadeEnableOption;
moduleOptions <opts> <args>
- создаёт attribute set с<opts>
для пути текущего модуля. Обычно, необходимо использоватьname
ещё раз, чтобы обозначить опции, но эта функция делает это автоматически.<args>
это набор передаваемых аргументов. Если<opts>
это функция, тогда<args>
является её аргументом. Пример:
nix
# имя текущего модуля это "programs.category.example".
# если не хватает `singleEnableOption`:
options = with delib; moduleOptions {
enable = boolOption true;
device = strOption "desktop";
};
# блок опций выше эквивалентен блоку ниже:
options.programs.category.example = with delib; {
enable = boolOption true;
device = strOption "desktop";
};
# а если не хватает `singleCascadeEnableOption`:
options = with delib; moduleOptions ({ parent, ... }: {
enable = boolOption parent.enable;
device = strOption "desktop";
}); # обратите внимание на скобки
# снова, блок опций выше эквивалентен блоку ниже:
options = with delib; { parent, ... }: {
programs.category.example = {
enable = boolOption parent.enable;
device = strOption "desktop";
};
};
Список актуальных опций можно найти в исходном коде: github:yunfachi/denix?path=lib/options.nix
Примеры
Denix | lib.mkOption |
---|---|
portOption 22 | mkOption {type = types.port; default = 22;} |
noDefault (portOption null) | mkOption {type = types.port;} |
noNullDefault (if myconfig.server.enable then "127.0.0.1:4533" else null) | mkOption {type = types.str;} // (if myconfig.server.enable then {default = "127.0.0.1:4533";} else {}) |
allowNull (portOption null) | mkOption {type = types.nullOr types.port; default = null;} |
allowStr (portOption "22") | mkOption {type = types.strOr types.port; default = "22";} |
listOfOption port [] | mkOption {type = types.listOf types.port; default = [];} |
readOnly (noDefault (portOption null)) | mkOption {type = types.port; readOnly = true;} |
singleEnableOption true {name = "git";} | git.enable = mkEnableOption "git" // {default = true;} |
(Обычно
{name = "git";}
указывать не требуется, так как эта функция в основном используется вdelib.module :: options
)