242f9bf3dc
I had started the trend of doing `std::visit` by value (because a type error once mislead me into thinking that was the only form that existed). While the optomizer in principle should be able to deal with extra coppying or extra indirection once the lambdas inlined, sticking with by reference is the conventional default. I hope this might even improve performance.
122 lines
3.8 KiB
C++
122 lines
3.8 KiB
C++
// FIXME: integrate this with nix path-info?
|
|
// FIXME: rename to 'nix store show-derivation' or 'nix debug show-derivation'?
|
|
|
|
#include "command.hh"
|
|
#include "common-args.hh"
|
|
#include "store-api.hh"
|
|
#include "archive.hh"
|
|
#include "json.hh"
|
|
#include "derivations.hh"
|
|
|
|
using namespace nix;
|
|
|
|
struct CmdShowDerivation : InstallablesCommand
|
|
{
|
|
bool recursive = false;
|
|
|
|
CmdShowDerivation()
|
|
{
|
|
addFlag({
|
|
.longName = "recursive",
|
|
.shortName = 'r',
|
|
.description = "Include the dependencies of the specified derivations.",
|
|
.handler = {&recursive, true}
|
|
});
|
|
}
|
|
|
|
std::string description() override
|
|
{
|
|
return "show the contents of a store derivation";
|
|
}
|
|
|
|
std::string doc() override
|
|
{
|
|
return
|
|
#include "show-derivation.md"
|
|
;
|
|
}
|
|
|
|
Category category() override { return catUtility; }
|
|
|
|
void run(ref<Store> store) override
|
|
{
|
|
auto drvPaths = toDerivations(store, installables, true);
|
|
|
|
if (recursive) {
|
|
StorePathSet closure;
|
|
store->computeFSClosure(drvPaths, closure);
|
|
drvPaths = std::move(closure);
|
|
}
|
|
|
|
{
|
|
|
|
JSONObject jsonRoot(std::cout, true);
|
|
|
|
for (auto & drvPath : drvPaths) {
|
|
if (!drvPath.isDerivation()) continue;
|
|
|
|
auto drvObj(jsonRoot.object(store->printStorePath(drvPath)));
|
|
|
|
auto drv = store->readDerivation(drvPath);
|
|
|
|
{
|
|
auto outputsObj(drvObj.object("outputs"));
|
|
for (auto & [_outputName, output] : drv.outputs) {
|
|
auto & outputName = _outputName; // work around clang bug
|
|
auto outputObj { outputsObj.object(outputName) };
|
|
std::visit(overloaded {
|
|
[&](const DerivationOutputInputAddressed & doi) {
|
|
outputObj.attr("path", store->printStorePath(doi.path));
|
|
},
|
|
[&](const DerivationOutputCAFixed & dof) {
|
|
outputObj.attr("path", store->printStorePath(dof.path(*store, drv.name, outputName)));
|
|
outputObj.attr("hashAlgo", dof.hash.printMethodAlgo());
|
|
outputObj.attr("hash", dof.hash.hash.to_string(Base16, false));
|
|
},
|
|
[&](const DerivationOutputCAFloating & dof) {
|
|
outputObj.attr("hashAlgo", makeFileIngestionPrefix(dof.method) + printHashType(dof.hashType));
|
|
},
|
|
[&](const DerivationOutputDeferred &) {},
|
|
}, output.output);
|
|
}
|
|
}
|
|
|
|
{
|
|
auto inputsList(drvObj.list("inputSrcs"));
|
|
for (auto & input : drv.inputSrcs)
|
|
inputsList.elem(store->printStorePath(input));
|
|
}
|
|
|
|
{
|
|
auto inputDrvsObj(drvObj.object("inputDrvs"));
|
|
for (auto & input : drv.inputDrvs) {
|
|
auto inputList(inputDrvsObj.list(store->printStorePath(input.first)));
|
|
for (auto & outputId : input.second)
|
|
inputList.elem(outputId);
|
|
}
|
|
}
|
|
|
|
drvObj.attr("system", drv.platform);
|
|
drvObj.attr("builder", drv.builder);
|
|
|
|
{
|
|
auto argsList(drvObj.list("args"));
|
|
for (auto & arg : drv.args)
|
|
argsList.elem(arg);
|
|
}
|
|
|
|
{
|
|
auto envObj(drvObj.object("env"));
|
|
for (auto & var : drv.env)
|
|
envObj.attr(var.first, var.second);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
std::cout << "\n";
|
|
}
|
|
};
|
|
|
|
static auto rCmdShowDerivation = registerCommand<CmdShowDerivation>("show-derivation");
|