Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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
[RFC 0092] Computed derivations #92
[RFC 0092] Computed derivations #92
Changes from 56 commits
3a8338a
3b8422a
4da9193
800b5f3
f708983
6a87c1b
36193e5
ffb9203
5564fdb
22f8322
7f5f854
5c9f1fb
5e56f21
ba7dcce
8bcb4e6
baae1e6
9448a2a
37a643e
14b134d
1b0a6a1
3fe1c3d
a38f245
4022058
6c01e4d
6d97de1
2079528
fd7bb41
ec622cd
ad74b68
0eaa6bb
49070db
c50ee43
98ea32a
c01f07c
3f187a3
7d18780
5e92cc9
1e2012c
5836c02
970ff43
d6d6b17
6ab3338
5f7d4da
ea388e7
f6741c4
b5aa21d
866dc5e
098fe68
fed8991
854fd9b
f853a6f
1abaf30
ef1d9aa
5115ebb
fdbf778
2388cbe
404ad6d
a906a7c
4d579ed
File filter
Filter by extension
Conversations
Jump to
There are no files selected for viewing
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 is not entirely true because as with IFD, you can't get the (final) output path without building something. So
--dry-run
cannot show you what paths will be built/downloaded.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.
Going from unknown unknowns to known unknowns is a slight improvement.
Note that we already don't know the total size of downloads in advance because of fixed-output fetching. This could have been worked around long ago, but I am not aware of anyone complaining about this after years, so I don't think it's all that important.
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 seems suboptimal UX to me, because it requires the user to be aware of the fact that a package uses plan dynamism. I.e. a package that uses dynamism requires a call like
nix build <foo>!bla!bla...
, whereas a regular package requiresnix build <foo>
.It would seem more user-friendly if
nix build
by default builds the entire chain of!out!out!...
until it gets to a non-derivation.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.
What if you want to build just the first layer?
I think there's another potential solution here:
nix build
builds only the derivation specified (like right now), but it is extended such that it can build derivations at floating paths.E.g. if we build the following code:
Then
nix build
could perhaps automatically build the prerequisite for the floating path.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.
See #92 (comment).
The suggestion below that would return something akin to what @L-as describes succinctly in their example.
@Ericson2314 I think I could write out that
mkPackage
function if you think that's helpful at this stage.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.
There are also advanced situations where downstream derivations want to be sure they depend on "intermediate" derivations.
For example, if one is using GHC to find the dependencies between between modules of a package, we do need to know what packages are provided by upstream libraries, but we don't need to have actually built those upstream libriaries. I am would want to run the dep solver on the current library, depending on just the "module manifest" to allow it not to fail on upstream library
import
s, and then create derivations that depend on the upstream derivations, for maximum incrementality.Long story short, supporting that example means situations like:
bar
depends onfoo!out
: drv generaterbar
depends on drv created byfoo
bar!out
depends onfoo!out!out
: drv generated by bar depends on result of building the drv generated byfoo
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.
If this is done consistently, it would mean having to say
nix shell nixpkgs#hello!out
rather thannix shell nixpkgs#hello
(sincenix shell
operates on the derivation output rather than the derivation). That would be pretty verbose.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 it'd be ok for
nix shell
to operate oninstallable.drvPath
or evennix-store -q --deriver $(nix-instantiate --eval "installable.outPath")
so to speak.Doesn't
nix build
do the same? It also operates on a derivation. The only difference is that it produces outputs.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.
@edolstra in my view
!
is just a syntax for literal paths, the lowest level way to createDerivedPath
s.nix shell nixpkgs#hello
I have no desire to change, we could make it stay as is and e.g.nix shell nixpkgs#hello.drvPath
be how one avoids needing--derivation
.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.
What does this do?
And what does
nix build
on this Nix expression produce?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.
Building it should give you (a symbolic link to)
hello
.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.
The "cp" of the top-level drv is asymmetrical and ugly, since we don't copy any of the dependencies. Since we just want to return a .drv that already exists, it might be nicer to do:
or
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.
The best solution might perhaps be having a way of specifying an existing store path as the output.
This problem also occurs in other paths of
nix-build.nix
, where we want to output an already built path.ln -s
gives you an extra symbolic link in the output. Copying it then patching the self references is a viable solution but not optimal at all.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.
@edolstra BTW that "specify store path as output" idea is the ancestor of the "finish outputs then keep running derivations to finish tests" idea I mentioned on the #95 call today.
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.
What are the constraints on the .drv? All the
inputSrcs
andinputDrvs
have to be in the producing derivation's input closure or added via recursive 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.
Considering this example does not make use of recursive Nix, they do have to be in the input closure in this case. A better example might perhaps be using
${pkgs.hello}
, etc. instead of the raw paths.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.
@edolstra if we assume "text mode hashing" is only going to be used by derivations, when we validate the output/calculate it's references we could just parse the drv file rather than doing the usual "lookin for hashes", and fail if any of those are not on the possible references whitelist.
(The possible references whitelist is compute in the usual way, based on existing inputs and extended by recursive nix. There is no change there.)
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.
Some explanation of the semantics and usage of this expression would be helpful. What does the .drv resulting from instantiating
pkgs.runComand ...
look like? What doesnix build
produce? Do I need to add!out
to get the actual output?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've made an example here: https://github.com/L-as/nix-build.nix/blob/9526175a6f607f480bc494f804b5e3226d667f5d/manual.nix
The derivation for the wrapper looks like this:
Note: the flake exports a
nix92
package which you can use to test.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 is a good question, since whether a package uses plan dynamism should be an implementation detail of that package that doesn't get exposed to the consumers of that package. So a derivation that uses
hello
shouldn't have to do${builtins.outputOf hello.out "out"}/bin/hello
if the hello package uses plan dynamism. Instead${hello}/bin/hello
should work as expected.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 should be the responsibility of the package expressions that use plan dynamism. Ie a package output must not be a derivation path, whereas derivations in general can do anything. We'll have to stop conflating derivations and packages.
I would define a package as an attrset with attributes like
meta
,outPath
and possiblybin
, etc, whereas a derivation is a more low level concept represented by attrsets that may have little more than outputs in them.This is a taste of what a package using
outputOf
might look like, although I think we'll build abstractions on top ofmkPackage
to facilitate specific use cases like the specific language integrations that use plan dynamism.