diff options
author | Eelco Dolstra <eelco.dolstra@logicblox.com> | 2015-10-14 18:05:50 +0200 |
---|---|---|
committer | Eelco Dolstra <eelco.dolstra@logicblox.com> | 2015-10-14 18:18:47 +0200 |
commit | 5f077e229625583072ebf63ea48b11170771b0ed (patch) | |
tree | fcd1a6ee296febd5d0ba956dcff2f0176c9661b0 /lib/modules.nix | |
parent | 7b001ed68a6cc0dd4c2982fdf72c9c26d0595eee (diff) | |
download | nixlib-5f077e229625583072ebf63ea48b11170771b0ed.tar nixlib-5f077e229625583072ebf63ea48b11170771b0ed.tar.gz nixlib-5f077e229625583072ebf63ea48b11170771b0ed.tar.bz2 nixlib-5f077e229625583072ebf63ea48b11170771b0ed.tar.lz nixlib-5f077e229625583072ebf63ea48b11170771b0ed.tar.xz nixlib-5f077e229625583072ebf63ea48b11170771b0ed.tar.zst nixlib-5f077e229625583072ebf63ea48b11170771b0ed.zip |
Factor out option renaming
Option aliases/deprecations can now be declared in any NixOS module, not just in nixos/modules/rename.nix. This is more modular (since it allows for example grub-related aliases to be declared in the grub module), and allows aliases outside of NixOS (e.g. in NixOps modules). The syntax is a bit funky. Ideally we'd have something like: options = { foo.bar.newOption = mkOption { ... }; foo.bar.oldOption = mkAliasOption [ "foo" "bar" "newOption" ]; }; but that's not possible because options cannot define values in *other* options - you need to have a "config" for that. So instead we have functions that return a *module*: mkRemovedOptionModule, mkRenamedOptionModule and mkAliasOptionModule. These can be used via "imports", e.g. imports = [ (mkAliasOptionModule [ "foo" "bar" "oldOption" ] [ "foo" "bar" "newOption" ]); ]; As an added bonus, deprecation warnings now show the file name of the offending module. Fixes #10385.
Diffstat (limited to 'lib/modules.nix')
-rw-r--r-- | lib/modules.nix | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/lib/modules.nix b/lib/modules.nix index 3e4d0547ecc5..12ec7004d1ee 100644 --- a/lib/modules.nix +++ b/lib/modules.nix @@ -469,6 +469,7 @@ rec { mkBefore = mkOrder 500; mkAfter = mkOrder 1500; + # Convenient property used to transfer all definitions and their # properties from one option to another. This property is useful for # renaming options, and also for including properties from another module @@ -498,4 +499,68 @@ rec { /* Compatibility. */ fixMergeModules = modules: args: evalModules { inherit modules args; check = false; }; + + /* Return a module that causes a warning to be shown if the + specified option is defined. For example, + + mkRemovedOptionModule [ "boot" "loader" "grub" "bootDevice" ] + + causes a warning if the user defines boot.loader.grub.bootDevice. + */ + mkRemovedOptionModule = optionName: + { options, ... }: + { options = setAttrByPath optionName (mkOption { + visible = false; + }); + config.warnings = + let opt = getAttrFromPath optionName options; in + optional opt.isDefined + "The option definition `${showOption optionName}' in ${showFiles opt.files} no longer has any effect; please remove it."; + }; + + /* Return a module that causes a warning to be shown if the + specified "from" option is defined; the defined value is however + forwarded to the "to" option. This can be used to rename options + while providing backward compatibility. For example, + + mkRenamedOptionModule [ "boot" "copyKernels" ] [ "boot" "loader" "grub" "copyKernels" ] + + forwards any definitions of boot.copyKernels to + boot.loader.grub.copyKernels while printing a warning. + */ + mkRenamedOptionModule = from: to: doRename { + inherit from to; + visible = false; + warn = true; + use = builtins.trace "Obsolete option `${showOption from}' is used. It was renamed to `${showOption to}'."; + }; + + /* Like ‘mkRenamedOptionModule’, but doesn't show a warning. */ + mkAliasOptionModule = from: to: doRename { + inherit from to; + visible = true; + warn = false; + use = id; + }; + + doRename = { from, to, visible, warn, use }: + let + toOf = attrByPath to + (abort "Renaming error: option `${showOption to}' does not exists."); + in + { config, options, ... }: + { options = setAttrByPath from (mkOption { + description = "Alias of <option>${showOption to}</option>."; + apply = x: use (toOf config); + }); + config = { + /* + warnings = + let opt = getAttrFromPath from options; in + optional (warn && opt.isDefined) + "The option `${showOption from}' defined in ${showFiles opt.files} has been renamed to `${showOption to}'."; + */ + } // setAttrByPath to (mkAliasDefinitions (getAttrFromPath from options)); + }; + } |