Skip to content

Commit

Permalink
nix-shell: Use bashInteractive from <nixpkgs>
Browse files Browse the repository at this point in the history
This adds about 0.1s to nix-shell runtime in the case where
bashInteractive already exists.

See discussion at NixOS/nixpkgs#27493.
  • Loading branch information
edolstra committed Jul 20, 2017
1 parent 57a30e1 commit c94f3d5
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 13 deletions.
7 changes: 3 additions & 4 deletions src/libexpr/get-drvs.cc
Expand Up @@ -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());
}


Expand Down
8 changes: 4 additions & 4 deletions src/libexpr/get-drvs.hh
Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion src/nix-build/local.mk
Expand Up @@ -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))
44 changes: 43 additions & 1 deletion src/nix-build/nix-build.cc
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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
Expand Down Expand Up @@ -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");
}
Expand Down Expand Up @@ -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", "");

This comment has been minimized.

Copy link
@Ericson2314

Ericson2314 Jul 23, 2017

Member

@domenkozar I was thinking, what if we instead looked for like a stdenv.debugShell attribute or similar on the current derivation? That seems slightly more modular to me.

CC @edolstra @DavidEGrayson @ttuegel

This comment has been minimized.

Copy link
@DavidEGrayson

DavidEGrayson Jul 23, 2017

I think you're not addressing what happens with child bash shells inside nix-shell so it's not that interesting. My thoughts are too long to fit here so I posted them here:
NixOS/nixpkgs#27126 (comment)

This comment has been minimized.

Copy link
@Ericson2314

Ericson2314 Jul 23, 2017

Member

For anyone else that sees this; I responded there.


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();

Expand Down
6 changes: 3 additions & 3 deletions src/nix/repl.cc
Expand Up @@ -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;
Expand Down

0 comments on commit c94f3d5

Please sign in to comment.