forked from lix-project/lix
nix flake show --json: Add type info
For extensibility, every leaf node is now an object that contains at least a type field (e.g. "type": "derivation").
This commit is contained in:
parent
f3259af73e
commit
1fbaf36729
|
@ -876,56 +876,54 @@ struct CmdFlakeShow : FlakeCommand, MixJSON
|
||||||
auto state = getEvalState();
|
auto state = getEvalState();
|
||||||
auto flake = std::make_shared<LockedFlake>(lockFlake());
|
auto flake = std::make_shared<LockedFlake>(lockFlake());
|
||||||
|
|
||||||
std::function<void(eval_cache::AttrCursor & visitor, const std::vector<Symbol> & attrPath, const std::string & headerPrefix, const std::string & nextPrefix)> visit;
|
std::function<nlohmann::json(
|
||||||
|
eval_cache::AttrCursor & visitor,
|
||||||
|
const std::vector<Symbol> & attrPath,
|
||||||
|
const std::string & headerPrefix,
|
||||||
|
const std::string & nextPrefix)> visit;
|
||||||
|
|
||||||
nlohmann::json j;
|
visit = [&](
|
||||||
// Populate json attributes along `attrPath` with a leaf value of `name`
|
eval_cache::AttrCursor & visitor,
|
||||||
auto populateJson = [&](const std::vector<Symbol> & attrPath, const std::string name)
|
const std::vector<Symbol> & attrPath,
|
||||||
|
const std::string & headerPrefix,
|
||||||
|
const std::string & nextPrefix)
|
||||||
|
-> nlohmann::json
|
||||||
{
|
{
|
||||||
nlohmann::json* r = & j;
|
auto j = nlohmann::json::object();
|
||||||
for (const auto & element : attrPath){
|
|
||||||
(*r)[element] = (*r)[element].is_null() ? nlohmann::json({}) : (*r)[element];
|
|
||||||
r = & (*r)[element];
|
|
||||||
}
|
|
||||||
(*r) = name;
|
|
||||||
};
|
|
||||||
|
|
||||||
visit = [&](eval_cache::AttrCursor & visitor, const std::vector<Symbol> & attrPath, const std::string & headerPrefix, const std::string & nextPrefix)
|
|
||||||
{
|
|
||||||
Activity act(*logger, lvlInfo, actUnknown,
|
Activity act(*logger, lvlInfo, actUnknown,
|
||||||
fmt("evaluating '%s'", concatStringsSep(".", attrPath)));
|
fmt("evaluating '%s'", concatStringsSep(".", attrPath)));
|
||||||
try {
|
try {
|
||||||
auto recurse = [&]()
|
auto recurse = [&]()
|
||||||
{
|
{
|
||||||
if (!json){
|
if (!json)
|
||||||
logger->cout("%s", headerPrefix);
|
logger->cout("%s", headerPrefix);
|
||||||
}
|
|
||||||
auto attrs = visitor.getAttrs();
|
auto attrs = visitor.getAttrs();
|
||||||
for (const auto & [i, attr] : enumerate(attrs)) {
|
for (const auto & [i, attr] : enumerate(attrs)) {
|
||||||
bool last = i + 1 == attrs.size();
|
bool last = i + 1 == attrs.size();
|
||||||
auto visitor2 = visitor.getAttr(attr);
|
auto visitor2 = visitor.getAttr(attr);
|
||||||
auto attrPath2(attrPath);
|
auto attrPath2(attrPath);
|
||||||
attrPath2.push_back(attr);
|
attrPath2.push_back(attr);
|
||||||
visit(*visitor2, attrPath2,
|
auto j2 = visit(*visitor2, attrPath2,
|
||||||
fmt(ANSI_GREEN "%s%s" ANSI_NORMAL ANSI_BOLD "%s" ANSI_NORMAL, nextPrefix, last ? treeLast : treeConn, attr),
|
fmt(ANSI_GREEN "%s%s" ANSI_NORMAL ANSI_BOLD "%s" ANSI_NORMAL, nextPrefix, last ? treeLast : treeConn, attr),
|
||||||
nextPrefix + (last ? treeNull : treeLine));
|
nextPrefix + (last ? treeNull : treeLine));
|
||||||
|
if (json) j.emplace(attr, std::move(j2));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
auto showDerivation = [&]()
|
auto showDerivation = [&]()
|
||||||
{
|
{
|
||||||
auto name = visitor.getAttr(state->sName)->getString();
|
auto name = visitor.getAttr(state->sName)->getString();
|
||||||
|
if (json) {
|
||||||
/*
|
std::optional<std::string> description;
|
||||||
std::string description;
|
|
||||||
|
|
||||||
if (auto aMeta = visitor.maybeGetAttr("meta")) {
|
if (auto aMeta = visitor.maybeGetAttr("meta")) {
|
||||||
if (auto aDescription = aMeta->maybeGetAttr("description"))
|
if (auto aDescription = aMeta->maybeGetAttr("description"))
|
||||||
description = aDescription->getString();
|
description = aDescription->getString();
|
||||||
}
|
}
|
||||||
*/
|
j.emplace("type", "derivation");
|
||||||
if (json){
|
j.emplace("name", name);
|
||||||
populateJson(attrPath,name);
|
if (description)
|
||||||
|
j.emplace("description", *description);
|
||||||
} else {
|
} else {
|
||||||
logger->cout("%s: %s '%s'",
|
logger->cout("%s: %s '%s'",
|
||||||
headerPrefix,
|
headerPrefix,
|
||||||
|
@ -996,8 +994,8 @@ struct CmdFlakeShow : FlakeCommand, MixJSON
|
||||||
auto aType = visitor.maybeGetAttr("type");
|
auto aType = visitor.maybeGetAttr("type");
|
||||||
if (!aType || aType->getString() != "app")
|
if (!aType || aType->getString() != "app")
|
||||||
throw EvalError("not an app definition");
|
throw EvalError("not an app definition");
|
||||||
if(json){
|
if (json) {
|
||||||
populateJson(attrPath,"app");
|
j.emplace("type", "app");
|
||||||
} else {
|
} else {
|
||||||
logger->cout("%s: app", headerPrefix);
|
logger->cout("%s: app", headerPrefix);
|
||||||
}
|
}
|
||||||
|
@ -1008,21 +1006,23 @@ struct CmdFlakeShow : FlakeCommand, MixJSON
|
||||||
(attrPath.size() == 2 && attrPath[0] == "templates"))
|
(attrPath.size() == 2 && attrPath[0] == "templates"))
|
||||||
{
|
{
|
||||||
auto description = visitor.getAttr("description")->getString();
|
auto description = visitor.getAttr("description")->getString();
|
||||||
if(json){
|
if (json) {
|
||||||
populateJson(attrPath,description);
|
j.emplace("type", "template");
|
||||||
|
j.emplace("description", description);
|
||||||
} else {
|
} else {
|
||||||
logger->cout("%s: template: " ANSI_BOLD "%s" ANSI_NORMAL, headerPrefix, description);
|
logger->cout("%s: template: " ANSI_BOLD "%s" ANSI_NORMAL, headerPrefix, description);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
else {
|
||||||
auto description = (attrPath.size() == 1 && attrPath[0] == "overlay")
|
auto [type, description] =
|
||||||
|| (attrPath.size() == 2 && attrPath[0] == "overlays") ? "Nixpkgs overlay" :
|
(attrPath.size() == 1 && attrPath[0] == "overlay")
|
||||||
attrPath.size() == 2 && attrPath[0] == "nixosConfigurations" ? "NixOS configuration" :
|
|| (attrPath.size() == 2 && attrPath[0] == "overlays") ? std::make_pair("nixpkgs-overlay", "Nixpkgs overlay") :
|
||||||
attrPath.size() == 2 && attrPath[0] == "nixosModules" ? "NixOS module" :
|
attrPath.size() == 2 && attrPath[0] == "nixosConfigurations" ? std::make_pair("nixos-configuration", "NixOS configuration") :
|
||||||
"unknown";
|
attrPath.size() == 2 && attrPath[0] == "nixosModules" ? std::make_pair("nixos-module", "NixOS module") :
|
||||||
if(json){
|
std::make_pair("unknown", "unknown");
|
||||||
populateJson(attrPath,description);
|
if (json) {
|
||||||
|
j.emplace("type", type);
|
||||||
} else {
|
} else {
|
||||||
logger->cout("%s: " ANSI_WARNING "%s" ANSI_NORMAL, headerPrefix, description);
|
logger->cout("%s: " ANSI_WARNING "%s" ANSI_NORMAL, headerPrefix, description);
|
||||||
}
|
}
|
||||||
|
@ -1031,15 +1031,16 @@ struct CmdFlakeShow : FlakeCommand, MixJSON
|
||||||
if (!(attrPath.size() > 0 && attrPath[0] == "legacyPackages"))
|
if (!(attrPath.size() > 0 && attrPath[0] == "legacyPackages"))
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return j;
|
||||||
};
|
};
|
||||||
|
|
||||||
auto cache = openEvalCache(*state, flake);
|
auto cache = openEvalCache(*state, flake);
|
||||||
|
|
||||||
visit(*cache->getRoot(), {}, fmt(ANSI_BOLD "%s" ANSI_NORMAL, flake->flake.lockedRef), "");
|
auto j = visit(*cache->getRoot(), {}, fmt(ANSI_BOLD "%s" ANSI_NORMAL, flake->flake.lockedRef), "");
|
||||||
if(json){
|
if (json)
|
||||||
logger->cout("%s", j.dump());
|
logger->cout("%s", j.dump());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CmdFlakePrefetch : FlakeCommand, MixJSON
|
struct CmdFlakePrefetch : FlakeCommand, MixJSON
|
||||||
|
|
Loading…
Reference in a new issue