-
-
Notifications
You must be signed in to change notification settings - Fork 14.9k
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
lib: add flake information to lib.trivial #278522
Conversation
Looks very solid. Minimal and effective. |
575987d
to
07d87e8
Compare
(CI exploded due to github shenanigans) |
07d87e8
to
6e58051
Compare
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.
Overall looking good :)
@@ -16,5 +16,8 @@ finalLib: prevLib: # lib overlay | |||
versionSuffix = | |||
".${finalLib.substring 0 8 (self.lastModifiedDate or "19700101")}.${self.shortRev or "dirty"}"; | |||
revisionWithDefault = default: self.rev or default; | |||
|
|||
isFlake = true; | |||
nixpkgsStorePathString = toString self; |
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.
Needs a comment why this is needed and correct.
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.
use builtins.storePath to establish a dependency on this nixpkgs' sources
I believe we'll soon want this to be a path value. Nix 2.20 already includes a significant part of the lazy trees infrastructure, so a compatible and reproducible variation of that branch is on the horizon. That is, compatible and reproducible wrt traditional Nix expressions. I do not know if Flakes will change, but it may.
Normally toString
should not be called on path values, because the result lacks a string context.
In this case, self
is already string-coercible, thanks to self.outPath
, so we don't seem to need the positive functionality of toString
here. I think you've used it to isolate the "path-like" property and expose that in an encapsulated way. I believe this could be done more reliably by returning self.outPath
, which has the same effect, and does not break if self.outPath
is changed to a path value.
This will have the effect of passing along Nix 2.18's string with context, but naturally upgrade that to a path value if that becomes the new behavior.
Regardless of how we decide to implement this, I believe this attribute should not be part of the public interface, ie nixpkgsFlake.lib.trivial.nixpkgsStorePathString
(nor that it is trivial. I think it's the worst name, or on par with "util". Should we have lib.flake
? Maybe, but certainly not for this purpose.).
Presumably this is for pkgs.path
, right? I don't see a reason for this to exist as a flake output, because flake consumers can do nixpkgsFlake + "/some/path"
(not that they should reach into the internals, but that's a different conversation). That does need to be fixed somehow, but my last attempt did not go well: #153594 (comment).
Solutions that increase the interface area may well make it much harder to solve the problem properly, so I humbly ask you to remove this attribute.
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.
No, the reasoning for why this is here is written down in the comment itself. Without this attribute, we cannot ship #254405.
That is why we are doing this. Maybe it should be somewhere internal, I'm indifferent about that. But we do need it for good UX in NixOS flake systems. This particular use case does involve copying the whole nixpkgs into the store, unavoidably, since it will wind up in a derivation; it's not intended to be used for imports as we can already do that with pkgs.path, modulesPath, etc etc.
I'm personally lightly pessimistic about lazy trees getting in, but regardless of my own views on this, it would be annoying to gate the UX improvement that many people want on a new Nix version that will take some time to stabilize and shake out the regressions.
I do acknowledge this is extremely cursed code that depends on a load of C++nix implementation details and I would like to minimize the amount that it will break in the foreseeable future.
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.
We need some way to inject the dependency to NixOS so we can put the nixpkgs into the resulting closure so the UX of nix-shell and nix shell isn't awful. My last attempt was just injecting it directly into NixOS, but I saw this infrastructure that felt more appropriate.
But now I wonder if injecting it directly into NixOS is the least bad option; the disadvantage of that one is this infrastructure not being reusable and not working for non-flakes, but perhaps that's for the better since it's rather cursed?
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.
depends on a load of C++nix implementation details
I don't think path value semantics can be considered implementation details.
Path values have been an integral part of the language since basically forever. Any Nix implementation needs to implement path value semantics. I don't think the lazy-trees author appreciated that when they wrote the branch.
The problems with self.outPath
and in-flake ./.
are squarely with Flakes.
gate the UX improvement that many people want on a new Nix version
This is unfortunate, but I don't think it's an excuse for making a mess in nixpkgs
.
wonder if injecting it directly into NixOS is the least bad option
I'll take a messy implementation over a messy interface any day.
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.
ship #254405.
For context, this can't be done correctly and I don't think we should try to pretend that we have a mechanism that forwards pkgs
to other evaluations on the machine for which it was used. Usually I support incremental improvements, but if they can't lead to a good end state, the approach should be reconsidered in its entirety.
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.
Hmmm wait a minute. Wait a minute. We can probably actually fix this properly by forwarding the metadata of the flake input locking into the registry entry. 🤦🏻♀️ which would actually do this properly and not add to closure size, since we can forward to the flake registry for NIX_PATH.
The only thing we lose there is sending nixpkgs to the new installation automatically so it works offline, rather than just merely putting the metadata in to get the right version lazily.
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.
Hmm. Nope. You can't get info of your own lock file entry from inside a flake. This is .... probably reasonable, because it would enable some truly spectacular spooky action at a distance, but it is quite sad for this purpose.
In conclusion, we still need something like this.
33e6358
to
0cf661a
Compare
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.
Looking good to me! I'm guessing @roberth probably also has an opinion on this, but otherwise I'll merge soon (ping me if I don't)
…xt for self This is an extremely subtle feature which is necessary to be able to incur dependencies on this nixpkgs's source code without copying it twice (NixOS/nix#9428, NixOS/nix#5868). pkgs.path is not sufficient, because actually using it incurs a copy, which winds up looking like /nix/store/HASH-HASH-source in flakes. Similarly, `toString pkgs.path` is not sufficient because that does not have any string context, so it will not incur a dependency if it's used. It's exceptionally subtle. There are four cases: - non flakes, pure mode: can't do anything about this, we must copy to the store. - non flakes, not already in the store: can't do anything about this, we are copying to the store. - non flakes, already in the store: storePath gives us a string with context for free. - flakes: overlay makes it a stringification of self.outPath. In all cases, this is a string with appropriate context to transfer this nixpkgs to another system.
This is intended to be used for making NixOS pick up that it is being used from a flake and configure the NIX_PATH and flake registry appropriately.
0cf661a
to
4c934f1
Compare
Poked at the comments some more. |
# this overrides lib/trivial.nix, in which isFlake is unconditionally set | ||
# to false. | ||
isFlake = true; |
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.
We have a bunch of dynamic type checking functions, such as isString
, isPath
, etc. This looks like that, and that's a problem, because flakes can be checked reliably with x._type or null == "flake"
, and it is important enough to warrant a function.
- (and I think time is coming to revisit lib.types: Add flake type #210572 (comment))
# this overrides lib/trivial.nix, in which isFlake is unconditionally set | |
# to false. | |
isFlake = true; | |
# this overrides lib/trivial.nix, in which isFlake is unconditionally set | |
# to false. | |
isFlakeLib = true; |
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.
Note that this may suffer from a similar expectation, but that expectation is less realistic to be executed, unless we give lib
a special treatment in Nix's call-flake.nix
. I don't like that idea.
@@ -16,5 +16,8 @@ finalLib: prevLib: # lib overlay | |||
versionSuffix = | |||
".${finalLib.substring 0 8 (self.lastModifiedDate or "19700101")}.${self.shortRev or "dirty"}"; | |||
revisionWithDefault = default: self.rev or default; | |||
|
|||
isFlake = true; | |||
nixpkgsStorePathString = toString self; |
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.
use builtins.storePath to establish a dependency on this nixpkgs' sources
I believe we'll soon want this to be a path value. Nix 2.20 already includes a significant part of the lazy trees infrastructure, so a compatible and reproducible variation of that branch is on the horizon. That is, compatible and reproducible wrt traditional Nix expressions. I do not know if Flakes will change, but it may.
Normally toString
should not be called on path values, because the result lacks a string context.
In this case, self
is already string-coercible, thanks to self.outPath
, so we don't seem to need the positive functionality of toString
here. I think you've used it to isolate the "path-like" property and expose that in an encapsulated way. I believe this could be done more reliably by returning self.outPath
, which has the same effect, and does not break if self.outPath
is changed to a path value.
This will have the effect of passing along Nix 2.18's string with context, but naturally upgrade that to a path value if that becomes the new behavior.
Regardless of how we decide to implement this, I believe this attribute should not be part of the public interface, ie nixpkgsFlake.lib.trivial.nixpkgsStorePathString
(nor that it is trivial. I think it's the worst name, or on par with "util". Should we have lib.flake
? Maybe, but certainly not for this purpose.).
Presumably this is for pkgs.path
, right? I don't see a reason for this to exist as a flake output, because flake consumers can do nixpkgsFlake + "/some/path"
(not that they should reach into the internals, but that's a different conversation). That does need to be fixed somehow, but my last attempt did not go well: #153594 (comment).
Solutions that increase the interface area may well make it much harder to solve the problem properly, so I humbly ask you to remove this attribute.
/* Whether this nixpkgs is being used directly as a flake. | ||
|
||
Note that this is not set for `import nixpkgs` from another flake; it is | ||
only set if using `nixpkgs.lib` or the `lib` flake. | ||
|
||
Type: Bool | ||
*/ | ||
isFlake = |
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.
This isn't just about how it's loaded, but about an architectural property.
/* Whether this nixpkgs is being used directly as a flake. | |
Note that this is not set for `import nixpkgs` from another flake; it is | |
only set if using `nixpkgs.lib` or the `lib` flake. | |
Type: Bool | |
*/ | |
isFlake = | |
/* Whether this is the `nixpkgs.lib` library (`nixpkgs` being the Nixpkgs flake), or just the Nixpkgs library. | |
The name `lib` may refer to, among other things: | |
- the Nixpkgs library, or | |
- a `lib` attribute on any flake, which has the purpose of exposing functions that are relevant to the consumer of the flake. | |
The Nixpkgs flake uniquely combines both roles, and does so by extending its traditional library of non-building functions with extra attributes, such as `nixos` and `nixosSystem`. | |
Note that this is not set for `import nixpkgs` from another flake; it is | |
only set if using `nixpkgs.lib` or the `lib` flake. | |
Type: Bool | |
*/ | |
isFlakeLib = |
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.
Ohh
I glossed over the Nixpkgs library flake. Should that even have isFlakeLib
? I think not; that lib
is / should be very very close to the traditional library.
The library flake should definitely not expose its parent directory. That was never the intended architecture before flakes, and it would perpetuate (well, relatively) the current inefficiency of subdirectory flakes.
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.
Hmmm. I can see why this would be faulty. Putting it in pkgs is ugly for different reasons of (very) poor discoverability, since it's mixed into a delicious soup of packages in all-packages, which is annoying.
Closing since most of this is probably a bad idea. |
Description of changes
@infinisil
This is a splitting of the now-rewritten lib parts off of #254405, with the hopes it will be easier to merge.
This adds
lib.trivial.selfPath
(name subject to discussion) andlib.isFlake
, implemented via the overlay we use for versions. The purpose of lib.trivial.selfPath is as a way of incurring a dependency on this nixpkgs that is not affected by NixOS/nix#9428. Please see the commit messages for more contextThings done
nix.conf
? (See Nix manual)sandbox = relaxed
sandbox = true
nix-shell -p nixpkgs-review --run "nixpkgs-review rev HEAD"
. Note: all changes have to be committed, also see nixpkgs-review usage./result/bin/
)Add a 👍 reaction to pull requests you find important.