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 <raito@lix.systems>
(cherry picked from commit 992c3ae981)
This commit is contained in:
@@ -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.<output>.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.
|
||||
@@ -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<Result<StorePath>> getDerivationEnvironment(ref<Store> store, ref<Store> 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";
|
||||
|
||||
Reference in New Issue
Block a user