summary refs log tree commit diff
path: root/lib
diff options
context:
space:
mode:
authorNicolas B. Pierron <nicolas.b.pierron@gmail.com>2019-01-14 20:28:28 +0100
committerGitHub <noreply@github.com>2019-01-14 20:28:28 +0100
commita3beabf32750cbefa2d8a6b0bb48a7c8c2e805f7 (patch)
treeada57301bcda591d0a3f213d91ba519e55948caa /lib
parente0fad4b9c57b6d7f67a9b667cf80850bcca57e30 (diff)
parent7314d885a1547d3db6b0447fbeb3bcb1ff7f13de (diff)
downloadnixpkgs-a3beabf32750cbefa2d8a6b0bb48a7c8c2e805f7.tar
nixpkgs-a3beabf32750cbefa2d8a6b0bb48a7c8c2e805f7.tar.gz
nixpkgs-a3beabf32750cbefa2d8a6b0bb48a7c8c2e805f7.tar.bz2
nixpkgs-a3beabf32750cbefa2d8a6b0bb48a7c8c2e805f7.tar.lz
nixpkgs-a3beabf32750cbefa2d8a6b0bb48a7c8c2e805f7.tar.xz
nixpkgs-a3beabf32750cbefa2d8a6b0bb48a7c8c2e805f7.tar.zst
nixpkgs-a3beabf32750cbefa2d8a6b0bb48a7c8c2e805f7.zip
Merge pull request #53397 from cdepillabout/aliasoptionmodule-set-priority
lib/modules: Add function to create option alias that respects priority
Diffstat (limited to 'lib')
-rw-r--r--lib/default.nix2
-rw-r--r--lib/modules.nix34
-rwxr-xr-xlib/tests/modules.sh6
-rw-r--r--lib/tests/modules/alias-with-priority-can-override.nix52
-rw-r--r--lib/tests/modules/alias-with-priority.nix52
5 files changed, 140 insertions, 6 deletions
diff --git a/lib/default.nix b/lib/default.nix
index 40116063bf2..48eb99a7198 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 5fb83a4a538..9f8e196ee0f 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
@@ -556,8 +557,20 @@ 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 defaultPriority.
+  mkAliasAndWrapDefsWithPriority = wrap: option:
+    let
+      prio = option.highestPrio or defaultPriority;
+      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.sh b/lib/tests/modules.sh
index b83e1eb7d82..a72777cbf2a 100755
--- a/lib/tests/modules.sh
+++ b/lib/tests/modules.sh
@@ -149,6 +149,12 @@ 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
+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 <<EOF
 ====== module tests ======
 $pass Pass
diff --git a/lib/tests/modules/alias-with-priority-can-override.nix b/lib/tests/modules/alias-with-priority-can-override.nix
new file mode 100644
index 00000000000..a6b26895f3a
--- /dev/null
+++ b/lib/tests/modules/alias-with-priority-can-override.nix
@@ -0,0 +1,52 @@
+# This is a test to show that mkAliasOptionModule sets the priority correctly
+# for aliased options.
+
+{ config, lib, ... }:
+
+with lib;
+
+{
+  options = {
+    # A simple boolean option that can be enabled or disabled.
+    enable = lib.mkOption {
+      type = types.nullOr types.bool;
+      default = null;
+      example = true;
+      description = ''
+        Some descriptive text
+      '';
+    };
+
+    # mkAliasOptionModule sets warnings, so this has to be defined.
+    warnings = mkOption {
+      internal = true;
+      default = [];
+      type = types.listOf types.str;
+      example = [ "The `foo' service is deprecated and will go away soon!" ];
+      description = ''
+        This option allows modules to show warnings to users during
+        the evaluation of the system configuration.
+      '';
+    };
+  };
+
+  imports = [
+    # Create an alias for the "enable" option.
+    (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.
+    ( { config, lib, ... }:
+      {
+        enableAlias = lib.mkForce false;
+      }
+    )
+
+    # Enable the normal (non-aliased) option.
+    ( { config, lib, ... }:
+      {
+        enable = true;
+      }
+    )
+  ];
+}
diff --git a/lib/tests/modules/alias-with-priority.nix b/lib/tests/modules/alias-with-priority.nix
new file mode 100644
index 00000000000..923483684cb
--- /dev/null
+++ b/lib/tests/modules/alias-with-priority.nix
@@ -0,0 +1,52 @@
+# This is a test to show that mkAliasOptionModule sets the priority correctly
+# for aliased options.
+
+{ config, lib, ... }:
+
+with lib;
+
+{
+  options = {
+    # A simple boolean option that can be enabled or disabled.
+    enable = lib.mkOption {
+      type = types.nullOr types.bool;
+      default = null;
+      example = true;
+      description = ''
+        Some descriptive text
+      '';
+    };
+
+    # mkAliasOptionModule sets warnings, so this has to be defined.
+    warnings = mkOption {
+      internal = true;
+      default = [];
+      type = types.listOf types.str;
+      example = [ "The `foo' service is deprecated and will go away soon!" ];
+      description = ''
+        This option allows modules to show warnings to users during
+        the evaluation of the system configuration.
+      '';
+    };
+  };
+
+  imports = [
+    # Create an alias for the "enable" option.
+    (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.
+    ( { config, lib, ... }:
+      {
+        enableAlias = lib.mkDefault false;
+      }
+    )
+
+    # Enable the normal (non-aliased) option.
+    ( { config, lib, ... }:
+      {
+        enable = true;
+      }
+    )
+  ];
+}