-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Lazy paths #11367
base: master
Are you sure you want to change the base?
Lazy paths #11367
Conversation
Co-authored-by: Eelco Dolstra <[email protected]> Co-authored-by: Robert Hensing <[email protected]>
This fixes the double copy problem and improves performance for expressions that don't force the whole source to be added to the store. Rules for fast expressions: - Use path literals where possible - import ./foo.nix - Use + operator with slash in string - src = fetchTree foo + "/src"; - Use source filtering, lib.fileset - AVOID toString - If possible, AVOID interpolations ("${./.}") - If possible, move slashes into the interpolation to add less to the store - "${./src}/foo" -> "${./src/foo}" toString may be improved later as part of lazy-trees, so these recommendations are a snapshot. Path values are quite nice though.
This allows clever editors/IDEs to discern the path more easily for Ctrl+Click navigate to functionality, e.g. when building .?ref=HEAD
This showPath is getting a little too ad hoc, but it works for now.
A string is only allowed to create one path component; containing no slashes.
PosixAccessor calls assertNoSymlinks too often?[ RUN ] PrimOpTest.unsafeGetAttrPos
unknown file: Failure
C++ exception with description "error:
… while calling the 'unsafeGetAttrPos' builtin
at «string»:1:1:
1| builtins.unsafeGetAttrPos "y" (import <nix/foo.nix>)
| ^
… while calling the 'import' builtin
at «string»:1:32:
1| builtins.unsafeGetAttrPos "y" (import <nix/foo.nix>)
| ^
(stack trace truncated; use '--show-trace' to show the full, detailed trace)
error: path '/home/tom/.nix-defexpr/channels' is a symlink" thrown in the test body.
[ FAILED ] PrimOpTest.unsafeGetAttrPos (0 ms) findFile prefix/suffix separator is ":" or "/"+(lang.sh:61) bash lang/eval-fail-derivation-name.postprocess lang/eval-fail-derivation-name
--- lang/eval-fail-derivation-name.err.exp 2024-08-25 17:27:55.317195410 -0400
+++ lang/eval-fail-derivation-name.err 2024-08-26 00:34:52.148460570 -0400
@@ -1,20 +1,20 @@
error:
… while evaluating the attribute 'outPath'
- at <nix/derivation-internal.nix>:<number>:<number>:
+ at <nix:derivation-internal.nix>:<number>:<number>:
<number>| value = commonAttrs // {
<number>| outPath = builtins.getAttr outputName strict;
| ^
<number>| drvPath = strict.drvPath;
… while calling the 'getAttr' builtin
- at <nix/derivation-internal.nix>:<number>:<number>:
+ at <nix:derivation-internal.nix>:<number>:<number>:
<number>| value = commonAttrs // {
<number>| outPath = builtins.getAttr outputName strict;
| ^
<number>| drvPath = strict.drvPath;
… while calling the 'derivationStrict' builtin
- at <nix/derivation-internal.nix>:<number>:<number>:
+ at <nix:derivation-internal.nix>:<number>:<number>:
<number>|
<number>| strict = derivationStrict drvAttrs;
| ^ SourceAccessor is relative to root not to absolute path++(toString-path.sh:8) nix eval --raw --impure --expr 'builtins.readFile (builtins.toString (builtins.fetchTree { type = "path"; path = "/tmp/nix-shell.yXAp0S/nix-test/toString-path/foo"; } + "/bar"))'
error:
… while calling the 'readFile' builtin
at «string»:1:1:
1| builtins.readFile (builtins.toString (builtins.fetchTree { type = "path"; path = "/tmp/nix-shell.yXAp0S/nix-test/toString-path/foo"; } + "/bar"))
| ^
error: opening file '/bar': No such file or directory
+(toString-path.sh:8) [[ '' = bla ]]
++(toString-path.sh:8) onError
++(/home/tom/nix/lazy-paths/build/src/nix-functional-tests/common/functions.sh:237) set +x
toString-path.sh: test failed at:
main in toString-path.sh:8
――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
117/183 nix-functional-tests:main / read-only-store Absolute path is used relative to root++(toString-path.sh:8) nix eval --raw --impure --expr 'builtins.readFile (builtins.toString (builtins.fetchTree { type = "path"; path = "/tmp/nix-shell.yXAp0S/nix-test/toString-path/foo"; } + "/bar"))'
error:
… while calling the 'readFile' builtin
at «string»:1:1:
1| builtins.readFile (builtins.toString (builtins.fetchTree { type = "path"; path = "/tmp/nix-shell.yXAp0S/nix-test/toString-path/foo"; } + "/bar"))
| ^
error: opening file '/bar': No such file or directory
+(toString-path.sh:8) [[ '' = bla ]]
++(toString-path.sh:8) onError
++(/home/tom/nix/lazy-paths/build/src/nix-functional-tests/common/functions.sh:237) set +x
toString-path.sh: test failed at:
main in toString-path.sh:8
――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
117/183 nix-functional-tests:main / read-only-store |
Unable to find input at specified path+(follow-paths.sh:80) nix flake metadata /tmp/nix-shell.yXAp0S/nix-test/flakes/follow-paths/follows/flakeA
warning: Git tree '/tmp/nix-shell.yXAp0S/nix-test/flakes/follow-paths/follows/flakeA' is dirty
error:
… while updating the lock file of flake 'git+file:///tmp/nix-shell.yXAp0S/nix-test/flakes/follow-paths/follows/flakeA'
… while updating the flake input 'B'
… while fetching the input 'path:./flakeB'
error: path 'flakeB' does not exist
++(follow-paths.sh:80) onError
++(/home/tom/nix/lazy-paths/build/src/nix-functional-tests/common/functions.sh:237) set +x
follow-paths.sh: test failed at:
main in follow-paths.sh:80 |
This is probably the right behavior for a SourceAccessor, but we shouldn't use a SourceAccessor directly, or not its low level methods or not for this purpose. |
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/2024-08-26-nix-team-meeting-minutes-172/51300/1 |
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/how-are-flake-dependencies-fetched/52638/8 |
Next steps:
|
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/2024-10-07-nix-team-meeting-minutes-184/54046/1 |
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: |
(This is #10252, but as an upstream branch for easier collaboration)
Motivation
Improve performance, and make the
fetchTree
interface more capable while keeping it clean.Description
This makes
fetchTree
return lazyInputAccessor
-basedSourcePath
s instead of "cowardly" fetching them to the store and returning absolute "system" paths.It stays close to existing path semantics, including support for
readFile "${toString p}/.."
, which some expressions rely on.It does not go as far as lazy-trees, but judging from the amount of change I could reuse, and how little of my own I had to add, lazy-trees will be a natural extension of this PR.
Done:
nixpkgs#hello
, and 1s reduction onnixosTests.simple
Conclusion so far:
Viable
TODO:
narHash
in some observable placestoString path
behavior to lazy-trees(fetchTree x).outPath
flake.outPath
Context
Priorities and Process
Add 👍 to pull requests you find important.
The Nix maintainer team uses a GitHub project board to schedule and track reviews.