-
-
Notifications
You must be signed in to change notification settings - Fork 852
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
nix: overlay polish for prev parameter #4558
Conversation
Overlays make my head hurt. I'll have to ask @spikespaz to give his thoughts on this as well. |
Glad to have learned about |
This PR should be rebased to remove the merge commit, and rebased onto the |
Since the idea of the overlay is to allow for composition, we should not rely on this exact derivation for any of the derivations in this flake. That would break downstream overrides.
|
I have also looked at the previous PR, #4555. I welcome the |
I would like to just add one more thing: the naming |
Great feedback, I'll make changes accordingly! @spikespaz should I change |
28d53d0
to
1bd29f7
Compare
also change wlroots to wlroots-hyprland in default.nix, this is in line with the earlier comments and the original code overriding wlroots with a custom wlroots-hyprland package
@GrizzlT Are you talking about renaming Regardless of the disagreement that I've read (and participated in), I do name them differently from
|
I think my comments must be marked as "resolved" before I can approve properly. That just changed my existing requested changes into an approved review. |
@spikespaz Are you sure you're looking at the changes of all commits combined? My force-pushed commits should already contain all the changes requested. This looks like something from git(hub) on your side. (missing fetch?) |
It looks like Would there be any merit to shadowing dependencies? Is it always encouraged to let downstream users "force" the use of a specific version of a dependency across all packages that have that dependency? I'm struggling to find resources that explain what to do when exposing an overlay that depends on the results of another overlay (such as fenix for rust). |
I'll go watch that. My "convention" comes from reasoning with myself, plus trial and error to the effect of avoiding infinite recursion. Perhaps I am mistaken. If I am wrong, all of the flakes in this org (and others) are incorrect because I made pull requests specifically to address this problem. Perhaps the fault was with my usage, not the overlay definitions. I may also be misremembering.
This exactly is why the flake is structured as it is. I could not find an answer to this question either, and NobbZ in the Discord said essentially that it was up to me to make that decision. So I opted to provide all important derivations as their own overlay, and then also export ones that are joined together which contain the dependency overlays in the correct order. This is done for some reasons:
|
I am playing around with a new solution to this problem right now. I find it a limitation that dependencies of the final output package should be exposed to the pkgs root. This makes it difficult for example to use different versions of the rust compiler for different packages. And if you change the default I propose the following method: let
overlayOutsideHidden = self: super: {
myPackage = self.hello;
};
overlayCustomExposed = self: super: let
extraPkgs = overlayOutsideHidden self super;
in {
myCustomHello = super.callPackage ./package.nix extraPkgs;
};
overlayOverrideCustom = self: super: {
myCustomHello = super.myCustomHello.override { myPackage = self.fd; };
};
overlayOverrideOutsideDep = self: super: {
hello = self.zoxide;
};
in {
overlay1 = overlayCustomExposed;
overlay2 = overlayOverrideCustom;
overlay3 = overlayOverrideOutsideDep;
} I am assuming here that the I showed 4 overlays to cover the edge cases I could think of:
The only requirement of this convention is that all dependency overlays must not depend on package overrides defined in their own overlay (but there's an easy fix using I know my shadowing approach will not work with overlays that want to expose packages that depend on each other but even for those overlays, I find this dependency hiding useful. This is the case for the |
True, although this has the cost of an extra nixpkgs fixpoint calculation. This might also make cross-compiling difficult but I can't say much about that. See my comment above for a possible solution.
It would be nice to have more conventions for defining and using overlays.
I agree, also see my solution in the comment above where I do this by pushing the name change from the nixpkgs fixpoint to the package derivation definition (also a change committed to this PR). |
So, a few days ago (as per your suggestion), I watched the first 4/5 of Nicolas Pierron's standup at NixConf 2017. He did briefly show a "bad example", telling us that functions ought to be used from I didn't immediately discredit this evidence though, and persisted in my research. I inspected the relevant section of the Nixpkgs manual which states that:
That statement, again, with no explanation whatsoever. I question this, since to me, and through experience, using functions from I followed the commit history back to the introduction of the original As it turns out, I'm not the first person to question this. In another PR, a commit tries to change The first, and most convincing, is that there is a performance penalty to using functions from As an aside, as far as I am concerned: even if the function is overridden, the performance penalty is the cost of intended behavior and should not be a consideration. The second argument from Nicolas is that there would be some undesirable (yet unspecified) interaction with a feature called "automatic grafting". This feature was never merged into Nixpkgs. Lastly, I found another forum post, in which lies a comment by Silvian Mosberger (@infinisil, a member of the NixOS organization):
I believe this summarizes what my own experience and intuition indicated to me: prefer |
Using overlays, you knowlingly give this up.
Can you please elaborate? What do you mean by shadowing?
The hyprland package overlays are for adding composable attributes to the top level
Yes, but the overlays output of this flake should also optionally provide the pinned packages used here, fairly granularly. Renaming them with a
I'm reading through instances of scope-making in Nixpkgs. There seems to be a few ways to do it, but looks like one of them allows providing overlays to the scope. If we do that, we can have the overlays exported as flake outputs, but do not export them in the larger default package set overlays. The other way to do it is importing Nixpkgs twice. We don't want to do that. Your approach here: let
extraPkgs = overlayOutsideHidden self super;
in Is an incorrect application of an overlay. The
I quite like this example, but I believe it is outdated: |
I apologize for the lack of context so far, the following is an overview of my thinking: I liked the idea of automatic input extraction in my flake for my nixossystem configs. Instead of manually defining all the overlays used for my systems, I wanted to include all I was then confronted by hyprland's need for While I currently don't think I should commit to this "auto-extract packages from input overlays" idea, I still think it might be valuable to be able to use derivations from an outside overlay without unnecessary exposure of dependencies from said overlay to the nixpkgs fixpoint. I think this because I want to create a Rust project with Nix and I would like to choose the compiler version used in the derivation. The two most interesting overlays for this purpose seem fenix and rust-overlay in my opinion. Maybe it's my tendency to abstract that doesn't align well with nixpkgs but I don't like the idea of multiple rust packages exposing the same overlay only to use a specific rust compiler from that overlay. Instead of exposing all the compilers to the fixpoint, I would much rather just pick a specific compiler and export only that one compiler under a different name linked to my project. This would allow for the proper overlay mechanism to still provide flexibility for users that which override the compiler used in my project, while exposing a clean, minimal set of derivations.
I am interested in the specific way you discovered. So far I came up with this snippet to scope the outputs of an overlay. let
overlayOutsideHidden = self: super: {
myPackageDependency = self.hello;
};
overlayToScope = overlay: (final: prev: (
lib.makeScope final.newScope (self:
final // (overlay self (prev // { inherit (self) callPackage; }))
)
));
in
myOverlay = self: super: let
extraPkgs = overlayToScope overlayOutsideHidden self super;
in {
myCustomHello = self.callPackage ({ myPackageDependency }: myPackageDependency) extraPkgs; # this is oversimplified, not all attributes from extraPkgs are used
}; This way, no overlay out there needs to change and as long as no one uses This reinforces the idea for me that |
@spikespaz This PR is also ready for merge last I checked, I only changed the overlay to use |
Oh, I approved it just because I'm struggling with the UI (I don't think it's me, but maybe). However, I do request that, since we are here, you rename the Aside from that, all looks good. |
I realized that changing |
I would like not to break compatibility, as long as it's not too much work to get the overlays working fine as well. |
- Remove breaking change to wlroots-hyprland
Then I think it's best to revert #4555's changes to |
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.
Perhaps we should have udis86-hyprland
instead of hyprland-udis86
, to be more in line with the already existing wlroots-hyprland
.
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.
LGTM, thank you!
Describe your PR, what does it fix/add?
After a good night's sleep, I realized I was a bit too quick in #4555. Since the overlay composition also overrides
udis86
,hyprland-protocols
andwlroots-hyprland
. These too, should be taken fromprev
instead offinal
, or my shadowing trick would not work anymore. This is changed in this PR.Is there anything you want to mention? (unchecked code, possible bugs, found problems, breaking compatibility, etc.)
I don't know if
callPackage
should be taken fromfinal
orprev
in this case. Since it's just a function, I assume either would be fine if there is no explicit overriding in this project. Something to note then would be the requirement to explicitly reference all custom inputs not taken fromnixpkgs
when making thehyprland
derivation.In the same mindset, one might want to change the references to
final.hyprland
to something tied to the scope of the overlay. There exists a functionmakeScope
in nixpkgs for this. I have not looked at this yet and would be implemented in a following PR. For now, for my workflow with shadowing input overlays, this could easily be worked around by adding a overlay that exports the hyprland package from my shadowed name set, should I need these extra outputs.Is it ready for merging, or does it need work?
ready, might want to add a comment