You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This allows optionally not having a definition at all, which makes sure to use the default instead. E.g.
{config, ... }: {value=mkIfconfig.enable{foo=mkIfconfig.enableFoo"foo";};}# turns into (wich enable = true and enableFoo = false){value={};}
Option and type merging
Options can be defined multiple times with different types, which are then merged together. Useful for submodule modularity and changing submodule defaults. This is used for the fileSystems NixOS option. E.g. this allows splitting modules into backend-specific settings:
{options.value=mkOption{type=attrsOf(submodule({config, ... }: {options={result=mkOption{type=lines;};backend=mkOption{type=enum[];};shared=mkOption{type=types.str;};};config.result='' shared = ${config.shared}; '';}));};}# Another module (and can be many more like this){options.value=mkOption{type=attrsOf(submodule({config, ... }: {options.backend=mkOption{type=enum["foo"];default="foo";};options.foo.fooSpecific=mkOption{type=str;};config.result=mkIf(config.backend=="foo")'' foo = ${config.foo.fooSpecific} '';}));};}
Custom types
lib.types provides a bunch of ready-made types, but users can also define their own, with custom checks and merging strategies. See also NixOS/nixpkgs#75584
{options.smolString=mkOption{type=types.addCheck(s: builtins.stringLengths<32)types.str;};options.funType=mkOption{type=types.mkOptionType{check=builtins.isFunction;# Merge functions by joining the attributes they createmerge=loc: defs: arg: foldl'(l: r: l//r){}(map(d: d.valuearg)defs);};};}
Freeform modules
Recently introduced freeform modules add the ability to not have to declare all options, providing a fallback type for all definitions not matched to an option, which gets merged into the result. Very useful for not having to declare every option of package settings, while still having custom type checking for some of them:
{options.settings=mkOption{default={};type=withtypes;submodule{# All values that don't have an associated option have to be of this typefreeformType=attrsOfint;options.port=mkOption{type=port;default=80;description="The port to use.";};};};# Works, even though foo isn't declared as an optionconfig.settings.foo=10;# error: The option value `settings.port' in `example.nix' is not of type# `16 bit unsigned integer; between 0 and 65535 (both inclusive)'.#config.settings.port = "not-a-port";## Overrides default valueconfig.settings.port=8080;}
Disabling of modules
If a modules is included by default, it can be removed with disabledModules:
{disabledModules=[# Disable because it slows things down"tasks/lvm.nix"# Disable because I want to provide my own services.murmur.* set"services/networking/murmur.nix"];}
Read-only options
Aka, only allow 1 definition, which is usually declared by the module that sets read-only directly. This is usually used for exposing module evaluation results.
{options.value=mkOption{readOnly=true;# We set it here, nobody else can set it nowdefault="value";};}
Type coercion
This is really just another custom type, but its implementation allows converting one definition type into another one. Very useful for backwards compatibility
{# First versionoptions.value=mkOption{type=str;};# Backwards-compatible second versionoptions.value=mkOption{type=coercedTostr(s: {name=s;})(submodule{options.name=mkOption{type=str;};options.other=mkOption{/* ... */};});};}
Inspecting options
Including their type, defaults, definitions, etc., and using them for new options or configs:
Aliased packages and package sets
as I understand what functor does is object closure ( eg summing some integers ), I am not sure how that helps with overriding args of the function
-- noob
Module system features and use-cases for them
Priority-based merging
mkDefault
,mkForce
, etc. Also works recursively. This allows precise control over how defaults are persisted or overridden. E.g.Conditional definitions using
mkIf
This allows optionally not having a definition at all, which makes sure to use the default instead. E.g.
Option and type merging
Options can be defined multiple times with different types, which are then merged together. Useful for submodule modularity and changing submodule defaults. This is used for the fileSystems NixOS option. E.g. this allows splitting modules into backend-specific settings:
Custom types
lib.types
provides a bunch of ready-made types, but users can also define their own, with custom checks and merging strategies. See also NixOS/nixpkgs#75584Freeform modules
Recently introduced freeform modules add the ability to not have to declare all options, providing a fallback type for all definitions not matched to an option, which gets merged into the result. Very useful for not having to declare every option of package settings, while still having custom type checking for some of them:
Disabling of modules
If a modules is included by default, it can be removed with
disabledModules
:Read-only options
Aka, only allow 1 definition, which is usually declared by the module that sets read-only directly. This is usually used for exposing module evaluation results.
Type coercion
This is really just another custom type, but its implementation allows converting one definition type into another one. Very useful for backwards compatibility
Inspecting options
Including their type, defaults, definitions, etc., and using them for new options or configs:
Priority-based definition ordering
Using
mkBefore
,mkAfter
, and co. This is mostly useful for specifying element orders in lists. But it could also be used for e.g. overlay order.Overlay/overrides features and use-cases of them
Overriding package sets
Such that package changes propagate to all the dependents of it
Overriding callPackage arguments per-package
Changing the callPackage arguments for just a single package, without influencing others:
Similarly with
.override
Overriding package sets per-package
If a package and all its dependencies need a different version, this could be done with override like this:
Which is very painful, and incorrect if you missed a dependency. Some package sets (like the haskell one) provide
.overrideScope
for this purpose:See also NixOS/nixpkgs#67422.
pkgs.appendOverlays
andpkgs.extend
work like this as well. Also, this can also work on package sets themselves, e.g.Overriding mkDerivation, derivation, and other function arguments
See also NixOS/rfcs#67
Aliased packages and package sets
This should ideally be disallowed, but this is currently a thing:
Overriding function arguments
Possible using __functor:
The text was updated successfully, but these errors were encountered: