mirror of
https://github.com/NixOS/nix.git
synced 2025-11-15 06:52:43 +01:00
Make the JSON format for derivation use basename store paths
See #13570 for details --- the idea is that included the store dir in store paths makes systematic JSON parting with e.g. Serde, Aeson, nlohmann, or similiar harder. After talking to Eelco, we are changing the `Derivation` format right away because not only is `nix derivation` technically experimental, we think it is also less widely used in practice than, say, `nix path-info`. Progress on #13570
This commit is contained in:
parent
187520ce88
commit
9d7229a2a4
31 changed files with 275 additions and 140 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue