diff --git a/src/nix/dev-shell.cc b/src/nix/dev-shell.cc index 6b1cf0ffd..53d2e4e25 100644 --- a/src/nix/dev-shell.cc +++ b/src/nix/dev-shell.cc @@ -303,12 +303,13 @@ 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 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(); diff --git a/src/nix/installables.cc b/src/nix/installables.cc index cae85b34e..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,6 +492,25 @@ 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 = getLockedFlake(); + + 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..a2db71389 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 @@ -83,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) @@ -104,6 +110,10 @@ struct InstallableFlake : InstallableValue std::vector, std::string>> getCursor(EvalState & state, bool useEvalCache) override; + + std::shared_ptr getLockedFlake() const; + + FlakeRef nixpkgsFlakeRef() const override; }; ref openEvalCache(