1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-11-14 06:22:42 +01:00

Merge pull request #13980 from obsidiansystems/drv-json-issue-13570

Make the JSON format for derivation use basename store paths
This commit is contained in:
Robert Hensing 2025-09-17 23:31:41 +02:00 committed by GitHub
commit b4fcb64276
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
31 changed files with 275 additions and 140 deletions

View file

@ -181,7 +181,7 @@ nix_derivation * nix_derivation_from_json(nix_c_context * context, Store * store
if (context)
context->last_err_code = NIX_OK;
try {
auto drv = nix::Derivation::fromJSON(*store->ptr, nlohmann::json::parse(json));
auto drv = static_cast<nix::Derivation>(nlohmann::json::parse(json));
auto drvPath = nix::writeDerivation(*store->ptr, drv, nix::NoRepair, /* read only */ true);

View file

@ -21,5 +21,6 @@
"method": "nar"
}
},
"system": "my-system"
"system": "my-system",
"version": 3
}

View file

@ -32,5 +32,6 @@
],
"system": "my-system"
},
"system": "my-system"
"system": "my-system",
"version": 3
}

View file

@ -10,14 +10,14 @@
"out": "/1rz4g4znpzjwh1xymhjpm42vipw92pr73vdgl6xs1hycac8kf2n9"
},
"inputDrvs": {
"/nix/store/j56sf12rxpcv5swr14vsjn5cwm6bj03h-foo.drv": {
"j56sf12rxpcv5swr14vsjn5cwm6bj03h-foo.drv": {
"dynamicOutputs": {},
"outputs": [
"dev",
"out"
]
},
"/nix/store/qnml92yh97a6fbrs2m5qg5cqlc8vni58-bar.drv": {
"qnml92yh97a6fbrs2m5qg5cqlc8vni58-bar.drv": {
"dynamicOutputs": {},
"outputs": [
"dev",
@ -26,7 +26,7 @@
}
},
"inputSrcs": [
"/nix/store/qnml92yh97a6fbrs2m5qg5cqlc8vni58-bar.drv"
"qnml92yh97a6fbrs2m5qg5cqlc8vni58-bar.drv"
],
"name": "advanced-attributes-structured-attrs",
"outputs": {
@ -100,5 +100,6 @@
],
"system": "my-system"
},
"system": "my-system"
"system": "my-system",
"version": 3
}

View file

@ -26,14 +26,14 @@
"system": "my-system"
},
"inputDrvs": {
"/nix/store/j56sf12rxpcv5swr14vsjn5cwm6bj03h-foo.drv": {
"j56sf12rxpcv5swr14vsjn5cwm6bj03h-foo.drv": {
"dynamicOutputs": {},
"outputs": [
"dev",
"out"
]
},
"/nix/store/qnml92yh97a6fbrs2m5qg5cqlc8vni58-bar.drv": {
"qnml92yh97a6fbrs2m5qg5cqlc8vni58-bar.drv": {
"dynamicOutputs": {},
"outputs": [
"dev",
@ -42,7 +42,7 @@
}
},
"inputSrcs": [
"/nix/store/qnml92yh97a6fbrs2m5qg5cqlc8vni58-bar.drv"
"qnml92yh97a6fbrs2m5qg5cqlc8vni58-bar.drv"
],
"name": "advanced-attributes",
"outputs": {
@ -51,5 +51,6 @@
"method": "nar"
}
},
"system": "my-system"
"system": "my-system",
"version": 3
}

View file

@ -19,5 +19,6 @@
"method": "nar"
}
},
"system": "x86_64-linux"
"system": "x86_64-linux",
"version": 3
}

View file

@ -8,7 +8,7 @@
"BIG_BAD": "WOLF"
},
"inputDrvs": {
"/nix/store/c015dhfh5l0lp6wxyvdn7bmwhbbr6hr9-dep2.drv": {
"c015dhfh5l0lp6wxyvdn7bmwhbbr6hr9-dep2.drv": {
"dynamicOutputs": {
"cat": {
"dynamicOutputs": {},
@ -30,9 +30,10 @@
}
},
"inputSrcs": [
"/nix/store/c015dhfh5l0lp6wxyvdn7bmwhbbr6hr9-dep1"
"c015dhfh5l0lp6wxyvdn7bmwhbbr6hr9-dep1"
],
"name": "dyn-dep-derivation",
"outputs": {},
"system": "wasm-sel4"
"system": "wasm-sel4",
"version": 3
}

View file

@ -15,8 +15,9 @@
"name": "advanced-attributes-defaults",
"outputs": {
"out": {
"path": "/nix/store/1qsc7svv43m4dw2prh6mvyf7cai5czji-advanced-attributes-defaults"
"path": "1qsc7svv43m4dw2prh6mvyf7cai5czji-advanced-attributes-defaults"
}
},
"system": "my-system"
"system": "my-system",
"version": 3
}

View file

@ -13,10 +13,10 @@
"name": "advanced-attributes-structured-attrs-defaults",
"outputs": {
"dev": {
"path": "/nix/store/8bazivnbipbyi569623skw5zm91z6kc2-advanced-attributes-structured-attrs-defaults-dev"
"path": "8bazivnbipbyi569623skw5zm91z6kc2-advanced-attributes-structured-attrs-defaults-dev"
},
"out": {
"path": "/nix/store/f8f8nvnx32bxvyxyx2ff7akbvwhwd9dw-advanced-attributes-structured-attrs-defaults"
"path": "f8f8nvnx32bxvyxyx2ff7akbvwhwd9dw-advanced-attributes-structured-attrs-defaults"
}
},
"structuredAttrs": {
@ -28,5 +28,6 @@
],
"system": "my-system"
},
"system": "my-system"
"system": "my-system",
"version": 3
}

View file

@ -10,14 +10,14 @@
"out": "/nix/store/7cxy4zx1vqc885r4jl2l64pymqbdmhii-advanced-attributes-structured-attrs"
},
"inputDrvs": {
"/nix/store/afc3vbjbzql750v2lp8gxgaxsajphzih-foo.drv": {
"afc3vbjbzql750v2lp8gxgaxsajphzih-foo.drv": {
"dynamicOutputs": {},
"outputs": [
"dev",
"out"
]
},
"/nix/store/vj2i49jm2868j2fmqvxm70vlzmzvgv14-bar.drv": {
"vj2i49jm2868j2fmqvxm70vlzmzvgv14-bar.drv": {
"dynamicOutputs": {},
"outputs": [
"dev",
@ -26,18 +26,18 @@
}
},
"inputSrcs": [
"/nix/store/vj2i49jm2868j2fmqvxm70vlzmzvgv14-bar.drv"
"vj2i49jm2868j2fmqvxm70vlzmzvgv14-bar.drv"
],
"name": "advanced-attributes-structured-attrs",
"outputs": {
"bin": {
"path": "/nix/store/33qms3h55wlaspzba3brlzlrm8m2239g-advanced-attributes-structured-attrs-bin"
"path": "33qms3h55wlaspzba3brlzlrm8m2239g-advanced-attributes-structured-attrs-bin"
},
"dev": {
"path": "/nix/store/wyfgwsdi8rs851wmy1xfzdxy7y5vrg5l-advanced-attributes-structured-attrs-dev"
"path": "wyfgwsdi8rs851wmy1xfzdxy7y5vrg5l-advanced-attributes-structured-attrs-dev"
},
"out": {
"path": "/nix/store/7cxy4zx1vqc885r4jl2l64pymqbdmhii-advanced-attributes-structured-attrs"
"path": "7cxy4zx1vqc885r4jl2l64pymqbdmhii-advanced-attributes-structured-attrs"
}
},
"structuredAttrs": {
@ -95,5 +95,6 @@
],
"system": "my-system"
},
"system": "my-system"
"system": "my-system",
"version": 3
}

View file

@ -24,14 +24,14 @@
"system": "my-system"
},
"inputDrvs": {
"/nix/store/afc3vbjbzql750v2lp8gxgaxsajphzih-foo.drv": {
"afc3vbjbzql750v2lp8gxgaxsajphzih-foo.drv": {
"dynamicOutputs": {},
"outputs": [
"dev",
"out"
]
},
"/nix/store/vj2i49jm2868j2fmqvxm70vlzmzvgv14-bar.drv": {
"vj2i49jm2868j2fmqvxm70vlzmzvgv14-bar.drv": {
"dynamicOutputs": {},
"outputs": [
"dev",
@ -40,13 +40,14 @@
}
},
"inputSrcs": [
"/nix/store/vj2i49jm2868j2fmqvxm70vlzmzvgv14-bar.drv"
"vj2i49jm2868j2fmqvxm70vlzmzvgv14-bar.drv"
],
"name": "advanced-attributes",
"outputs": {
"out": {
"path": "/nix/store/wyhpwd748pns4k7svh48wdrc8kvjk0ra-advanced-attributes"
"path": "wyhpwd748pns4k7svh48wdrc8kvjk0ra-advanced-attributes"
}
},
"system": "my-system"
"system": "my-system",
"version": 3
}

View file

@ -1,6 +1,5 @@
{
"hash": "894517c9163c896ec31a2adbd33c0681fd5f45b2c0ef08a64c92a03fb97f390f",
"hashAlgo": "sha256",
"method": "flat",
"path": "/nix/store/rhcg9h16sqvlbpsa6dqm57sbr2al6nzg-drv-name-output-name"
"method": "flat"
}

View file

@ -1,6 +1,5 @@
{
"hash": "894517c9163c896ec31a2adbd33c0681fd5f45b2c0ef08a64c92a03fb97f390f",
"hashAlgo": "sha256",
"method": "nar",
"path": "/nix/store/c015dhfh5l0lp6wxyvdn7bmwhbbr6hr9-drv-name-output-name"
"method": "nar"
}

View file

@ -1,6 +1,5 @@
{
"hash": "894517c9163c896ec31a2adbd33c0681fd5f45b2c0ef08a64c92a03fb97f390f",
"hashAlgo": "sha256",
"method": "text",
"path": "/nix/store/6s1zwabh956jvhv4w9xcdb5jiyanyxg1-drv-name-output-name"
"method": "text"
}

View file

@ -1,3 +1,3 @@
{
"path": "/nix/store/c015dhfh5l0lp6wxyvdn7bmwhbbr6hr9-drv-name-output-name"
"path": "c015dhfh5l0lp6wxyvdn7bmwhbbr6hr9-drv-name-output-name"
}

View file

@ -8,7 +8,7 @@
"BIG_BAD": "WOLF"
},
"inputDrvs": {
"/nix/store/c015dhfh5l0lp6wxyvdn7bmwhbbr6hr9-dep2.drv": {
"c015dhfh5l0lp6wxyvdn7bmwhbbr6hr9-dep2.drv": {
"dynamicOutputs": {},
"outputs": [
"cat",
@ -17,9 +17,10 @@
}
},
"inputSrcs": [
"/nix/store/c015dhfh5l0lp6wxyvdn7bmwhbbr6hr9-dep1"
"c015dhfh5l0lp6wxyvdn7bmwhbbr6hr9-dep1"
],
"name": "simple-derivation",
"outputs": {},
"system": "wasm-sel4"
"system": "wasm-sel4",
"version": 3
}

View file

@ -0,0 +1 @@
"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo.drv"

View file

@ -51,45 +51,44 @@ using BothFixtures = ::testing::Types<DerivationAdvancedAttrsTest, CaDerivationA
TYPED_TEST_SUITE(DerivationAdvancedAttrsBothTest, BothFixtures);
#define TEST_ATERM_JSON(STEM, NAME) \
TYPED_TEST(DerivationAdvancedAttrsBothTest, Derivation_##STEM##_from_json) \
{ \
this->readTest(NAME ".json", [&](const auto & encoded_) { \
auto encoded = json::parse(encoded_); \
/* Use DRV file instead of C++ literal as source of truth. */ \
auto aterm = readFile(this->goldenMaster(NAME ".drv")); \
auto expected = parseDerivation(*this->store, std::move(aterm), NAME, this->mockXpSettings); \
Derivation got = Derivation::fromJSON(*this->store, encoded, this->mockXpSettings); \
EXPECT_EQ(got, expected); \
}); \
} \
\
TYPED_TEST(DerivationAdvancedAttrsBothTest, Derivation_##STEM##_to_json) \
{ \
this->writeTest( \
NAME ".json", \
[&]() -> json { \
/* Use DRV file instead of C++ literal as source of truth. */ \
auto aterm = readFile(this->goldenMaster(NAME ".drv")); \
return parseDerivation(*this->store, std::move(aterm), NAME, this->mockXpSettings) \
.toJSON(*this->store); \
}, \
[](const auto & file) { return json::parse(readFile(file)); }, \
[](const auto & file, const auto & got) { return writeFile(file, got.dump(2) + "\n"); }); \
} \
\
TYPED_TEST(DerivationAdvancedAttrsBothTest, Derivation_##STEM##_from_aterm) \
{ \
this->readTest(NAME ".drv", [&](auto encoded) { \
/* Use JSON file instead of C++ literal as source of truth. */ \
auto json = json::parse(readFile(this->goldenMaster(NAME ".json"))); \
auto expected = Derivation::fromJSON(*this->store, json, this->mockXpSettings); \
auto got = parseDerivation(*this->store, std::move(encoded), NAME, this->mockXpSettings); \
EXPECT_EQ(got.toJSON(*this->store), expected.toJSON(*this->store)); \
EXPECT_EQ(got, expected); \
}); \
} \
\
#define TEST_ATERM_JSON(STEM, NAME) \
TYPED_TEST(DerivationAdvancedAttrsBothTest, Derivation_##STEM##_from_json) \
{ \
this->readTest(NAME ".json", [&](const auto & encoded_) { \
auto encoded = json::parse(encoded_); \
/* Use DRV file instead of C++ literal as source of truth. */ \
auto aterm = readFile(this->goldenMaster(NAME ".drv")); \
auto expected = parseDerivation(*this->store, std::move(aterm), NAME, this->mockXpSettings); \
Derivation got = Derivation::fromJSON(encoded, this->mockXpSettings); \
EXPECT_EQ(got, expected); \
}); \
} \
\
TYPED_TEST(DerivationAdvancedAttrsBothTest, Derivation_##STEM##_to_json) \
{ \
this->writeTest( \
NAME ".json", \
[&]() -> json { \
/* Use DRV file instead of C++ literal as source of truth. */ \
auto aterm = readFile(this->goldenMaster(NAME ".drv")); \
return parseDerivation(*this->store, std::move(aterm), NAME, this->mockXpSettings).toJSON(); \
}, \
[](const auto & file) { return json::parse(readFile(file)); }, \
[](const auto & file, const auto & got) { return writeFile(file, got.dump(2) + "\n"); }); \
} \
\
TYPED_TEST(DerivationAdvancedAttrsBothTest, Derivation_##STEM##_from_aterm) \
{ \
this->readTest(NAME ".drv", [&](auto encoded) { \
/* Use JSON file instead of C++ literal as source of truth. */ \
auto json = json::parse(readFile(this->goldenMaster(NAME ".json"))); \
auto expected = Derivation::fromJSON(json, this->mockXpSettings); \
auto got = parseDerivation(*this->store, std::move(encoded), NAME, this->mockXpSettings); \
EXPECT_EQ(got.toJSON(), expected.toJSON()); \
EXPECT_EQ(got, expected); \
}); \
} \
\
/* No corresponding write test, because we need to read the drv to write the json file */
TEST_ATERM_JSON(advancedAttributes, "advanced-attributes-defaults");

View file

@ -66,24 +66,24 @@ TEST_F(DynDerivationTest, BadATerm_oldVersionDynDeps)
FormatError);
}
#define TEST_JSON(FIXTURE, NAME, VAL, DRV_NAME, OUTPUT_NAME) \
TEST_F(FIXTURE, DerivationOutput_##NAME##_from_json) \
{ \
readTest("output-" #NAME ".json", [&](const auto & encoded_) { \
auto encoded = json::parse(encoded_); \
DerivationOutput got = DerivationOutput::fromJSON(*store, DRV_NAME, OUTPUT_NAME, encoded, mockXpSettings); \
DerivationOutput expected{VAL}; \
ASSERT_EQ(got, expected); \
}); \
} \
\
TEST_F(FIXTURE, DerivationOutput_##NAME##_to_json) \
{ \
writeTest( \
"output-" #NAME ".json", \
[&]() -> json { return DerivationOutput{(VAL)}.toJSON(*store, (DRV_NAME), (OUTPUT_NAME)); }, \
[](const auto & file) { return json::parse(readFile(file)); }, \
[](const auto & file, const auto & got) { return writeFile(file, got.dump(2) + "\n"); }); \
#define TEST_JSON(FIXTURE, NAME, VAL, DRV_NAME, OUTPUT_NAME) \
TEST_F(FIXTURE, DerivationOutput_##NAME##_from_json) \
{ \
readTest("output-" #NAME ".json", [&](const auto & encoded_) { \
auto encoded = json::parse(encoded_); \
DerivationOutput got = DerivationOutput::fromJSON(DRV_NAME, OUTPUT_NAME, encoded, mockXpSettings); \
DerivationOutput expected{VAL}; \
ASSERT_EQ(got, expected); \
}); \
} \
\
TEST_F(FIXTURE, DerivationOutput_##NAME##_to_json) \
{ \
writeTest( \
"output-" #NAME ".json", \
[&]() -> json { return DerivationOutput{(VAL)}.toJSON((DRV_NAME), (OUTPUT_NAME)); }, \
[](const auto & file) { return json::parse(readFile(file)); }, \
[](const auto & file, const auto & got) { return writeFile(file, got.dump(2) + "\n"); }); \
}
TEST_JSON(
@ -164,7 +164,7 @@ TEST_JSON(
readTest(#NAME ".json", [&](const auto & encoded_) { \
auto encoded = json::parse(encoded_); \
Derivation expected{VAL}; \
Derivation got = Derivation::fromJSON(*store, encoded, mockXpSettings); \
Derivation got = Derivation::fromJSON(encoded, mockXpSettings); \
ASSERT_EQ(got, expected); \
}); \
} \
@ -173,7 +173,7 @@ TEST_JSON(
{ \
writeTest( \
#NAME ".json", \
[&]() -> json { return Derivation{VAL}.toJSON(*store); }, \
[&]() -> json { return Derivation{VAL}.toJSON(); }, \
[](const auto & file) { return json::parse(readFile(file)); }, \
[](const auto & file, const auto & got) { return writeFile(file, got.dump(2) + "\n"); }); \
}
@ -184,7 +184,7 @@ TEST_JSON(
readTest(#NAME ".drv", [&](auto encoded) { \
Derivation expected{VAL}; \
auto got = parseDerivation(*store, std::move(encoded), DRV_NAME, mockXpSettings); \
ASSERT_EQ(got.toJSON(*store), expected.toJSON(*store)); \
ASSERT_EQ(got.toJSON(), expected.toJSON()); \
ASSERT_EQ(got, expected); \
}); \
} \

View file

@ -7,7 +7,7 @@
#include "nix/store/path-regex.hh"
#include "nix/store/store-api.hh"
#include "nix/util/tests/hash.hh"
#include "nix/util/tests/characterization.hh"
#include "nix/store/tests/libstore.hh"
#include "nix/store/tests/path.hh"
@ -16,8 +16,17 @@ namespace nix {
#define STORE_DIR "/nix/store/"
#define HASH_PART "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q"
class StorePathTest : public LibStoreTest
{};
class StorePathTest : public CharacterizationTest, public LibStoreTest
{
std::filesystem::path unitTestData = getUnitTestData() / "store-path";
public:
std::filesystem::path goldenMaster(std::string_view testStem) const override
{
return unitTestData / testStem;
}
};
static std::regex nameRegex{std::string{nameRegexStr}};
@ -134,4 +143,33 @@ RC_GTEST_FIXTURE_PROP(StorePathTest, prop_check_regex_eq_parse, ())
#endif
/* ----------------------------------------------------------------------------
* JSON
* --------------------------------------------------------------------------*/
using nlohmann::json;
#define TEST_JSON(FIXTURE, NAME, VAL) \
static const StorePath NAME = VAL; \
\
TEST_F(FIXTURE, NAME##_from_json) \
{ \
readTest(#NAME ".json", [&](const auto & encoded_) { \
auto encoded = json::parse(encoded_); \
StorePath got = static_cast<StorePath>(encoded); \
ASSERT_EQ(got, NAME); \
}); \
} \
\
TEST_F(FIXTURE, NAME##_to_json) \
{ \
writeTest( \
#NAME ".json", \
[&]() -> json { return static_cast<json>(NAME); }, \
[](const auto & file) { return json::parse(readFile(file)); }, \
[](const auto & file, const auto & got) { return writeFile(file, got.dump(2) + "\n"); }); \
}
TEST_JSON(StorePathTest, simple, StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo.drv"});
} // namespace nix

View file

@ -1257,15 +1257,14 @@ void Derivation::checkInvariants(Store & store, const StorePath & drvPath) const
const Hash impureOutputHash = hashString(HashAlgorithm::SHA256, "impure");
nlohmann::json
DerivationOutput::toJSON(const StoreDirConfig & store, std::string_view drvName, OutputNameView outputName) const
nlohmann::json DerivationOutput::toJSON(std::string_view drvName, OutputNameView outputName) const
{
nlohmann::json res = nlohmann::json::object();
std::visit(
overloaded{
[&](const DerivationOutput::InputAddressed & doi) { res["path"] = store.printStorePath(doi.path); },
[&](const DerivationOutput::InputAddressed & doi) { res["path"] = doi.path; },
[&](const DerivationOutput::CAFixed & dof) {
res["path"] = store.printStorePath(dof.path(store, drvName, outputName));
// res["path"] = dof.path(store, drvName, outputName);
res["method"] = std::string{dof.ca.method.render()};
res["hashAlgo"] = printHashAlgo(dof.ca.hash.algo);
res["hash"] = dof.ca.hash.to_string(HashFormat::Base16, false);
@ -1287,7 +1286,6 @@ DerivationOutput::toJSON(const StoreDirConfig & store, std::string_view drvName,
}
DerivationOutput DerivationOutput::fromJSON(
const StoreDirConfig & store,
std::string_view drvName,
OutputNameView outputName,
const nlohmann::json & _json,
@ -1310,11 +1308,11 @@ DerivationOutput DerivationOutput::fromJSON(
if (keys == (std::set<std::string_view>{"path"})) {
return DerivationOutput::InputAddressed{
.path = store.parseStorePath(getString(valueAt(json, "path"))),
.path = valueAt(json, "path"),
};
}
else if (keys == (std::set<std::string_view>{"path", "method", "hashAlgo", "hash"})) {
else if (keys == (std::set<std::string_view>{"method", "hashAlgo", "hash"})) {
auto [method, hashAlgo] = methodAlgo();
auto dof = DerivationOutput::CAFixed{
.ca =
@ -1323,8 +1321,10 @@ DerivationOutput DerivationOutput::fromJSON(
.hash = Hash::parseNonSRIUnprefixed(getString(valueAt(json, "hash")), hashAlgo),
},
};
if (dof.path(store, drvName, outputName) != store.parseStorePath(getString(valueAt(json, "path"))))
#if 0
if (dof.path(store, drvName, outputName) != static_cast<StorePath>(valueAt(json, "path")))
throw Error("Path doesn't match derivation output");
#endif
return dof;
}
@ -1355,17 +1355,19 @@ DerivationOutput DerivationOutput::fromJSON(
}
}
nlohmann::json Derivation::toJSON(const StoreDirConfig & store) const
nlohmann::json Derivation::toJSON() const
{
nlohmann::json res = nlohmann::json::object();
res["name"] = name;
res["version"] = 3;
{
nlohmann::json & outputsObj = res["outputs"];
outputsObj = nlohmann::json::object();
for (auto & [outputName, output] : outputs) {
outputsObj[outputName] = output.toJSON(store, name, outputName);
outputsObj[outputName] = output.toJSON(name, outputName);
}
}
@ -1373,7 +1375,7 @@ nlohmann::json Derivation::toJSON(const StoreDirConfig & store) const
auto & inputsList = res["inputSrcs"];
inputsList = nlohmann::json ::array();
for (auto & input : inputSrcs)
inputsList.emplace_back(store.printStorePath(input));
inputsList.emplace_back(input);
}
{
@ -1393,7 +1395,7 @@ nlohmann::json Derivation::toJSON(const StoreDirConfig & store) const
auto & inputDrvsObj = res["inputDrvs"];
inputDrvsObj = nlohmann::json::object();
for (auto & [inputDrv, inputNode] : inputDrvs.map) {
inputDrvsObj[store.printStorePath(inputDrv)] = doInput(inputNode);
inputDrvsObj[inputDrv.to_string()] = doInput(inputNode);
}
}
}
@ -1409,8 +1411,7 @@ nlohmann::json Derivation::toJSON(const StoreDirConfig & store) const
return res;
}
Derivation Derivation::fromJSON(
const StoreDirConfig & store, const nlohmann::json & _json, const ExperimentalFeatureSettings & xpSettings)
Derivation Derivation::fromJSON(const nlohmann::json & _json, const ExperimentalFeatureSettings & xpSettings)
{
using nlohmann::detail::value_t;
@ -1420,11 +1421,14 @@ Derivation Derivation::fromJSON(
res.name = getString(valueAt(json, "name"));
if (valueAt(json, "version") != 3)
throw Error("Only derivation format version 3 is currently supported.");
try {
auto outputs = getObject(valueAt(json, "outputs"));
for (auto & [outputName, output] : outputs) {
res.outputs.insert_or_assign(
outputName, DerivationOutput::fromJSON(store, res.name, outputName, output, xpSettings));
outputName, DerivationOutput::fromJSON(res.name, outputName, output, xpSettings));
}
} catch (Error & e) {
e.addTrace({}, "while reading key 'outputs'");
@ -1434,7 +1438,7 @@ Derivation Derivation::fromJSON(
try {
auto inputSrcs = getArray(valueAt(json, "inputSrcs"));
for (auto & input : inputSrcs)
res.inputSrcs.insert(store.parseStorePath(static_cast<const std::string &>(input)));
res.inputSrcs.insert(input);
} catch (Error & e) {
e.addTrace({}, "while reading key 'inputSrcs'");
throw;
@ -1455,7 +1459,7 @@ Derivation Derivation::fromJSON(
};
auto drvs = getObject(valueAt(json, "inputDrvs"));
for (auto & [inputDrvPath, inputOutputs] : drvs)
res.inputDrvs.map[store.parseStorePath(inputDrvPath)] = doInput(inputOutputs);
res.inputDrvs.map[StorePath{inputDrvPath}] = doInput(inputOutputs);
} catch (Error & e) {
e.addTrace({}, "while reading key 'inputDrvs'");
throw;
@ -1480,3 +1484,19 @@ Derivation Derivation::fromJSON(
}
} // namespace nix
namespace nlohmann {
using namespace nix;
Derivation adl_serializer<Derivation>::from_json(const json & json)
{
return Derivation::fromJSON(json);
}
void adl_serializer<Derivation>::to_json(json & json, Derivation c)
{
json = c.toJSON();
}
} // namespace nlohmann

View file

@ -135,12 +135,11 @@ struct DerivationOutput
std::optional<StorePath>
path(const StoreDirConfig & store, std::string_view drvName, OutputNameView outputName) const;
nlohmann::json toJSON(const StoreDirConfig & store, std::string_view drvName, OutputNameView outputName) const;
nlohmann::json toJSON(std::string_view drvName, OutputNameView outputName) const;
/**
* @param xpSettings Stop-gap to avoid globals during unit tests.
*/
static DerivationOutput fromJSON(
const StoreDirConfig & store,
std::string_view drvName,
OutputNameView outputName,
const nlohmann::json & json,
@ -394,11 +393,9 @@ struct Derivation : BasicDerivation
{
}
nlohmann::json toJSON(const StoreDirConfig & store) const;
static Derivation fromJSON(
const StoreDirConfig & store,
const nlohmann::json & json,
const ExperimentalFeatureSettings & xpSettings = experimentalFeatureSettings);
nlohmann::json toJSON() const;
static Derivation
fromJSON(const nlohmann::json & json, const ExperimentalFeatureSettings & xpSettings = experimentalFeatureSettings);
bool operator==(const Derivation &) const = default;
// TODO libc++ 16 (used by darwin) missing `std::map::operator <=>`, can't do yet.
@ -542,3 +539,5 @@ void writeDerivation(Sink & out, const StoreDirConfig & store, const BasicDeriva
std::string hashPlaceholder(const OutputNameView outputName);
} // namespace nix
JSON_IMPL(nix::Derivation)

View file

@ -4,6 +4,8 @@
#include <string_view>
#include "nix/util/types.hh"
#include "nix/util/json-impls.hh"
#include "nix/util/json-non-null.hh"
namespace nix {
@ -87,6 +89,10 @@ typedef std::vector<StorePath> StorePaths;
*/
constexpr std::string_view drvExtension = ".drv";
template<>
struct json_avoids_null<StorePath> : std::true_type
{};
} // namespace nix
namespace std {
@ -101,3 +107,5 @@ struct hash<nix::StorePath>
};
} // namespace std
JSON_IMPL(nix::StorePath)

View file

@ -1,4 +1,7 @@
#include <nlohmann/json.hpp>
#include "nix/store/store-dir-config.hh"
#include "nix/util/json-utils.hh"
namespace nix {
@ -75,3 +78,19 @@ StorePath StorePath::random(std::string_view name)
}
} // namespace nix
namespace nlohmann {
using namespace nix;
StorePath adl_serializer<StorePath>::from_json(const json & json)
{
return StorePath{getString(json)};
}
void adl_serializer<StorePath>::to_json(json & json, StorePath storePath)
{
json = storePath.to_string();
}
} // namespace nlohmann

View file

@ -33,7 +33,7 @@ struct CmdAddDerivation : MixDryRun, StoreCommand
{
auto json = nlohmann::json::parse(drainFD(STDIN_FILENO));
auto drv = Derivation::fromJSON(*store, json);
auto drv = Derivation::fromJSON(json);
auto drvPath = writeDerivation(*store, drv, NoRepair, /* read only */ dryRun);

View file

@ -58,7 +58,7 @@ struct CmdShowDerivation : InstallablesCommand, MixPrintJSON
if (!drvPath.isDerivation())
continue;
jsonRoot[store->printStorePath(drvPath)] = store->readDerivation(drvPath).toJSON(*store);
jsonRoot[drvPath.to_string()] = store->readDerivation(drvPath).toJSON();
}
printJSON(jsonRoot);
}