From 75c03142049242a5687309e59e4f356fbc92789a Mon Sep 17 00:00:00 2001 From: Raito Bezarius Date: Fri, 19 Sep 2025 17:56:12 +0200 Subject: [PATCH] nix3/develop: support structured attrs-based output checks nix develop should ignore output checks in general. This was done only for the old way of specifying output checks, the structured attrs way requires rewriting the JSON and removing the output checks pieces. We take a brutal approach of removing as many as possible including non-recommended ways of doing it. Fixes #997. Change-Id: Iaf83029016c71b5171e56e15d4eadc1a60a8be98 Signed-off-by: Raito Bezarius (cherry picked from commit 992c3ae981e75c902f72e8a04b44e902e9501642) --- .../rl-next/nix-develop-output-checks.md | 29 +++++++++++++++++++ lix/nix/develop.cc | 17 +++++++++++ 2 files changed, 46 insertions(+) create mode 100644 doc/manual/rl-next/nix-develop-output-checks.md diff --git a/doc/manual/rl-next/nix-develop-output-checks.md b/doc/manual/rl-next/nix-develop-output-checks.md new file mode 100644 index 000000000..dbb358958 --- /dev/null +++ b/doc/manual/rl-next/nix-develop-output-checks.md @@ -0,0 +1,29 @@ +--- +synopsis: "Fix nix develop for derivations that rejects dependencies with structured attrs" +issues: [fj#997] +cls: [4182, 4214] +category: Fixes +credits: [raito] +--- + +For the sake of concision, we refer to `disallowedReferences` in what follows, +but all output checks were equally fixed: +`{dis,}allowed{References,Requisites}`. + +Derivations can define *output checks* to reject unwanted dependencies, such as +interpreters like `bash` or compilers like `gcc`. This can be done in two ways: + +* **Legacy style**: `disallowedReferences = [ ... ]` in the environment. +* **Structured attrs**: `outputChecks..disallowedReferences = [ ... ]`, + typically used in `__json`. + +Only the structured form supports derivations with multiple outputs. + +`nix develop` internally rewrites derivations to create development shells. It +relied on the legacy `disallowedReferences`, and failed to honor the structured +variant. This led to broken shells in cases where `bashInteractive` was +explicitly disallowed using structured output checks, e.g. `nix develop +nixpkgs#systemd` after the "bash-less NixOS" changes. + +This fix teaches `nix develop` to respect structured output checks, restoring +support for such derivations. diff --git a/lix/nix/develop.cc b/lix/nix/develop.cc index 52a6f5d4f..f6d4f79c6 100644 --- a/lix/nix/develop.cc +++ b/lix/nix/develop.cc @@ -6,6 +6,7 @@ #include "lix/libstore/store-api.hh" #include "lix/libstore/outputs-spec.hh" #include "lix/libstore/derivations.hh" +#include "lix/libstore/parsed-derivations.hh" #include "lix/libutil/async.hh" #include "lix/libutil/json.hh" #include "run.hh" @@ -214,6 +215,8 @@ const static std::string getEnvSh = static kj::Promise> getDerivationEnvironment(ref store, ref evalStore, const StorePath & drvPath) try { auto drv = TRY_AWAIT(evalStore->derivationFromPath(drvPath)); + ParsedDerivation parsedDrv(drvPath, drv); + JSON updatedStructuredAttrs; auto builder = baseNameOf(drv.builder); if (builder != "bash") @@ -230,6 +233,20 @@ try { drv.env.erase("disallowedRequisites"); drv.env.erase("name"); + /* Remove output checks in structured attrs. */ + if (auto structuredAttrs = parsedDrv.getStructuredAttrs()) { + drv.env.erase("__json"); + updatedStructuredAttrs = *structuredAttrs; + updatedStructuredAttrs.erase("allowedReferences"); + updatedStructuredAttrs.erase("allowedRequisites"); + updatedStructuredAttrs.erase("disallowedReferences"); + updatedStructuredAttrs.erase("disallowedRequisites"); + updatedStructuredAttrs.erase("maxSize"); + updatedStructuredAttrs.erase("maxClosureSize"); + updatedStructuredAttrs.erase("outputChecks"); + drv.env.emplace("__json", updatedStructuredAttrs.dump()); + } + /* Rehash and write the derivation. FIXME: would be nice to use 'buildDerivation', but that's privileged. */ drv.name += "-env";