-
-
Notifications
You must be signed in to change notification settings - Fork 14.4k
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
Module system: detect and report erroneous diamond dependency #215496
Comments
A workaround is to let |
Correct.
However, there's a good chance two versions of EDIT: updated the description to say not same version of |
I think it's the final application flake's responsibility to ensure diamond dependencies reference the same copy of the module by specifying |
I think the hashed file name approach works as expected and is consistent with other Nix practices, for example, having different paths of the same version of |
If the user "properly" uses |
@mightyiam and I just ran into a flavor of this diamond dependency issue: our flake has 3 NixOS modules structured like this:
The way we have our flake structured results in I am left with some questions:
|
The downside of adding a key is that it could erroneously deduplicate modules that are actually distinct, leading to only one of them taking effect, silently ignore the other(s). (ie the problem at the start of the issue description) So it's a tradeoff where we have to try and pick the lesser evil on a case by case basis until we have a mechanism by which this conflict can be detected.
No, anonymous modules that are only part of the # file.nix
{ someFlake }: {
imports = [
# These don't need keys
(mkRemovedModuleOption <...>)
({ ... }: { foo = true; })
# These do
someFlake.modules.foo.bar
];
}
# flake.nix outputs, bad
nixosModules.foo = {
imports = [
# This might actually work if foo.nix only has mergeable things in it
# It'd be best to turn foo.nix into a function that's in an attribute, and name it like mkRemovedOptionModule etc.
(importApply ./foo.nix { inherit self; })
(importApply ./foo.nix { self = inputs.nixpkgs; })
];
} For flakes in particular, I would recommend to always set the file and key generically.
TBD. The reference documentation is already incomplete, and this is an emergent behavior, so yeah. But this needs to be documented 👍
This would at least give a hint, but a section about deduplication or perhaps even best practices would be in order. |
Thank you for the quick, and wonderfully complete answer.
Can I help with this? Would https://nix.dev/tutorials/module-system/ be the right place to document it? |
As far as I know, we don't have any resources yet for designing and implementing a new module system application, let alone an ecosystem, which is where this comes in. I guess we could do it there, and perhaps some of it could be in tutorial form, but it's mostly not in actionable form, but rather just informative. This suggests that perhaps the Nixpkgs manual would be a better place for it. Currently the module system's reference documentation is split between Nixpkgs and NixOS manuals, with little more than |
Describe the bug
A correct diamond dependency looks like this
The module system handles that just fine, deduplicating
D
, based onkey
or imported file name.However, in a more distributed setting, it may happen that the intermediate dependencies don't reference the same version of
D
.Depending on the contents of
D1
and the very similarD2
, this may or may not result in an error.Specifically, this is a bug when
D1
andD2
happen to be mergeable at the module system level, but not in practice; for example if both add packaged
to an list of packages to be added to a single environment.In other cases, where the definitions can not be merged, the problem is merely a hard to understand error message. The error will be about some specific option, whereas the root causes is
D1
andD2
were expected to be the same, but were not.Steps To Reproduce
Steps to reproduce the behavior:
follows
, or run into the flakes bug where updates don't propagate the way they should.Expected behavior
A clear error message describing the root cause:
D1
andD2
were expected to be the same module but were not. Also suggest a solution or link to a document that explains it.Towards a solution
It seems that we don't have the right data to act on this today. A module can declare its "role" (
D
in the example) withkey
, but the deduplication logic can't detect the conflict, becausefile
could refer toB
orC
whenD
happens to be an "anonymous module with key". Maybe this is a module system implementation artifact and not a consequence of the established syntax for modules and therefore solvable entirely within the context of the current module system <-> module interface, but I'm not sure about it.Screenshots
Additional context
Notify maintainers
Metadata
Please run
nix-shell -p nix-info --run "nix-info -m"
and paste the result.The text was updated successfully, but these errors were encountered: