Add read-only options

These are options that can have only one definition, regardless of
priority.

Changed files
+16 -5
lib
nixos
doc
modules
+8 -3
lib/modules.nix
···
evalOptionValue = loc: opt: defs:
let
# Add in the default value for this option, if any.
-
defs' = (optional (opt ? default)
-
{ file = head opt.declarations; value = mkOptionDefault opt.default; }) ++ defs;
+
defs' =
+
(optional (opt ? default)
+
{ file = head opt.declarations; value = mkOptionDefault opt.default; }) ++ defs;
# Handle properties, check types, and merge everything together.
-
res = mergeDefinitions loc opt.type defs';
+
res =
+
if opt.readOnly or false && length defs' > 1 then
+
throw "The option `${showOption loc}' is read-only, but it's set multiple times."
+
else
+
mergeDefinitions loc opt.type defs';
# Check whether the option is defined, and apply the ‘apply’
# function to the merged value. This allows options to yield a
+2
lib/options.nix
···
, apply ? null # Function that converts the option value to something else.
, internal ? null # Whether the option is for NixOS developers only.
, visible ? null # Whether the option shows up in the manual.
+
, readOnly ? null # Whether the option can be set only once
, options ? null # Obsolete, used by types.optionSet.
} @ attrs:
attrs // { _type = "option"; };
···
declarations = filter (x: x != unknownModule) opt.declarations;
internal = opt.internal or false;
visible = opt.visible or true;
+
readOnly = opt.readOnly or false;
type = opt.type.name or null;
}
// (if opt ? example then { example = scrubOptionValue opt.example; } else {})
+4
nixos/doc/manual/options-to-docbook.xsl
···
<emphasis>Type:</emphasis>
<xsl:text> </xsl:text>
<xsl:apply-templates select="attr[@name = 'type']" mode="top" />
+
<xsl:if test="attr[@name = 'readOnly']/bool/@value = 'true'">
+
<xsl:text> </xsl:text>
+
<emphasis>(read only)</emphasis>
+
</xsl:if>
</para>
</xsl:if>
+2 -2
nixos/modules/misc/version.nix
···
};
system.nixosRelease = mkOption {
-
internal = true;
+
readOnly = true;
type = types.str;
default = readFile "${toString pkgs.path}/.version";
description = "NixOS release.";
···
};
system.nixosCodeName = mkOption {
-
internal = true;
+
readOnly = true;
type = types.str;
description = "NixOS release code name.";
};