That’s rather unfortunate, but unsurprising.
Hmm, how about an extension of the flake interface? Right now the currently unsolved problem is something along the lines of:
- Need to capture a strict superset of all
import
calls (because even a single one missing is an eval failure). - Need to make the superset only as big as is necessary to achieve Point 1 so we don’t end up hitting
throw
s andabort
s that were meant to be lazy. Basically, backing up imports should never itself act as a strict operation. - The set required by Point 2 is slowly shrinking as more aspects of the language become lazy.
- Point 3 renders the output of whatever mechanism used for this purpose both unstable and unstabilisable without significantly constraining future increases in laziness.
- Because of Point 4 and implicit pure-nix return value stability guarantees, I can’t just make this a primop.
Leaving it to the user was an attempt to get around this, but what if I instead shove the perpetually-unstable parts into the output of some flake subcommand (let’s call it nix flake reify
) and declare that while using it ensures you can evaluate the flake in question offline, whatever actually ends up in the file is an implementation detail? Then, the stable, well-behaved remainder (inputDrvs
, inputSrcs
, and dynamic drivers) can be retrieved via primop.
Also,
after some more thinking, I’m retracting this statement. Just came to the realization that even if you could lose inputDrvs
, those missing dependencies would not be mounted in the sandbox of their dependent either, so the online build would fail too (if it tried to access said path). So build dependencies are indeed just inputDrvs
, and instantiation dependencies are inputSrcs
+ dynamic derivers + import
s.
P.S. To expound on my concern about import
s, consider the following toy example:
let
instanDep = <something that does a download>
importedBool = import (instanDep/false.nix);
in
usedElsewhere = if importedBool then derivation {...} else derivation {...}
Now we have an invisible dependency on instanDep
(evaluation fails without it present). Notably, this is an issue whether instanDep
is produced by build-time IFD of a FOD or eval-time builtin fetcher (which is how flake inputs are obtained, last I checked).