From 8fbc8540d3ea540d985b577166a1168d472c2d70 Mon Sep 17 00:00:00 2001 From: Matthew Kenigsberg Date: Mon, 27 Apr 2020 12:17:58 -0600 Subject: [PATCH 1/5] use nixpkgs#bashInteractive for dev-shell --- src/nix/dev-shell.cc | 41 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/src/nix/dev-shell.cc b/src/nix/dev-shell.cc index 6b1cf0ffd..d842be79f 100644 --- a/src/nix/dev-shell.cc +++ b/src/nix/dev-shell.cc @@ -6,6 +6,9 @@ #include "derivations.hh" #include "affinity.hh" #include "progress-bar.hh" +#include "attr-path.hh" +#include "eval-cache.hh" +#include "flake/flake.hh" #include @@ -281,6 +284,41 @@ struct CmdDevShell : Common, MixEnvironment }; } + std::string getBashPath(ref store) + { + auto flakeRef = FlakeRef::fromAttrs({{"type","indirect"}, {"id", "nixpkgs"}}); + auto state = getEvalState(); + auto lockedFlake = std::make_shared(lockFlake(*state, flakeRef, lockFlags)); + auto cache = openEvalCache(*state, lockedFlake, true); + auto root = cache->getRoot(); + + auto attrPath = "legacyPackages." + settings.thisSystem.get() + ".bashInteractive"; + auto attr = root->findAlongAttrPath(parseAttrPath(*state, attrPath)); + if (!attr || !attr->isDerivation()) throw Error("couldn't find bashInteractive derivation"); + + auto aDrvPath = attr->getAttr(state->sDrvPath); + auto drvPath = store->parseStorePath(aDrvPath->getString()); + if (!store->isValidPath(drvPath) && !settings.readOnlyMode) { + /* The eval cache contains 'drvPath', but the actual path + has been garbage-collected. So force it to be + regenerated. */ + aDrvPath->forceValue(); + if (!store->isValidPath(drvPath)) + throw Error("don't know how to recreate store derivation '%s'!", + store->printStorePath(drvPath)); + } + + auto outputName = attr->getAttr(state->sOutputName)->getString(); + if (outputName == "") + throw Error("derivation '%s' lacks an 'outputName' attribute", store->printStorePath(drvPath)); + + auto outPath = store->parseStorePath(attr->getAttr(state->sOutPath)->getString()); + + store->buildPaths({{drvPath, {outputName}}}); + + return store->printStorePath(outPath) + "/bin/bash"; + } + void run(ref store) override { auto [buildEnvironment, gcroot] = getBuildEnvironment(store); @@ -303,12 +341,11 @@ struct CmdDevShell : Common, MixEnvironment stopProgressBar(); - auto shell = getEnv("SHELL").value_or("bash"); - setEnviron(); // prevent garbage collection until shell exits setenv("NIX_GCROOT", gcroot.data(), 1); + auto shell = getBashPath(store); auto args = Strings{std::string(baseNameOf(shell)), "--rcfile", rcFilePath}; restoreAffinity(); From 04821bc1718aff975b51e98ce7bfb91888167c6d Mon Sep 17 00:00:00 2001 From: Matthew Kenigsberg Date: Tue, 5 May 2020 10:49:39 -0600 Subject: [PATCH 2/5] use flake's nixpkgs to find bashInteractive --- src/nix/dev-shell.cc | 3 +-- src/nix/installables.cc | 12 ++++++++++++ src/nix/installables.hh | 7 +++++++ 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/nix/dev-shell.cc b/src/nix/dev-shell.cc index d842be79f..b3314021f 100644 --- a/src/nix/dev-shell.cc +++ b/src/nix/dev-shell.cc @@ -286,9 +286,8 @@ struct CmdDevShell : Common, MixEnvironment std::string getBashPath(ref store) { - auto flakeRef = FlakeRef::fromAttrs({{"type","indirect"}, {"id", "nixpkgs"}}); auto state = getEvalState(); - auto lockedFlake = std::make_shared(lockFlake(*state, flakeRef, lockFlags)); + auto lockedFlake = std::make_shared(lockFlake(*state, installable->nixpkgsFlakeRef(), lockFlags)); auto cache = openEvalCache(*state, lockedFlake, true); auto root = cache->getRoot(); diff --git a/src/nix/installables.cc b/src/nix/installables.cc index cae85b34e..4e38876ca 100644 --- a/src/nix/installables.cc +++ b/src/nix/installables.cc @@ -493,6 +493,18 @@ InstallableFlake::getCursor(EvalState & state, bool useEvalCache) return res; } +FlakeRef InstallableFlake::nixpkgsFlakeRef() const +{ + auto lockedFlake = lockFlake(*(cmd.getEvalState()), flakeRef, cmd.lockFlags); + + auto nixpkgsInput = lockedFlake.flake.inputs.find("nixpkgs"); + if (nixpkgsInput != lockedFlake.flake.inputs.end()) { + return std::move(nixpkgsInput->second.ref); + } + + return Installable::nixpkgsFlakeRef(); +} + std::vector> SourceExprCommand::parseInstallables( ref store, std::vector ss) { diff --git a/src/nix/installables.hh b/src/nix/installables.hh index 531720de6..57e3d6c8e 100644 --- a/src/nix/installables.hh +++ b/src/nix/installables.hh @@ -57,6 +57,11 @@ struct Installable virtual std::vector, std::string>> getCursor(EvalState & state, bool useEvalCache); + + virtual FlakeRef nixpkgsFlakeRef() const + { + return std::move(FlakeRef::fromAttrs({{"type","indirect"}, {"id", "nixpkgs"}})); + } }; struct InstallableValue : Installable @@ -104,6 +109,8 @@ struct InstallableFlake : InstallableValue std::vector, std::string>> getCursor(EvalState & state, bool useEvalCache) override; + + FlakeRef nixpkgsFlakeRef() const override; }; ref openEvalCache( From 085879360415a2c667c6d75dce5765f01afbb25d Mon Sep 17 00:00:00 2001 From: Matthew Kenigsberg Date: Tue, 12 May 2020 23:45:45 -0600 Subject: [PATCH 3/5] Call lockFlake once and store in _lockedFlake --- src/nix/installables.cc | 20 +++++++++++++------- src/nix/installables.hh | 3 +++ 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/nix/installables.cc b/src/nix/installables.cc index 4e38876ca..21fd54f64 100644 --- a/src/nix/installables.cc +++ b/src/nix/installables.cc @@ -408,8 +408,7 @@ ref openEvalCache( std::tuple InstallableFlake::toDerivation() { - auto lockedFlake = std::make_shared( - lockFlake(*state, flakeRef, lockFlags)); + auto lockedFlake = getLockedFlake(); auto cache = openEvalCache(*state, lockedFlake, true); auto root = cache->getRoot(); @@ -455,9 +454,9 @@ std::vector InstallableFlake::toDerivations() std::pair InstallableFlake::toValue(EvalState & state) { - auto lockedFlake = lockFlake(state, flakeRef, lockFlags); + auto lockedFlake = getLockedFlake(); - auto vOutputs = getFlakeOutputs(state, lockedFlake); + auto vOutputs = getFlakeOutputs(state, *lockedFlake); auto emptyArgs = state.allocBindings(0); @@ -493,12 +492,19 @@ InstallableFlake::getCursor(EvalState & state, bool useEvalCache) return res; } +std::shared_ptr InstallableFlake::getLockedFlake() const +{ + if (!_lockedFlake) + _lockedFlake = std::make_shared(lockFlake(*state, flakeRef, lockFlags)); + return _lockedFlake; +} + FlakeRef InstallableFlake::nixpkgsFlakeRef() const { - auto lockedFlake = lockFlake(*(cmd.getEvalState()), flakeRef, cmd.lockFlags); + auto lockedFlake = getLockedFlake(); - auto nixpkgsInput = lockedFlake.flake.inputs.find("nixpkgs"); - if (nixpkgsInput != lockedFlake.flake.inputs.end()) { + auto nixpkgsInput = lockedFlake->flake.inputs.find("nixpkgs"); + if (nixpkgsInput != lockedFlake->flake.inputs.end()) { return std::move(nixpkgsInput->second.ref); } diff --git a/src/nix/installables.hh b/src/nix/installables.hh index 57e3d6c8e..a2db71389 100644 --- a/src/nix/installables.hh +++ b/src/nix/installables.hh @@ -88,6 +88,7 @@ struct InstallableFlake : InstallableValue Strings attrPaths; Strings prefixes; const flake::LockFlags & lockFlags; + mutable std::shared_ptr _lockedFlake; InstallableFlake(ref state, FlakeRef && flakeRef, Strings && attrPaths, Strings && prefixes, const flake::LockFlags & lockFlags) @@ -110,6 +111,8 @@ struct InstallableFlake : InstallableValue std::vector, std::string>> getCursor(EvalState & state, bool useEvalCache) override; + std::shared_ptr getLockedFlake() const; + FlakeRef nixpkgsFlakeRef() const override; }; From ba7d7ed2e34b57ed15fc7473622ecfac2df77434 Mon Sep 17 00:00:00 2001 From: Matthew Kenigsberg Date: Thu, 14 May 2020 16:43:06 -0600 Subject: [PATCH 4/5] Create bashInteractive InstallableFlake --- src/nix/dev-shell.cc | 38 +++----------------------------------- 1 file changed, 3 insertions(+), 35 deletions(-) diff --git a/src/nix/dev-shell.cc b/src/nix/dev-shell.cc index b3314021f..9f84992b4 100644 --- a/src/nix/dev-shell.cc +++ b/src/nix/dev-shell.cc @@ -284,40 +284,6 @@ struct CmdDevShell : Common, MixEnvironment }; } - std::string getBashPath(ref store) - { - auto state = getEvalState(); - auto lockedFlake = std::make_shared(lockFlake(*state, installable->nixpkgsFlakeRef(), lockFlags)); - auto cache = openEvalCache(*state, lockedFlake, true); - auto root = cache->getRoot(); - - auto attrPath = "legacyPackages." + settings.thisSystem.get() + ".bashInteractive"; - auto attr = root->findAlongAttrPath(parseAttrPath(*state, attrPath)); - if (!attr || !attr->isDerivation()) throw Error("couldn't find bashInteractive derivation"); - - auto aDrvPath = attr->getAttr(state->sDrvPath); - auto drvPath = store->parseStorePath(aDrvPath->getString()); - if (!store->isValidPath(drvPath) && !settings.readOnlyMode) { - /* The eval cache contains 'drvPath', but the actual path - has been garbage-collected. So force it to be - regenerated. */ - aDrvPath->forceValue(); - if (!store->isValidPath(drvPath)) - throw Error("don't know how to recreate store derivation '%s'!", - store->printStorePath(drvPath)); - } - - auto outputName = attr->getAttr(state->sOutputName)->getString(); - if (outputName == "") - throw Error("derivation '%s' lacks an 'outputName' attribute", store->printStorePath(drvPath)); - - auto outPath = store->parseStorePath(attr->getAttr(state->sOutPath)->getString()); - - store->buildPaths({{drvPath, {outputName}}}); - - return store->printStorePath(outPath) + "/bin/bash"; - } - void run(ref store) override { auto [buildEnvironment, gcroot] = getBuildEnvironment(store); @@ -344,7 +310,9 @@ struct CmdDevShell : Common, MixEnvironment // prevent garbage collection until shell exits setenv("NIX_GCROOT", gcroot.data(), 1); - auto shell = getBashPath(store); + auto state = getEvalState(); + auto bashInstallable = std::make_shared(state, std::move(installable->nixpkgsFlakeRef()), Strings{"bashInteractive"}, Strings{"legacyPackages." + settings.thisSystem.get() + "."}, lockFlags); + auto shell = state->store->printStorePath(toStorePath(state->store, Build, bashInstallable)) + "/bin/bash"; auto args = Strings{std::string(baseNameOf(shell)), "--rcfile", rcFilePath}; restoreAffinity(); From c4beded32e2909651c95f6fabf5c78537bd37e68 Mon Sep 17 00:00:00 2001 From: Matthew Kenigsberg Date: Sat, 16 May 2020 11:19:41 -0600 Subject: [PATCH 5/5] rm includes --- src/nix/dev-shell.cc | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/nix/dev-shell.cc b/src/nix/dev-shell.cc index 9f84992b4..53d2e4e25 100644 --- a/src/nix/dev-shell.cc +++ b/src/nix/dev-shell.cc @@ -6,9 +6,6 @@ #include "derivations.hh" #include "affinity.hh" #include "progress-bar.hh" -#include "attr-path.hh" -#include "eval-cache.hh" -#include "flake/flake.hh" #include