mirror of
https://github.com/privatevoid-net/nix-super.git
synced 2024-11-10 08:16:15 +02:00
Move enabled experimental feature to libutil struct
This is needed in subsequent commits to allow the settings and CLI args infrastructure itself to read this setting.
This commit is contained in:
parent
1b6c96bbcb
commit
296831f641
28 changed files with 113 additions and 70 deletions
|
@ -305,7 +305,7 @@ connected:
|
||||||
|
|
||||||
std::set<Realisation> missingRealisations;
|
std::set<Realisation> missingRealisations;
|
||||||
StorePathSet missingPaths;
|
StorePathSet missingPaths;
|
||||||
if (settings.isExperimentalFeatureEnabled(Xp::CaDerivations) && !drv.type().hasKnownOutputPaths()) {
|
if (experimentalFeatureSettings.isEnabled(Xp::CaDerivations) && !drv.type().hasKnownOutputPaths()) {
|
||||||
for (auto & outputName : wantedOutputs) {
|
for (auto & outputName : wantedOutputs) {
|
||||||
auto thisOutputHash = outputHashes.at(outputName);
|
auto thisOutputHash = outputHashes.at(outputName);
|
||||||
auto thisOutputId = DrvOutput{ thisOutputHash, outputName };
|
auto thisOutputId = DrvOutput{ thisOutputHash, outputName };
|
||||||
|
@ -337,7 +337,7 @@ connected:
|
||||||
for (auto & realisation : missingRealisations) {
|
for (auto & realisation : missingRealisations) {
|
||||||
// Should hold, because if the feature isn't enabled the set
|
// Should hold, because if the feature isn't enabled the set
|
||||||
// of missing realisations should be empty
|
// of missing realisations should be empty
|
||||||
settings.requireExperimentalFeature(Xp::CaDerivations);
|
experimentalFeatureSettings.require(Xp::CaDerivations);
|
||||||
store->registerDrvOutput(realisation);
|
store->registerDrvOutput(realisation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -166,7 +166,7 @@ Path lookupFileArg(EvalState & state, std::string_view s)
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (hasPrefix(s, "flake:")) {
|
else if (hasPrefix(s, "flake:")) {
|
||||||
settings.requireExperimentalFeature(Xp::Flakes);
|
experimentalFeatureSettings.require(Xp::Flakes);
|
||||||
auto flakeRef = parseFlakeRef(std::string(s.substr(6)), {}, true, false);
|
auto flakeRef = parseFlakeRef(std::string(s.substr(6)), {}, true, false);
|
||||||
auto storePath = flakeRef.resolve(state.store).fetchTree(state.store).first.storePath;
|
auto storePath = flakeRef.resolve(state.store).fetchTree(state.store).first.storePath;
|
||||||
return state.store->toRealPath(storePath);
|
return state.store->toRealPath(storePath);
|
||||||
|
|
|
@ -332,7 +332,7 @@ void completeFlakeRefWithFragment(
|
||||||
|
|
||||||
void completeFlakeRef(ref<Store> store, std::string_view prefix)
|
void completeFlakeRef(ref<Store> store, std::string_view prefix)
|
||||||
{
|
{
|
||||||
if (!settings.isExperimentalFeatureEnabled(Xp::Flakes))
|
if (!experimentalFeatureSettings.isEnabled(Xp::Flakes))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (prefix == "")
|
if (prefix == "")
|
||||||
|
|
|
@ -320,7 +320,7 @@ LockedFlake lockFlake(
|
||||||
const FlakeRef & topRef,
|
const FlakeRef & topRef,
|
||||||
const LockFlags & lockFlags)
|
const LockFlags & lockFlags)
|
||||||
{
|
{
|
||||||
settings.requireExperimentalFeature(Xp::Flakes);
|
experimentalFeatureSettings.require(Xp::Flakes);
|
||||||
|
|
||||||
FlakeCache flakeCache;
|
FlakeCache flakeCache;
|
||||||
|
|
||||||
|
|
|
@ -469,7 +469,7 @@ expr_simple
|
||||||
new ExprString(std::move(path))});
|
new ExprString(std::move(path))});
|
||||||
}
|
}
|
||||||
| URI {
|
| URI {
|
||||||
static bool noURLLiterals = settings.isExperimentalFeatureEnabled(Xp::NoUrlLiterals);
|
static bool noURLLiterals = experimentalFeatureSettings.isEnabled(Xp::NoUrlLiterals);
|
||||||
if (noURLLiterals)
|
if (noURLLiterals)
|
||||||
throw ParseError({
|
throw ParseError({
|
||||||
.msg = hintfmt("URL literals are disabled"),
|
.msg = hintfmt("URL literals are disabled"),
|
||||||
|
@ -816,7 +816,7 @@ std::pair<bool, std::string> EvalState::resolveSearchPathElem(const SearchPathEl
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (hasPrefix(elem.second, "flake:")) {
|
else if (hasPrefix(elem.second, "flake:")) {
|
||||||
settings.requireExperimentalFeature(Xp::Flakes);
|
experimentalFeatureSettings.require(Xp::Flakes);
|
||||||
auto flakeRef = parseFlakeRef(elem.second.substr(6), {}, true, false);
|
auto flakeRef = parseFlakeRef(elem.second.substr(6), {}, true, false);
|
||||||
debug("fetching flake search path element '%s''", elem.second);
|
debug("fetching flake search path element '%s''", elem.second);
|
||||||
auto storePath = flakeRef.resolve(store).fetchTree(store).first.storePath;
|
auto storePath = flakeRef.resolve(store).fetchTree(store).first.storePath;
|
||||||
|
|
|
@ -1141,13 +1141,13 @@ drvName, Bindings * attrs, Value & v)
|
||||||
if (i->name == state.sContentAddressed) {
|
if (i->name == state.sContentAddressed) {
|
||||||
contentAddressed = state.forceBool(*i->value, noPos, context_below);
|
contentAddressed = state.forceBool(*i->value, noPos, context_below);
|
||||||
if (contentAddressed)
|
if (contentAddressed)
|
||||||
settings.requireExperimentalFeature(Xp::CaDerivations);
|
experimentalFeatureSettings.require(Xp::CaDerivations);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (i->name == state.sImpure) {
|
else if (i->name == state.sImpure) {
|
||||||
isImpure = state.forceBool(*i->value, noPos, context_below);
|
isImpure = state.forceBool(*i->value, noPos, context_below);
|
||||||
if (isImpure)
|
if (isImpure)
|
||||||
settings.requireExperimentalFeature(Xp::ImpureDerivations);
|
experimentalFeatureSettings.require(Xp::ImpureDerivations);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The `args' attribute is special: it supplies the
|
/* The `args' attribute is special: it supplies the
|
||||||
|
@ -4114,7 +4114,7 @@ void EvalState::createBaseEnv()
|
||||||
if (RegisterPrimOp::primOps)
|
if (RegisterPrimOp::primOps)
|
||||||
for (auto & primOp : *RegisterPrimOp::primOps)
|
for (auto & primOp : *RegisterPrimOp::primOps)
|
||||||
if (!primOp.experimentalFeature
|
if (!primOp.experimentalFeature
|
||||||
|| settings.isExperimentalFeatureEnabled(*primOp.experimentalFeature))
|
|| experimentalFeatureSettings.isEnabled(*primOp.experimentalFeature))
|
||||||
{
|
{
|
||||||
addPrimOp({
|
addPrimOp({
|
||||||
.fun = primOp.fun,
|
.fun = primOp.fun,
|
||||||
|
|
|
@ -190,7 +190,7 @@ static void fetchTree(
|
||||||
|
|
||||||
static void prim_fetchTree(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_fetchTree(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
settings.requireExperimentalFeature(Xp::Flakes);
|
experimentalFeatureSettings.require(Xp::Flakes);
|
||||||
fetchTree(state, pos, args, v, std::nullopt, FetchTreeParams { .allowNameArgument = false });
|
fetchTree(state, pos, args, v, std::nullopt, FetchTreeParams { .allowNameArgument = false });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -199,10 +199,10 @@ void DerivationGoal::haveDerivation()
|
||||||
parsedDrv = std::make_unique<ParsedDerivation>(drvPath, *drv);
|
parsedDrv = std::make_unique<ParsedDerivation>(drvPath, *drv);
|
||||||
|
|
||||||
if (!drv->type().hasKnownOutputPaths())
|
if (!drv->type().hasKnownOutputPaths())
|
||||||
settings.requireExperimentalFeature(Xp::CaDerivations);
|
experimentalFeatureSettings.require(Xp::CaDerivations);
|
||||||
|
|
||||||
if (!drv->type().isPure()) {
|
if (!drv->type().isPure()) {
|
||||||
settings.requireExperimentalFeature(Xp::ImpureDerivations);
|
experimentalFeatureSettings.require(Xp::ImpureDerivations);
|
||||||
|
|
||||||
for (auto & [outputName, output] : drv->outputs) {
|
for (auto & [outputName, output] : drv->outputs) {
|
||||||
auto randomPath = StorePath::random(outputPathName(drv->name, outputName));
|
auto randomPath = StorePath::random(outputPathName(drv->name, outputName));
|
||||||
|
@ -336,7 +336,7 @@ void DerivationGoal::gaveUpOnSubstitution()
|
||||||
for (auto & i : dynamic_cast<Derivation *>(drv.get())->inputDrvs) {
|
for (auto & i : dynamic_cast<Derivation *>(drv.get())->inputDrvs) {
|
||||||
/* Ensure that pure, non-fixed-output derivations don't
|
/* Ensure that pure, non-fixed-output derivations don't
|
||||||
depend on impure derivations. */
|
depend on impure derivations. */
|
||||||
if (settings.isExperimentalFeatureEnabled(Xp::ImpureDerivations) && drv->type().isPure() && !drv->type().isFixed()) {
|
if (experimentalFeatureSettings.isEnabled(Xp::ImpureDerivations) && drv->type().isPure() && !drv->type().isFixed()) {
|
||||||
auto inputDrv = worker.evalStore.readDerivation(i.first);
|
auto inputDrv = worker.evalStore.readDerivation(i.first);
|
||||||
if (!inputDrv.type().isPure())
|
if (!inputDrv.type().isPure())
|
||||||
throw Error("pure derivation '%s' depends on impure derivation '%s'",
|
throw Error("pure derivation '%s' depends on impure derivation '%s'",
|
||||||
|
@ -477,7 +477,7 @@ void DerivationGoal::inputsRealised()
|
||||||
ca.fixed
|
ca.fixed
|
||||||
/* Can optionally resolve if fixed, which is good
|
/* Can optionally resolve if fixed, which is good
|
||||||
for avoiding unnecessary rebuilds. */
|
for avoiding unnecessary rebuilds. */
|
||||||
? settings.isExperimentalFeatureEnabled(Xp::CaDerivations)
|
? experimentalFeatureSettings.isEnabled(Xp::CaDerivations)
|
||||||
/* Must resolve if floating and there are any inputs
|
/* Must resolve if floating and there are any inputs
|
||||||
drvs. */
|
drvs. */
|
||||||
: true);
|
: true);
|
||||||
|
@ -488,7 +488,7 @@ void DerivationGoal::inputsRealised()
|
||||||
}, drvType.raw());
|
}, drvType.raw());
|
||||||
|
|
||||||
if (resolveDrv && !fullDrv.inputDrvs.empty()) {
|
if (resolveDrv && !fullDrv.inputDrvs.empty()) {
|
||||||
settings.requireExperimentalFeature(Xp::CaDerivations);
|
experimentalFeatureSettings.require(Xp::CaDerivations);
|
||||||
|
|
||||||
/* We are be able to resolve this derivation based on the
|
/* We are be able to resolve this derivation based on the
|
||||||
now-known results of dependencies. If so, we become a
|
now-known results of dependencies. If so, we become a
|
||||||
|
@ -1352,7 +1352,7 @@ std::pair<bool, DrvOutputs> DerivationGoal::checkPathValidity()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
auto drvOutput = DrvOutput{info.outputHash, i.first};
|
auto drvOutput = DrvOutput{info.outputHash, i.first};
|
||||||
if (settings.isExperimentalFeatureEnabled(Xp::CaDerivations)) {
|
if (experimentalFeatureSettings.isEnabled(Xp::CaDerivations)) {
|
||||||
if (auto real = worker.store.queryRealisation(drvOutput)) {
|
if (auto real = worker.store.queryRealisation(drvOutput)) {
|
||||||
info.known = {
|
info.known = {
|
||||||
.path = real->outPath,
|
.path = real->outPath,
|
||||||
|
|
|
@ -413,7 +413,7 @@ void LocalDerivationGoal::startBuilder()
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
#if __linux__
|
#if __linux__
|
||||||
settings.requireExperimentalFeature(Xp::Cgroups);
|
experimentalFeatureSettings.require(Xp::Cgroups);
|
||||||
|
|
||||||
auto cgroupFS = getCgroupFS();
|
auto cgroupFS = getCgroupFS();
|
||||||
if (!cgroupFS)
|
if (!cgroupFS)
|
||||||
|
@ -1393,7 +1393,7 @@ struct RestrictedStore : public virtual RestrictedStoreConfig, public virtual Lo
|
||||||
|
|
||||||
void LocalDerivationGoal::startDaemon()
|
void LocalDerivationGoal::startDaemon()
|
||||||
{
|
{
|
||||||
settings.requireExperimentalFeature(Xp::RecursiveNix);
|
experimentalFeatureSettings.require(Xp::RecursiveNix);
|
||||||
|
|
||||||
Store::Params params;
|
Store::Params params;
|
||||||
params["path-info-cache-size"] = "0";
|
params["path-info-cache-size"] = "0";
|
||||||
|
@ -2268,7 +2268,7 @@ DrvOutputs LocalDerivationGoal::registerOutputs()
|
||||||
bool discardReferences = false;
|
bool discardReferences = false;
|
||||||
if (auto structuredAttrs = parsedDrv->getStructuredAttrs()) {
|
if (auto structuredAttrs = parsedDrv->getStructuredAttrs()) {
|
||||||
if (auto udr = get(*structuredAttrs, "unsafeDiscardReferences")) {
|
if (auto udr = get(*structuredAttrs, "unsafeDiscardReferences")) {
|
||||||
settings.requireExperimentalFeature(Xp::DiscardReferences);
|
experimentalFeatureSettings.require(Xp::DiscardReferences);
|
||||||
if (auto output = get(*udr, outputName)) {
|
if (auto output = get(*udr, outputName)) {
|
||||||
if (!output->is_boolean())
|
if (!output->is_boolean())
|
||||||
throw Error("attribute 'unsafeDiscardReferences.\"%s\"' of derivation '%s' must be a Boolean", outputName, drvPath.to_string());
|
throw Error("attribute 'unsafeDiscardReferences.\"%s\"' of derivation '%s' must be a Boolean", outputName, drvPath.to_string());
|
||||||
|
@ -2688,7 +2688,7 @@ DrvOutputs LocalDerivationGoal::registerOutputs()
|
||||||
},
|
},
|
||||||
.outPath = newInfo.path
|
.outPath = newInfo.path
|
||||||
};
|
};
|
||||||
if (settings.isExperimentalFeatureEnabled(Xp::CaDerivations)
|
if (experimentalFeatureSettings.isEnabled(Xp::CaDerivations)
|
||||||
&& drv->type().isPure())
|
&& drv->type().isPure())
|
||||||
{
|
{
|
||||||
signRealisation(thisRealisation);
|
signRealisation(thisRealisation);
|
||||||
|
|
|
@ -231,10 +231,10 @@ struct ClientSettings
|
||||||
try {
|
try {
|
||||||
if (name == "ssh-auth-sock") // obsolete
|
if (name == "ssh-auth-sock") // obsolete
|
||||||
;
|
;
|
||||||
else if (name == settings.experimentalFeatures.name) {
|
else if (name == experimentalFeatureSettings.experimentalFeatures.name) {
|
||||||
// We don’t want to forward the experimental features to
|
// We don’t want to forward the experimental features to
|
||||||
// the daemon, as that could cause some pretty weird stuff
|
// the daemon, as that could cause some pretty weird stuff
|
||||||
if (parseFeatures(tokenizeString<StringSet>(value)) != settings.experimentalFeatures.get())
|
if (parseFeatures(tokenizeString<StringSet>(value)) != experimentalFeatureSettings.experimentalFeatures.get())
|
||||||
debug("Ignoring the client-specified experimental features");
|
debug("Ignoring the client-specified experimental features");
|
||||||
} else if (name == settings.pluginFiles.name) {
|
} else if (name == settings.pluginFiles.name) {
|
||||||
if (tokenizeString<Paths>(value) != settings.pluginFiles.get())
|
if (tokenizeString<Paths>(value) != settings.pluginFiles.get())
|
||||||
|
|
|
@ -221,7 +221,7 @@ static DerivationOutput parseDerivationOutput(const Store & store,
|
||||||
}
|
}
|
||||||
const auto hashType = parseHashType(hashAlgo);
|
const auto hashType = parseHashType(hashAlgo);
|
||||||
if (hash == "impure") {
|
if (hash == "impure") {
|
||||||
settings.requireExperimentalFeature(Xp::ImpureDerivations);
|
experimentalFeatureSettings.require(Xp::ImpureDerivations);
|
||||||
assert(pathS == "");
|
assert(pathS == "");
|
||||||
return DerivationOutput::Impure {
|
return DerivationOutput::Impure {
|
||||||
.method = std::move(method),
|
.method = std::move(method),
|
||||||
|
@ -236,7 +236,7 @@ static DerivationOutput parseDerivationOutput(const Store & store,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
settings.requireExperimentalFeature(Xp::CaDerivations);
|
experimentalFeatureSettings.require(Xp::CaDerivations);
|
||||||
assert(pathS == "");
|
assert(pathS == "");
|
||||||
return DerivationOutput::CAFloating {
|
return DerivationOutput::CAFloating {
|
||||||
.method = std::move(method),
|
.method = std::move(method),
|
||||||
|
|
|
@ -105,7 +105,7 @@ RealisedPath::Set BuiltPath::toRealisedPaths(Store & store) const
|
||||||
auto drvHashes =
|
auto drvHashes =
|
||||||
staticOutputHashes(store, store.readDerivation(p.drvPath));
|
staticOutputHashes(store, store.readDerivation(p.drvPath));
|
||||||
for (auto& [outputName, outputPath] : p.outputs) {
|
for (auto& [outputName, outputPath] : p.outputs) {
|
||||||
if (settings.isExperimentalFeatureEnabled(
|
if (experimentalFeatureSettings.isEnabled(
|
||||||
Xp::CaDerivations)) {
|
Xp::CaDerivations)) {
|
||||||
auto drvOutput = get(drvHashes, outputName);
|
auto drvOutput = get(drvHashes, outputName);
|
||||||
if (!drvOutput)
|
if (!drvOutput)
|
||||||
|
|
|
@ -166,18 +166,6 @@ StringSet Settings::getDefaultExtraPlatforms()
|
||||||
return extraPlatforms;
|
return extraPlatforms;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Settings::isExperimentalFeatureEnabled(const ExperimentalFeature & feature)
|
|
||||||
{
|
|
||||||
auto & f = experimentalFeatures.get();
|
|
||||||
return std::find(f.begin(), f.end(), feature) != f.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Settings::requireExperimentalFeature(const ExperimentalFeature & feature)
|
|
||||||
{
|
|
||||||
if (!isExperimentalFeatureEnabled(feature))
|
|
||||||
throw MissingExperimentalFeature(feature);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Settings::isWSL1()
|
bool Settings::isWSL1()
|
||||||
{
|
{
|
||||||
struct utsname utsbuf;
|
struct utsname utsbuf;
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
#include "types.hh"
|
#include "types.hh"
|
||||||
#include "config.hh"
|
#include "config.hh"
|
||||||
#include "util.hh"
|
#include "util.hh"
|
||||||
#include "experimental-features.hh"
|
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
@ -932,13 +931,6 @@ public:
|
||||||
are loaded as plugins (non-recursively).
|
are loaded as plugins (non-recursively).
|
||||||
)"};
|
)"};
|
||||||
|
|
||||||
Setting<std::set<ExperimentalFeature>> experimentalFeatures{this, {}, "experimental-features",
|
|
||||||
"Experimental Nix features to enable."};
|
|
||||||
|
|
||||||
bool isExperimentalFeatureEnabled(const ExperimentalFeature &);
|
|
||||||
|
|
||||||
void requireExperimentalFeature(const ExperimentalFeature &);
|
|
||||||
|
|
||||||
Setting<size_t> narBufferSize{this, 32 * 1024 * 1024, "nar-buffer-size",
|
Setting<size_t> narBufferSize{this, 32 * 1024 * 1024, "nar-buffer-size",
|
||||||
"Maximum size of NARs before spilling them to disk."};
|
"Maximum size of NARs before spilling them to disk."};
|
||||||
|
|
||||||
|
|
|
@ -336,7 +336,7 @@ LocalStore::LocalStore(const Params & params)
|
||||||
|
|
||||||
else openDB(*state, false);
|
else openDB(*state, false);
|
||||||
|
|
||||||
if (settings.isExperimentalFeatureEnabled(Xp::CaDerivations)) {
|
if (experimentalFeatureSettings.isEnabled(Xp::CaDerivations)) {
|
||||||
migrateCASchema(state->db, dbDir + "/ca-schema", globalLock);
|
migrateCASchema(state->db, dbDir + "/ca-schema", globalLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -366,7 +366,7 @@ LocalStore::LocalStore(const Params & params)
|
||||||
state->stmts->QueryPathFromHashPart.create(state->db,
|
state->stmts->QueryPathFromHashPart.create(state->db,
|
||||||
"select path from ValidPaths where path >= ? limit 1;");
|
"select path from ValidPaths where path >= ? limit 1;");
|
||||||
state->stmts->QueryValidPaths.create(state->db, "select path from ValidPaths");
|
state->stmts->QueryValidPaths.create(state->db, "select path from ValidPaths");
|
||||||
if (settings.isExperimentalFeatureEnabled(Xp::CaDerivations)) {
|
if (experimentalFeatureSettings.isEnabled(Xp::CaDerivations)) {
|
||||||
state->stmts->RegisterRealisedOutput.create(state->db,
|
state->stmts->RegisterRealisedOutput.create(state->db,
|
||||||
R"(
|
R"(
|
||||||
insert into Realisations (drvPath, outputName, outputPath, signatures)
|
insert into Realisations (drvPath, outputName, outputPath, signatures)
|
||||||
|
@ -754,7 +754,7 @@ void LocalStore::checkDerivationOutputs(const StorePath & drvPath, const Derivat
|
||||||
|
|
||||||
void LocalStore::registerDrvOutput(const Realisation & info, CheckSigsFlag checkSigs)
|
void LocalStore::registerDrvOutput(const Realisation & info, CheckSigsFlag checkSigs)
|
||||||
{
|
{
|
||||||
settings.requireExperimentalFeature(Xp::CaDerivations);
|
experimentalFeatureSettings.require(Xp::CaDerivations);
|
||||||
if (checkSigs == NoCheckSigs || !realisationIsUntrusted(info))
|
if (checkSigs == NoCheckSigs || !realisationIsUntrusted(info))
|
||||||
registerDrvOutput(info);
|
registerDrvOutput(info);
|
||||||
else
|
else
|
||||||
|
@ -763,7 +763,7 @@ void LocalStore::registerDrvOutput(const Realisation & info, CheckSigsFlag check
|
||||||
|
|
||||||
void LocalStore::registerDrvOutput(const Realisation & info)
|
void LocalStore::registerDrvOutput(const Realisation & info)
|
||||||
{
|
{
|
||||||
settings.requireExperimentalFeature(Xp::CaDerivations);
|
experimentalFeatureSettings.require(Xp::CaDerivations);
|
||||||
retrySQLite<void>([&]() {
|
retrySQLite<void>([&]() {
|
||||||
auto state(_state.lock());
|
auto state(_state.lock());
|
||||||
if (auto oldR = queryRealisation_(*state, info.id)) {
|
if (auto oldR = queryRealisation_(*state, info.id)) {
|
||||||
|
@ -1052,7 +1052,7 @@ LocalStore::queryPartialDerivationOutputMap(const StorePath & path_)
|
||||||
return outputs;
|
return outputs;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!settings.isExperimentalFeatureEnabled(Xp::CaDerivations))
|
if (!experimentalFeatureSettings.isEnabled(Xp::CaDerivations))
|
||||||
return outputs;
|
return outputs;
|
||||||
|
|
||||||
auto drv = readInvalidDerivation(path);
|
auto drv = readInvalidDerivation(path);
|
||||||
|
|
|
@ -129,7 +129,7 @@ struct AutoUserLock : UserLock
|
||||||
useUserNamespace = false;
|
useUserNamespace = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
settings.requireExperimentalFeature(Xp::AutoAllocateUids);
|
experimentalFeatureSettings.require(Xp::AutoAllocateUids);
|
||||||
assert(settings.startId > 0);
|
assert(settings.startId > 0);
|
||||||
assert(settings.uidCount % maxIdsPerBuild == 0);
|
assert(settings.uidCount % maxIdsPerBuild == 0);
|
||||||
assert((uint64_t) settings.startId + (uint64_t) settings.uidCount <= std::numeric_limits<uid_t>::max());
|
assert((uint64_t) settings.startId + (uint64_t) settings.uidCount <= std::numeric_limits<uid_t>::max());
|
||||||
|
|
|
@ -326,7 +326,7 @@ OutputPathMap resolveDerivedPath(Store & store, const DerivedPath::Built & bfd,
|
||||||
throw Error(
|
throw Error(
|
||||||
"the derivation '%s' doesn't have an output named '%s'",
|
"the derivation '%s' doesn't have an output named '%s'",
|
||||||
store.printStorePath(bfd.drvPath), output);
|
store.printStorePath(bfd.drvPath), output);
|
||||||
if (settings.isExperimentalFeatureEnabled(Xp::CaDerivations)) {
|
if (experimentalFeatureSettings.isEnabled(Xp::CaDerivations)) {
|
||||||
DrvOutput outputId { *outputHash, output };
|
DrvOutput outputId { *outputHash, output };
|
||||||
auto realisation = store.queryRealisation(outputId);
|
auto realisation = store.queryRealisation(outputId);
|
||||||
if (!realisation)
|
if (!realisation)
|
||||||
|
|
|
@ -265,7 +265,7 @@ void RemoteStore::setOptions(Connection & conn)
|
||||||
overrides.erase(settings.buildCores.name);
|
overrides.erase(settings.buildCores.name);
|
||||||
overrides.erase(settings.useSubstitutes.name);
|
overrides.erase(settings.useSubstitutes.name);
|
||||||
overrides.erase(loggerSettings.showTrace.name);
|
overrides.erase(loggerSettings.showTrace.name);
|
||||||
overrides.erase(settings.experimentalFeatures.name);
|
overrides.erase(experimentalFeatureSettings.experimentalFeatures.name);
|
||||||
overrides.erase(settings.pluginFiles.name);
|
overrides.erase(settings.pluginFiles.name);
|
||||||
conn.to << overrides.size();
|
conn.to << overrides.size();
|
||||||
for (auto & i : overrides)
|
for (auto & i : overrides)
|
||||||
|
@ -876,7 +876,7 @@ std::vector<BuildResult> RemoteStore::buildPathsWithResults(
|
||||||
"the derivation '%s' doesn't have an output named '%s'",
|
"the derivation '%s' doesn't have an output named '%s'",
|
||||||
printStorePath(bfd.drvPath), output);
|
printStorePath(bfd.drvPath), output);
|
||||||
auto outputId = DrvOutput{ *outputHash, output };
|
auto outputId = DrvOutput{ *outputHash, output };
|
||||||
if (settings.isExperimentalFeatureEnabled(Xp::CaDerivations)) {
|
if (experimentalFeatureSettings.isEnabled(Xp::CaDerivations)) {
|
||||||
auto realisation =
|
auto realisation =
|
||||||
queryRealisation(outputId);
|
queryRealisation(outputId);
|
||||||
if (!realisation)
|
if (!realisation)
|
||||||
|
|
|
@ -445,10 +445,10 @@ StringSet StoreConfig::getDefaultSystemFeatures()
|
||||||
{
|
{
|
||||||
auto res = settings.systemFeatures.get();
|
auto res = settings.systemFeatures.get();
|
||||||
|
|
||||||
if (settings.isExperimentalFeatureEnabled(Xp::CaDerivations))
|
if (experimentalFeatureSettings.isEnabled(Xp::CaDerivations))
|
||||||
res.insert("ca-derivations");
|
res.insert("ca-derivations");
|
||||||
|
|
||||||
if (settings.isExperimentalFeatureEnabled(Xp::RecursiveNix))
|
if (experimentalFeatureSettings.isEnabled(Xp::RecursiveNix))
|
||||||
res.insert("recursive-nix");
|
res.insert("recursive-nix");
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
|
@ -1017,7 +1017,7 @@ std::map<StorePath, StorePath> copyPaths(
|
||||||
for (auto & path : paths) {
|
for (auto & path : paths) {
|
||||||
storePaths.insert(path.path());
|
storePaths.insert(path.path());
|
||||||
if (auto realisation = std::get_if<Realisation>(&path.raw)) {
|
if (auto realisation = std::get_if<Realisation>(&path.raw)) {
|
||||||
settings.requireExperimentalFeature(Xp::CaDerivations);
|
experimentalFeatureSettings.require(Xp::CaDerivations);
|
||||||
toplevelRealisations.insert(*realisation);
|
toplevelRealisations.insert(*realisation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1250,7 +1250,7 @@ std::optional<StorePath> Store::getBuildDerivationPath(const StorePath & path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!settings.isExperimentalFeatureEnabled(Xp::CaDerivations) || !isValidPath(path))
|
if (!experimentalFeatureSettings.isEnabled(Xp::CaDerivations) || !isValidPath(path))
|
||||||
return path;
|
return path;
|
||||||
|
|
||||||
auto drv = readDerivation(path);
|
auto drv = readDerivation(path);
|
||||||
|
|
|
@ -444,4 +444,30 @@ GlobalConfig::Register::Register(Config * config)
|
||||||
configRegistrations->emplace_back(config);
|
configRegistrations->emplace_back(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ExperimentalFeatureSettings experimentalFeatureSettings;
|
||||||
|
|
||||||
|
static GlobalConfig::Register rSettings(&experimentalFeatureSettings);
|
||||||
|
|
||||||
|
bool ExperimentalFeatureSettings::isEnabled(const ExperimentalFeature & feature) const
|
||||||
|
{
|
||||||
|
auto & f = experimentalFeatures.get();
|
||||||
|
return std::find(f.begin(), f.end(), feature) != f.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExperimentalFeatureSettings::require(const ExperimentalFeature & feature) const
|
||||||
|
{
|
||||||
|
if (!isEnabled(feature))
|
||||||
|
throw MissingExperimentalFeature(feature);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ExperimentalFeatureSettings::isEnabled(const std::optional<ExperimentalFeature> & feature) const
|
||||||
|
{
|
||||||
|
return !feature || isEnabled(*feature);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExperimentalFeatureSettings::require(const std::optional<ExperimentalFeature> & feature) const
|
||||||
|
{
|
||||||
|
if (feature) require(*feature);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
#include "types.hh"
|
|
||||||
|
|
||||||
#include <nlohmann/json_fwd.hpp>
|
#include <nlohmann/json_fwd.hpp>
|
||||||
|
|
||||||
#pragma once
|
#include "types.hh"
|
||||||
|
#include "experimental-features.hh"
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
@ -357,4 +358,37 @@ struct GlobalConfig : public AbstractConfig
|
||||||
|
|
||||||
extern GlobalConfig globalConfig;
|
extern GlobalConfig globalConfig;
|
||||||
|
|
||||||
|
|
||||||
|
struct ExperimentalFeatureSettings : Config {
|
||||||
|
|
||||||
|
Setting<std::set<ExperimentalFeature>> experimentalFeatures{this, {}, "experimental-features",
|
||||||
|
"Experimental Nix features to enable."};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether the given experimental feature is enabled.
|
||||||
|
*/
|
||||||
|
bool isEnabled(const ExperimentalFeature &) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Require an experimental feature be enabled, throwing an error if it is
|
||||||
|
* not.
|
||||||
|
*/
|
||||||
|
void require(const ExperimentalFeature &) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* `std::nullopt` pointer means no feature, which means there is nothing that could be
|
||||||
|
* disabled, and so the function returns true in that case.
|
||||||
|
*/
|
||||||
|
bool isEnabled(const std::optional<ExperimentalFeature> &) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* `std::nullopt` pointer means no feature, which means there is nothing that could be
|
||||||
|
* disabled, and so the function does nothing in that case.
|
||||||
|
*/
|
||||||
|
void require(const std::optional<ExperimentalFeature> &) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
// FIXME: don't use a global variable.
|
||||||
|
extern ExperimentalFeatureSettings experimentalFeatureSettings;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -440,7 +440,7 @@ static void main_nix_build(int argc, char * * argv)
|
||||||
shell = store->printStorePath(shellDrvOutputs.at("out").value()) + "/bin/bash";
|
shell = store->printStorePath(shellDrvOutputs.at("out").value()) + "/bin/bash";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (settings.isExperimentalFeatureEnabled(Xp::CaDerivations)) {
|
if (experimentalFeatureSettings.isEnabled(Xp::CaDerivations)) {
|
||||||
auto resolvedDrv = drv.tryResolve(*store);
|
auto resolvedDrv = drv.tryResolve(*store);
|
||||||
assert(resolvedDrv && "Successfully resolved the derivation");
|
assert(resolvedDrv && "Successfully resolved the derivation");
|
||||||
drv = *resolvedDrv;
|
drv = *resolvedDrv;
|
||||||
|
|
|
@ -208,7 +208,7 @@ static StorePath getDerivationEnvironment(ref<Store> store, ref<Store> evalStore
|
||||||
drv.name += "-env";
|
drv.name += "-env";
|
||||||
drv.env.emplace("name", drv.name);
|
drv.env.emplace("name", drv.name);
|
||||||
drv.inputSrcs.insert(std::move(getEnvShPath));
|
drv.inputSrcs.insert(std::move(getEnvShPath));
|
||||||
if (settings.isExperimentalFeatureEnabled(Xp::CaDerivations)) {
|
if (experimentalFeatureSettings.isEnabled(Xp::CaDerivations)) {
|
||||||
for (auto & output : drv.outputs) {
|
for (auto & output : drv.outputs) {
|
||||||
output.second = DerivationOutput::Deferred {},
|
output.second = DerivationOutput::Deferred {},
|
||||||
drv.env[output.first] = hashPlaceholder(output.first);
|
drv.env[output.first] = hashPlaceholder(output.first);
|
||||||
|
|
|
@ -1328,7 +1328,7 @@ struct CmdFlake : NixMultiCommand
|
||||||
{
|
{
|
||||||
if (!command)
|
if (!command)
|
||||||
throw UsageError("'nix flake' requires a sub-command.");
|
throw UsageError("'nix flake' requires a sub-command.");
|
||||||
settings.requireExperimentalFeature(Xp::Flakes);
|
experimentalFeatureSettings.require(Xp::Flakes);
|
||||||
command->second->run();
|
command->second->run();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -297,7 +297,10 @@ void mainWrapped(int argc, char * * argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argc == 2 && std::string(argv[1]) == "__dump-builtins") {
|
if (argc == 2 && std::string(argv[1]) == "__dump-builtins") {
|
||||||
settings.experimentalFeatures = {Xp::Flakes, Xp::FetchClosure};
|
experimentalFeatureSettings.experimentalFeatures = {
|
||||||
|
Xp::Flakes,
|
||||||
|
Xp::FetchClosure,
|
||||||
|
};
|
||||||
evalSettings.pureEval = false;
|
evalSettings.pureEval = false;
|
||||||
EvalState state({}, openStore("dummy://"));
|
EvalState state({}, openStore("dummy://"));
|
||||||
auto res = nlohmann::json::object();
|
auto res = nlohmann::json::object();
|
||||||
|
@ -366,7 +369,7 @@ void mainWrapped(int argc, char * * argv)
|
||||||
if (args.command->first != "repl"
|
if (args.command->first != "repl"
|
||||||
&& args.command->first != "doctor"
|
&& args.command->first != "doctor"
|
||||||
&& args.command->first != "upgrade-nix")
|
&& args.command->first != "upgrade-nix")
|
||||||
settings.requireExperimentalFeature(Xp::NixCommand);
|
experimentalFeatureSettings.require(Xp::NixCommand);
|
||||||
|
|
||||||
if (args.useNet && !haveInternet()) {
|
if (args.useNet && !haveInternet()) {
|
||||||
warn("you don't have Internet access; disabling some network-dependent features");
|
warn("you don't have Internet access; disabling some network-dependent features");
|
||||||
|
|
|
@ -45,7 +45,7 @@ struct CmdRealisationInfo : BuiltPathsCommand, MixJSON
|
||||||
|
|
||||||
void run(ref<Store> store, BuiltPaths && paths) override
|
void run(ref<Store> store, BuiltPaths && paths) override
|
||||||
{
|
{
|
||||||
settings.requireExperimentalFeature(Xp::CaDerivations);
|
experimentalFeatureSettings.require(Xp::CaDerivations);
|
||||||
RealisedPath::Set realisations;
|
RealisedPath::Set realisations;
|
||||||
|
|
||||||
for (auto & builtPath : paths) {
|
for (auto & builtPath : paths) {
|
||||||
|
|
|
@ -224,7 +224,7 @@ struct CmdRegistry : virtual NixMultiCommand
|
||||||
|
|
||||||
void run() override
|
void run() override
|
||||||
{
|
{
|
||||||
settings.requireExperimentalFeature(Xp::Flakes);
|
experimentalFeatureSettings.require(Xp::Flakes);
|
||||||
if (!command)
|
if (!command)
|
||||||
throw UsageError("'nix registry' requires a sub-command.");
|
throw UsageError("'nix registry' requires a sub-command.");
|
||||||
command->second->run();
|
command->second->run();
|
||||||
|
|
|
@ -37,7 +37,7 @@ struct CmdRepl : RawInstallablesCommand
|
||||||
|
|
||||||
void applyDefaultInstallables(std::vector<std::string> & rawInstallables) override
|
void applyDefaultInstallables(std::vector<std::string> & rawInstallables) override
|
||||||
{
|
{
|
||||||
if (!settings.isExperimentalFeatureEnabled(Xp::ReplFlake) && !(file) && rawInstallables.size() >= 1) {
|
if (!experimentalFeatureSettings.isEnabled(Xp::ReplFlake) && !(file) && rawInstallables.size() >= 1) {
|
||||||
warn("future versions of Nix will require using `--file` to load a file");
|
warn("future versions of Nix will require using `--file` to load a file");
|
||||||
if (rawInstallables.size() > 1)
|
if (rawInstallables.size() > 1)
|
||||||
warn("more than one input file is not currently supported");
|
warn("more than one input file is not currently supported");
|
||||||
|
|
Loading…
Reference in a new issue