pkgs/by-name/README: explicitly suggest version specific override interfaces#444420
Conversation
…erfaces The current advice of "keeping the override interface" is actively bad, because it hides certain expectations of a package function in an undiscoverable place. Ideally, all information about a package is in one, single place instead. Version-specific argument names, if required, also have the *benefit* of creating errors with downstream overrides, much like merge conflicts do. Instead of possibly silently breaking certain behavior, they make a change in expectations clear - which might feel annoying when upgrading, but is ultimately much less problematic down the road.
|
This is non-blocking feedback. I'm sympathetic to the argument being made here — if a package is known to build with Consequently, I think that the documentation should be more nuanced than what is proposed here. Allow for the possibility that depending on an abstract or a concrete package attribute may be appropriate, and that the choice depends on how much the package ‘knows’ about what it needs. I'd even be reasonably happy with language like ‘in most cases’ favoring the concrete attribute, just as long as there's enough wiggle room in the guidelines that nobody on a tree-wide crusade can use it to justify coming for |
philiptaron
left a comment
There was a problem hiding this comment.
I agree with the removal of the previous advice. Breaking earlier is better, and while it causes some issues for users, they're good issues to have -- the "merge conflict" metaphor is well-chosen.
What needs more substantiation and advice, in my view, is the "but what if libbar_2 is needed?" question. That very well may be done in a separate PR, but I'm writing it up here.
Too many derivations experience temporary breakage as a result of a version bump then end up pinning older versions for years to sometimes decades. That's the case whether the pinning is done in all-packages.nix, whether it's done in an override, or whether it's done by adjusting the inputs in the callPackage style.
|
Agreed with both this PR and @philiptaron mention of needing more clarity surrounding other circumstances that can "break" the interface. I'd like to see a more universal policy that's applicable for all sorts of derivation changes, so that we can settle the problems regarding interface changes easier. That can come in a different PR discussion of course. |
It seems like the correct thing to do in this case is to just take a dependency on plain I do think there is a legitimate use case for “you can give me whatever X you want and I consider this public API, but in lieu of you doing so I will use this specific X that is distinct from the default Nixpkgs X”, although it is not the common case. In that case, I think we should just document a convention for how to name these parameters to not collide with the global X. Say, in this case, |
|
(I think it is unfortunate in general that |
That seems like unnecessary churn should we get something like option 3 of #404946, which would resolve the code locality concerns without changing the override interface. |
|
I believe that the cases where my suggestion is relevant are few, and would essentially be background noise in terms of breaking changes to I think there are broader improvements to |
I didn't say that. The program doesn't reliably open a window when run with
The trouble is that my ‘particular insight’ is negative, not positive. I don't know that MapTool needs So since there's no way for me to express via the callPackages interface ‘
Yes, this.
I don't want to get too off-topic in this thread; regardless of what I think is best, I believe all of your feedback about my comment applies to the OP's recommendation as well and you should have that debate in that issue if you want. As far as it is relevant to this thread, I take and agree with your point that the All that said, again, my feedback is non-blocking, I'm not really expecting to be able to reverse your opinion on this, and I ask only that the official advice leave space for nuance here and not leave the impression that it is now open season on any hand-written dependency injection you see. |
|
Does my proposal not address your use case, then? I think some churn in the name is acceptable, here, for the benefits of the uniform approach, and to avoid the confusion of a
This case seems exactly where @wolfgangwalther’s point of “if you are overriding a pinning decision that was made for a reason, it should be clear that you are doing so, and if the situation around that pin changes in the package you should be notified of the ‘semantic merge conflict’ that results so you can decide what to do” is applicable. I agree that my opposition also applies to option 3 in #404946, and prefer other solutions to the fundamental problem. I would like disjoint override interfaces for public API knobs and arbitrary dependencies, in time. But I think my proposal here is perfectly fine in the meantime and has distinct advantages over the “external overrides of packages that already exist” approach that @wolfgangwalther seeks to deprecate here. We do want to have an approach that doesn’t involve |
The fact that there are differences, that are relevant to MapTool, between all of these means that the abstraction "any It's not a useful abstraction to have, though, because it is not defined anywhere in a way like "X, Y and Z are As long as that's not the case, I think the best thing to do is actually to use (I'm not even sure whether
That in itself is quite a strong argument for any kind of |
|
After discussing a bit with @emilazy about that Personally, I think both of |
|
If we were ever to go about "formalizing" the override interface, I think we should make it so that only In that sense, for a package needing any JDK, we do: This is also nice at formalizing an expected way to override certain things, so that consumers dont have to change their attributes name based on whatever the derivation is doing. Then further along with this, any changes that change the |
If this (or something like it; there are a lot of I would suggest the following, though: The package shouldn't communicate that it has a dependency on |
emilazy
left a comment
There was a problem hiding this comment.
I am okay with withJdk or similar as a colour for that particular bikeshed. (It’s a bit ambiguous since you’d usually expect that to be a boolean meaning “use a JDK at all?”, but one can always disambiguate with withJdkPackage or such.)
I think it’s orthogonal to the specific thing being discussed in this part of the README – I don’t think we want every single version pin to be like this for precisely the reason given here, and many package maintainers prefer to expose fewer intended‐as‐stable‐API flags rather than more, given the support burden of the combinatorial explosion in integration and limits of automated validation – and not in contradiction to it, but we could add a note to the place feature flags are documented to say that they can also be of package type? TBH, we don’t have coherent guidelines on flags anyway, given the wide variation in naming they have. Standardizing that stuff seems like a separate task.
|
I'm comfortable with considering the override interface unstable on |
Do you mean packages which are updated on master and then backported? I would like to agree that changing the override interface here should constitute a breaking change, but only because of the choice to backport. |
|
For the specific case discussed in this issue, which is pinned versions as arguments, I don't think these should be considered breaking for stable either. After all, we're not considering updating everything that has reverse dependencies a breaking change either. |
Okay yeah you're right, because this circles back to the argument of what we should honour as "official interfaces" for overrides, and that's bogging down this specific issue from moving forward. Deciding the line can't be done in this PR, it's gotta be discussed elsewhere. |
|
I think we have never worried about backporting a backwards‐compatible “foo: 1.2 → 1.3” commit that happens to drop a dependency on |
|
Just because most of us here have not worried about that in the past does not mean that it was "correct". To be clear, I'm in favor of permitting it, I'm just making sure we fully explore the problem space. |
pbsds
left a comment
There was a problem hiding this comment.
I'm putting my approval here, because the open question in my comment above may not be actionable
|
Right. Well, I think in the limit of “a package cannot stop depending on another package on a stable release, because it’d break overrides”… that’s basically just fully accepting Hyrum’s law as policy, I think. There’s nothing you could do there other than not update the package; the newer version will make any overrides ineffective. We don’t keep Explicit feature flags intended as stable API are things we should be careful about breaking on stable branches, of course, even when those feature flags are of package type. (But if the flag is to enable or disable a dependency, it still may be unavoidable.) |
|
Ack. |
| This approach also has the benefit that, if the expectation of the package changes to require a different version of `libbar`, a downstream user with an override of this argument will receive an error. | ||
| This is comparable to a merge conflict in git: It's much better to be forced to explicitly address the conflict instead of silently keeping the override - which might lead to a different problem that is likely much harder to debug. |
There was a problem hiding this comment.
Electron is one example of a package that would require an exception to this rule
There was a problem hiding this comment.
Could you elaborate?
There was a problem hiding this comment.
So, this is anecdotal evidence of course, but I had been using logseq for a year or two at some point, and there was barely a commit where I didn't have to do something like logseq.override { electron_27 = final.electron; }, each time with a different number. The pin would usually be marked insecure, and whichever version electron would actually be compatible was fairly random.
Sentiment basically is: out-of-tree customization is the one (technical) feature about Nixpkgs that, IMO and only maybe, excuses all our other crimes and debts, so advertising a policy or recommendation that, applied at large, might make it even harder to maintain overlays does not seem like a desirable tradeoff to me.
There was a problem hiding this comment.
I'm not sure I understand why you think there should be an exception made here. What I understand is that you think logseq had pinned an electron version that was just wrong because it was insecure and/or the package was broken with it. Instead, it could have pinned a different, working version or could have just used electron without a pin.
But.. how is that related to this PR? This just sounds like logseq was not well maintained.
There was a problem hiding this comment.
To put it another way, if logseq supports latest electron, it should just use latest electron instead of pinning. And if it doesn't support latest electron, then the pin is correct, and your override is at least risky - hence the override interface pointing out said risk is appropriate.
Also, upstream itself has so many repeat issues where they are behind on updating the electron version:
- Update to Electron 24 / 25 logseq/logseq#8702
- Electron 25 EOL logseq/logseq#10681
- Electron 27 is end of life logseq/logseq#11303
- Electron 28 has reached end-of-life logseq/logseq#11378
- Electron version in use is outdated and marked insecure logseq/logseq#11644
So if you're unhappy with that, don't use logseq IMO.
I also don't think it's that hard to change one line of code but 🤷
There was a problem hiding this comment.
So if you're unhappy with that, don't use logseq IMO.
Indeed, I no longer do
I also don't think it's that hard to change one line of code
One line, perhaps. That's why I'm uncomfortable advertising this approach as "preferable"
There was a problem hiding this comment.
Does the withElectronPackage approach discussed above, if agreed‐upon by the package maintainer, not address this?
There was a problem hiding this comment.
Does the withElectronPackage approach discussed above, if agreed‐upon by the package maintainer, not address this?
It indeed does, but it's still vapourware: we'll do another mass-rename, tamper with the git-blames, deprecate the many withXXXX ? true odd cases, and then find ourselves having to repeat the process once we finally have a tool to replace the convention. Of the suggestions linked from the parent issue so far, the "dream2nix-inspired" deps pattern in #273815 seems like the closest to actually attempting to address the underlying problem.
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
There was a problem hiding this comment.
It's the discussion in this PR that started with jdk_maptool, turned into withJDK in my comment in #444420 (comment) and ended up as withJdkPackage in #444420 (review).
|
Assuming there's no overlap with real packages, one way to determine in (say) |
|
That's quite a wide net to detect custom args, that assumes the scope is |
The current advice of "keeping the override interface" is actively bad, because it hides certain expectations of a package function in an undiscoverable place. Ideally, all information about a package is in one, single place instead.
Version-specific argument names, if required, also have the benefit of creating errors with downstream overrides, much like merge conflicts do. Instead of possibly silently breaking certain behavior, they make a change in expectations clear - which might feel annoying when upgrading, but is ultimately much less problematic down the road.
Resolves #404946, as proposed in #404946 (comment)
Things done
Add a 👍 reaction to pull requests you find important.