forked from lix-project/lix
Merge pull request #7863 from obsidiansystems/test-derivation-to-json
Move Derivation JSON printing logic to lib and test it
This commit is contained in:
commit
c7bd3a874f
|
@ -5,6 +5,7 @@
|
||||||
#include "worker-protocol.hh"
|
#include "worker-protocol.hh"
|
||||||
#include "fs-accessor.hh"
|
#include "fs-accessor.hh"
|
||||||
#include <boost/container/small_vector.hpp>
|
#include <boost/container/small_vector.hpp>
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
@ -890,4 +891,62 @@ std::optional<BasicDerivation> Derivation::tryResolve(
|
||||||
|
|
||||||
const Hash impureOutputHash = hashString(htSHA256, "impure");
|
const Hash impureOutputHash = hashString(htSHA256, "impure");
|
||||||
|
|
||||||
|
nlohmann::json DerivationOutput::toJSON(
|
||||||
|
const Store & store, std::string_view drvName, std::string_view outputName) const
|
||||||
|
{
|
||||||
|
nlohmann::json res = nlohmann::json::object();
|
||||||
|
std::visit(overloaded {
|
||||||
|
[&](const DerivationOutput::InputAddressed & doi) {
|
||||||
|
res["path"] = store.printStorePath(doi.path);
|
||||||
|
},
|
||||||
|
[&](const DerivationOutput::CAFixed & dof) {
|
||||||
|
res["path"] = store.printStorePath(dof.path(store, drvName, outputName));
|
||||||
|
res["hashAlgo"] = dof.hash.printMethodAlgo();
|
||||||
|
res["hash"] = dof.hash.hash.to_string(Base16, false);
|
||||||
|
},
|
||||||
|
[&](const DerivationOutput::CAFloating & dof) {
|
||||||
|
res["hashAlgo"] = makeFileIngestionPrefix(dof.method) + printHashType(dof.hashType);
|
||||||
|
},
|
||||||
|
[&](const DerivationOutput::Deferred &) {},
|
||||||
|
[&](const DerivationOutput::Impure & doi) {
|
||||||
|
res["hashAlgo"] = makeFileIngestionPrefix(doi.method) + printHashType(doi.hashType);
|
||||||
|
res["impure"] = true;
|
||||||
|
},
|
||||||
|
}, raw());
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
nlohmann::json Derivation::toJSON(const Store & store) const
|
||||||
|
{
|
||||||
|
nlohmann::json res = nlohmann::json::object();
|
||||||
|
|
||||||
|
{
|
||||||
|
nlohmann::json & outputsObj = res["outputs"];
|
||||||
|
outputsObj = nlohmann::json::object();
|
||||||
|
for (auto & [outputName, output] : outputs) {
|
||||||
|
outputsObj[outputName] = output.toJSON(store, name, outputName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto& inputsList = res["inputSrcs"];
|
||||||
|
inputsList = nlohmann::json ::array();
|
||||||
|
for (auto & input : inputSrcs)
|
||||||
|
inputsList.emplace_back(store.printStorePath(input));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto& inputDrvsObj = res["inputDrvs"];
|
||||||
|
inputDrvsObj = nlohmann::json ::object();
|
||||||
|
for (auto & input : inputDrvs)
|
||||||
|
inputDrvsObj[store.printStorePath(input.first)] = input.second;
|
||||||
|
}
|
||||||
|
|
||||||
|
res["system"] = platform;
|
||||||
|
res["builder"] = builder;
|
||||||
|
res["args"] = args;
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,6 +83,11 @@ struct DerivationOutput : _DerivationOutputRaw
|
||||||
inline const Raw & raw() const {
|
inline const Raw & raw() const {
|
||||||
return static_cast<const Raw &>(*this);
|
return static_cast<const Raw &>(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nlohmann::json toJSON(
|
||||||
|
const Store & store,
|
||||||
|
std::string_view drvName,
|
||||||
|
std::string_view outputName) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::map<std::string, DerivationOutput> DerivationOutputs;
|
typedef std::map<std::string, DerivationOutput> DerivationOutputs;
|
||||||
|
@ -210,6 +215,8 @@ struct Derivation : BasicDerivation
|
||||||
Derivation() = default;
|
Derivation() = default;
|
||||||
Derivation(const BasicDerivation & bd) : BasicDerivation(bd) { }
|
Derivation(const BasicDerivation & bd) : BasicDerivation(bd) { }
|
||||||
Derivation(BasicDerivation && bd) : BasicDerivation(std::move(bd)) { }
|
Derivation(BasicDerivation && bd) : BasicDerivation(std::move(bd)) { }
|
||||||
|
|
||||||
|
nlohmann::json toJSON(const Store & store) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
115
src/libstore/tests/derivation.cc
Normal file
115
src/libstore/tests/derivation.cc
Normal file
|
@ -0,0 +1,115 @@
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
#include "derivations.hh"
|
||||||
|
|
||||||
|
#include "tests/libstore.hh"
|
||||||
|
|
||||||
|
namespace nix {
|
||||||
|
|
||||||
|
class DerivationTest : public LibStoreTest
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
#define TEST_JSON(TYPE, NAME, STR, VAL, ...) \
|
||||||
|
TEST_F(DerivationTest, TYPE ## _ ## NAME ## _to_json) { \
|
||||||
|
using nlohmann::literals::operator "" _json; \
|
||||||
|
ASSERT_EQ( \
|
||||||
|
STR ## _json, \
|
||||||
|
(TYPE { VAL }).toJSON(*store __VA_OPT__(,) __VA_ARGS__)); \
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_JSON(DerivationOutput, inputAddressed,
|
||||||
|
R"({
|
||||||
|
"path": "/nix/store/c015dhfh5l0lp6wxyvdn7bmwhbbr6hr9-drv-name-output-name"
|
||||||
|
})",
|
||||||
|
(DerivationOutput::InputAddressed {
|
||||||
|
.path = store->parseStorePath("/nix/store/c015dhfh5l0lp6wxyvdn7bmwhbbr6hr9-drv-name-output-name"),
|
||||||
|
}),
|
||||||
|
"drv-name", "output-name")
|
||||||
|
|
||||||
|
TEST_JSON(DerivationOutput, caFixed,
|
||||||
|
R"({
|
||||||
|
"hashAlgo": "r:sha256",
|
||||||
|
"hash": "894517c9163c896ec31a2adbd33c0681fd5f45b2c0ef08a64c92a03fb97f390f",
|
||||||
|
"path": "/nix/store/c015dhfh5l0lp6wxyvdn7bmwhbbr6hr9-drv-name-output-name"
|
||||||
|
})",
|
||||||
|
(DerivationOutput::CAFixed {
|
||||||
|
.hash = {
|
||||||
|
.method = FileIngestionMethod::Recursive,
|
||||||
|
.hash = Hash::parseAnyPrefixed("sha256-iUUXyRY8iW7DGirb0zwGgf1fRbLA7wimTJKgP7l/OQ8="),
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
"drv-name", "output-name")
|
||||||
|
|
||||||
|
TEST_JSON(DerivationOutput, caFloating,
|
||||||
|
R"({
|
||||||
|
"hashAlgo": "r:sha256"
|
||||||
|
})",
|
||||||
|
(DerivationOutput::CAFloating {
|
||||||
|
.method = FileIngestionMethod::Recursive,
|
||||||
|
.hashType = htSHA256,
|
||||||
|
}),
|
||||||
|
"drv-name", "output-name")
|
||||||
|
|
||||||
|
TEST_JSON(DerivationOutput, deferred,
|
||||||
|
R"({ })",
|
||||||
|
DerivationOutput::Deferred { },
|
||||||
|
"drv-name", "output-name")
|
||||||
|
|
||||||
|
TEST_JSON(DerivationOutput, impure,
|
||||||
|
R"({
|
||||||
|
"hashAlgo": "r:sha256",
|
||||||
|
"impure": true
|
||||||
|
})",
|
||||||
|
(DerivationOutput::Impure {
|
||||||
|
.method = FileIngestionMethod::Recursive,
|
||||||
|
.hashType = htSHA256,
|
||||||
|
}),
|
||||||
|
"drv-name", "output-name")
|
||||||
|
|
||||||
|
TEST_JSON(Derivation, impure,
|
||||||
|
R"({
|
||||||
|
"inputSrcs": [
|
||||||
|
"/nix/store/c015dhfh5l0lp6wxyvdn7bmwhbbr6hr9-dep1"
|
||||||
|
],
|
||||||
|
"inputDrvs": {
|
||||||
|
"/nix/store/c015dhfh5l0lp6wxyvdn7bmwhbbr6hr9-dep2.drv": [
|
||||||
|
"cat",
|
||||||
|
"dog"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"system": "wasm-sel4",
|
||||||
|
"builder": "foo",
|
||||||
|
"args": [
|
||||||
|
"bar",
|
||||||
|
"baz"
|
||||||
|
],
|
||||||
|
"outputs": {}
|
||||||
|
})",
|
||||||
|
({
|
||||||
|
Derivation drv;
|
||||||
|
drv.inputSrcs = {
|
||||||
|
store->parseStorePath("/nix/store/c015dhfh5l0lp6wxyvdn7bmwhbbr6hr9-dep1"),
|
||||||
|
};
|
||||||
|
drv.inputDrvs = {
|
||||||
|
{
|
||||||
|
store->parseStorePath("/nix/store/c015dhfh5l0lp6wxyvdn7bmwhbbr6hr9-dep2.drv"),
|
||||||
|
{
|
||||||
|
"cat",
|
||||||
|
"dog",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
drv.platform = "wasm-sel4";
|
||||||
|
drv.builder = "foo";
|
||||||
|
drv.args = {
|
||||||
|
"bar",
|
||||||
|
"baz",
|
||||||
|
};
|
||||||
|
drv;
|
||||||
|
}))
|
||||||
|
|
||||||
|
#undef TEST_JSON
|
||||||
|
|
||||||
|
}
|
|
@ -54,56 +54,8 @@ struct CmdShowDerivation : InstallablesCommand
|
||||||
for (auto & drvPath : drvPaths) {
|
for (auto & drvPath : drvPaths) {
|
||||||
if (!drvPath.isDerivation()) continue;
|
if (!drvPath.isDerivation()) continue;
|
||||||
|
|
||||||
json& drvObj = jsonRoot[store->printStorePath(drvPath)];
|
jsonRoot[store->printStorePath(drvPath)] =
|
||||||
|
store->readDerivation(drvPath).toJSON(*store);
|
||||||
auto drv = store->readDerivation(drvPath);
|
|
||||||
|
|
||||||
{
|
|
||||||
json& outputsObj = drvObj["outputs"];
|
|
||||||
outputsObj = json::object();
|
|
||||||
for (auto & [_outputName, output] : drv.outputs) {
|
|
||||||
auto & outputName = _outputName; // work around clang bug
|
|
||||||
auto& outputObj = outputsObj[outputName];
|
|
||||||
outputObj = json::object();
|
|
||||||
std::visit(overloaded {
|
|
||||||
[&](const DerivationOutput::InputAddressed & doi) {
|
|
||||||
outputObj["path"] = store->printStorePath(doi.path);
|
|
||||||
},
|
|
||||||
[&](const DerivationOutput::CAFixed & dof) {
|
|
||||||
outputObj["path"] = store->printStorePath(dof.path(*store, drv.name, outputName));
|
|
||||||
outputObj["hashAlgo"] = dof.hash.printMethodAlgo();
|
|
||||||
outputObj["hash"] = dof.hash.hash.to_string(Base16, false);
|
|
||||||
},
|
|
||||||
[&](const DerivationOutput::CAFloating & dof) {
|
|
||||||
outputObj["hashAlgo"] = makeFileIngestionPrefix(dof.method) + printHashType(dof.hashType);
|
|
||||||
},
|
|
||||||
[&](const DerivationOutput::Deferred &) {},
|
|
||||||
[&](const DerivationOutput::Impure & doi) {
|
|
||||||
outputObj["hashAlgo"] = makeFileIngestionPrefix(doi.method) + printHashType(doi.hashType);
|
|
||||||
outputObj["impure"] = true;
|
|
||||||
},
|
|
||||||
}, output.raw());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
auto& inputsList = drvObj["inputSrcs"];
|
|
||||||
inputsList = json::array();
|
|
||||||
for (auto & input : drv.inputSrcs)
|
|
||||||
inputsList.emplace_back(store->printStorePath(input));
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
auto& inputDrvsObj = drvObj["inputDrvs"];
|
|
||||||
inputDrvsObj = json::object();
|
|
||||||
for (auto & input : drv.inputDrvs)
|
|
||||||
inputDrvsObj[store->printStorePath(input.first)] = input.second;
|
|
||||||
}
|
|
||||||
|
|
||||||
drvObj["system"] = drv.platform;
|
|
||||||
drvObj["builder"] = drv.builder;
|
|
||||||
drvObj["args"] = drv.args;
|
|
||||||
drvObj["env"] = drv.env;
|
|
||||||
}
|
}
|
||||||
std::cout << jsonRoot.dump(2) << std::endl;
|
std::cout << jsonRoot.dump(2) << std::endl;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue