test.nix:
lib:
with lib;
let
someModule = {
options.foo = mkOption {
type = types.bool;
default = true;
};
};
in
evalModules {
modules =
[ someModule
(mkAliasOptionModule [ "bar" ] [ "foo" ])
];
check = false;
}
Let’s load it in the REPL:
nix-repl> :l <nixpkgs>
Added 10082 variables.
nix-repl> cfg = import ./test.nix lib
nix-repl> cfg.config.foo
true
nix-repl> cfg.config.bar
error: The option `bar' is used but not defined.
The option bar
is defined as an alias of foo
. How can it be that foo
is defined but bar
is not?
I’m using NixOS 19.03.
Looking at the definition of mkAliasOptionModule
, it appears that all definitions of bar
get propagated to foo
, but not vice versa, which is why bar
is not defined. I find this confusing, because I thought that "option a
is an alias of option b
" means "option a
is the same option as option b
", i.e. every definition of a
counts as a definition of b
and vice versa. I feel like this is a bug that should be fixed.
Ok, I’m pretty sure this is a bug, here’s why:
-
mkAliasOptionModule
sets the apply
attribute of the newly created option (code), so that when its value is computed, it evaluates to the value of the target option. So, in principle, evaluating cfg.config.bar
should evaluate to exactly the same thing as cfg.config.foo
.
- This doesn’t happen, because the option
bar
does not have any definitions, and the apply
attribute of the option isn’t used (code).
A workaround would be for mkAliasOptionModule
to define the newly created option, but give it a very high priority number (so that its priority is very low) and a value that throws an error when evaluated.
I’ve created an issue on github.