Skip to content

Commit 2704e1a

Browse files
committed
WIP JSON impls without store dir
If we depend on the store dir, our JSON serializers/deserializers take extra arguements, and that interfaces with the likes of various frameworks for associating these with types (e.g. nlohmann in C++, Serde in Rust, and Aeson in Haskell).
1 parent 7658f00 commit 2704e1a

File tree

12 files changed

+187
-11
lines changed

12 files changed

+187
-11
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo.drv"

src/libstore-tests/path.cc

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
#include "nix/store/path-regex.hh"
88
#include "nix/store/store-api.hh"
99

10-
#include "nix/util/tests/hash.hh"
10+
#include "nix/util/tests/characterization.hh"
1111
#include "nix/store/tests/libstore.hh"
1212
#include "nix/store/tests/path.hh"
1313

@@ -16,8 +16,17 @@ namespace nix {
1616
#define STORE_DIR "/nix/store/"
1717
#define HASH_PART "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q"
1818

19-
class StorePathTest : public LibStoreTest
20-
{};
19+
class StorePathTest : public CharacterizationTest, public LibStoreTest
20+
{
21+
std::filesystem::path unitTestData = getUnitTestData() / "store-path";
22+
23+
public:
24+
25+
std::filesystem::path goldenMaster(std::string_view testStem) const override
26+
{
27+
return unitTestData / testStem;
28+
}
29+
};
2130

2231
static std::regex nameRegex{std::string{nameRegexStr}};
2332

@@ -134,4 +143,33 @@ RC_GTEST_FIXTURE_PROP(StorePathTest, prop_check_regex_eq_parse, ())
134143

135144
#endif
136145

146+
/* ----------------------------------------------------------------------------
147+
* JSON
148+
* --------------------------------------------------------------------------*/
149+
150+
using nlohmann::json;
151+
152+
#define TEST_JSON(FIXTURE, NAME, VAL) \
153+
static const StorePath NAME = VAL; \
154+
\
155+
TEST_F(FIXTURE, NAME##_from_json) \
156+
{ \
157+
readTest(#NAME ".json", [&](const auto & encoded_) { \
158+
auto encoded = json::parse(encoded_); \
159+
StorePath got = static_cast<StorePath>(encoded); \
160+
ASSERT_EQ(got, NAME); \
161+
}); \
162+
} \
163+
\
164+
TEST_F(FIXTURE, NAME##_to_json) \
165+
{ \
166+
writeTest( \
167+
#NAME ".json", \
168+
[&]() -> json { return static_cast<json>(NAME); }, \
169+
[](const auto & file) { return json::parse(readFile(file)); }, \
170+
[](const auto & file, const auto & got) { return writeFile(file, got.dump(2) + "\n"); }); \
171+
}
172+
173+
TEST_JSON(StorePathTest, simple, StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo.drv"});
174+
137175
} // namespace nix

src/libstore/include/nix/store/derivations.hh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -532,3 +532,6 @@ void writeDerivation(Sink & out, const StoreDirConfig & store, const BasicDeriva
532532
std::string hashPlaceholder(const OutputNameView outputName);
533533

534534
} // namespace nix
535+
536+
JSON_IMPL(nix::DerivationOutput)
537+
JSON_IMPL(nix::Derivation)

src/libstore/include/nix/store/derived-path.hh

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,4 +304,11 @@ typedef std::vector<DerivedPath> DerivedPaths;
304304
*/
305305
void drvRequireExperiment(
306306
const SingleDerivedPath & drv, const ExperimentalFeatureSettings & xpSettings = experimentalFeatureSettings);
307+
307308
} // namespace nix
309+
310+
JSON_IMPL(nix::DerivedPathOpaque)
311+
JSON_IMPL(nix::SingleDerivedPathBuilt)
312+
JSON_IMPL(nix::SingleDerivedPath)
313+
JSON_IMPL(nix::DerivedPathBuilt)
314+
JSON_IMPL(nix::DerivedPath)

src/libstore/include/nix/store/nar-info.hh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,5 @@ struct NarInfo : ValidPathInfo
4646
};
4747

4848
} // namespace nix
49+
50+
JSON_IMPL(nix::NarInfo)

src/libstore/include/nix/store/path-info.hh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,3 +191,5 @@ static_assert(std::is_move_constructible_v<ValidPathInfo>);
191191
using ValidPathInfos = std::map<StorePath, ValidPathInfo>;
192192

193193
} // namespace nix
194+
195+
JSON_IMPL(nix::ValidPathInfo)

src/libstore/include/nix/store/path.hh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <string_view>
55

66
#include "nix/util/types.hh"
7+
#include "nix/util/json-impls.hh"
78

89
namespace nix {
910

@@ -101,3 +102,5 @@ struct hash<nix::StorePath>
101102
};
102103

103104
} // namespace std
105+
106+
JSON_IMPL(nix::StorePath)

src/libstore/path.cc

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1+
#include <nlohmann/json.hpp>
2+
13
#include "nix/store/store-dir-config.hh"
4+
#include "nix/util/json-utils.hh"
25

36
namespace nix {
47

@@ -75,3 +78,19 @@ StorePath StorePath::random(std::string_view name)
7578
}
7679

7780
} // namespace nix
81+
82+
namespace nlohmann {
83+
84+
using namespace nix;
85+
86+
StorePath adl_serializer<StorePath>::from_json(const json & json)
87+
{
88+
return StorePath{getString(json)};
89+
}
90+
91+
void adl_serializer<StorePath>::to_json(json & json, StorePath storePath)
92+
{
93+
json = storePath.to_string();
94+
}
95+
96+
} // namespace nlohmann
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"algorithm": "sha256",
3+
"format": "base64",
4+
"hash": "8OTC92xYkW7CWPJGhRvqCR0U1CR6L8PhhpRGGxgW4Ts="
5+
}

src/libutil-tests/hash.cc

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
#include <regex>
22

33
#include <gtest/gtest.h>
4+
#include <nlohmann/json.hpp>
45

56
#include "nix/util/hash.hh"
7+
#include "nix/util/tests/characterization.hh"
68

79
namespace nix {
810

9-
class BLAKE3HashTest : public virtual ::testing::Test
11+
class HashTest : public CharacterizationTest
1012
{
13+
std::filesystem::path unitTestData = getUnitTestData() / "hash";
14+
1115
public:
1216

1317
/**
@@ -16,8 +20,14 @@ class BLAKE3HashTest : public virtual ::testing::Test
1620
*/
1721
ExperimentalFeatureSettings mockXpSettings;
1822

19-
private:
23+
std::filesystem::path goldenMaster(std::string_view testStem) const override
24+
{
25+
return unitTestData / testStem;
26+
}
27+
};
2028

29+
class BLAKE3HashTest : public HashTest
30+
{
2131
void SetUp() override
2232
{
2333
mockXpSettings.set("experimental-features", "blake3-hashes");
@@ -153,4 +163,34 @@ TEST(hashFormat, testParseHashFormatOptException)
153163
{
154164
ASSERT_EQ(parseHashFormatOpt("sha0042"), std::nullopt);
155165
}
166+
167+
/* ----------------------------------------------------------------------------
168+
* JSON
169+
* --------------------------------------------------------------------------*/
170+
171+
using nlohmann::json;
172+
173+
#define TEST_JSON(FIXTURE, NAME, VAL) \
174+
static const Hash NAME = VAL; \
175+
\
176+
TEST_F(FIXTURE, NAME##_from_json) \
177+
{ \
178+
readTest(#NAME ".json", [&](const auto & encoded_) { \
179+
auto encoded = json::parse(encoded_); \
180+
Hash got = static_cast<Hash>(encoded); \
181+
ASSERT_EQ(got, NAME); \
182+
}); \
183+
} \
184+
\
185+
TEST_F(FIXTURE, NAME##_to_json) \
186+
{ \
187+
writeTest( \
188+
#NAME ".json", \
189+
[&]() -> json { return static_cast<json>(NAME); }, \
190+
[](const auto & file) { return json::parse(readFile(file)); }, \
191+
[](const auto & file, const auto & got) { return writeFile(file, got.dump(2) + "\n"); }); \
192+
}
193+
194+
TEST_JSON(HashTest, simple, hashString(HashAlgorithm::SHA256, "asdf"));
195+
156196
} // namespace nix

0 commit comments

Comments
 (0)