lib/modules: Add a function to create an option alias that respects the priority

This commit adds a function `mkAliasOptionModuleWithPriority`.  This
function will make an alias to an existing option and copy over the
priority.

This functionality is needed for PRs like #53041.  In that case
`nixos-generate-config` added an option to `hardware-configuration.nix`
with `mkDefault`.  That option was then changed and an alias created for
the old name.

The end user should be able to set the non-alias option in their
`configuration.nix` and have everything work correctly.  Without this
function, the priority for the option won't be copied over correctly
and the end-user will get a message saying they have the same option
set to two different values.
This commit is contained in:
(cdep)illabout 2019-01-03 23:15:01 +09:00
parent da00ec4b45
commit b81b3ad1b0
No known key found for this signature in database
GPG key ID: 462E0C03D11422F4
3 changed files with 29 additions and 5 deletions

View file

@ -109,7 +109,7 @@ let
mkFixStrictness mkOrder mkBefore mkAfter mkAliasDefinitions
mkAliasAndWrapDefinitions fixMergeModules mkRemovedOptionModule
mkRenamedOptionModule mkMergedOptionModule mkChangedOptionModule
mkAliasOptionModule doRename filterModules;
mkAliasOptionModule mkAliasOptionModuleWithPriority doRename filterModules;
inherit (options) isOption mkEnableOption mkSinkUndeclaredOptions
mergeDefaultOption mergeOneOption mergeEqualOption getValues
getFiles optionAttrSetToDocList optionAttrSetToDocList'

View file

@ -556,8 +556,21 @@ rec {
#
mkAliasDefinitions = mkAliasAndWrapDefinitions id;
mkAliasAndWrapDefinitions = wrap: option:
mkIf (isOption option && option.isDefined) (wrap (mkMerge option.definitions));
mkAliasIfDef option (wrap (mkMerge option.definitions));
# Similar to mkAliasAndWrapDefinitions but copies over the priority from the
# option as well.
#
# If a priority is not set, it assumes a priority of 100.
mkAliasAndWrapDefsWithPriority = wrap: option:
let
defaultPrio = 100;
prio = option.highestPrio or defaultPrio;
defsWithPrio = map (mkOverride prio) option.definitions;
in mkAliasIfDef option (wrap (mkMerge defsWithPrio));
mkAliasIfDef = option:
mkIf (isOption option && option.isDefined);
/* Compatibility. */
fixMergeModules = modules: args: evalModules { inherit modules args; check = false; };
@ -690,7 +703,16 @@ rec {
use = id;
};
doRename = { from, to, visible, warn, use }:
/* Like mkAliasOptionModule, but copy over the priority of the option as well. */
mkAliasOptionModuleWithPriority = from: to: doRename {
inherit from to;
visible = true;
warn = false;
use = id;
withPriority = true;
};
doRename = { from, to, visible, warn, use, withPriority ? false }:
{ config, options, ... }:
let
fromOpt = getAttrFromPath from options;
@ -708,7 +730,9 @@ rec {
warnings = optional (warn && fromOpt.isDefined)
"The option `${showOption from}' defined in ${showFiles fromOpt.files} has been renamed to `${showOption to}'.";
}
(mkAliasAndWrapDefinitions (setAttrByPath to) fromOpt)
(if withPriority
then mkAliasAndWrapDefsWithPriority (setAttrByPath to) fromOpt
else mkAliasAndWrapDefinitions (setAttrByPath to) fromOpt)
];
};

View file

@ -32,7 +32,7 @@ with lib;
imports = [
# Create an alias for the "enable" option.
(mkAliasOptionModule [ "enableAlias" ] [ "enable" ])
(mkAliasOptionModuleWithPriority [ "enableAlias" ] [ "enable" ])
# Disable the aliased option, but with a default (low) priority so it
# should be able to be overridden by the next import.