Merge branch 'balsoft/nix-repl-log' of https://github.com/tweag/nix

This commit is contained in:
Eelco Dolstra 2021-12-07 21:33:32 +01:00
commit 8b5088b62f
8 changed files with 57 additions and 6 deletions

View file

@ -8,3 +8,5 @@
* New built-in function: `builtins.groupBy`, with the same functionality as * New built-in function: `builtins.groupBy`, with the same functionality as
Nixpkgs' `lib.groupBy`, but faster. Nixpkgs' `lib.groupBy`, but faster.
* `nix repl` now has a `:log` command.

View file

@ -427,7 +427,7 @@ RunPager::RunPager()
}); });
pid.setKillSignal(SIGINT); pid.setKillSignal(SIGINT);
stdout = fcntl(STDOUT_FILENO, F_DUPFD_CLOEXEC, 0);
if (dup2(toPager.writeSide.get(), STDOUT_FILENO) == -1) if (dup2(toPager.writeSide.get(), STDOUT_FILENO) == -1)
throw SysError("dupping stdout"); throw SysError("dupping stdout");
} }
@ -438,7 +438,7 @@ RunPager::~RunPager()
try { try {
if (pid != -1) { if (pid != -1) {
std::cout.flush(); std::cout.flush();
close(STDOUT_FILENO); dup2(stdout, STDOUT_FILENO);
pid.wait(); pid.wait();
} }
} catch (...) { } catch (...) {

View file

@ -88,6 +88,7 @@ public:
private: private:
Pid pid; Pid pid;
int stdout;
}; };
extern volatile ::sig_atomic_t blockInt; extern volatile ::sig_atomic_t blockInt;

View file

@ -430,7 +430,8 @@ bool NixRepl::processLine(string line)
<< " :s <expr> Build dependencies of derivation, then start nix-shell\n" << " :s <expr> Build dependencies of derivation, then start nix-shell\n"
<< " :t <expr> Describe result of evaluation\n" << " :t <expr> Describe result of evaluation\n"
<< " :u <expr> Build derivation, then start nix-shell\n" << " :u <expr> Build derivation, then start nix-shell\n"
<< " :doc <expr> Show documentation of a builtin function\n"; << " :doc <expr> Show documentation of a builtin function\n"
<< " :log <expr> Show logs for a derivation\n";
} }
else if (command == ":a" || command == ":add") { else if (command == ":a" || command == ":add") {
@ -500,7 +501,7 @@ bool NixRepl::processLine(string line)
runNix("nix-shell", {state->store->printStorePath(drvPath)}); runNix("nix-shell", {state->store->printStorePath(drvPath)});
} }
else if (command == ":b" || command == ":i" || command == ":s") { else if (command == ":b" || command == ":i" || command == ":s" || command == ":log") {
Value v; Value v;
evalString(arg, v); evalString(arg, v);
StorePath drvPath = getDerivationPath(v); StorePath drvPath = getDerivationPath(v);
@ -514,6 +515,27 @@ bool NixRepl::processLine(string line)
logger->cout(" %s -> %s", outputName, state->store->printStorePath(outputPath)); logger->cout(" %s -> %s", outputName, state->store->printStorePath(outputPath));
} else if (command == ":i") { } else if (command == ":i") {
runNix("nix-env", {"-i", drvPathRaw}); runNix("nix-env", {"-i", drvPathRaw});
} else if (command == ":log") {
settings.readOnlyMode = true;
Finally roModeReset([&]() {
settings.readOnlyMode = false;
});
auto subs = getDefaultSubstituters();
subs.push_front(state->store);
bool foundLog = false;
RunPager pager;
for (auto & sub : subs) {
auto log = sub->getBuildLog(drvPath);
if (log) {
printInfo("got build log for '%s' from '%s'", drvPathRaw, sub->getUri());
logger->writeToStdout(*log);
foundLog = true;
break;
}
}
if (!foundLog) throw Error("build log of '%s' is not available", drvPathRaw);
} else { } else {
runNix("nix-shell", {drvPathRaw}); runNix("nix-shell", {drvPathRaw});
} }

View file

@ -35,14 +35,17 @@ R""(
nix-repl> emacs.drvPath nix-repl> emacs.drvPath
"/nix/store/lp0sjrhgg03y2n0l10n70rg0k7hhyz0l-emacs-27.1.drv" "/nix/store/lp0sjrhgg03y2n0l10n70rg0k7hhyz0l-emacs-27.1.drv"
nix-repl> drv = runCommand "hello" { buildInputs = [ hello ]; } "hello > $out" nix-repl> drv = runCommand "hello" { buildInputs = [ hello ]; } "hello; hello > $out"
nix-repl> :b x nix-repl> :b drv
this derivation produced the following outputs: this derivation produced the following outputs:
out -> /nix/store/0njwbgwmkwls0w5dv9mpc1pq5fj39q0l-hello out -> /nix/store/0njwbgwmkwls0w5dv9mpc1pq5fj39q0l-hello
nix-repl> builtins.readFile drv nix-repl> builtins.readFile drv
"Hello, world!\n" "Hello, world!\n"
nix-repl> :log drv
Hello, world!
``` ```
# Description # Description

View file

@ -3,6 +3,13 @@ source common.sh
replCmds=" replCmds="
simple = import ./simple.nix simple = import ./simple.nix
:b simple :b simple
:log simple
"
replFailingCmds="
failing = import ./simple-failing.nix
:b failing
:log failing
" "
testRepl () { testRepl () {
@ -12,6 +19,12 @@ testRepl () {
local outPath=$(echo "$replOutput" |& local outPath=$(echo "$replOutput" |&
grep -o -E "$NIX_STORE_DIR/\w*-simple") grep -o -E "$NIX_STORE_DIR/\w*-simple")
nix path-info "${nixArgs[@]}" "$outPath" nix path-info "${nixArgs[@]}" "$outPath"
# simple.nix prints a PATH during build
echo "$replOutput" | grep -qs 'PATH=' || fail "nix repl :log doesn't output logs"
local replOutput="$(nix repl "${nixArgs[@]}" <<< "$replFailingCmds")"
echo "$replOutput"
echo "$replOutput" | grep -qs 'This should fail' \
|| fail "nix repl :log doesn't output logs for a failed derivation"
} }
# Simple test, try building a drv # Simple test, try building a drv

View file

@ -0,0 +1,2 @@
echo "This should fail"
exit 1

8
tests/simple-failing.nix Normal file
View file

@ -0,0 +1,8 @@
with import ./config.nix;
mkDerivation {
name = "simple-failing";
builder = ./simple-failing.builder.sh;
PATH = "";
goodPath = path;
}