New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Handle submodules for type "either" #14053
Conversation
This reverts commit 0f0805b, because @nbp had concerns about whether this would be a good idea and pointed out problems with this. We currently do not have a case where "either" is used in conjunction with submodules, but I'm reverting it anyway to prevent people from adding options using that type in that way. This is now being reviewed in #14053. Signed-off-by: aszlig <aszlig@redmoonstudios.org>
So far the "either" type only handled "flat" types, so you couldn't do something like: type = either int (submodule { options = ...; }); Not only caused this the submodule's options not being checked but also not show up in the documentation. This was something we stumbled on with NixOS#13916. Signed-off-by: aszlig <aszlig@redmoonstudios.org> Cc: @edolstra
6ff8f7f
to
154b7a6
Compare
For reference, I'm adding the concerns raised by @nbp here:
|
So far the "either" type only handled "flat" types, so you couldn't do something like: type = either int (submodule { options = ...; }); Not only caused this the submodule's options not being checked but also not show up in the documentation. This was something we stumbled on with #13916. Signed-off-by: aszlig <aszlig@redmoonstudios.org> Cc: @edolstra
@nbp: And here again, I still don't understand what you mean by "changing the semantics", for example if I use something like this: { lib, ... }:
{
options = {
foo = lib.mkOption {
type = with lib.types; either str int;
description = "foo";
};
};
imports = lib.singleton { foo = 666; };
config = {
foo = "bar";
};
} I get an error as expected:
|
What I meant by "changing the semantics" is best explained with the following example: If you have an option definition that can be interpreted with both side of the "either", then you will consider the first operand of either to merge the values. The problem appears, as soon as you have a second option definition, but which only validates with the second type. In such case, the first option definition would be interpreted with the second type instead of the first one, as it used to be without the second option definition. I think it would be wise to ensure that either is exclusive. I understand the need for having a simple type, as a way to make a simple/refined interface. (even if I would be tempted to have the simple type definition be mapped to one of the submodule options instead of using either) Still I think the patch which got landed lack the disjoint feature, which I do not want to have to explain nor support in the future. |
@@ -246,7 +246,25 @@ rec { | |||
either = t1: t2: mkOptionType { | |||
name = "${t1.name} or ${t2.name}"; | |||
check = x: t1.check x || t2.check x; | |||
merge = mergeOneOption; | |||
merge = loc: defs: | |||
if all t1.check (getValues defs) then t1.merge loc defs |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will recommend to go for all t1.check values && all (x: ! t2.check x) values
in the condition, and identically for the second condition.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, another way could be to ensure that either isn't applied to the same types, so things like either submodule1 submodule1
will cause an error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OTOH, things such as either attrs submodule
will hit the same issue in this case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And this would be fine, because submodules is a refined attribute set. So this would still be ambiguous. And this might be even worse with either submodule attrs
, as all attribute sets would be considered as valid submodules containing undeclared options.
Edit: this would be fine to raise an error in the case of either attrs submodule
.
@aszlig I wonder, would it make more sense to do it as an option set attribute which is interpreted to forward simple value (no attribute set) as the value of an option which is located below, such as:
What do you think? This way we would have a similar feature without the burden of creating submodules, when we just want a shortcut notation. One case where this would make total sense, would be for url, where we might want to decompose them into multiple options:
|
Hm, I think this makes more sense and we should also ensure that |
I agree, if we have the possibility of failing sooner we should consider it. |
What's the consensus now, so I can make the necessary changes to my PR? #13916 |
@CMCDragonkai I think the above discussion settled on the |
@nbp: I haven't started to work on it, yet. Will see whether I get to it next week, but I can't promise that it'll work out. |
Any news on this? |
@CMCDragonkai: Yep, we now have |
@aszlig Cool, so how do we use it? |
I'm seeing a problem where I'm doing something like
where the 2 submodules have different options inside (for example the first one has option
It seems to bail out immediately checking only the left side of the Is it possible that this issue was not fully solved? |
@nh2 This issue is fully solved, but this is a deliberate limitation of the You cannot use Moreover, this would be difficult to document, and thus confusing for the users. If you want to do so, create 2 options, where each has a submodule type. |
So far the
either
type only handled "flat" types, so you couldn't do something like:Not only caused this the submodule's options not being checked but also
not show up in the documentation.
This was something we stumbled on with #13916.
Cc: @edolstra, @nbp