From da00ec4b45f5cfc5b47825818b57db1d1950757d Mon Sep 17 00:00:00 2001 From: "(cdep)illabout" Date: Fri, 4 Jan 2019 16:34:59 +0900 Subject: Add a failing test for mkAliasOptionModule. --- lib/tests/modules.sh | 3 ++ lib/tests/modules/alias-with-priority.nix | 52 +++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 lib/tests/modules/alias-with-priority.nix (limited to 'lib') diff --git a/lib/tests/modules.sh b/lib/tests/modules.sh index b83e1eb7d82d0..45f391785228c 100755 --- a/lib/tests/modules.sh +++ b/lib/tests/modules.sh @@ -149,6 +149,9 @@ checkConfigOutput "1 2 3 4 5 6 7 8 9 10" config.result ./loaOf-with-long-list.ni # Check loaOf with many merges of lists. checkConfigOutput "1 2 3 4 5 6 7 8 9 10" config.result ./loaOf-with-many-list-merges.nix +# Check mkAliasOptionModuleWithPriority. +checkConfigOutput "true" config.enable ./alias-with-priority.nix + cat < Date: Thu, 3 Jan 2019 23:15:01 +0900 Subject: 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. --- lib/default.nix | 2 +- lib/modules.nix | 30 +++++++++++++++++++++++++++--- lib/tests/modules/alias-with-priority.nix | 2 +- 3 files changed, 29 insertions(+), 5 deletions(-) (limited to 'lib') diff --git a/lib/default.nix b/lib/default.nix index 916f6e05190b0..17a74cd213553 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -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' diff --git a/lib/modules.nix b/lib/modules.nix index 5fb83a4a538cc..4e259cce2ba4d 100644 --- a/lib/modules.nix +++ b/lib/modules.nix @@ -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) ]; }; diff --git a/lib/tests/modules/alias-with-priority.nix b/lib/tests/modules/alias-with-priority.nix index ba25b527aa2dc..923483684cb16 100644 --- a/lib/tests/modules/alias-with-priority.nix +++ b/lib/tests/modules/alias-with-priority.nix @@ -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. -- cgit 1.4.1 From f24e2d0721c99acf84220d8ba56c66e422687669 Mon Sep 17 00:00:00 2001 From: "(cdep)illabout" Date: Sun, 6 Jan 2019 17:48:37 +0900 Subject: Pull out defaultPriority to a top-level definition. --- lib/modules.nix | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'lib') diff --git a/lib/modules.nix b/lib/modules.nix index 4e259cce2ba4d..9f8e196ee0f73 100644 --- a/lib/modules.nix +++ b/lib/modules.nix @@ -450,8 +450,7 @@ rec { filterOverrides' = defs: let - defaultPrio = 100; - getPrio = def: if def.value._type or "" == "override" then def.value.priority else defaultPrio; + getPrio = def: if def.value._type or "" == "override" then def.value.priority else defaultPriority; highestPrio = foldl' (prio: def: min (getPrio def) prio) 9999 defs; strip = def: if def.value._type or "" == "override" then def // { value = def.value.content; } else def; in { @@ -534,6 +533,8 @@ rec { mkBefore = mkOrder 500; mkAfter = mkOrder 1500; + # The default priority for things that don't have a priority specified. + defaultPriority = 100; # Convenient property used to transfer all definitions and their # properties from one option to another. This property is useful for @@ -561,11 +562,10 @@ rec { # 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. + # If a priority is not set, it assumes a priority of defaultPriority. mkAliasAndWrapDefsWithPriority = wrap: option: let - defaultPrio = 100; - prio = option.highestPrio or defaultPrio; + prio = option.highestPrio or defaultPriority; defsWithPrio = map (mkOverride prio) option.definitions; in mkAliasIfDef option (wrap (mkMerge defsWithPrio)); -- cgit 1.4.1 From 7314d885a1547d3db6b0447fbeb3bcb1ff7f13de Mon Sep 17 00:00:00 2001 From: "(cdep)illabout" Date: Sun, 6 Jan 2019 18:10:03 +0900 Subject: Add test that shows that the aliases are able to override options. --- lib/tests/modules.sh | 3 ++ .../modules/alias-with-priority-can-override.nix | 52 ++++++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 lib/tests/modules/alias-with-priority-can-override.nix (limited to 'lib') diff --git a/lib/tests/modules.sh b/lib/tests/modules.sh index 45f391785228c..a72777cbf2a68 100755 --- a/lib/tests/modules.sh +++ b/lib/tests/modules.sh @@ -151,6 +151,9 @@ checkConfigOutput "1 2 3 4 5 6 7 8 9 10" config.result ./loaOf-with-many-list-me # Check mkAliasOptionModuleWithPriority. checkConfigOutput "true" config.enable ./alias-with-priority.nix +checkConfigOutput "true" config.enableAlias ./alias-with-priority.nix +checkConfigOutput "false" config.enable ./alias-with-priority-can-override.nix +checkConfigOutput "false" config.enableAlias ./alias-with-priority-can-override.nix cat <