diff --git a/src/libstore/derived-path.cc b/src/libstore/derived-path.cc index 11a3f5e23..f6a0c01df 100644 --- a/src/libstore/derived-path.cc +++ b/src/libstore/derived-path.cc @@ -97,8 +97,12 @@ DerivedPath::Built DerivedPath::Built::parse(const Store & store, std::string_vi { auto drvPath = store.parseStorePath(drvS); std::set outputs; - if (outputsS != "*") + if (outputsS != "*") { outputs = tokenizeString>(outputsS, ","); + if (outputs.empty()) + throw Error( + "Explicit list of wanted outputs '%s' must not be empty. Consider using '*' as a wildcard meaning all outputs if no output in particular is wanted.", outputsS); + } return {drvPath, outputs}; } diff --git a/src/nix/nix.md b/src/nix/nix.md index 32112d38d..5d669e8b1 100644 --- a/src/nix/nix.md +++ b/src/nix/nix.md @@ -134,8 +134,9 @@ the Nix store. Here are the recognised types of installables: *(Experimental, part of by the `computed-derivations` experimental feature.)* - Store derivations can be indexed with a specific output name. This - allows finer control versus just specifying a derivation (without + Store derivations can be indexed with a non-empty comma-separated list + of specific output names, or `*` meaning all ouptuts. This allows + finer control versus just specifying a derivation (without `--derivation`) and getting all the outputs. This is especially useful for (currently unstable) floating content diff --git a/tests/build-explicit-output.sh b/tests/build-explicit-output.sh index 68fd2f128..a4cb1c5ad 100644 --- a/tests/build-explicit-output.sh +++ b/tests/build-explicit-output.sh @@ -1,14 +1,24 @@ source common.sh +set -o pipefail + enableFeatures "computed-derivations" restartDaemon drv=$(nix eval -f multiple-outputs.nix --raw a.drvPath) -if nix build "$drv^not-an-output" --json; then +if nix build "$drv^not-an-output" --no-link --json; then fail "'not-an-output' should fail to build" fi -nix build "$drv^first" --json | jq --exit-status ' +if nix build "$drv^" --no-link --json; then + fail "'empty outputs list' should fail to build" +fi + +if nix build "$drv^*nope" --no-link --json; then + fail "'* must be entire string' should fail to build" +fi + +nix build "$drv^first" --no-link --json | jq --exit-status ' (.[0] | (.drvPath | match(".*multiple-outputs-a.drv")) and (.outputs | @@ -16,3 +26,21 @@ nix build "$drv^first" --json | jq --exit-status ' (.first | match(".*multiple-outputs-a-first")) and (has("second") | not))) ' + +nix build "$drv^first,second" --no-link --json | jq --exit-status ' + (.[0] | + (.drvPath | match(".*multiple-outputs-a.drv")) and + (.outputs | + (keys | length == 2) and + (.first | match(".*multiple-outputs-a-first")) and + (.second | match(".*multiple-outputs-a-second")))) +' + +nix build "$drv^*" --no-link --json | jq --exit-status ' + (.[0] | + (.drvPath | match(".*multiple-outputs-a.drv")) and + (.outputs | + (keys | length == 2) and + (.first | match(".*multiple-outputs-a-first")) and + (.second | match(".*multiple-outputs-a-second")))) +'