-
-
Notifications
You must be signed in to change notification settings - Fork 159
[RFC 0192] version pins for the pkgs/by-name structure
#192
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
base: master
Are you sure you want to change the base?
Conversation
Co-authored-by: Michael Daniels <mdaniels5757@gmail.com>
|
Related: NixOS/nixpkgs#421201 |
| - Every attrName in the resulting attribute set has to be a valid package | ||
| attribute name. | ||
| - Every attrValue should be the pinned version of the respectice attrName | ||
| package, this is however hard to check I think. | ||
| - Every attrName has to be a functionArg of the `package.nix`. |
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.
Maybe this is out of scope, but can we also pin dependencies that not just differ in their semantic versions like nodejs = nodejs_22, but have other overrides or logic?
Some example pins.nix:
{
darwin,
stdenv,
}@args:
{
stdenv = if args.stdenv.hostPlatform.isDarwin then darwin.bootstrapStdenv else args.stdenv;
}{
luajit,
}@args:
{
luajit = args.luajit.override { enable52Compat = true; };
}This would be useful to keep compatibility with previous overrides of a package when removing by-name overrides.
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 think we lose some of the usefulness if we allow that
also like with version pins we can already do that just in the package.nix with let in
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.
Yes, let in handles most of the cases, but there are a few edge cases when it breaks override compatibility.
package called in all-package.nix
Consider this package and it's possible usage before it being fully self contained in by-name:
# file: pkgs/all-packages.nix
{
aegisub = callPackage ../by-name/ae/aegisub/package.nix {
luajit = luajit.override { enable52Compat = false; };
};
# ...
}# file: pkgs/by-name/ae/aegisub/package.nix
{
stdenv,
luajit,
# ...
}:
stdenv.mkDerivation {
buildInputs = [ luajit ];
# ...
}# file: configuration.nix
{ pkgs, ... }:
{
environment.systemPackages = [
(pkgs.aegisub.override { luajit = luajit_2_0.override { enable52Compat = true; })
]
}The above code builds fine, luajit_2_0.override { enable52Compat = true; will be in buildInputs.
package is only in by name using let in, breaks override compatibility
Now let's move the override from all-packages to the by-name package:
# file: pkgs/all-packages.nix
{
# no override for aegisub
}# file: pkgs/by-name/ae/aegisub/package.nix
{
stdenv,
luajit,
# ...
}:
let
luajit' = luajit.override { enable52Compat = true; };
in
stdenv.mkDerivation {
buildInputs = [ luajit' ];
# ...
}# file: configuration.nix
{ pkgs, ... }:
{
environment.systemPackages = [
(pkgs.aegisub.override { luajit = luajit_2_0.override { enable52Compat = true; })
]
}The above code fails to build, (luajit_2_0.override { enable52Compat = true; }).override { enable52Compat = false; } will be in buildInputs. There is no way to override a variable in a let binding.
package using pins, override compatible and doesn't touch all-packages
To solve this, we may use versions pins:
# file: pkgs/all-packages.nix
{
# no override for aegisub
}# file: pkgs/by-name/ae/aegisub/package.nix
{
stdenv,
luajit
# ...
}:
stdenv.mkDerivation {
buildInputs = [ luajit ];
# ...
}# file: pkgs/by-name/ae/aegisub/pins.nix
{
luajit
}:
{
luajit = luajit.override { enable52Compat = false; };
}# file: configuration.nix
{ pkgs, ... }:
{
environment.systemPackages = [
(pkgs.aegisub.override { luajit = luajit_2_0.override { enable52Compat = true; })
]
}The above code should build and should produce the same derivation as the first, all-packages example.
(The details in this example is unrealistic: enable52Compat is set to true in nixpkgs and it's unlikely for someone to override it. The PR I linked in my previous comment talked about overriding platforms, but I didn't want to complicate this example by introducing platforms.)
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 think this falls under
- Some more generalized
overrides.nixwithout the strict requirements.
While I get the problem this is trying to solve, in my opinion it overcomplicates things.
Especially the resulting need to have overrideOverrides/overridePins is too confusing for people I think.
| lists the problem this RFC is trying to solve under "Future work". | ||
|
|
||
| # Unresolved questions | ||
| [unresolved]: #unresolved-questions |
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.
When overriding a package, will it override the the arguments of pins.nix or the arguments of package.nix?
Perhaps it could override package.nix and we could have an overridePins function.
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.
.override {} overrides the package.nix
why would someone need to override the pins?
package.overridePins {
dependency_3 = my-dependency_3;
}would be the same as
package.override {
dependency = my-dependency_3;
}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 think there is an ambiguity here. Overrides relative to callPackage path/to/package.nix {} are not provided at all, because this would break more than help (and also override works relative to a package that is defined, and the package defined does use pins). You can just override all the pinned stuff one-by-one, though, if for some specific package it makes sense.
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.
sorry, i don't understand what you are trying to say
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.
why would someone need to override the pins?
I forgot to mention it's heavily related to my other comment, so it's only useful if we also want to pin non-versioned packages.
Following the last example in that thread, we have:
# file: pkgs/by-name/ae/aegisub/pins.nix
{
luajit
}:
{
luajit = luajit.override { enable52Compat = false; };
}# file: pkgs/by-name/ae/aegisub/package.nix
{
stdenv,
luajit
# ...
}:
stdenv.mkDerivation {
buildInputs = [ luajit ];
# ...
}
The package.nix override that turns on enable52Compat could be written as:
aegisub.override {
luajit = luajit.override { enable52Compat = true; };
}And a pins.nix override that uses luajit_2_0 instead of luajit could be written as:
aegisub.overridePins {
luajit = luajit_2_0;
}The latter will result in luajit_2_0.override { enable52Compat = false; } getting into buildInputs, because it replace's the pin's input, the pin adds the override { enable52Compat = false; } and passes this to the package's input.
Rendered
Sorry if the RFC text is short, i don't know what else to write. The feature is quite simple.