nix-shell: Use bashInteractive from <nixpkgs>
This adds about 0.1s to nix-shell runtime in the case where bashInteractive already exists. See discussion at https://github.com/NixOS/nixpkgs/issues/27493.
This commit is contained in:
parent
57a30e101b
commit
c94f3d5575
5 changed files with 54 additions and 13 deletions
|
@ -267,15 +267,14 @@ static bool getDerivation(EvalState & state, Value & v,
|
|||
}
|
||||
|
||||
|
||||
bool getDerivation(EvalState & state, Value & v, DrvInfo & drv,
|
||||
std::experimental::optional<DrvInfo> getDerivation(EvalState & state, Value & v,
|
||||
bool ignoreAssertionFailures)
|
||||
{
|
||||
Done done;
|
||||
DrvInfos drvs;
|
||||
getDerivation(state, v, "", drvs, done, ignoreAssertionFailures);
|
||||
if (drvs.size() != 1) return false;
|
||||
drv = drvs.front();
|
||||
return true;
|
||||
if (drvs.size() != 1) return {};
|
||||
return std::move(drvs.front());
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -75,10 +75,10 @@ typedef list<DrvInfo> DrvInfos;
|
|||
#endif
|
||||
|
||||
|
||||
/* If value `v' denotes a derivation, store information about the
|
||||
derivation in `drv' and return true. Otherwise, return false. */
|
||||
bool getDerivation(EvalState & state, Value & v, DrvInfo & drv,
|
||||
bool ignoreAssertionFailures);
|
||||
/* If value `v' denotes a derivation, return a DrvInfo object
|
||||
describing it. Otherwise return nothing. */
|
||||
std::experimental::optional<DrvInfo> getDerivation(EvalState & state,
|
||||
Value & v, bool ignoreAssertionFailures);
|
||||
|
||||
void getDerivations(EvalState & state, Value & v, const string & pathPrefix,
|
||||
Bindings & autoArgs, DrvInfos & drvs,
|
||||
|
|
|
@ -4,6 +4,6 @@ nix-build_DIR := $(d)
|
|||
|
||||
nix-build_SOURCES := $(d)/nix-build.cc
|
||||
|
||||
nix-build_LIBS = libmain libstore libutil libformat
|
||||
nix-build_LIBS = libmain libexpr libstore libutil libformat
|
||||
|
||||
$(eval $(call install-symlink, nix-build, $(bindir)/nix-shell))
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
#include "affinity.hh"
|
||||
#include "util.hh"
|
||||
#include "shared.hh"
|
||||
#include "eval.hh"
|
||||
#include "get-drvs.hh"
|
||||
|
||||
using namespace nix;
|
||||
using namespace std::string_literals;
|
||||
|
@ -75,6 +77,8 @@ int main(int argc, char ** argv)
|
|||
{
|
||||
return handleExceptions(argv[0], [&]() {
|
||||
initNix();
|
||||
initGC();
|
||||
|
||||
auto store = openStore();
|
||||
auto dryRun = false;
|
||||
auto verbose = false;
|
||||
|
@ -88,6 +92,7 @@ int main(int argc, char ** argv)
|
|||
Strings instArgs;
|
||||
Strings buildArgs;
|
||||
Strings exprs;
|
||||
Strings searchPath;
|
||||
|
||||
auto shell = getEnv("SHELL", "/bin/sh");
|
||||
std::string envCommand; // interactive shell
|
||||
|
@ -320,6 +325,8 @@ int main(int argc, char ** argv)
|
|||
}
|
||||
}
|
||||
|
||||
EvalState state(searchPath, store);
|
||||
|
||||
if (packages && fromArgs) {
|
||||
throw UsageError("‘-p’ and ‘-E’ are mutually exclusive");
|
||||
}
|
||||
|
@ -465,7 +472,42 @@ int main(int argc, char ** argv)
|
|||
|
||||
auto envPtrs = stringsToCharPtrs(envStrs);
|
||||
|
||||
auto shell = getEnv("NIX_BUILD_SHELL", "bash");
|
||||
auto shell = getEnv("NIX_BUILD_SHELL", "");
|
||||
|
||||
if (shell == "") {
|
||||
|
||||
try {
|
||||
|
||||
auto expr = state.parseExprFromString("(import <nixpkgs> {}).bashInteractive", absPath("."));
|
||||
|
||||
Value v;
|
||||
state.eval(expr, v);
|
||||
|
||||
auto drv = getDerivation(state, v, false);
|
||||
if (!drv)
|
||||
throw Error("the ‘bashInteractive’ attribute in <nixpkgs> did not evaluate to a derivation");
|
||||
|
||||
auto drvPath = drv->queryDrvPath();
|
||||
|
||||
unsigned long long downloadSize, narSize;
|
||||
PathSet willBuild, willSubstitute, unknown;
|
||||
store->queryMissing({drvPath},
|
||||
willBuild, willSubstitute, unknown, downloadSize, narSize);
|
||||
|
||||
if (settings.printMissing)
|
||||
printMissing(ref<Store>(store), willBuild, willSubstitute, unknown, downloadSize, narSize);
|
||||
|
||||
store->buildPaths({drvPath});
|
||||
|
||||
shell = drv->queryOutPath() + "/bin/bash";
|
||||
if (!pathExists(shell))
|
||||
throw Error("expected shell ‘%s’ to exist, but it doesn't", shell);
|
||||
|
||||
} catch (Error & e) {
|
||||
printError("warning: %s; will use bash from your environment", e.what());
|
||||
shell = "bash";
|
||||
}
|
||||
}
|
||||
|
||||
environ = envPtrs.data();
|
||||
|
||||
|
|
|
@ -292,10 +292,10 @@ bool isVarName(const string & s)
|
|||
|
||||
|
||||
Path NixRepl::getDerivationPath(Value & v) {
|
||||
DrvInfo drvInfo(state);
|
||||
if (!getDerivation(state, v, drvInfo, false))
|
||||
auto drvInfo = getDerivation(state, v, false);
|
||||
if (!drvInfo)
|
||||
throw Error("expression does not evaluate to a derivation, so I can't build it");
|
||||
Path drvPath = drvInfo.queryDrvPath();
|
||||
Path drvPath = drvInfo->queryDrvPath();
|
||||
if (drvPath == "" || !state.store->isValidPath(drvPath))
|
||||
throw Error("expression did not evaluate to a valid derivation");
|
||||
return drvPath;
|
||||
|
|
Loading…
Reference in a new issue