Skip to content

Commit

Permalink
document "Import From Derivation"
Browse files Browse the repository at this point in the history
  • Loading branch information
fricklerhandwerk committed Jul 13, 2023
1 parent 8e2d34f commit 8b18c67
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 5 deletions.
1 change: 1 addition & 0 deletions doc/manual/src/SUMMARY.md.in
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
- [Operators](language/operators.md)
- [Derivations](language/derivations.md)
- [Advanced Attributes](language/advanced-attributes.md)
- [Import From Derivation](language/import-from-derivation.md)
- [Built-in Constants](language/builtin-constants.md)
- [Built-in Functions](language/builtins.md)
- [Advanced Topics](advanced-topics/advanced-topics.md)
Expand Down
3 changes: 3 additions & 0 deletions doc/manual/src/glossary.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,9 @@
derivations that are stored in the Nix store. These derivations can
then be built.

- [IFD]{#gloss-ifd}\
[Import From Derivation](./language/import-from-derivation.md)

- [reference]{#gloss-reference}\
A [store object] `O` is said to have a *reference* to a store object `P` if a [store path] to `P` appears in the contents of `O`.

Expand Down
86 changes: 86 additions & 0 deletions doc/manual/src/language/import-from-derivation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# Import From Derivation

The value of a Nix expression can depend on the contents of a [store object] produced by a [derivation].
In this case, when that store object is needed, evaluation will be paused, the store object [realised], and then evaluation resumed.

[store object]: /glossary.md#gloss-store-object
[derivation]: /glossary.md#gloss-derivation
[realised]: /glossary.md#gloss-realise

This has performance implications:
Since evaluation is sequential, each required store object that is not already in the store will also be realised sequentially.

Passing a derivation `drv` to any built-in function that reads from the filesystem constitutes Import From Derivation:

- [`import`](./language/builtins.md#builtins-import)` drv`
- [`builtins.readFile`](./language/builtins.md#builtins-readFile)` drv`
- [`builtins.readDir`](./language/builtins.md#builtins-readDir)` drv`
- [`builtins.pathExists`](./language/builtins.md#builtins-pathExists)` drv`
- [`builtins.filterSource`](./language/builtins.md#builtins-filterSource)` f drv`
- [`builtins.path`](./language/builtins.md#builtins-path)` { path = drv; }`
- [`builtins.hashFile`](./language/builtins.md#builtins-hashFile)` t drv`
- `builtins.scopedImport x drv`

Building during evaluation can be disabled by setting [`allow-import-from-derivation`](../command-ref/conf-file.md#conf-allow-import-from-derivation) to `false`.

## Example

In the following Nix expression, the inner derivation `drv` produces a file containing `"hello"`.

```nix
# IFD.nix
let
drv = derivation {
name = "hello";
builder = /bin/sh;
args = [ "-c" ''echo \"hello\" > $out'' ];
system = builtins.currentSystem;
};
in "${import drv} world"
```

```shellSession
nix-instantiate IFD.nix --eval --read-write-mode
```

```
building '/nix/store/348q1cal6sdgfxs8zqi9v8llrsn4kqkq-hello.drv'...
"hello world"
```

Since `"hello"` is a valid Nix expression, it can be [`import`](./builtins.md#builtins-import)ed.
That requires reading from the output [store path](@docroot@/glossary.md#gloss-store-path) of `drv`, which has to be [realised] before its contents can be read and evaluated.

## Illustration

The following diagram shows how evaluation is interrupted by a build, if the value of a Nix expression depends on realising a store object.

```
+----------------------+ +------------------------+
| Nix language | | Nix store |
| .----------------. | | |
| | Nix expression | | | |
| '----------------' | | |
| | | | |
| evaluate | | |
| | | | |
| V | | |
| .------------. | | .------------------. |
| | derivation |----|-instantiate-|->| store derivation | |
| '------------' | | '------------------' |
| | | | |
| | | realise |
| | | | |
| | | V |
| .----------------. | | .--------------. |
| | Nix expression |<-|----read-----|----| store object | |
| '----------------' | | '--------------' |
| | | | |
| evaluate | | |
| | | | |
| V | | |
| .------------. | | |
| | value | | | |
| '------------' | | |
+----------------------+ +------------------------+
```
8 changes: 3 additions & 5 deletions src/libexpr/eval.hh
Original file line number Diff line number Diff line change
Expand Up @@ -835,11 +835,9 @@ struct EvalSettings : Config
Setting<bool> enableImportFromDerivation{
this, true, "allow-import-from-derivation",
R"(
By default, Nix allows you to `import` from a derivation, allowing
building at evaluation time. With this option set to false, Nix will
throw an error when evaluating an expression that uses this feature,
allowing users to ensure their evaluation will not require any
builds to take place.
By default, Nix allows [Import from Derivation](@docroot@/language/import-from-derivation.md).
With this option set to `false`, Nix will throw an error when evaluating an expression that uses this feature,
ensuring that evaluation will not require any builds to take place.
)"};

Setting<Strings> allowedUris{this, {}, "allowed-uris",
Expand Down

0 comments on commit 8b18c67

Please sign in to comment.