diff --git a/src/libexpr/primops/context.cc b/src/libexpr/primops/context.cc index 8b3468009bab..8868dbf611e5 100644 --- a/src/libexpr/primops/context.cc +++ b/src/libexpr/primops/context.cc @@ -38,12 +38,6 @@ static RegisterPrimOp primop_hasContext({ }); -/* Sometimes we want to pass a derivation path (i.e. pkg.drvPath) to a - builder without causing the derivation to be built (for instance, - in the derivation that builds NARs in nix-push, when doing - source-only deployment). This primop marks the string context so - that builtins.derivation adds the path to drv.inputSrcs rather than - drv.inputDrvs. */ static void prim_unsafeDiscardOutputDependency(EvalState & state, const PosIdx pos, Value * * args, Value & v) { NixStringContext context; @@ -67,10 +61,51 @@ static void prim_unsafeDiscardOutputDependency(EvalState & state, const PosIdx p static RegisterPrimOp primop_unsafeDiscardOutputDependency({ .name = "__unsafeDiscardOutputDependency", .arity = 1, + .doc = R"( + TODO! Old comment is not good. + + Sometimes we want to pass a derivation path (i.e. `pkg.drvPath`) to a builder without causing the derivation to be built + (for instance, in the derivation that builds NARs in nix-push, when doing source-only deployment). + This primop marks the string context so that `builtins.derivation` adds the path to `drv.inputSrcs` rather than `drv.inputDrvs`. + + Opposite of [`builtins.addDrvOutputDependencies`](#builtins-addDrvOutputDependencies). + )", .fun = prim_unsafeDiscardOutputDependency }); +static void prim_addDrvOutputDependencies(EvalState & state, const PosIdx pos, Value * * args, Value & v) +{ + NixStringContext context; + auto s = state.coerceToString(pos, *args[0], context, "while evaluating the argument passed to builtins.addDrvOutputDependencies"); + + NixStringContext context2; + for (auto && c : context) { + if (auto * ptr = std::get_if(&c)) { + context2.emplace(NixStringContextElem::DrvDeep { + .drvPath = ptr->path + }); + } else { + /* Can reuse original item */ + context2.emplace(std::move(c)); + } + } + + v.mkString(*s, context2); +} + +static RegisterPrimOp primop_addDrvOutputDependencies({ + .name = "__addDrvOutputDependencies", + .arity = 1, + .doc = R"( + TODO! + + Opposite of [`builtins.addDrvOutputDependencies`](#builtins-addDrvOutputDependencies). + )", + .fun = prim_addDrvOutputDependencies +}); + + /* Extract the context of a string as a structured Nix value. The context is represented as an attribute set whose keys are the diff --git a/tests/build.sh b/tests/build.sh index 8ae20f0dff5e..1d70170979e7 100644 --- a/tests/build.sh +++ b/tests/build.sh @@ -66,7 +66,7 @@ nix build -f multiple-outputs.nix --json 'e.a_a.outPath' --no-link | jq --exit-s ' # Illegal type of string context -expectStderr 1 nix build -f multiple-outputs.nix 'e.a_a.drvPath' \ +expectStderr 1 nix build --impure --expr 'builtins.addDrvOutputDependencies (import ./multiple-outputs.nix).e.a_a.drvPath' \ | grepQuiet "has a context which refers to a complete source and binary closure." # No string context @@ -77,7 +77,7 @@ expectStderr 1 nix build --expr '""' --no-link \ expectStderr 1 nix build --impure --expr 'with (import ./multiple-outputs.nix).e.a_a; "${drvPath}${outPath}"' --no-link \ | grepQuiet "has 2 entries in its context. It should only have exactly one entry" -nix build --impure --json --expr 'builtins.unsafeDiscardOutputDependency (import ./multiple-outputs.nix).e.a_a.drvPath' --no-link | jq --exit-status ' +nix build --json -f multiple-outputs.nix e.a_a.drvPath --no-link | jq --exit-status ' (.[0] | .path | match(".*multiple-outputs-e.drv")) ' diff --git a/tests/config.nix.in b/tests/config.nix.in index 7facbdcbc98e..99655552e48f 100644 --- a/tests/config.nix.in +++ b/tests/config.nix.in @@ -16,12 +16,28 @@ rec { shared = builtins.getEnv "_NIX_TEST_SHARED"; - mkDerivation = args: - derivation ({ + mkDerivation = args: let + + drv = derivation ({ inherit system; builder = shell; args = ["-e" args.builder or (builtins.toFile "builder-${args.name}.sh" "if [ -e .attrs.sh ]; then source .attrs.sh; fi; eval \"$buildCommand\"")]; PATH = path; - } // caArgs // removeAttrs args ["builder" "meta"]) - // { meta = args.meta or {}; }; + } // caArgs // removeAttrs args ["builder" "meta"]); + + fixUp = value: value // outputsMap // { + # Not unsafe, and we will add back if we need it. + drvPath = (builtins.unsafeDiscardOutputDependency value.drvPath); + }; + + outputsMap = builtins.listToAttrs (map + (name: { + inherit name; + value = fixUp drv.${name}; + }) + (drv.outputs or [])); + + in fixUp drv // { + meta = args.meta or {}; + }; } diff --git a/tests/dyn-drv/recursive-mod-json.nix b/tests/dyn-drv/recursive-mod-json.nix index c6a24ca4f3bc..3e5a4469ba18 100644 --- a/tests/dyn-drv/recursive-mod-json.nix +++ b/tests/dyn-drv/recursive-mod-json.nix @@ -8,7 +8,7 @@ mkDerivation rec { requiredSystemFeatures = [ "recursive-nix" ]; - drv = builtins.unsafeDiscardOutputDependency (import ./text-hashed-output.nix).hello.drvPath; + drv = (import ./text-hashed-output.nix).hello.drvPath; buildCommand = '' export NIX_CONFIG='experimental-features = nix-command ca-derivations' diff --git a/tests/dyn-drv/text-hashed-output.nix b/tests/dyn-drv/text-hashed-output.nix index a700fd102de0..51fed0de7dd8 100644 --- a/tests/dyn-drv/text-hashed-output.nix +++ b/tests/dyn-drv/text-hashed-output.nix @@ -20,7 +20,7 @@ rec { name = "hello.drv"; buildCommand = '' echo "Copying the derivation" - cp ${builtins.unsafeDiscardOutputDependency hello.drvPath} $out + cp ${hello.drvPath} $out ''; __contentAddressed = true; outputHashMode = "text"; diff --git a/tests/export-graph.nix b/tests/export-graph.nix index fdac9583db2c..b93d8cbb29d7 100644 --- a/tests/export-graph.nix +++ b/tests/export-graph.nix @@ -23,7 +23,7 @@ rec { foo."bar.buildGraph" = mkDerivation { name = "dependencies"; builder = builtins.toFile "build-graph-builder" "${printRefs}"; - exportReferencesGraph = ["refs" (import ./dependencies.nix).drvPath]; + exportReferencesGraph = ["refs" (builtins.addDrvOutputDependencies (import ./dependencies.nix).drvPath) ]; }; } diff --git a/tests/flakes/build-paths.sh b/tests/flakes/build-paths.sh index ff012e1b3bba..0d002a569c38 100644 --- a/tests/flakes/build-paths.sh +++ b/tests/flakes/build-paths.sh @@ -49,9 +49,9 @@ cat > $flake1Dir/flake.nix <