Merge pull request #11115 from NixOS/doc-derivation

Document builtins.derivation
This commit is contained in:
John Ericson 2024-07-25 00:21:53 -04:00 committed by GitHub
commit 90f7f2139e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 67 additions and 15 deletions

View File

@ -1,6 +1,31 @@
/* This is the implementation of the derivation builtin function. # This is the implementation of the derivation builtin function.
It's actually a wrapper around the derivationStrict primop. */ # It's actually a wrapper around the derivationStrict primop.
# Note that the following comment will be shown in :doc in the repl, but not in the manual.
/**
Create a derivation.
# Inputs
The single argument is an attribute set that describes what to build and how to build it.
See https://nix.dev/manual/nix/2.23/language/derivations
# Output
The result is an attribute set that describes the derivation.
Notably it contains the outputs, which in the context of the Nix language are special strings that refer to the output paths, which may not yet exist.
The realisation of these outputs only occurs when needed; for example
* When `nix-build` or a similar command is run, it realises the outputs that were requested on its command line.
See https://nix.dev/manual/nix/2.23/command-ref/nix-build
* When `import`, `readFile`, `readDir` or some other functions are called, they have to realise the outputs they depend on.
This is referred to as "import from derivation".
See https://nix.dev/manual/nix/2.23/language/import-from-derivation
Note that `derivation` is very bare-bones, and provides almost no commands during the build.
Most likely, you'll want to use functions like `stdenv.mkDerivation` in Nixpkgs to set up a basic environment.
*/
drvAttrs @ { outputs ? [ "out" ], ... }: drvAttrs @ { outputs ? [ "out" ], ... }:
let let

View File

@ -50,11 +50,25 @@ set +x
badDiff=0 badDiff=0
badExitCode=0 badExitCode=0
# Extra post-processing that's specific to each test case
postprocess() {
if [[ -e "lang/$1.postprocess" ]]; then
(
# We could allow arbitrary interpreters in .postprocess, but that
# just exposes us to the complexity of not having /usr/bin/env in
# the sandbox. So let's just hardcode bash for now.
set -x;
bash "lang/$1.postprocess" "lang/$1"
)
fi
}
for i in lang/parse-fail-*.nix; do for i in lang/parse-fail-*.nix; do
echo "parsing $i (should fail)"; echo "parsing $i (should fail)";
i=$(basename "$i" .nix) i=$(basename "$i" .nix)
if expectStderr 1 nix-instantiate --parse - < "lang/$i.nix" > "lang/$i.err" if expectStderr 1 nix-instantiate --parse - < "lang/$i.nix" > "lang/$i.err"
then then
postprocess "$i"
diffAndAccept "$i" err err.exp diffAndAccept "$i" err err.exp
else else
echo "FAIL: $i shouldn't parse" echo "FAIL: $i shouldn't parse"
@ -71,6 +85,7 @@ for i in lang/parse-okay-*.nix; do
2> "lang/$i.err" 2> "lang/$i.err"
then then
sed "s!$(pwd)!/pwd!g" "lang/$i.out" "lang/$i.err" sed "s!$(pwd)!/pwd!g" "lang/$i.out" "lang/$i.err"
postprocess "$i"
diffAndAccept "$i" out exp diffAndAccept "$i" out exp
diffAndAccept "$i" err err.exp diffAndAccept "$i" err err.exp
else else
@ -94,6 +109,7 @@ for i in lang/eval-fail-*.nix; do
expectStderr 1 nix-instantiate $flags "lang/$i.nix" \ expectStderr 1 nix-instantiate $flags "lang/$i.nix" \
| sed "s!$(pwd)!/pwd!g" > "lang/$i.err" | sed "s!$(pwd)!/pwd!g" > "lang/$i.err"
then then
postprocess "$i"
diffAndAccept "$i" err err.exp diffAndAccept "$i" err err.exp
else else
echo "FAIL: $i shouldn't evaluate" echo "FAIL: $i shouldn't evaluate"
@ -109,6 +125,7 @@ for i in lang/eval-okay-*.nix; do
if expect 0 nix-instantiate --eval --xml --no-location --strict \ if expect 0 nix-instantiate --eval --xml --no-location --strict \
"lang/$i.nix" > "lang/$i.out.xml" "lang/$i.nix" > "lang/$i.out.xml"
then then
postprocess "$i"
diffAndAccept "$i" out.xml exp.xml diffAndAccept "$i" out.xml exp.xml
else else
echo "FAIL: $i should evaluate" echo "FAIL: $i should evaluate"
@ -129,6 +146,7 @@ for i in lang/eval-okay-*.nix; do
2> "lang/$i.err" 2> "lang/$i.err"
then then
sed -i "s!$(pwd)!/pwd!g" "lang/$i.out" "lang/$i.err" sed -i "s!$(pwd)!/pwd!g" "lang/$i.out" "lang/$i.err"
postprocess "$i"
diffAndAccept "$i" out exp diffAndAccept "$i" out exp
diffAndAccept "$i" err err.exp diffAndAccept "$i" err err.exp
else else

View File

@ -1,26 +1,26 @@
error: error:
… while evaluating the attribute 'outPath' … while evaluating the attribute 'outPath'
at <nix/derivation-internal.nix>:19:9: at <nix/derivation-internal.nix>:<number>:<number>:
18| value = commonAttrs // { <number>| value = commonAttrs // {
19| outPath = builtins.getAttr outputName strict; <number>| outPath = builtins.getAttr outputName strict;
| ^ | ^
20| drvPath = strict.drvPath; <number>| drvPath = strict.drvPath;
… while calling the 'getAttr' builtin … while calling the 'getAttr' builtin
at <nix/derivation-internal.nix>:19:19: at <nix/derivation-internal.nix>:<number>:<number>:
18| value = commonAttrs // { <number>| value = commonAttrs // {
19| outPath = builtins.getAttr outputName strict; <number>| outPath = builtins.getAttr outputName strict;
| ^ | ^
20| drvPath = strict.drvPath; <number>| drvPath = strict.drvPath;
… while calling the 'derivationStrict' builtin … while calling the 'derivationStrict' builtin
at <nix/derivation-internal.nix>:9:12: at <nix/derivation-internal.nix>:<number>:<number>:
8| <number>|
9| strict = derivationStrict drvAttrs; <number>| strict = derivationStrict drvAttrs;
| ^ | ^
10| <number>|
… while evaluating derivation '~jiggle~' … while evaluating derivation '~jiggle~'
whose name attribute is located at /pwd/lang/eval-fail-derivation-name.nix:2:3 whose name attribute is located at /pwd/lang/eval-fail-derivation-name.nix:<number>:<number>
error: invalid derivation name: name '~jiggle~' contains illegal character '~'. Please pass a different 'name'. error: invalid derivation name: name '~jiggle~' contains illegal character '~'. Please pass a different 'name'.

View File

@ -0,0 +1,9 @@
# shellcheck shell=bash
set -euo pipefail
testcaseBasename=$1
# Line numbers change when derivation.nix docs are updated.
sed -i "$testcaseBasename.err" \
-e 's/[0-9 ][0-9 ][0-9 ][0-9 ][0-9 ][0-9 ][0-9 ][0-9]\([^0-9]\)/<number>\1/g' \
-e 's/[0-9][0-9]*/<number>/g' \
;