nix path-info: Add --json flag
Also, factor out JSON generation from value-to-json.{cc,hh}, and support producing indented JSON.
This commit is contained in:
parent
9fa21765e7
commit
c0a7b84748
|
@ -1,4 +1,5 @@
|
|||
#include "value-to-json.hh"
|
||||
#include "json.hh"
|
||||
#include "eval-inline.hh"
|
||||
#include "util.hh"
|
||||
|
||||
|
@ -8,24 +9,8 @@
|
|||
|
||||
namespace nix {
|
||||
|
||||
|
||||
void escapeJSON(std::ostream & str, const string & s)
|
||||
{
|
||||
str << "\"";
|
||||
for (auto & i : s)
|
||||
if (i == '\"' || i == '\\') str << "\\" << i;
|
||||
else if (i == '\n') str << "\\n";
|
||||
else if (i == '\r') str << "\\r";
|
||||
else if (i == '\t') str << "\\t";
|
||||
else if (i >= 0 && i < 32)
|
||||
str << "\\u" << std::setfill('0') << std::setw(4) << std::hex << (uint16_t) i << std::dec;
|
||||
else str << i;
|
||||
str << "\"";
|
||||
}
|
||||
|
||||
|
||||
void printValueAsJSON(EvalState & state, bool strict,
|
||||
Value & v, std::ostream & str, PathSet & context)
|
||||
Value & v, JSONPlaceholder & out, PathSet & context)
|
||||
{
|
||||
checkInterrupt();
|
||||
|
||||
|
@ -34,58 +19,58 @@ void printValueAsJSON(EvalState & state, bool strict,
|
|||
switch (v.type) {
|
||||
|
||||
case tInt:
|
||||
str << v.integer;
|
||||
out.write(v.integer);
|
||||
break;
|
||||
|
||||
case tBool:
|
||||
str << (v.boolean ? "true" : "false");
|
||||
out.write(v.boolean);
|
||||
break;
|
||||
|
||||
case tString:
|
||||
copyContext(v, context);
|
||||
escapeJSON(str, v.string.s);
|
||||
out.write(v.string.s);
|
||||
break;
|
||||
|
||||
case tPath:
|
||||
escapeJSON(str, state.copyPathToStore(context, v.path));
|
||||
out.write(state.copyPathToStore(context, v.path));
|
||||
break;
|
||||
|
||||
case tNull:
|
||||
str << "null";
|
||||
out.write(nullptr);
|
||||
break;
|
||||
|
||||
case tAttrs: {
|
||||
Bindings::iterator i = v.attrs->find(state.sOutPath);
|
||||
if (i == v.attrs->end()) {
|
||||
JSONObject json(str);
|
||||
auto obj(out.object());
|
||||
StringSet names;
|
||||
for (auto & j : *v.attrs)
|
||||
names.insert(j.name);
|
||||
for (auto & j : names) {
|
||||
Attr & a(*v.attrs->find(state.symbols.create(j)));
|
||||
json.attr(j);
|
||||
printValueAsJSON(state, strict, *a.value, str, context);
|
||||
auto placeholder(obj.placeholder(j));
|
||||
printValueAsJSON(state, strict, *a.value, placeholder, context);
|
||||
}
|
||||
} else
|
||||
printValueAsJSON(state, strict, *i->value, str, context);
|
||||
printValueAsJSON(state, strict, *i->value, out, context);
|
||||
break;
|
||||
}
|
||||
|
||||
case tList1: case tList2: case tListN: {
|
||||
JSONList json(str);
|
||||
auto list(out.list());
|
||||
for (unsigned int n = 0; n < v.listSize(); ++n) {
|
||||
json.elem();
|
||||
printValueAsJSON(state, strict, *v.listElems()[n], str, context);
|
||||
auto placeholder(list.placeholder());
|
||||
printValueAsJSON(state, strict, *v.listElems()[n], placeholder, context);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case tExternal:
|
||||
v.external->printValueAsJSON(state, strict, str, context);
|
||||
v.external->printValueAsJSON(state, strict, out, context);
|
||||
break;
|
||||
|
||||
case tFloat:
|
||||
str << v.fpoint;
|
||||
out.write(v.fpoint);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -93,9 +78,15 @@ void printValueAsJSON(EvalState & state, bool strict,
|
|||
}
|
||||
}
|
||||
|
||||
void printValueAsJSON(EvalState & state, bool strict,
|
||||
Value & v, std::ostream & str, PathSet & context)
|
||||
{
|
||||
JSONPlaceholder out(str);
|
||||
printValueAsJSON(state, strict, v, out, context);
|
||||
}
|
||||
|
||||
void ExternalValueBase::printValueAsJSON(EvalState & state, bool strict,
|
||||
std::ostream & str, PathSet & context) const
|
||||
JSONPlaceholder & out, PathSet & context) const
|
||||
{
|
||||
throw TypeError(format("cannot convert %1% to JSON") % showType());
|
||||
}
|
||||
|
|
|
@ -8,73 +8,12 @@
|
|||
|
||||
namespace nix {
|
||||
|
||||
class JSONPlaceholder;
|
||||
|
||||
void printValueAsJSON(EvalState & state, bool strict,
|
||||
Value & v, std::ostream & out, PathSet & context);
|
||||
Value & v, JSONPlaceholder & out, PathSet & context);
|
||||
|
||||
void escapeJSON(std::ostream & str, const string & s);
|
||||
|
||||
struct JSONObject
|
||||
{
|
||||
std::ostream & str;
|
||||
bool first;
|
||||
JSONObject(std::ostream & str) : str(str), first(true)
|
||||
{
|
||||
str << "{";
|
||||
}
|
||||
~JSONObject()
|
||||
{
|
||||
str << "}";
|
||||
}
|
||||
void attr(const string & s)
|
||||
{
|
||||
if (!first) str << ","; else first = false;
|
||||
escapeJSON(str, s);
|
||||
str << ":";
|
||||
}
|
||||
void attr(const string & s, const string & t)
|
||||
{
|
||||
attr(s);
|
||||
escapeJSON(str, t);
|
||||
}
|
||||
void attr(const string & s, const char * t)
|
||||
{
|
||||
attr(s);
|
||||
escapeJSON(str, t);
|
||||
}
|
||||
void attr(const string & s, bool b)
|
||||
{
|
||||
attr(s);
|
||||
str << (b ? "true" : "false");
|
||||
}
|
||||
template<typename T>
|
||||
void attr(const string & s, const T & n)
|
||||
{
|
||||
attr(s);
|
||||
str << n;
|
||||
}
|
||||
};
|
||||
|
||||
struct JSONList
|
||||
{
|
||||
std::ostream & str;
|
||||
bool first;
|
||||
JSONList(std::ostream & str) : str(str), first(true)
|
||||
{
|
||||
str << "[";
|
||||
}
|
||||
~JSONList()
|
||||
{
|
||||
str << "]";
|
||||
}
|
||||
void elem()
|
||||
{
|
||||
if (!first) str << ","; else first = false;
|
||||
}
|
||||
void elem(const string & s)
|
||||
{
|
||||
elem();
|
||||
escapeJSON(str, s);
|
||||
}
|
||||
};
|
||||
void printValueAsJSON(EvalState & state, bool strict,
|
||||
Value & v, std::ostream & str, PathSet & context);
|
||||
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ class Symbol;
|
|||
struct Pos;
|
||||
class EvalState;
|
||||
class XMLWriter;
|
||||
class JSONPlaceholder;
|
||||
|
||||
|
||||
typedef long NixInt;
|
||||
|
@ -73,7 +74,7 @@ class ExternalValueBase
|
|||
|
||||
/* Print the value as JSON. Defaults to unconvertable, i.e. throws an error */
|
||||
virtual void printValueAsJSON(EvalState & state, bool strict,
|
||||
std::ostream & str, PathSet & context) const;
|
||||
JSONPlaceholder & out, PathSet & context) const;
|
||||
|
||||
/* Print the value as XML. Defaults to unevaluated */
|
||||
virtual void printValueAsXML(EvalState & state, bool strict, bool location,
|
||||
|
|
171
src/libutil/json.cc
Normal file
171
src/libutil/json.cc
Normal file
|
@ -0,0 +1,171 @@
|
|||
#include "json.hh"
|
||||
|
||||
#include <iomanip>
|
||||
#include <cstring>
|
||||
|
||||
namespace nix {
|
||||
|
||||
void toJSON(std::ostream & str, const char * start, const char * end)
|
||||
{
|
||||
str << '"';
|
||||
for (auto i = start; i != end; i++)
|
||||
if (*i == '\"' || *i == '\\') str << '\\' << *i;
|
||||
else if (*i == '\n') str << "\\n";
|
||||
else if (*i == '\r') str << "\\r";
|
||||
else if (*i == '\t') str << "\\t";
|
||||
else if (*i >= 0 && *i < 32)
|
||||
str << "\\u" << std::setfill('0') << std::setw(4) << std::hex << (uint16_t) *i << std::dec;
|
||||
else str << *i;
|
||||
str << '"';
|
||||
}
|
||||
|
||||
void toJSON(std::ostream & str, const std::string & s)
|
||||
{
|
||||
toJSON(str, s.c_str(), s.c_str() + s.size());
|
||||
}
|
||||
|
||||
void toJSON(std::ostream & str, const char * s)
|
||||
{
|
||||
if (!s) str << "null"; else toJSON(str, s, s + strlen(s));
|
||||
}
|
||||
|
||||
void toJSON(std::ostream & str, unsigned long n)
|
||||
{
|
||||
str << n;
|
||||
}
|
||||
|
||||
void toJSON(std::ostream & str, long n)
|
||||
{
|
||||
str << n;
|
||||
}
|
||||
|
||||
void toJSON(std::ostream & str, double f)
|
||||
{
|
||||
str << f;
|
||||
}
|
||||
|
||||
void toJSON(std::ostream & str, bool b)
|
||||
{
|
||||
str << (b ? "true" : "false");
|
||||
}
|
||||
|
||||
JSONWriter::JSONWriter(std::ostream & str, bool indent)
|
||||
: state(new JSONState(str, indent))
|
||||
{
|
||||
state->stack.push_back(this);
|
||||
}
|
||||
|
||||
JSONWriter::JSONWriter(JSONState * state)
|
||||
: state(state)
|
||||
{
|
||||
state->stack.push_back(this);
|
||||
}
|
||||
|
||||
JSONWriter::~JSONWriter()
|
||||
{
|
||||
assertActive();
|
||||
state->stack.pop_back();
|
||||
if (state->stack.empty()) delete state;
|
||||
}
|
||||
|
||||
void JSONWriter::comma()
|
||||
{
|
||||
assertActive();
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
state->str << ',';
|
||||
}
|
||||
if (state->indent) indent();
|
||||
}
|
||||
|
||||
void JSONWriter::indent()
|
||||
{
|
||||
state->str << '\n' << std::string(state->depth * 2, ' ');
|
||||
}
|
||||
|
||||
void JSONList::open()
|
||||
{
|
||||
state->depth++;
|
||||
state->str << '[';
|
||||
}
|
||||
|
||||
JSONList::~JSONList()
|
||||
{
|
||||
state->depth--;
|
||||
if (state->indent && !first) indent();
|
||||
state->str << "]";
|
||||
}
|
||||
|
||||
JSONList JSONList::list()
|
||||
{
|
||||
comma();
|
||||
return JSONList(state);
|
||||
}
|
||||
|
||||
JSONObject JSONList::object()
|
||||
{
|
||||
comma();
|
||||
return JSONObject(state);
|
||||
}
|
||||
|
||||
JSONPlaceholder JSONList::placeholder()
|
||||
{
|
||||
comma();
|
||||
return JSONPlaceholder(state);
|
||||
}
|
||||
|
||||
void JSONObject::open()
|
||||
{
|
||||
state->depth++;
|
||||
state->str << '{';
|
||||
}
|
||||
|
||||
JSONObject::~JSONObject()
|
||||
{
|
||||
state->depth--;
|
||||
if (state->indent && !first) indent();
|
||||
state->str << "}";
|
||||
}
|
||||
|
||||
void JSONObject::attr(const std::string & s)
|
||||
{
|
||||
comma();
|
||||
toJSON(state->str, s);
|
||||
state->str << ':';
|
||||
if (state->indent) state->str << ' ';
|
||||
}
|
||||
|
||||
JSONList JSONObject::list(const std::string & name)
|
||||
{
|
||||
attr(name);
|
||||
return JSONList(state);
|
||||
}
|
||||
|
||||
JSONObject JSONObject::object(const std::string & name)
|
||||
{
|
||||
attr(name);
|
||||
return JSONObject(state);
|
||||
}
|
||||
|
||||
JSONPlaceholder JSONObject::placeholder(const std::string & name)
|
||||
{
|
||||
attr(name);
|
||||
return JSONPlaceholder(state);
|
||||
}
|
||||
|
||||
JSONList JSONPlaceholder::list()
|
||||
{
|
||||
assertValid();
|
||||
first = false;
|
||||
return JSONList(state);
|
||||
}
|
||||
|
||||
JSONObject JSONPlaceholder::object()
|
||||
{
|
||||
assertValid();
|
||||
first = false;
|
||||
return JSONObject(state);
|
||||
}
|
||||
|
||||
}
|
183
src/libutil/json.hh
Normal file
183
src/libutil/json.hh
Normal file
|
@ -0,0 +1,183 @@
|
|||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <cassert>
|
||||
|
||||
namespace nix {
|
||||
|
||||
void toJSON(std::ostream & str, const char * start, const char * end);
|
||||
void toJSON(std::ostream & str, const std::string & s);
|
||||
void toJSON(std::ostream & str, const char * s);
|
||||
void toJSON(std::ostream & str, unsigned long n);
|
||||
void toJSON(std::ostream & str, long n);
|
||||
void toJSON(std::ostream & str, double f);
|
||||
void toJSON(std::ostream & str, bool b);
|
||||
|
||||
class JSONWriter
|
||||
{
|
||||
protected:
|
||||
|
||||
struct JSONState
|
||||
{
|
||||
std::ostream & str;
|
||||
bool indent;
|
||||
size_t depth = 0;
|
||||
std::vector<JSONWriter *> stack;
|
||||
JSONState(std::ostream & str, bool indent) : str(str), indent(indent) { }
|
||||
~JSONState()
|
||||
{
|
||||
assert(stack.empty());
|
||||
}
|
||||
};
|
||||
|
||||
JSONState * state;
|
||||
|
||||
bool first = true;
|
||||
|
||||
JSONWriter(std::ostream & str, bool indent);
|
||||
|
||||
JSONWriter(JSONState * state);
|
||||
|
||||
~JSONWriter();
|
||||
|
||||
void assertActive()
|
||||
{
|
||||
assert(!state->stack.empty() && state->stack.back() == this);
|
||||
}
|
||||
|
||||
void comma();
|
||||
|
||||
void indent();
|
||||
};
|
||||
|
||||
class JSONObject;
|
||||
class JSONPlaceholder;
|
||||
|
||||
class JSONList : JSONWriter
|
||||
{
|
||||
private:
|
||||
|
||||
friend class JSONObject;
|
||||
friend class JSONPlaceholder;
|
||||
|
||||
void open();
|
||||
|
||||
JSONList(JSONState * state)
|
||||
: JSONWriter(state)
|
||||
{
|
||||
open();
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
JSONList(std::ostream & str, bool indent = false)
|
||||
: JSONWriter(str, indent)
|
||||
{
|
||||
open();
|
||||
}
|
||||
|
||||
~JSONList();
|
||||
|
||||
template<typename T>
|
||||
JSONList & elem(const T & v)
|
||||
{
|
||||
comma();
|
||||
toJSON(state->str, v);
|
||||
return *this;
|
||||
}
|
||||
|
||||
JSONList list();
|
||||
|
||||
JSONObject object();
|
||||
|
||||
JSONPlaceholder placeholder();
|
||||
};
|
||||
|
||||
class JSONObject : JSONWriter
|
||||
{
|
||||
private:
|
||||
|
||||
friend class JSONList;
|
||||
friend class JSONPlaceholder;
|
||||
|
||||
void open();
|
||||
|
||||
JSONObject(JSONState * state)
|
||||
: JSONWriter(state)
|
||||
{
|
||||
open();
|
||||
}
|
||||
|
||||
void attr(const std::string & s);
|
||||
|
||||
public:
|
||||
|
||||
JSONObject(std::ostream & str, bool indent = false)
|
||||
: JSONWriter(str, indent)
|
||||
{
|
||||
open();
|
||||
}
|
||||
|
||||
~JSONObject();
|
||||
|
||||
template<typename T>
|
||||
JSONObject & attr(const std::string & name, const T & v)
|
||||
{
|
||||
attr(name);
|
||||
toJSON(state->str, v);
|
||||
return *this;
|
||||
}
|
||||
|
||||
JSONList list(const std::string & name);
|
||||
|
||||
JSONObject object(const std::string & name);
|
||||
|
||||
JSONPlaceholder placeholder(const std::string & name);
|
||||
};
|
||||
|
||||
class JSONPlaceholder : JSONWriter
|
||||
{
|
||||
|
||||
private:
|
||||
|
||||
friend class JSONList;
|
||||
friend class JSONObject;
|
||||
|
||||
JSONPlaceholder(JSONState * state)
|
||||
: JSONWriter(state)
|
||||
{
|
||||
}
|
||||
|
||||
void assertValid()
|
||||
{
|
||||
assertActive();
|
||||
assert(first);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
JSONPlaceholder(std::ostream & str, bool indent = false)
|
||||
: JSONWriter(str, indent)
|
||||
{
|
||||
}
|
||||
|
||||
~JSONPlaceholder()
|
||||
{
|
||||
assert(!first || std::uncaught_exception());
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void write(const T & v)
|
||||
{
|
||||
assertValid();
|
||||
first = false;
|
||||
toJSON(state->str, v);
|
||||
}
|
||||
|
||||
JSONList list();
|
||||
|
||||
JSONObject object();
|
||||
};
|
||||
|
||||
}
|
|
@ -10,6 +10,7 @@
|
|||
#include "store-api.hh"
|
||||
#include "user-env.hh"
|
||||
#include "util.hh"
|
||||
#include "json.hh"
|
||||
#include "value-to-json.hh"
|
||||
#include "xml-writer.hh"
|
||||
|
||||
|
@ -860,26 +861,24 @@ static VersionDiff compareVersionAgainstSet(
|
|||
|
||||
static void queryJSON(Globals & globals, vector<DrvInfo> & elems)
|
||||
{
|
||||
JSONObject topObj(cout);
|
||||
JSONObject topObj(cout, true);
|
||||
for (auto & i : elems) {
|
||||
topObj.attr(i.attrPath);
|
||||
JSONObject pkgObj(cout);
|
||||
JSONObject pkgObj = topObj.object(i.attrPath);
|
||||
|
||||
pkgObj.attr("name", i.name);
|
||||
pkgObj.attr("system", i.system);
|
||||
|
||||
pkgObj.attr("meta");
|
||||
JSONObject metaObj(cout);
|
||||
JSONObject metaObj = pkgObj.object("meta");
|
||||
StringSet metaNames = i.queryMetaNames();
|
||||
for (auto & j : metaNames) {
|
||||
metaObj.attr(j);
|
||||
auto placeholder = metaObj.placeholder(j);
|
||||
Value * v = i.queryMeta(j);
|
||||
if (!v) {
|
||||
printMsg(lvlError, format("derivation ‘%1%’ has invalid meta attribute ‘%2%’") % i.name % j);
|
||||
cout << "null";
|
||||
placeholder.write(nullptr);
|
||||
} else {
|
||||
PathSet context;
|
||||
printValueAsJSON(*globals.state, true, *v, cout, context);
|
||||
printValueAsJSON(*globals.state, true, *v, placeholder, context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,10 @@
|
|||
#include "shared.hh"
|
||||
#include "store-api.hh"
|
||||
|
||||
|
||||
#include "json.hh"
|
||||
|
||||
|
||||
#include <iomanip>
|
||||
#include <algorithm>
|
||||
|
||||
|
@ -12,12 +16,14 @@ struct CmdPathInfo : StorePathsCommand
|
|||
bool showSize = false;
|
||||
bool showClosureSize = false;
|
||||
bool showSigs = false;
|
||||
bool json = false;
|
||||
|
||||
CmdPathInfo()
|
||||
{
|
||||
mkFlag('s', "size", "print size of the NAR dump of each path", &showSize);
|
||||
mkFlag('S', "closure-size", "print sum size of the NAR dumps of the closure of each path", &showClosureSize);
|
||||
mkFlag(0, "sigs", "show signatures", &showSigs);
|
||||
mkFlag(0, "json", "produce JSON output", &json);
|
||||
}
|
||||
|
||||
std::string name() override
|
||||
|
@ -41,6 +47,10 @@ struct CmdPathInfo : StorePathsCommand
|
|||
"To check the existence of a path in a binary cache:",
|
||||
"nix path-info -r /nix/store/7qvk5c91...-geeqie-1.1 --store https://cache.nixos.org/"
|
||||
},
|
||||
Example{
|
||||
"To print the 10 most recently added paths (using --json and the jq(1) command):",
|
||||
"nix path-info --all --json | jq -r 'sort_by(.registrationTime)[-11:-1][].path'"
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -50,36 +60,85 @@ struct CmdPathInfo : StorePathsCommand
|
|||
for (auto & storePath : storePaths)
|
||||
pathLen = std::max(pathLen, storePath.size());
|
||||
|
||||
for (auto storePath : storePaths) {
|
||||
auto info = store->queryPathInfo(storePath);
|
||||
storePath = info->path; // FIXME: screws up padding
|
||||
auto getClosureSize = [&](const Path & storePath) {
|
||||
size_t totalSize = 0;
|
||||
PathSet closure;
|
||||
store->computeFSClosure(storePath, closure, false, false);
|
||||
for (auto & p : closure)
|
||||
totalSize += store->queryPathInfo(p)->narSize;
|
||||
return totalSize;
|
||||
};
|
||||
|
||||
std::cout << storePath << std::string(std::max(0, (int) pathLen - (int) storePath.size()), ' ');
|
||||
if (json) {
|
||||
JSONList jsonRoot(std::cout, true);
|
||||
|
||||
if (showSize) {
|
||||
std::cout << '\t' << std::setw(11) << info->narSize;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
if (showClosureSize) {
|
||||
size_t totalSize = 0;
|
||||
PathSet closure;
|
||||
store->computeFSClosure(storePath, closure, false, false);
|
||||
for (auto & p : closure)
|
||||
totalSize += store->queryPathInfo(p)->narSize;
|
||||
std::cout << '\t' << std::setw(11) << totalSize;
|
||||
}
|
||||
|
||||
if (showSigs) {
|
||||
std::cout << '\t';
|
||||
Strings ss;
|
||||
if (info->ultimate) ss.push_back("ultimate");
|
||||
if (info->ca != "") ss.push_back("ca:" + info->ca);
|
||||
for (auto & sig : info->sigs) ss.push_back(sig);
|
||||
std::cout << concatStringsSep(" ", ss);
|
||||
}
|
||||
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
else {
|
||||
|
||||
for (auto storePath : storePaths) {
|
||||
auto info = store->queryPathInfo(storePath);
|
||||
storePath = info->path; // FIXME: screws up padding
|
||||
|
||||
std::cout << storePath << std::string(std::max(0, (int) pathLen - (int) storePath.size()), ' ');
|
||||
|
||||
if (showSize)
|
||||
std::cout << '\t' << std::setw(11) << info->narSize;
|
||||
|
||||
if (showClosureSize)
|
||||
std::cout << '\t' << std::setw(11) << getClosureSize(storePath);
|
||||
|
||||
if (showSigs) {
|
||||
std::cout << '\t';
|
||||
Strings ss;
|
||||
if (info->ultimate) ss.push_back("ultimate");
|
||||
if (info->ca != "") ss.push_back("ca:" + info->ca);
|
||||
for (auto & sig : info->sigs) ss.push_back(sig);
|
||||
std::cout << concatStringsSep(" ", ss);
|
||||
}
|
||||
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue