diff --git a/doc/manual/release-notes.xml b/doc/manual/release-notes.xml
index 28ce94661..2f2b1a040 100644
--- a/doc/manual/release-notes.xml
+++ b/doc/manual/release-notes.xml
@@ -5,6 +5,23 @@
+
+
+Release 0.11 (TBA)
+
+
+
+ nix-store has a new operation
+ ()
+ paths that shows the build log of the given
+ paths.
+
+
+
+
+
+
+
Release 0.10.1 (October 11, 2006)
diff --git a/src/libstore/build.cc b/src/libstore/build.cc
index 2388d008f..43ac5cf53 100644
--- a/src/libstore/build.cc
+++ b/src/libstore/build.cc
@@ -1511,7 +1511,7 @@ void DerivationGoal::computeClosure()
}
-static string drvsLogDir = "drvs";
+string drvsLogDir = "drvs";
void DerivationGoal::openLogFile()
diff --git a/src/libstore/build.hh b/src/libstore/build.hh
index c90c12676..71895c0a9 100644
--- a/src/libstore/build.hh
+++ b/src/libstore/build.hh
@@ -8,6 +8,9 @@
namespace nix {
+extern string drvsLogDir;
+
+
/* Ensure that the output paths of the derivation are valid. If they
are already valid, this is a no-op. Otherwise, validity can
be reached in two ways. First, if the output paths have
diff --git a/src/nix-store/help.txt b/src/nix-store/help.txt
index 388a7521f..df84a2a76 100644
--- a/src/nix-store/help.txt
+++ b/src/nix-store/help.txt
@@ -9,6 +9,7 @@ Operations:
--add / -A: copy a path to the Nix store
--delete: safely delete paths from the Nix store
--query / -q: query information
+ --read-log / -l: print build log of given store paths
--register-substitutes: register a substitute expression (dangerous!)
--clear-substitutes: clear all substitutes
diff --git a/src/nix-store/main.cc b/src/nix-store/main.cc
index b83eb8837..ec35d430d 100644
--- a/src/nix-store/main.cc
+++ b/src/nix-store/main.cc
@@ -46,6 +46,17 @@ static Path fixPath(Path path)
}
+static Path useDeriver(Path path)
+{
+ if (!isDerivation(path)) {
+ path = queryDeriver(noTxn, path);
+ if (path == "")
+ throw Error(format("deriver of path `%1%' is not known") % path);
+ }
+ return path;
+}
+
+
/* Realisation the given path. For a derivation that means build it;
for other paths it means ensure their validity. */
static Path realisePath(const Path & path)
@@ -360,12 +371,12 @@ static void opQuery(Strings opFlags, Strings opArgs)
for (Strings::iterator i = opArgs.begin();
i != opArgs.end(); ++i)
{
- *i = fixPath(*i);
- Derivation drv = derivationFromPath(*i);
+ Path path = useDeriver(fixPath(*i));
+ Derivation drv = derivationFromPath(path);
StringPairs::iterator j = drv.env.find(bindingName);
if (j == drv.env.end())
throw Error(format("derivation `%1%' has no environment binding named `%2%'")
- % *i % bindingName);
+ % path % bindingName);
cout << format("%1%\n") % j->second;
}
break;
@@ -404,6 +415,28 @@ static void opQuery(Strings opFlags, Strings opArgs)
}
+static void opReadLog(Strings opFlags, Strings opArgs)
+{
+ if (!opFlags.empty()) throw UsageError("unknown flag");
+
+ for (Strings::iterator i = opArgs.begin();
+ i != opArgs.end(); ++i)
+ {
+ Path path = useDeriver(fixPath(*i));
+
+ Path logPath = (format("%1%/%2%/%3%") %
+ nixLogDir % drvsLogDir % baseNameOf(path)).str();
+
+ if (!pathExists(logPath))
+ throw Error(format("build log of derivation `%1%' is not available") % path);
+
+ /* !!! Make this run in O(1) memory. */
+ string log = readFile(logPath);
+ writeFull(STDOUT_FILENO, (const unsigned char *) log.c_str(), log.size());
+ }
+}
+
+
static void opRegisterSubstitutes(Strings opFlags, Strings opArgs)
{
if (!opFlags.empty()) throw UsageError("unknown flag");
@@ -663,6 +696,8 @@ void run(Strings args)
op = opDelete;
else if (arg == "--query" || arg == "-q")
op = opQuery;
+ else if (arg == "--read-log" || arg == "-l")
+ op = opReadLog;
else if (arg == "--register-substitutes")
op = opRegisterSubstitutes;
else if (arg == "--clear-substitutes")