From 74698d54c82fa302dc0c82f68c796eda673090d9 Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Wed, 10 Jul 2024 13:34:42 +0200 Subject: [PATCH 1/3] Document builtins.derivation --- src/libexpr/primops/derivation.nix | 29 +++++++++++++++++-- .../lang/eval-fail-derivation-name.err.exp | 24 +++++++-------- 2 files changed, 39 insertions(+), 14 deletions(-) diff --git a/src/libexpr/primops/derivation.nix b/src/libexpr/primops/derivation.nix index c0fbe8082..f329ff71e 100644 --- a/src/libexpr/primops/derivation.nix +++ b/src/libexpr/primops/derivation.nix @@ -1,6 +1,31 @@ -/* This is the implementation of the ‘derivation’ builtin function. - It's actually a wrapper around the ‘derivationStrict’ primop. */ +# This is the implementation of the ‘derivation’ builtin function. +# 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" ], ... }: let diff --git a/tests/functional/lang/eval-fail-derivation-name.err.exp b/tests/functional/lang/eval-fail-derivation-name.err.exp index eb2206df1..ae7b47712 100644 --- a/tests/functional/lang/eval-fail-derivation-name.err.exp +++ b/tests/functional/lang/eval-fail-derivation-name.err.exp @@ -1,24 +1,24 @@ error: … while evaluating the attribute 'outPath' - at :19:9: - 18| value = commonAttrs // { - 19| outPath = builtins.getAttr outputName strict; + at :44:9: + 43| value = commonAttrs // { + 44| outPath = builtins.getAttr outputName strict; | ^ - 20| drvPath = strict.drvPath; + 45| drvPath = strict.drvPath; … while calling the 'getAttr' builtin - at :19:19: - 18| value = commonAttrs // { - 19| outPath = builtins.getAttr outputName strict; + at :44:19: + 43| value = commonAttrs // { + 44| outPath = builtins.getAttr outputName strict; | ^ - 20| drvPath = strict.drvPath; + 45| drvPath = strict.drvPath; … while calling the 'derivationStrict' builtin - at :9:12: - 8| - 9| strict = derivationStrict drvAttrs; + at :34:12: + 33| + 34| strict = derivationStrict drvAttrs; | ^ - 10| + 35| … while evaluating derivation '~jiggle~' whose name attribute is located at /pwd/lang/eval-fail-derivation-name.nix:2:3 From f9a1d6b0188a2d0e9ad84f1e735e560320380501 Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Tue, 16 Jul 2024 17:36:30 +0200 Subject: [PATCH 2/3] tests/functional/lang: Add post processing and remove certain line numbers --- tests/functional/lang.sh | 15 +++++++++++ .../lang/eval-fail-derivation-name.err.exp | 26 +++++++++---------- .../eval-fail-derivation-name.postprocess | 9 +++++++ 3 files changed, 37 insertions(+), 13 deletions(-) create mode 100755 tests/functional/lang/eval-fail-derivation-name.postprocess diff --git a/tests/functional/lang.sh b/tests/functional/lang.sh index 8cb8e98fb..5a8cefd13 100755 --- a/tests/functional/lang.sh +++ b/tests/functional/lang.sh @@ -50,11 +50,22 @@ set +x badDiff=0 badExitCode=0 +# Extra post-processing that's specific to each test case +postprocess() { + if [[ -e "lang/$1.postprocess" ]]; then + ( + set -x; + "lang/$1.postprocess" "lang/$1" + ) + fi +} + for i in lang/parse-fail-*.nix; do echo "parsing $i (should fail)"; i=$(basename "$i" .nix) if expectStderr 1 nix-instantiate --parse - < "lang/$i.nix" > "lang/$i.err" then + postprocess "$i" diffAndAccept "$i" err err.exp else echo "FAIL: $i shouldn't parse" @@ -71,6 +82,7 @@ for i in lang/parse-okay-*.nix; do 2> "lang/$i.err" then sed "s!$(pwd)!/pwd!g" "lang/$i.out" "lang/$i.err" + postprocess "$i" diffAndAccept "$i" out exp diffAndAccept "$i" err err.exp else @@ -94,6 +106,7 @@ for i in lang/eval-fail-*.nix; do expectStderr 1 nix-instantiate $flags "lang/$i.nix" \ | sed "s!$(pwd)!/pwd!g" > "lang/$i.err" then + postprocess "$i" diffAndAccept "$i" err err.exp else echo "FAIL: $i shouldn't evaluate" @@ -109,6 +122,7 @@ for i in lang/eval-okay-*.nix; do if expect 0 nix-instantiate --eval --xml --no-location --strict \ "lang/$i.nix" > "lang/$i.out.xml" then + postprocess "$i" diffAndAccept "$i" out.xml exp.xml else echo "FAIL: $i should evaluate" @@ -129,6 +143,7 @@ for i in lang/eval-okay-*.nix; do 2> "lang/$i.err" then sed -i "s!$(pwd)!/pwd!g" "lang/$i.out" "lang/$i.err" + postprocess "$i" diffAndAccept "$i" out exp diffAndAccept "$i" err err.exp else diff --git a/tests/functional/lang/eval-fail-derivation-name.err.exp b/tests/functional/lang/eval-fail-derivation-name.err.exp index ae7b47712..0ef98674d 100644 --- a/tests/functional/lang/eval-fail-derivation-name.err.exp +++ b/tests/functional/lang/eval-fail-derivation-name.err.exp @@ -1,26 +1,26 @@ error: … while evaluating the attribute 'outPath' - at :44:9: - 43| value = commonAttrs // { - 44| outPath = builtins.getAttr outputName strict; + at ::: + | value = commonAttrs // { + | outPath = builtins.getAttr outputName strict; | ^ - 45| drvPath = strict.drvPath; + | drvPath = strict.drvPath; … while calling the 'getAttr' builtin - at :44:19: - 43| value = commonAttrs // { - 44| outPath = builtins.getAttr outputName strict; + at ::: + | value = commonAttrs // { + | outPath = builtins.getAttr outputName strict; | ^ - 45| drvPath = strict.drvPath; + | drvPath = strict.drvPath; … while calling the 'derivationStrict' builtin - at :34:12: - 33| - 34| strict = derivationStrict drvAttrs; + at ::: + | + | strict = derivationStrict drvAttrs; | ^ - 35| + | … 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:: error: invalid derivation name: name '~jiggle~' contains illegal character '~'. Please pass a different 'name'. diff --git a/tests/functional/lang/eval-fail-derivation-name.postprocess b/tests/functional/lang/eval-fail-derivation-name.postprocess new file mode 100755 index 000000000..ab9fa5b5d --- /dev/null +++ b/tests/functional/lang/eval-fail-derivation-name.postprocess @@ -0,0 +1,9 @@ +#!/usr/bin/env 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]\)/\1/g' \ + -e 's/[0-9][0-9]*//g' \ + ; From 7dce07463429bb4a42a3b47a869f5eb488206c26 Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Tue, 16 Jul 2024 22:43:04 +0200 Subject: [PATCH 3/3] tests/functional/lang: Avoid /usr/bin/env for sandbox --- tests/functional/lang.sh | 5 ++++- tests/functional/lang/eval-fail-derivation-name.postprocess | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) mode change 100755 => 100644 tests/functional/lang/eval-fail-derivation-name.postprocess diff --git a/tests/functional/lang.sh b/tests/functional/lang.sh index 5a8cefd13..46cf3f1fe 100755 --- a/tests/functional/lang.sh +++ b/tests/functional/lang.sh @@ -54,8 +54,11 @@ badExitCode=0 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; - "lang/$1.postprocess" "lang/$1" + bash "lang/$1.postprocess" "lang/$1" ) fi } diff --git a/tests/functional/lang/eval-fail-derivation-name.postprocess b/tests/functional/lang/eval-fail-derivation-name.postprocess old mode 100755 new mode 100644 index ab9fa5b5d..ffbc2b5d4 --- a/tests/functional/lang/eval-fail-derivation-name.postprocess +++ b/tests/functional/lang/eval-fail-derivation-name.postprocess @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +# shellcheck shell=bash set -euo pipefail testcaseBasename=$1