forked from lix-project/lix
Remove default constructor from OutputsSpec
This forces us to be explicit. It also requires to rework how `from_json` works. A `JSON_IMPL` is added to assist with this.
This commit is contained in:
parent
114a6e2b09
commit
5ba6e5d0d9
12 changed files with 103 additions and 49 deletions
|
@ -827,7 +827,7 @@ std::vector<std::shared_ptr<Installable>> SourceExprCommand::parseInstallables(
|
||||||
return storePath.isDerivation()
|
return storePath.isDerivation()
|
||||||
? (DerivedPath) DerivedPath::Built {
|
? (DerivedPath) DerivedPath::Built {
|
||||||
.drvPath = std::move(storePath),
|
.drvPath = std::move(storePath),
|
||||||
.outputs = {},
|
.outputs = OutputsSpec::All {},
|
||||||
}
|
}
|
||||||
: (DerivedPath) DerivedPath::Opaque {
|
: (DerivedPath) DerivedPath::Opaque {
|
||||||
.path = std::move(storePath),
|
.path = std::move(storePath),
|
||||||
|
|
|
@ -641,7 +641,12 @@ bool NixRepl::processLine(std::string line)
|
||||||
Path drvPathRaw = state->store->printStorePath(drvPath);
|
Path drvPathRaw = state->store->printStorePath(drvPath);
|
||||||
|
|
||||||
if (command == ":b" || command == ":bl") {
|
if (command == ":b" || command == ":bl") {
|
||||||
state->store->buildPaths({DerivedPath::Built{drvPath}});
|
state->store->buildPaths({
|
||||||
|
DerivedPath::Built {
|
||||||
|
.drvPath = drvPath,
|
||||||
|
.outputs = OutputsSpec::All { },
|
||||||
|
},
|
||||||
|
});
|
||||||
auto drv = state->store->readDerivation(drvPath);
|
auto drv = state->store->readDerivation(drvPath);
|
||||||
logger->cout("\nThis derivation produced the following outputs:");
|
logger->cout("\nThis derivation produced the following outputs:");
|
||||||
for (auto & [outputName, outputPath] : state->store->queryDerivationOutputMap(drvPath)) {
|
for (auto & [outputName, outputPath] : state->store->queryDerivationOutputMap(drvPath)) {
|
||||||
|
|
|
@ -80,7 +80,7 @@ BuildResult Store::buildDerivation(const StorePath & drvPath, const BasicDerivat
|
||||||
BuildMode buildMode)
|
BuildMode buildMode)
|
||||||
{
|
{
|
||||||
Worker worker(*this, *this);
|
Worker worker(*this, *this);
|
||||||
auto goal = worker.makeBasicDerivationGoal(drvPath, drv, {}, buildMode);
|
auto goal = worker.makeBasicDerivationGoal(drvPath, drv, OutputsSpec::All {}, buildMode);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
worker.run(Goals{goal});
|
worker.run(Goals{goal});
|
||||||
|
@ -89,7 +89,10 @@ BuildResult Store::buildDerivation(const StorePath & drvPath, const BasicDerivat
|
||||||
return BuildResult {
|
return BuildResult {
|
||||||
.status = BuildResult::MiscFailure,
|
.status = BuildResult::MiscFailure,
|
||||||
.errorMsg = e.msg(),
|
.errorMsg = e.msg(),
|
||||||
.path = DerivedPath::Built { .drvPath = drvPath },
|
.path = DerivedPath::Built {
|
||||||
|
.drvPath = drvPath,
|
||||||
|
.outputs = OutputsSpec::All { },
|
||||||
|
},
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -279,7 +279,12 @@ public:
|
||||||
|
|
||||||
conn->to.flush();
|
conn->to.flush();
|
||||||
|
|
||||||
BuildResult status { .path = DerivedPath::Built { .drvPath = drvPath } };
|
BuildResult status {
|
||||||
|
.path = DerivedPath::Built {
|
||||||
|
.drvPath = drvPath,
|
||||||
|
.outputs = OutputsSpec::All { },
|
||||||
|
},
|
||||||
|
};
|
||||||
status.status = (BuildResult::Status) readInt(conn->from);
|
status.status = (BuildResult::Status) readInt(conn->from);
|
||||||
conn->from >> status.errorMsg;
|
conn->from >> status.errorMsg;
|
||||||
|
|
||||||
|
|
|
@ -110,9 +110,21 @@ bool OutputsSpec::merge(const OutputsSpec & that)
|
||||||
}, raw());
|
}, raw());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void to_json(nlohmann::json & json, const OutputsSpec & outputsSpec)
|
namespace nlohmann {
|
||||||
{
|
|
||||||
|
using namespace nix;
|
||||||
|
|
||||||
|
OutputsSpec adl_serializer<OutputsSpec>::from_json(const json & json) {
|
||||||
|
auto names = json.get<StringSet>();
|
||||||
|
if (names == StringSet({"*"}))
|
||||||
|
return OutputsSpec::All {};
|
||||||
|
else
|
||||||
|
return OutputsSpec::Names { std::move(names) };
|
||||||
|
}
|
||||||
|
|
||||||
|
void adl_serializer<OutputsSpec>::to_json(json & json, OutputsSpec t) {
|
||||||
std::visit(overloaded {
|
std::visit(overloaded {
|
||||||
[&](const OutputsSpec::All &) {
|
[&](const OutputsSpec::All &) {
|
||||||
json = std::vector<std::string>({"*"});
|
json = std::vector<std::string>({"*"});
|
||||||
|
@ -120,40 +132,27 @@ void to_json(nlohmann::json & json, const OutputsSpec & outputsSpec)
|
||||||
[&](const OutputsSpec::Names & names) {
|
[&](const OutputsSpec::Names & names) {
|
||||||
json = names;
|
json = names;
|
||||||
},
|
},
|
||||||
}, outputsSpec);
|
}, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void to_json(nlohmann::json & json, const ExtendedOutputsSpec & extendedOutputsSpec)
|
ExtendedOutputsSpec adl_serializer<ExtendedOutputsSpec>::from_json(const json & json) {
|
||||||
{
|
if (json.is_null())
|
||||||
|
return ExtendedOutputsSpec::Default {};
|
||||||
|
else {
|
||||||
|
return ExtendedOutputsSpec::Explicit { json.get<OutputsSpec>() };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void adl_serializer<ExtendedOutputsSpec>::to_json(json & json, ExtendedOutputsSpec t) {
|
||||||
std::visit(overloaded {
|
std::visit(overloaded {
|
||||||
[&](const ExtendedOutputsSpec::Default &) {
|
[&](const ExtendedOutputsSpec::Default &) {
|
||||||
json = nullptr;
|
json = nullptr;
|
||||||
},
|
},
|
||||||
[&](const ExtendedOutputsSpec::Explicit & e) {
|
[&](const ExtendedOutputsSpec::Explicit & e) {
|
||||||
to_json(json, e);
|
adl_serializer<OutputsSpec>::to_json(json, e);
|
||||||
},
|
},
|
||||||
}, extendedOutputsSpec);
|
}, t);
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void from_json(const nlohmann::json & json, OutputsSpec & outputsSpec)
|
|
||||||
{
|
|
||||||
auto names = json.get<StringSet>();
|
|
||||||
if (names == StringSet({"*"}))
|
|
||||||
outputsSpec = OutputsSpec::All {};
|
|
||||||
else
|
|
||||||
outputsSpec = OutputsSpec::Names { std::move(names) };
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void from_json(const nlohmann::json & json, ExtendedOutputsSpec & extendedOutputsSpec)
|
|
||||||
{
|
|
||||||
if (json.is_null())
|
|
||||||
extendedOutputsSpec = ExtendedOutputsSpec::Default {};
|
|
||||||
else {
|
|
||||||
extendedOutputsSpec = ExtendedOutputsSpec::Explicit { json.get<OutputsSpec>() };
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <variant>
|
#include <variant>
|
||||||
|
|
||||||
#include "nlohmann/json_fwd.hpp"
|
#include "json-impls.hh"
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
@ -35,6 +35,9 @@ struct OutputsSpec : _OutputsSpecRaw {
|
||||||
using Raw = _OutputsSpecRaw;
|
using Raw = _OutputsSpecRaw;
|
||||||
using Raw::Raw;
|
using Raw::Raw;
|
||||||
|
|
||||||
|
/* Force choosing a variant */
|
||||||
|
OutputsSpec() = delete;
|
||||||
|
|
||||||
using Names = OutputNames;
|
using Names = OutputNames;
|
||||||
using All = AllOutputs;
|
using All = AllOutputs;
|
||||||
|
|
||||||
|
@ -85,11 +88,7 @@ struct ExtendedOutputsSpec : _ExtendedOutputsSpecRaw {
|
||||||
std::string to_string() const;
|
std::string to_string() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
void to_json(nlohmann::json &, const OutputsSpec &);
|
|
||||||
void from_json(const nlohmann::json &, OutputsSpec &);
|
|
||||||
|
|
||||||
void to_json(nlohmann::json &, const ExtendedOutputsSpec &);
|
|
||||||
void from_json(const nlohmann::json &, ExtendedOutputsSpec &);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JSON_IMPL(OutputsSpec)
|
||||||
|
JSON_IMPL(ExtendedOutputsSpec)
|
||||||
|
|
|
@ -910,7 +910,12 @@ BuildResult RemoteStore::buildDerivation(const StorePath & drvPath, const BasicD
|
||||||
writeDerivation(conn->to, *this, drv);
|
writeDerivation(conn->to, *this, drv);
|
||||||
conn->to << buildMode;
|
conn->to << buildMode;
|
||||||
conn.processStderr();
|
conn.processStderr();
|
||||||
BuildResult res { .path = DerivedPath::Built { .drvPath = drvPath } };
|
BuildResult res {
|
||||||
|
.path = DerivedPath::Built {
|
||||||
|
.drvPath = drvPath,
|
||||||
|
.outputs = OutputsSpec::All { },
|
||||||
|
},
|
||||||
|
};
|
||||||
res.status = (BuildResult::Status) readInt(conn->from);
|
res.status = (BuildResult::Status) readInt(conn->from);
|
||||||
conn->from >> res.errorMsg;
|
conn->from >> res.errorMsg;
|
||||||
if (GET_PROTOCOL_MINOR(conn->daemonVersion) >= 29) {
|
if (GET_PROTOCOL_MINOR(conn->daemonVersion) >= 29) {
|
||||||
|
|
14
src/libutil/json-impls.hh
Normal file
14
src/libutil/json-impls.hh
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "nlohmann/json_fwd.hpp"
|
||||||
|
|
||||||
|
// Following https://github.com/nlohmann/json#how-can-i-use-get-for-non-default-constructiblenon-copyable-types
|
||||||
|
#define JSON_IMPL(TYPE) \
|
||||||
|
namespace nlohmann { \
|
||||||
|
using namespace nix; \
|
||||||
|
template <> \
|
||||||
|
struct adl_serializer<TYPE> { \
|
||||||
|
static TYPE from_json(const json & json); \
|
||||||
|
static void to_json(json & json, TYPE t); \
|
||||||
|
}; \
|
||||||
|
}
|
|
@ -478,9 +478,14 @@ static void printMissing(EvalState & state, DrvInfos & elems)
|
||||||
std::vector<DerivedPath> targets;
|
std::vector<DerivedPath> targets;
|
||||||
for (auto & i : elems)
|
for (auto & i : elems)
|
||||||
if (auto drvPath = i.queryDrvPath())
|
if (auto drvPath = i.queryDrvPath())
|
||||||
targets.push_back(DerivedPath::Built{*drvPath});
|
targets.push_back(DerivedPath::Built{
|
||||||
|
.drvPath = *drvPath,
|
||||||
|
.outputs = OutputsSpec::All { },
|
||||||
|
});
|
||||||
else
|
else
|
||||||
targets.push_back(DerivedPath::Opaque{i.queryOutPath()});
|
targets.push_back(DerivedPath::Opaque{
|
||||||
|
.path = i.queryOutPath(),
|
||||||
|
});
|
||||||
|
|
||||||
printMissing(state.store, targets);
|
printMissing(state.store, targets);
|
||||||
}
|
}
|
||||||
|
@ -751,8 +756,13 @@ static void opSet(Globals & globals, Strings opFlags, Strings opArgs)
|
||||||
auto drvPath = drv.queryDrvPath();
|
auto drvPath = drv.queryDrvPath();
|
||||||
std::vector<DerivedPath> paths {
|
std::vector<DerivedPath> paths {
|
||||||
drvPath
|
drvPath
|
||||||
? (DerivedPath) (DerivedPath::Built { *drvPath })
|
? (DerivedPath) (DerivedPath::Built {
|
||||||
: (DerivedPath) (DerivedPath::Opaque { drv.queryOutPath() }),
|
.drvPath = *drvPath,
|
||||||
|
.outputs = OutputsSpec::All { },
|
||||||
|
})
|
||||||
|
: (DerivedPath) (DerivedPath::Opaque {
|
||||||
|
.path = drv.queryOutPath(),
|
||||||
|
}),
|
||||||
};
|
};
|
||||||
printMissing(globals.state->store, paths);
|
printMissing(globals.state->store, paths);
|
||||||
if (globals.dryRun) return;
|
if (globals.dryRun) return;
|
||||||
|
|
|
@ -105,7 +105,12 @@ struct CmdBundle : InstallableCommand
|
||||||
|
|
||||||
auto outPath = evalState->coerceToStorePath(attr2->pos, *attr2->value, context2, "");
|
auto outPath = evalState->coerceToStorePath(attr2->pos, *attr2->value, context2, "");
|
||||||
|
|
||||||
store->buildPaths({ DerivedPath::Built { drvPath } });
|
store->buildPaths({
|
||||||
|
DerivedPath::Built {
|
||||||
|
.drvPath = drvPath,
|
||||||
|
.outputs = OutputsSpec::All { },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
auto outPathS = store->printStorePath(outPath);
|
auto outPathS = store->printStorePath(outPath);
|
||||||
|
|
||||||
|
|
|
@ -232,7 +232,12 @@ static StorePath getDerivationEnvironment(ref<Store> store, ref<Store> evalStore
|
||||||
auto shellDrvPath = writeDerivation(*evalStore, drv);
|
auto shellDrvPath = writeDerivation(*evalStore, drv);
|
||||||
|
|
||||||
/* Build the derivation. */
|
/* Build the derivation. */
|
||||||
store->buildPaths({DerivedPath::Built{shellDrvPath}}, bmNormal, evalStore);
|
store->buildPaths(
|
||||||
|
{ DerivedPath::Built {
|
||||||
|
.drvPath = shellDrvPath,
|
||||||
|
.outputs = OutputsSpec::All { },
|
||||||
|
}},
|
||||||
|
bmNormal, evalStore);
|
||||||
|
|
||||||
for (auto & [_0, optPath] : evalStore->queryPartialDerivationOutputMap(shellDrvPath)) {
|
for (auto & [_0, optPath] : evalStore->queryPartialDerivationOutputMap(shellDrvPath)) {
|
||||||
assert(optPath);
|
assert(optPath);
|
||||||
|
|
|
@ -513,8 +513,12 @@ struct CmdFlakeCheck : FlakeCommand
|
||||||
auto drvPath = checkDerivation(
|
auto drvPath = checkDerivation(
|
||||||
fmt("%s.%s.%s", name, attr_name, state->symbols[attr2.name]),
|
fmt("%s.%s.%s", name, attr_name, state->symbols[attr2.name]),
|
||||||
*attr2.value, attr2.pos);
|
*attr2.value, attr2.pos);
|
||||||
if (drvPath && attr_name == settings.thisSystem.get())
|
if (drvPath && attr_name == settings.thisSystem.get()) {
|
||||||
drvPaths.push_back(DerivedPath::Built{*drvPath});
|
drvPaths.push_back(DerivedPath::Built {
|
||||||
|
.drvPath = *drvPath,
|
||||||
|
.outputs = OutputsSpec::All { },
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue