aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2017-01-26 20:36:20 +0100
committerEelco Dolstra <edolstra@gmail.com>2017-01-26 20:41:08 +0100
commitc2b0d8749f7e77afc1c4b3e8dd36b7ee9720af4a (patch)
tree7f3c6b2eba4e0d7a82d5f281299d1cecd189c20c
parent6de33a9c675b187437a2e1abbcb290981a89ecb1 (diff)
exportReferencesGraph: Export more complete info in JSON format
This writes info about every path in the closure in the same format as ‘nix path-info --json’. Thus it also includes NAR hashes and sizes. Example: [ { "path": "/nix/store/10h6li26i7g6z3mdpvra09yyf10mmzdr-hello-2.10", "narHash": "sha256:0ckdc4z20kkmpqdilx0wl6cricxv90lh85xpv2qljppcmz6vzcxl", "narSize": 197648, "references": [ "/nix/store/10h6li26i7g6z3mdpvra09yyf10mmzdr-hello-2.10", "/nix/store/27binbdy296qvjycdgr1535v8872vz3z-glibc-2.24" ], "closureSize": 20939776 }, { "path": "/nix/store/27binbdy296qvjycdgr1535v8872vz3z-glibc-2.24", "narHash": "sha256:1nfn3m3p98y1c0kd0brp80dn9n5mycwgrk183j17rajya0h7gax3", "narSize": 20742128, "references": [ "/nix/store/27binbdy296qvjycdgr1535v8872vz3z-glibc-2.24" ], "closureSize": 20742128 } ] Fixes #1134.
-rw-r--r--src/libstore/build.cc12
-rw-r--r--src/libstore/store-api.cc59
-rw-r--r--src/libstore/store-api.hh14
-rw-r--r--src/nix/path-info.cc55
4 files changed, 90 insertions, 50 deletions
diff --git a/src/libstore/build.cc b/src/libstore/build.cc
index d76c8d172..7fb5271f4 100644
--- a/src/libstore/build.cc
+++ b/src/libstore/build.cc
@@ -10,6 +10,7 @@
#include "builtins.hh"
#include "finally.hh"
#include "compression.hh"
+#include "json.hh"
#include <algorithm>
#include <iostream>
@@ -2273,9 +2274,18 @@ void DerivationGoal::doExportReferencesGraph()
}
}
- /* Write closure info to `fileName'. */
+ /* Write closure info to <fileName>. */
writeFile(tmpDir + "/" + fileName,
worker.store.makeValidityRegistration(paths, false, false));
+
+ /* Write a more comprehensive JSON serialisation to
+ <fileName>.json. */
+ std::ostringstream str;
+ {
+ JSONPlaceholder jsonRoot(str, true);
+ worker.store.pathInfoToJSON(jsonRoot, paths, false, true);
+ }
+ writeFile(tmpDir + "/" + fileName + ".json", str.str());
}
}
diff --git a/src/libstore/store-api.cc b/src/libstore/store-api.cc
index 8fdd62771..a42d11834 100644
--- a/src/libstore/store-api.cc
+++ b/src/libstore/store-api.cc
@@ -4,6 +4,7 @@
#include "util.hh"
#include "nar-info-disk-cache.hh"
#include "thread-pool.hh"
+#include "json.hh"
#include <future>
@@ -439,6 +440,64 @@ string Store::makeValidityRegistration(const PathSet & paths,
}
+void Store::pathInfoToJSON(JSONPlaceholder & jsonOut, const PathSet & storePaths,
+ bool includeImpureInfo, bool showClosureSize)
+{
+ auto jsonList = jsonOut.list();
+
+ for (auto storePath : storePaths) {
+ auto info = queryPathInfo(storePath);
+ storePath = info->path;
+
+ auto jsonPath = jsonList.object();
+ jsonPath
+ .attr("path", storePath)
+ .attr("narHash", info->narHash.to_string())
+ .attr("narSize", info->narSize);
+
+ {
+ auto jsonRefs = jsonPath.list("references");
+ for (auto & ref : info->references)
+ jsonRefs.elem(ref);
+ }
+
+ if (info->ca != "")
+ jsonPath.attr("ca", info->ca);
+
+ if (showClosureSize)
+ jsonPath.attr("closureSize", getClosureSize(storePath));
+
+ if (!includeImpureInfo) continue;
+
+ if (info->deriver != "")
+ jsonPath.attr("deriver", info->deriver);
+
+ if (info->registrationTime)
+ jsonPath.attr("registrationTime", info->registrationTime);
+
+ if (info->ultimate)
+ jsonPath.attr("ultimate", info->ultimate);
+
+ if (!info->sigs.empty()) {
+ auto jsonSigs = jsonPath.list("signatures");
+ for (auto & sig : info->sigs)
+ jsonSigs.elem(sig);
+ }
+ }
+}
+
+
+unsigned long long Store::getClosureSize(const Path & storePath)
+{
+ unsigned long long totalSize = 0;
+ PathSet closure;
+ computeFSClosure(storePath, closure, false, false);
+ for (auto & p : closure)
+ totalSize += queryPathInfo(p)->narSize;
+ return totalSize;
+}
+
+
const Store::Stats & Store::getStats()
{
{
diff --git a/src/libstore/store-api.hh b/src/libstore/store-api.hh
index ec3bf5a6f..3fee99907 100644
--- a/src/libstore/store-api.hh
+++ b/src/libstore/store-api.hh
@@ -22,6 +22,7 @@ struct Derivation;
class FSAccessor;
class NarInfoDiskCache;
class Store;
+class JSONPlaceholder;
/* Size of the hash part of store paths, in base-32 characters. */
@@ -469,6 +470,19 @@ public:
string makeValidityRegistration(const PathSet & paths,
bool showDerivers, bool showHash);
+ /* Write a JSON representation of store path metadata, such as the
+ hash and the references. If ‘includeImpureInfo’ is true,
+ variable elements such as the registration time are
+ included. If ‘showClosureSize’ is true, the closure size of
+ each path is included. */
+ void pathInfoToJSON(JSONPlaceholder & jsonOut, const PathSet & storePaths,
+ bool includeImpureInfo, bool showClosureSize);
+
+ /* Return the size of the closure of the specified path, that is,
+ the sum of the size of the NAR serialisation of each path in
+ the closure. */
+ unsigned long long getClosureSize(const Path & storePath);
+
/* Optimise the disk space usage of the Nix store by hard-linking files
with the same contents. */
virtual void optimiseStore() = 0;
diff --git a/src/nix/path-info.cc b/src/nix/path-info.cc
index a9b33e187..0f9a1125f 100644
--- a/src/nix/path-info.cc
+++ b/src/nix/path-info.cc
@@ -65,55 +65,12 @@ struct CmdPathInfo : StorePathsCommand
for (auto & storePath : storePaths)
pathLen = std::max(pathLen, storePath.size());
- auto getClosureSize = [&](const Path & storePath) -> unsigned long long {
- unsigned long long totalSize = 0;
- PathSet closure;
- store->computeFSClosure(storePath, closure, false, false);
- for (auto & p : closure)
- totalSize += store->queryPathInfo(p)->narSize;
- return totalSize;
- };
-
if (json) {
- JSONList jsonRoot(std::cout, true);
-
- for (auto storePath : storePaths) {
- auto info = store->queryPathInfo(storePath);
- storePath = info->path;
-
- auto jsonPath = jsonRoot.object();
- jsonPath
- .attr("path", storePath)
- .attr("narHash", info->narHash.to_string())
- .attr("narSize", info->narSize);
-
- if (showClosureSize)
- jsonPath.attr("closureSize", getClosureSize(storePath));
-
- if (info->deriver != "")
- jsonPath.attr("deriver", info->deriver);
-
- {
- auto jsonRefs = jsonPath.list("references");
- for (auto & ref : info->references)
- jsonRefs.elem(ref);
- }
-
- if (info->registrationTime)
- jsonPath.attr("registrationTime", info->registrationTime);
-
- if (info->ultimate)
- jsonPath.attr("ultimate", info->ultimate);
-
- if (info->ca != "")
- jsonPath.attr("ca", info->ca);
-
- if (!info->sigs.empty()) {
- auto jsonSigs = jsonPath.list("signatures");
- for (auto & sig : info->sigs)
- jsonSigs.elem(sig);
- }
- }
+ JSONPlaceholder jsonRoot(std::cout, true);
+ store->pathInfoToJSON(jsonRoot,
+ // FIXME: preserve order?
+ PathSet(storePaths.begin(), storePaths.end()),
+ true, showClosureSize);
}
else {
@@ -128,7 +85,7 @@ struct CmdPathInfo : StorePathsCommand
std::cout << '\t' << std::setw(11) << info->narSize;
if (showClosureSize)
- std::cout << '\t' << std::setw(11) << getClosureSize(storePath);
+ std::cout << '\t' << std::setw(11) << store->getClosureSize(storePath);
if (showSigs) {
std::cout << '\t';