doRename
lib.modules.doRename
Docs pulled from | This Revision | 10 minutes ago
Return a module that help declares an option that has been renamed.
When a value is defined for the old option, it is forwarded to the to
option.
Noogle detected
Implementation
The following is the current implementation of this function.
doRename = {
# List of strings representing the attribute path of the old option.
from,
# List of strings representing the attribute path of the new option.
to,
# Boolean, whether the old option is to be included in documentation.
visible,
# Whether to warn when a value is defined for the old option.
# NOTE: This requires the NixOS assertions module to be imported, so
# - this generally does not work in submodules
# - this may or may not work outside NixOS
warn,
# A function that is applied to the option value, to form the value
# of the old `from` option.
#
# For example, the identity function can be passed, to return the option value unchanged.
# ```nix
# use = x: x;
# ```
#
# To add a warning, you can pass the partially applied `warn` function.
# ```nix
# use = lib.warn "Obsolete option `${opt.old}' is used. Use `${opt.to}' instead.";
# ```
use,
# Legacy option, enabled by default: whether to preserve the priority of definitions in `old`.
withPriority ? true,
# A boolean that defines the `mkIf` condition for `to`.
# If the condition evaluates to `true`, and the `to` path points into an
# `attrsOf (submodule ...)`, then `doRename` would cause an empty module to
# be created, even if the `from` option is undefined.
# By setting this to an expression that may return `false`, you can inhibit
# this undesired behavior.
#
# Example:
#
# ```nix
# { config, lib, ... }:
# let
# inherit (lib) mkOption mkEnableOption types doRename;
# in
# {
# options = {
#
# # Old service
# services.foo.enable = mkEnableOption "foo";
#
# # New multi-instance service
# services.foos = mkOption {
# type = types.attrsOf (types.submodule …);
# };
# };
# imports = [
# (doRename {
# from = [ "services" "foo" "bar" ];
# to = [ "services" "foos" "" "bar" ];
# visible = true;
# warn = false;
# use = x: x;
# withPriority = true;
# # Only define services.foos."" if needed. (It's not just about `bar`)
# condition = config.services.foo.enable;
# })
# ];
# }
# ```
condition ? true
}:
{ config, options, ... }:
let
fromOpt = getAttrFromPath from options;
toOf = attrByPath to
(abort "Renaming error: option `${showOption to}' does not exist.");
toType = let opt = attrByPath to {} options; in opt.type or (types.submodule {});
in
{
options = setAttrByPath from (mkOption {
inherit visible;
description = "Alias of {option}`${showOption to}`.";
apply = x: use (toOf config);
} // optionalAttrs (toType != null) {
type = toType;
});
config = mkIf condition (mkMerge [
(optionalAttrs (options ? warnings) {
warnings = optional (warn && fromOpt.isDefined)
"The option `${showOption from}' defined in ${showFiles fromOpt.files} has been renamed to `${showOption to}'.";
})
(if withPriority
then mkAliasAndWrapDefsWithPriority (setAttrByPath to) fromOpt
else mkAliasAndWrapDefinitions (setAttrByPath to) fromOpt)
]);
};