forked from lix-project/lix
Get rid of most .at
calls (#6393)
Use one of `get` or `getOr` instead which will either return a null-pointer (with a nicer error message) or a default value when the key is missing.
This commit is contained in:
parent
9489b4b7ef
commit
1385b20078
|
@ -871,12 +871,13 @@ std::vector<std::pair<std::shared_ptr<Installable>, BuiltPath>> Installable::bui
|
||||||
auto outputHashes = staticOutputHashes(*evalStore, drv); // FIXME: expensive
|
auto outputHashes = staticOutputHashes(*evalStore, drv); // FIXME: expensive
|
||||||
auto drvOutputs = drv.outputsAndOptPaths(*store);
|
auto drvOutputs = drv.outputsAndOptPaths(*store);
|
||||||
for (auto & output : bfd.outputs) {
|
for (auto & output : bfd.outputs) {
|
||||||
if (!outputHashes.count(output))
|
auto outputHash = get(outputHashes, output);
|
||||||
|
if (!outputHash)
|
||||||
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 (settings.isExperimentalFeatureEnabled(Xp::CaDerivations)) {
|
||||||
DrvOutput outputId { outputHashes.at(output), output };
|
DrvOutput outputId { *outputHash, output };
|
||||||
auto realisation = store->queryRealisation(outputId);
|
auto realisation = store->queryRealisation(outputId);
|
||||||
if (!realisation)
|
if (!realisation)
|
||||||
throw Error(
|
throw Error(
|
||||||
|
@ -887,10 +888,11 @@ std::vector<std::pair<std::shared_ptr<Installable>, BuiltPath>> Installable::bui
|
||||||
} else {
|
} else {
|
||||||
// If ca-derivations isn't enabled, assume that
|
// If ca-derivations isn't enabled, assume that
|
||||||
// the output path is statically known.
|
// the output path is statically known.
|
||||||
assert(drvOutputs.count(output));
|
auto drvOutput = get(drvOutputs, output);
|
||||||
assert(drvOutputs.at(output).second);
|
assert(drvOutput);
|
||||||
|
assert(drvOutput->second);
|
||||||
outputs.insert_or_assign(
|
outputs.insert_or_assign(
|
||||||
output, *drvOutputs.at(output).second);
|
output, *drvOutput->second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
res.push_back({installable, BuiltPath::Built { bfd.drvPath, outputs }});
|
res.push_back({installable, BuiltPath::Built { bfd.drvPath, outputs }});
|
||||||
|
|
|
@ -50,13 +50,11 @@ void ConfigFile::apply()
|
||||||
else
|
else
|
||||||
assert(false);
|
assert(false);
|
||||||
|
|
||||||
if (!whitelist.count(baseName)) {
|
if (!whitelist.count(baseName) && !nix::fetchSettings.acceptFlakeConfig) {
|
||||||
auto trustedList = readTrustedList();
|
|
||||||
|
|
||||||
bool trusted = false;
|
bool trusted = false;
|
||||||
if (nix::fetchSettings.acceptFlakeConfig){
|
auto trustedList = readTrustedList();
|
||||||
trusted = true;
|
auto tlname = get(trustedList, name);
|
||||||
} else if (auto saved = get(get(trustedList, name).value_or(std::map<std::string, bool>()), valueS)) {
|
if (auto saved = tlname ? get(*tlname, valueS) : nullptr) {
|
||||||
trusted = *saved;
|
trusted = *saved;
|
||||||
warn("Using saved setting for '%s = %s' from ~/.local/share/nix/trusted-settings.json.", name,valueS);
|
warn("Using saved setting for '%s = %s' from ~/.local/share/nix/trusted-settings.json.", name,valueS);
|
||||||
} else {
|
} else {
|
||||||
|
@ -69,7 +67,6 @@ void ConfigFile::apply()
|
||||||
writeTrustedList(trustedList);
|
writeTrustedList(trustedList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!trusted) {
|
if (!trusted) {
|
||||||
warn("ignoring untrusted flake configuration setting '%s'", name);
|
warn("ignoring untrusted flake configuration setting '%s'", name);
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -176,7 +176,7 @@ std::pair<FlakeRef, std::string> parseFlakeRefWithFragment(
|
||||||
parsedURL.query.insert_or_assign("shallow", "1");
|
parsedURL.query.insert_or_assign("shallow", "1");
|
||||||
|
|
||||||
return std::make_pair(
|
return std::make_pair(
|
||||||
FlakeRef(Input::fromURL(parsedURL), get(parsedURL.query, "dir").value_or("")),
|
FlakeRef(Input::fromURL(parsedURL), getOr(parsedURL.query, "dir", "")),
|
||||||
fragment);
|
fragment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,7 +189,7 @@ std::pair<FlakeRef, std::string> parseFlakeRefWithFragment(
|
||||||
if (!hasPrefix(path, "/"))
|
if (!hasPrefix(path, "/"))
|
||||||
throw BadURL("flake reference '%s' is not an absolute path", url);
|
throw BadURL("flake reference '%s' is not an absolute path", url);
|
||||||
auto query = decodeQuery(match[2]);
|
auto query = decodeQuery(match[2]);
|
||||||
path = canonPath(path + "/" + get(query, "dir").value_or(""));
|
path = canonPath(path + "/" + getOr(query, "dir", ""));
|
||||||
}
|
}
|
||||||
|
|
||||||
fetchers::Attrs attrs;
|
fetchers::Attrs attrs;
|
||||||
|
@ -208,7 +208,7 @@ std::pair<FlakeRef, std::string> parseFlakeRefWithFragment(
|
||||||
input.parent = baseDir;
|
input.parent = baseDir;
|
||||||
|
|
||||||
return std::make_pair(
|
return std::make_pair(
|
||||||
FlakeRef(std::move(input), get(parsedURL.query, "dir").value_or("")),
|
FlakeRef(std::move(input), getOr(parsedURL.query, "dir", "")),
|
||||||
fragment);
|
fragment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@ DrvInfo::DrvInfo(EvalState & state, ref<Store> store, const std::string & drvPat
|
||||||
|
|
||||||
outputName =
|
outputName =
|
||||||
selectedOutputs.empty()
|
selectedOutputs.empty()
|
||||||
? get(drv.env, "outputName").value_or("out")
|
? getOr(drv.env, "outputName", "out")
|
||||||
: *selectedOutputs.begin();
|
: *selectedOutputs.begin();
|
||||||
|
|
||||||
auto i = drv.outputs.find(outputName);
|
auto i = drv.outputs.find(outputName);
|
||||||
|
|
|
@ -68,14 +68,15 @@ StringMap EvalState::realiseContext(const PathSet & context)
|
||||||
|
|
||||||
/* Get all the output paths corresponding to the placeholders we had */
|
/* Get all the output paths corresponding to the placeholders we had */
|
||||||
for (auto & [drvPath, outputs] : drvs) {
|
for (auto & [drvPath, outputs] : drvs) {
|
||||||
auto outputPaths = store->queryDerivationOutputMap(drvPath);
|
const auto outputPaths = store->queryDerivationOutputMap(drvPath);
|
||||||
for (auto & outputName : outputs) {
|
for (auto & outputName : outputs) {
|
||||||
if (outputPaths.count(outputName) == 0)
|
auto outputPath = get(outputPaths, outputName);
|
||||||
|
if (!outputPath)
|
||||||
throw Error("derivation '%s' does not have an output named '%s'",
|
throw Error("derivation '%s' does not have an output named '%s'",
|
||||||
store->printStorePath(drvPath), outputName);
|
store->printStorePath(drvPath), outputName);
|
||||||
res.insert_or_assign(
|
res.insert_or_assign(
|
||||||
downstreamPlaceholder(*store, drvPath, outputName),
|
downstreamPlaceholder(*store, drvPath, outputName),
|
||||||
store->printStorePath(outputPaths.at(outputName))
|
store->printStorePath(*outputPath)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1249,8 +1250,13 @@ static void prim_derivationStrict(EvalState & state, const PosIdx pos, Value * *
|
||||||
switch (hashModulo.kind) {
|
switch (hashModulo.kind) {
|
||||||
case DrvHash::Kind::Regular:
|
case DrvHash::Kind::Regular:
|
||||||
for (auto & i : outputs) {
|
for (auto & i : outputs) {
|
||||||
auto h = hashModulo.hashes.at(i);
|
auto h = get(hashModulo.hashes, i);
|
||||||
auto outPath = state.store->makeOutputPath(i, h, drvName);
|
if (!h)
|
||||||
|
throw AssertionError({
|
||||||
|
.msg = hintfmt("derivation produced no hash for output '%s'", i),
|
||||||
|
.errPos = state.positions[posDrvName],
|
||||||
|
});
|
||||||
|
auto outPath = state.store->makeOutputPath(i, *h, drvName);
|
||||||
drv.env[i] = state.store->printStorePath(outPath);
|
drv.env[i] = state.store->printStorePath(outPath);
|
||||||
drv.outputs.insert_or_assign(
|
drv.outputs.insert_or_assign(
|
||||||
i,
|
i,
|
||||||
|
|
|
@ -984,21 +984,28 @@ void DerivationGoal::resolvedFinished()
|
||||||
realWantedOutputs = resolvedDrv.outputNames();
|
realWantedOutputs = resolvedDrv.outputNames();
|
||||||
|
|
||||||
for (auto & wantedOutput : realWantedOutputs) {
|
for (auto & wantedOutput : realWantedOutputs) {
|
||||||
assert(initialOutputs.count(wantedOutput) != 0);
|
auto initialOutput = get(initialOutputs, wantedOutput);
|
||||||
assert(resolvedHashes.count(wantedOutput) != 0);
|
auto resolvedHash = get(resolvedHashes, wantedOutput);
|
||||||
auto realisation = resolvedResult.builtOutputs.at(
|
if ((!initialOutput) || (!resolvedHash))
|
||||||
DrvOutput { resolvedHashes.at(wantedOutput), wantedOutput });
|
throw Error(
|
||||||
|
"derivation '%s' doesn't have expected output '%s' (derivation-goal.cc/resolvedFinished,resolve)",
|
||||||
|
worker.store.printStorePath(drvPath), wantedOutput);
|
||||||
|
auto realisation = get(resolvedResult.builtOutputs, DrvOutput { *resolvedHash, wantedOutput });
|
||||||
|
if (!realisation)
|
||||||
|
throw Error(
|
||||||
|
"derivation '%s' doesn't have expected output '%s' (derivation-goal.cc/resolvedFinished,realisation)",
|
||||||
|
worker.store.printStorePath(resolvedDrvGoal->drvPath), wantedOutput);
|
||||||
if (drv->type().isPure()) {
|
if (drv->type().isPure()) {
|
||||||
auto newRealisation = realisation;
|
auto newRealisation = *realisation;
|
||||||
newRealisation.id = DrvOutput { initialOutputs.at(wantedOutput).outputHash, wantedOutput };
|
newRealisation.id = DrvOutput { initialOutput->outputHash, wantedOutput };
|
||||||
newRealisation.signatures.clear();
|
newRealisation.signatures.clear();
|
||||||
if (!drv->type().isFixed())
|
if (!drv->type().isFixed())
|
||||||
newRealisation.dependentRealisations = drvOutputReferences(worker.store, *drv, realisation.outPath);
|
newRealisation.dependentRealisations = drvOutputReferences(worker.store, *drv, realisation->outPath);
|
||||||
signRealisation(newRealisation);
|
signRealisation(newRealisation);
|
||||||
worker.store.registerDrvOutput(newRealisation);
|
worker.store.registerDrvOutput(newRealisation);
|
||||||
}
|
}
|
||||||
outputPaths.insert(realisation.outPath);
|
outputPaths.insert(realisation->outPath);
|
||||||
builtOutputs.emplace(realisation.id, realisation);
|
builtOutputs.emplace(realisation->id, *realisation);
|
||||||
}
|
}
|
||||||
|
|
||||||
runPostBuildHook(
|
runPostBuildHook(
|
||||||
|
@ -1294,7 +1301,11 @@ std::pair<bool, DrvOutputs> DerivationGoal::checkPathValidity()
|
||||||
DrvOutputs validOutputs;
|
DrvOutputs validOutputs;
|
||||||
|
|
||||||
for (auto & i : queryPartialDerivationOutputMap()) {
|
for (auto & i : queryPartialDerivationOutputMap()) {
|
||||||
InitialOutput & info = initialOutputs.at(i.first);
|
auto initialOutput = get(initialOutputs, i.first);
|
||||||
|
if (!initialOutput)
|
||||||
|
// this is an invalid output, gets catched with (!wantedOutputsLeft.empty())
|
||||||
|
continue;
|
||||||
|
auto & info = *initialOutput;
|
||||||
info.wanted = wantOutput(i.first, wantedOutputs);
|
info.wanted = wantOutput(i.first, wantedOutputs);
|
||||||
if (info.wanted)
|
if (info.wanted)
|
||||||
wantedOutputsLeft.erase(i.first);
|
wantedOutputsLeft.erase(i.first);
|
||||||
|
@ -1309,7 +1320,7 @@ std::pair<bool, DrvOutputs> DerivationGoal::checkPathValidity()
|
||||||
: PathStatus::Corrupt,
|
: PathStatus::Corrupt,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
auto drvOutput = DrvOutput{initialOutputs.at(i.first).outputHash, i.first};
|
auto drvOutput = DrvOutput{info.outputHash, i.first};
|
||||||
if (settings.isExperimentalFeatureEnabled(Xp::CaDerivations)) {
|
if (settings.isExperimentalFeatureEnabled(Xp::CaDerivations)) {
|
||||||
if (auto real = worker.store.queryRealisation(drvOutput)) {
|
if (auto real = worker.store.queryRealisation(drvOutput)) {
|
||||||
info.known = {
|
info.known = {
|
||||||
|
|
|
@ -482,7 +482,7 @@ void LocalDerivationGoal::startBuilder()
|
||||||
temporary build directory. The text files have the format used
|
temporary build directory. The text files have the format used
|
||||||
by `nix-store --register-validity'. However, the deriver
|
by `nix-store --register-validity'. However, the deriver
|
||||||
fields are left empty. */
|
fields are left empty. */
|
||||||
auto s = get(drv->env, "exportReferencesGraph").value_or("");
|
auto s = getOr(drv->env, "exportReferencesGraph", "");
|
||||||
Strings ss = tokenizeString<Strings>(s);
|
Strings ss = tokenizeString<Strings>(s);
|
||||||
if (ss.size() % 2 != 0)
|
if (ss.size() % 2 != 0)
|
||||||
throw BuildError("odd number of tokens in 'exportReferencesGraph': '%1%'", s);
|
throw BuildError("odd number of tokens in 'exportReferencesGraph': '%1%'", s);
|
||||||
|
@ -989,7 +989,7 @@ void LocalDerivationGoal::initTmpDir() {
|
||||||
there is no size constraint). */
|
there is no size constraint). */
|
||||||
if (!parsedDrv->getStructuredAttrs()) {
|
if (!parsedDrv->getStructuredAttrs()) {
|
||||||
|
|
||||||
StringSet passAsFile = tokenizeString<StringSet>(get(drv->env, "passAsFile").value_or(""));
|
StringSet passAsFile = tokenizeString<StringSet>(getOr(drv->env, "passAsFile", ""));
|
||||||
for (auto & i : drv->env) {
|
for (auto & i : drv->env) {
|
||||||
if (passAsFile.find(i.first) == passAsFile.end()) {
|
if (passAsFile.find(i.first) == passAsFile.end()) {
|
||||||
env[i.first] = i.second;
|
env[i.first] = i.second;
|
||||||
|
@ -2128,12 +2128,22 @@ DrvOutputs LocalDerivationGoal::registerOutputs()
|
||||||
std::map<std::string, std::variant<AlreadyRegistered, PerhapsNeedToRegister>> outputReferencesIfUnregistered;
|
std::map<std::string, std::variant<AlreadyRegistered, PerhapsNeedToRegister>> outputReferencesIfUnregistered;
|
||||||
std::map<std::string, struct stat> outputStats;
|
std::map<std::string, struct stat> outputStats;
|
||||||
for (auto & [outputName, _] : drv->outputs) {
|
for (auto & [outputName, _] : drv->outputs) {
|
||||||
auto actualPath = toRealPathChroot(worker.store.printStorePath(scratchOutputs.at(outputName)));
|
auto scratchOutput = get(scratchOutputs, outputName);
|
||||||
|
if (!scratchOutput)
|
||||||
|
throw BuildError(
|
||||||
|
"builder for '%s' has no scratch output for '%s'",
|
||||||
|
worker.store.printStorePath(drvPath), outputName);
|
||||||
|
auto actualPath = toRealPathChroot(worker.store.printStorePath(*scratchOutput));
|
||||||
|
|
||||||
outputsToSort.insert(outputName);
|
outputsToSort.insert(outputName);
|
||||||
|
|
||||||
/* Updated wanted info to remove the outputs we definitely don't need to register */
|
/* Updated wanted info to remove the outputs we definitely don't need to register */
|
||||||
auto & initialInfo = initialOutputs.at(outputName);
|
auto initialOutput = get(initialOutputs, outputName);
|
||||||
|
if (!initialOutput)
|
||||||
|
throw BuildError(
|
||||||
|
"builder for '%s' has no initial output for '%s'",
|
||||||
|
worker.store.printStorePath(drvPath), outputName);
|
||||||
|
auto & initialInfo = *initialOutput;
|
||||||
|
|
||||||
/* Don't register if already valid, and not checking */
|
/* Don't register if already valid, and not checking */
|
||||||
initialInfo.wanted = buildMode == bmCheck
|
initialInfo.wanted = buildMode == bmCheck
|
||||||
|
@ -2185,6 +2195,11 @@ DrvOutputs LocalDerivationGoal::registerOutputs()
|
||||||
|
|
||||||
auto sortedOutputNames = topoSort(outputsToSort,
|
auto sortedOutputNames = topoSort(outputsToSort,
|
||||||
{[&](const std::string & name) {
|
{[&](const std::string & name) {
|
||||||
|
auto orifu = get(outputReferencesIfUnregistered, name);
|
||||||
|
if (!orifu)
|
||||||
|
throw BuildError(
|
||||||
|
"no output reference for '%s' in build of '%s'",
|
||||||
|
name, worker.store.printStorePath(drvPath));
|
||||||
return std::visit(overloaded {
|
return std::visit(overloaded {
|
||||||
/* Since we'll use the already installed versions of these, we
|
/* Since we'll use the already installed versions of these, we
|
||||||
can treat them as leaves and ignore any references they
|
can treat them as leaves and ignore any references they
|
||||||
|
@ -2199,7 +2214,7 @@ DrvOutputs LocalDerivationGoal::registerOutputs()
|
||||||
referencedOutputs.insert(o);
|
referencedOutputs.insert(o);
|
||||||
return referencedOutputs;
|
return referencedOutputs;
|
||||||
},
|
},
|
||||||
}, outputReferencesIfUnregistered.at(name));
|
}, *orifu);
|
||||||
}},
|
}},
|
||||||
{[&](const std::string & path, const std::string & parent) {
|
{[&](const std::string & path, const std::string & parent) {
|
||||||
// TODO with more -vvvv also show the temporary paths for manual inspection.
|
// TODO with more -vvvv also show the temporary paths for manual inspection.
|
||||||
|
@ -2213,9 +2228,10 @@ DrvOutputs LocalDerivationGoal::registerOutputs()
|
||||||
OutputPathMap finalOutputs;
|
OutputPathMap finalOutputs;
|
||||||
|
|
||||||
for (auto & outputName : sortedOutputNames) {
|
for (auto & outputName : sortedOutputNames) {
|
||||||
auto output = drv->outputs.at(outputName);
|
auto output = get(drv->outputs, outputName);
|
||||||
auto & scratchPath = scratchOutputs.at(outputName);
|
auto scratchPath = get(scratchOutputs, outputName);
|
||||||
auto actualPath = toRealPathChroot(worker.store.printStorePath(scratchPath));
|
assert(output && scratchPath);
|
||||||
|
auto actualPath = toRealPathChroot(worker.store.printStorePath(*scratchPath));
|
||||||
|
|
||||||
auto finish = [&](StorePath finalStorePath) {
|
auto finish = [&](StorePath finalStorePath) {
|
||||||
/* Store the final path */
|
/* Store the final path */
|
||||||
|
@ -2223,10 +2239,13 @@ DrvOutputs LocalDerivationGoal::registerOutputs()
|
||||||
/* The rewrite rule will be used in downstream outputs that refer to
|
/* The rewrite rule will be used in downstream outputs that refer to
|
||||||
use. This is why the topological sort is essential to do first
|
use. This is why the topological sort is essential to do first
|
||||||
before this for loop. */
|
before this for loop. */
|
||||||
if (scratchPath != finalStorePath)
|
if (*scratchPath != finalStorePath)
|
||||||
outputRewrites[std::string { scratchPath.hashPart() }] = std::string { finalStorePath.hashPart() };
|
outputRewrites[std::string { scratchPath->hashPart() }] = std::string { finalStorePath.hashPart() };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
auto orifu = get(outputReferencesIfUnregistered, outputName);
|
||||||
|
assert(orifu);
|
||||||
|
|
||||||
std::optional<StorePathSet> referencesOpt = std::visit(overloaded {
|
std::optional<StorePathSet> referencesOpt = std::visit(overloaded {
|
||||||
[&](const AlreadyRegistered & skippedFinalPath) -> std::optional<StorePathSet> {
|
[&](const AlreadyRegistered & skippedFinalPath) -> std::optional<StorePathSet> {
|
||||||
finish(skippedFinalPath.path);
|
finish(skippedFinalPath.path);
|
||||||
|
@ -2235,7 +2254,7 @@ DrvOutputs LocalDerivationGoal::registerOutputs()
|
||||||
[&](const PerhapsNeedToRegister & r) -> std::optional<StorePathSet> {
|
[&](const PerhapsNeedToRegister & r) -> std::optional<StorePathSet> {
|
||||||
return r.refs;
|
return r.refs;
|
||||||
},
|
},
|
||||||
}, outputReferencesIfUnregistered.at(outputName));
|
}, *orifu);
|
||||||
|
|
||||||
if (!referencesOpt)
|
if (!referencesOpt)
|
||||||
continue;
|
continue;
|
||||||
|
@ -2268,25 +2287,29 @@ DrvOutputs LocalDerivationGoal::registerOutputs()
|
||||||
for (auto & r : references) {
|
for (auto & r : references) {
|
||||||
auto name = r.name();
|
auto name = r.name();
|
||||||
auto origHash = std::string { r.hashPart() };
|
auto origHash = std::string { r.hashPart() };
|
||||||
if (r == scratchPath)
|
if (r == *scratchPath) {
|
||||||
res.first = true;
|
res.first = true;
|
||||||
else if (outputRewrites.count(origHash) == 0)
|
} else if (auto outputRewrite = get(outputRewrites, origHash)) {
|
||||||
res.second.insert(r);
|
std::string newRef = *outputRewrite;
|
||||||
else {
|
|
||||||
std::string newRef = outputRewrites.at(origHash);
|
|
||||||
newRef += '-';
|
newRef += '-';
|
||||||
newRef += name;
|
newRef += name;
|
||||||
res.second.insert(StorePath { newRef });
|
res.second.insert(StorePath { newRef });
|
||||||
|
} else {
|
||||||
|
res.second.insert(r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
};
|
};
|
||||||
|
|
||||||
auto newInfoFromCA = [&](const DerivationOutput::CAFloating outputHash) -> ValidPathInfo {
|
auto newInfoFromCA = [&](const DerivationOutput::CAFloating outputHash) -> ValidPathInfo {
|
||||||
auto & st = outputStats.at(outputName);
|
auto st = get(outputStats, outputName);
|
||||||
|
if (!st)
|
||||||
|
throw BuildError(
|
||||||
|
"output path %1% without valid stats info",
|
||||||
|
actualPath);
|
||||||
if (outputHash.method == FileIngestionMethod::Flat) {
|
if (outputHash.method == FileIngestionMethod::Flat) {
|
||||||
/* The output path should be a regular file without execute permission. */
|
/* The output path should be a regular file without execute permission. */
|
||||||
if (!S_ISREG(st.st_mode) || (st.st_mode & S_IXUSR) != 0)
|
if (!S_ISREG(st->st_mode) || (st->st_mode & S_IXUSR) != 0)
|
||||||
throw BuildError(
|
throw BuildError(
|
||||||
"output path '%1%' should be a non-executable regular file "
|
"output path '%1%' should be a non-executable regular file "
|
||||||
"since recursive hashing is not enabled (outputHashMode=flat)",
|
"since recursive hashing is not enabled (outputHashMode=flat)",
|
||||||
|
@ -2294,7 +2317,7 @@ DrvOutputs LocalDerivationGoal::registerOutputs()
|
||||||
}
|
}
|
||||||
rewriteOutput();
|
rewriteOutput();
|
||||||
/* FIXME optimize and deduplicate with addToStore */
|
/* FIXME optimize and deduplicate with addToStore */
|
||||||
std::string oldHashPart { scratchPath.hashPart() };
|
std::string oldHashPart { scratchPath->hashPart() };
|
||||||
HashModuloSink caSink { outputHash.hashType, oldHashPart };
|
HashModuloSink caSink { outputHash.hashType, oldHashPart };
|
||||||
switch (outputHash.method) {
|
switch (outputHash.method) {
|
||||||
case FileIngestionMethod::Recursive:
|
case FileIngestionMethod::Recursive:
|
||||||
|
@ -2313,7 +2336,7 @@ DrvOutputs LocalDerivationGoal::registerOutputs()
|
||||||
outputPathName(drv->name, outputName),
|
outputPathName(drv->name, outputName),
|
||||||
refs.second,
|
refs.second,
|
||||||
refs.first);
|
refs.first);
|
||||||
if (scratchPath != finalPath) {
|
if (*scratchPath != finalPath) {
|
||||||
// Also rewrite the output path
|
// Also rewrite the output path
|
||||||
auto source = sinkToSource([&](Sink & nextSink) {
|
auto source = sinkToSource([&](Sink & nextSink) {
|
||||||
StringSink sink;
|
StringSink sink;
|
||||||
|
@ -2354,9 +2377,9 @@ DrvOutputs LocalDerivationGoal::registerOutputs()
|
||||||
auto requiredFinalPath = output.path;
|
auto requiredFinalPath = output.path;
|
||||||
/* Preemptively add rewrite rule for final hash, as that is
|
/* Preemptively add rewrite rule for final hash, as that is
|
||||||
what the NAR hash will use rather than normalized-self references */
|
what the NAR hash will use rather than normalized-self references */
|
||||||
if (scratchPath != requiredFinalPath)
|
if (*scratchPath != requiredFinalPath)
|
||||||
outputRewrites.insert_or_assign(
|
outputRewrites.insert_or_assign(
|
||||||
std::string { scratchPath.hashPart() },
|
std::string { scratchPath->hashPart() },
|
||||||
std::string { requiredFinalPath.hashPart() });
|
std::string { requiredFinalPath.hashPart() });
|
||||||
rewriteOutput();
|
rewriteOutput();
|
||||||
auto narHashAndSize = hashPath(htSHA256, actualPath);
|
auto narHashAndSize = hashPath(htSHA256, actualPath);
|
||||||
|
@ -2409,7 +2432,7 @@ DrvOutputs LocalDerivationGoal::registerOutputs()
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
}, output.raw());
|
}, output->raw());
|
||||||
|
|
||||||
/* FIXME: set proper permissions in restorePath() so
|
/* FIXME: set proper permissions in restorePath() so
|
||||||
we don't have to do another traversal. */
|
we don't have to do another traversal. */
|
||||||
|
@ -2425,7 +2448,7 @@ DrvOutputs LocalDerivationGoal::registerOutputs()
|
||||||
derivations. */
|
derivations. */
|
||||||
PathLocks dynamicOutputLock;
|
PathLocks dynamicOutputLock;
|
||||||
dynamicOutputLock.setDeletion(true);
|
dynamicOutputLock.setDeletion(true);
|
||||||
auto optFixedPath = output.path(worker.store, drv->name, outputName);
|
auto optFixedPath = output->path(worker.store, drv->name, outputName);
|
||||||
if (!optFixedPath ||
|
if (!optFixedPath ||
|
||||||
worker.store.printStorePath(*optFixedPath) != finalDestPath)
|
worker.store.printStorePath(*optFixedPath) != finalDestPath)
|
||||||
{
|
{
|
||||||
|
@ -2491,11 +2514,10 @@ DrvOutputs LocalDerivationGoal::registerOutputs()
|
||||||
|
|
||||||
/* For debugging, print out the referenced and unreferenced paths. */
|
/* For debugging, print out the referenced and unreferenced paths. */
|
||||||
for (auto & i : inputPaths) {
|
for (auto & i : inputPaths) {
|
||||||
auto j = references.find(i);
|
if (references.count(i))
|
||||||
if (j == references.end())
|
|
||||||
debug("unreferenced input: '%1%'", worker.store.printStorePath(i));
|
|
||||||
else
|
|
||||||
debug("referenced input: '%1%'", worker.store.printStorePath(i));
|
debug("referenced input: '%1%'", worker.store.printStorePath(i));
|
||||||
|
else
|
||||||
|
debug("unreferenced input: '%1%'", worker.store.printStorePath(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (curRound == nrRounds) {
|
if (curRound == nrRounds) {
|
||||||
|
@ -2612,9 +2634,11 @@ DrvOutputs LocalDerivationGoal::registerOutputs()
|
||||||
DrvOutputs builtOutputs;
|
DrvOutputs builtOutputs;
|
||||||
|
|
||||||
for (auto & [outputName, newInfo] : infos) {
|
for (auto & [outputName, newInfo] : infos) {
|
||||||
|
auto oldinfo = get(initialOutputs, outputName);
|
||||||
|
assert(oldinfo);
|
||||||
auto thisRealisation = Realisation {
|
auto thisRealisation = Realisation {
|
||||||
.id = DrvOutput {
|
.id = DrvOutput {
|
||||||
initialOutputs.at(outputName).outputHash,
|
oldinfo->outputHash,
|
||||||
outputName
|
outputName
|
||||||
},
|
},
|
||||||
.outPath = newInfo.path
|
.outPath = newInfo.path
|
||||||
|
@ -2710,9 +2734,10 @@ void LocalDerivationGoal::checkOutputs(const std::map<std::string, ValidPathInfo
|
||||||
for (auto & i : *value) {
|
for (auto & i : *value) {
|
||||||
if (worker.store.isStorePath(i))
|
if (worker.store.isStorePath(i))
|
||||||
spec.insert(worker.store.parseStorePath(i));
|
spec.insert(worker.store.parseStorePath(i));
|
||||||
else if (outputs.count(i))
|
else if (auto output = get(outputs, i))
|
||||||
spec.insert(outputs.at(i).path);
|
spec.insert(output->path);
|
||||||
else throw BuildError("derivation contains an illegal reference specifier '%s'", i);
|
else
|
||||||
|
throw BuildError("derivation contains an illegal reference specifier '%s'", i);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto used = recursive
|
auto used = recursive
|
||||||
|
@ -2751,24 +2776,18 @@ void LocalDerivationGoal::checkOutputs(const std::map<std::string, ValidPathInfo
|
||||||
};
|
};
|
||||||
|
|
||||||
if (auto structuredAttrs = parsedDrv->getStructuredAttrs()) {
|
if (auto structuredAttrs = parsedDrv->getStructuredAttrs()) {
|
||||||
auto outputChecks = structuredAttrs->find("outputChecks");
|
if (auto outputChecks = get(*structuredAttrs, "outputChecks")) {
|
||||||
if (outputChecks != structuredAttrs->end()) {
|
if (auto output = get(*outputChecks, outputName)) {
|
||||||
auto output = outputChecks->find(outputName);
|
|
||||||
|
|
||||||
if (output != outputChecks->end()) {
|
|
||||||
Checks checks;
|
Checks checks;
|
||||||
|
|
||||||
auto maxSize = output->find("maxSize");
|
if (auto maxSize = get(*output, "maxSize"))
|
||||||
if (maxSize != output->end())
|
|
||||||
checks.maxSize = maxSize->get<uint64_t>();
|
checks.maxSize = maxSize->get<uint64_t>();
|
||||||
|
|
||||||
auto maxClosureSize = output->find("maxClosureSize");
|
if (auto maxClosureSize = get(*output, "maxClosureSize"))
|
||||||
if (maxClosureSize != output->end())
|
|
||||||
checks.maxClosureSize = maxClosureSize->get<uint64_t>();
|
checks.maxClosureSize = maxClosureSize->get<uint64_t>();
|
||||||
|
|
||||||
auto get = [&](const std::string & name) -> std::optional<Strings> {
|
auto get_ = [&](const std::string & name) -> std::optional<Strings> {
|
||||||
auto i = output->find(name);
|
if (auto i = get(*output, name)) {
|
||||||
if (i != output->end()) {
|
|
||||||
Strings res;
|
Strings res;
|
||||||
for (auto j = i->begin(); j != i->end(); ++j) {
|
for (auto j = i->begin(); j != i->end(); ++j) {
|
||||||
if (!j->is_string())
|
if (!j->is_string())
|
||||||
|
@ -2781,10 +2800,10 @@ void LocalDerivationGoal::checkOutputs(const std::map<std::string, ValidPathInfo
|
||||||
return {};
|
return {};
|
||||||
};
|
};
|
||||||
|
|
||||||
checks.allowedReferences = get("allowedReferences");
|
checks.allowedReferences = get_("allowedReferences");
|
||||||
checks.allowedRequisites = get("allowedRequisites");
|
checks.allowedRequisites = get_("allowedRequisites");
|
||||||
checks.disallowedReferences = get("disallowedReferences");
|
checks.disallowedReferences = get_("disallowedReferences");
|
||||||
checks.disallowedRequisites = get("disallowedRequisites");
|
checks.disallowedRequisites = get_("disallowedRequisites");
|
||||||
|
|
||||||
applyChecks(checks);
|
applyChecks(checks);
|
||||||
}
|
}
|
||||||
|
|
|
@ -380,7 +380,10 @@ void Worker::waitForInput()
|
||||||
std::set<int> fds2(j->fds);
|
std::set<int> fds2(j->fds);
|
||||||
std::vector<unsigned char> buffer(4096);
|
std::vector<unsigned char> buffer(4096);
|
||||||
for (auto & k : fds2) {
|
for (auto & k : fds2) {
|
||||||
if (pollStatus.at(fdToPollStatus.at(k)).revents) {
|
const auto fdPollStatusId = get(fdToPollStatus, k);
|
||||||
|
assert(fdPollStatusId);
|
||||||
|
assert(*fdPollStatusId < pollStatus.size());
|
||||||
|
if (pollStatus.at(*fdPollStatusId).revents) {
|
||||||
ssize_t rd = ::read(k, buffer.data(), buffer.size());
|
ssize_t rd = ::read(k, buffer.data(), buffer.size());
|
||||||
// FIXME: is there a cleaner way to handle pt close
|
// FIXME: is there a cleaner way to handle pt close
|
||||||
// than EIO? Is this even standard?
|
// than EIO? Is this even standard?
|
||||||
|
|
|
@ -24,7 +24,7 @@ void builtinFetchurl(const BasicDerivation & drv, const std::string & netrcData)
|
||||||
|
|
||||||
Path storePath = getAttr("out");
|
Path storePath = getAttr("out");
|
||||||
auto mainUrl = getAttr("url");
|
auto mainUrl = getAttr("url");
|
||||||
bool unpack = get(drv.env, "unpack").value_or("") == "1";
|
bool unpack = getOr(drv.env, "unpack", "") == "1";
|
||||||
|
|
||||||
/* Note: have to use a fresh fileTransfer here because we're in
|
/* Note: have to use a fresh fileTransfer here because we're in
|
||||||
a forked process. */
|
a forked process. */
|
||||||
|
|
|
@ -661,8 +661,10 @@ DrvHash hashDerivationModulo(Store & store, const Derivation & drv, bool maskOut
|
||||||
if (res.kind == DrvHash::Kind::Deferred)
|
if (res.kind == DrvHash::Kind::Deferred)
|
||||||
kind = DrvHash::Kind::Deferred;
|
kind = DrvHash::Kind::Deferred;
|
||||||
for (auto & outputName : inputOutputs) {
|
for (auto & outputName : inputOutputs) {
|
||||||
const auto h = res.hashes.at(outputName);
|
const auto h = get(res.hashes, outputName);
|
||||||
inputs2[h.to_string(Base16, false)].insert(outputName);
|
if (!h)
|
||||||
|
throw Error("no hash for output '%s' of derivation '%s'", outputName, drv.name);
|
||||||
|
inputs2[h->to_string(Base16, false)].insert(outputName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -836,8 +838,11 @@ static void rewriteDerivation(Store & store, BasicDerivation & drv, const String
|
||||||
auto hashModulo = hashDerivationModulo(store, Derivation(drv), true);
|
auto hashModulo = hashDerivationModulo(store, Derivation(drv), true);
|
||||||
for (auto & [outputName, output] : drv.outputs) {
|
for (auto & [outputName, output] : drv.outputs) {
|
||||||
if (std::holds_alternative<DerivationOutput::Deferred>(output.raw())) {
|
if (std::holds_alternative<DerivationOutput::Deferred>(output.raw())) {
|
||||||
auto & h = hashModulo.hashes.at(outputName);
|
auto h = get(hashModulo.hashes, outputName);
|
||||||
auto outPath = store.makeOutputPath(outputName, h, drv.name);
|
if (!h)
|
||||||
|
throw Error("derivation '%s' output '%s' has no hash (derivations.cc/rewriteDerivation)",
|
||||||
|
drv.name, outputName);
|
||||||
|
auto outPath = store.makeOutputPath(outputName, *h, drv.name);
|
||||||
drv.env[outputName] = store.printStorePath(outPath);
|
drv.env[outputName] = store.printStorePath(outPath);
|
||||||
output = DerivationOutput::InputAddressed {
|
output = DerivationOutput::InputAddressed {
|
||||||
.path = std::move(outPath),
|
.path = std::move(outPath),
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
|
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
nlohmann::json DerivedPath::Opaque::toJSON(ref<Store> store) const {
|
nlohmann::json DerivedPath::Opaque::toJSON(ref<Store> store) const {
|
||||||
|
@ -17,12 +19,12 @@ nlohmann::json DerivedPath::Built::toJSON(ref<Store> store) const {
|
||||||
res["drvPath"] = store->printStorePath(drvPath);
|
res["drvPath"] = store->printStorePath(drvPath);
|
||||||
// Fallback for the input-addressed derivation case: We expect to always be
|
// Fallback for the input-addressed derivation case: We expect to always be
|
||||||
// able to print the output paths, so let’s do it
|
// able to print the output paths, so let’s do it
|
||||||
auto knownOutputs = store->queryPartialDerivationOutputMap(drvPath);
|
const auto knownOutputs = store->queryPartialDerivationOutputMap(drvPath);
|
||||||
for (const auto& output : outputs) {
|
for (const auto& output : outputs) {
|
||||||
if (knownOutputs.at(output))
|
auto knownOutput = get(knownOutputs, output);
|
||||||
res["outputs"][output] = store->printStorePath(knownOutputs.at(output).value());
|
res["outputs"][output] = (knownOutput && *knownOutput)
|
||||||
else
|
? store->printStorePath(**knownOutput)
|
||||||
res["outputs"][output] = nullptr;
|
: nullptr;
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -123,10 +125,15 @@ RealisedPath::Set BuiltPath::toRealisedPaths(Store & store) const
|
||||||
for (auto& [outputName, outputPath] : p.outputs) {
|
for (auto& [outputName, outputPath] : p.outputs) {
|
||||||
if (settings.isExperimentalFeatureEnabled(
|
if (settings.isExperimentalFeatureEnabled(
|
||||||
Xp::CaDerivations)) {
|
Xp::CaDerivations)) {
|
||||||
|
auto drvOutput = get(drvHashes, outputName);
|
||||||
|
if (!drvOutput)
|
||||||
|
throw Error(
|
||||||
|
"the derivation '%s' has unrealised output '%s' (derived-path.cc/toRealisedPaths)",
|
||||||
|
store.printStorePath(p.drvPath), outputName);
|
||||||
auto thisRealisation = store.queryRealisation(
|
auto thisRealisation = store.queryRealisation(
|
||||||
DrvOutput{drvHashes.at(outputName), outputName});
|
DrvOutput{*drvOutput, outputName});
|
||||||
assert(thisRealisation); // We’ve built it, so we must h
|
assert(thisRealisation); // We’ve built it, so we must
|
||||||
// ve the realisation
|
// have the realisation
|
||||||
res.insert(*thisRealisation);
|
res.insert(*thisRealisation);
|
||||||
} else {
|
} else {
|
||||||
res.insert(outputPath);
|
res.insert(outputPath);
|
||||||
|
|
|
@ -692,10 +692,10 @@ struct curlFileTransfer : public FileTransfer
|
||||||
#if ENABLE_S3
|
#if ENABLE_S3
|
||||||
auto [bucketName, key, params] = parseS3Uri(request.uri);
|
auto [bucketName, key, params] = parseS3Uri(request.uri);
|
||||||
|
|
||||||
std::string profile = get(params, "profile").value_or("");
|
std::string profile = getOr(params, "profile", "");
|
||||||
std::string region = get(params, "region").value_or(Aws::Region::US_EAST_1);
|
std::string region = getOr(params, "region", Aws::Region::US_EAST_1);
|
||||||
std::string scheme = get(params, "scheme").value_or("");
|
std::string scheme = getOr(params, "scheme", "");
|
||||||
std::string endpoint = get(params, "endpoint").value_or("");
|
std::string endpoint = getOr(params, "endpoint", "");
|
||||||
|
|
||||||
S3Helper s3Helper(profile, region, scheme, endpoint);
|
S3Helper s3Helper(profile, region, scheme, endpoint);
|
||||||
|
|
||||||
|
|
|
@ -718,7 +718,11 @@ void LocalStore::checkDerivationOutputs(const StorePath & drvPath, const Derivat
|
||||||
// somewhat expensive so we do lazily
|
// somewhat expensive so we do lazily
|
||||||
hashesModulo = hashDerivationModulo(*this, drv, true);
|
hashesModulo = hashDerivationModulo(*this, drv, true);
|
||||||
}
|
}
|
||||||
StorePath recomputed = makeOutputPath(i.first, hashesModulo->hashes.at(i.first), drvName);
|
auto currentOutputHash = get(hashesModulo->hashes, i.first);
|
||||||
|
if (!currentOutputHash)
|
||||||
|
throw Error("derivation '%s' has unexpected output '%s' (local-store / hashesModulo) named '%s'",
|
||||||
|
printStorePath(drvPath), printStorePath(doia.path), i.first);
|
||||||
|
StorePath recomputed = makeOutputPath(i.first, *currentOutputHash, drvName);
|
||||||
if (doia.path != recomputed)
|
if (doia.path != recomputed)
|
||||||
throw Error("derivation '%s' has incorrect output '%s', should be '%s'",
|
throw Error("derivation '%s' has incorrect output '%s', should be '%s'",
|
||||||
printStorePath(drvPath), printStorePath(doia.path), printStorePath(recomputed));
|
printStorePath(drvPath), printStorePath(doia.path), printStorePath(recomputed));
|
||||||
|
|
|
@ -278,11 +278,16 @@ std::map<DrvOutput, StorePath> drvOutputReferences(
|
||||||
std::set<Realisation> inputRealisations;
|
std::set<Realisation> inputRealisations;
|
||||||
|
|
||||||
for (const auto & [inputDrv, outputNames] : drv.inputDrvs) {
|
for (const auto & [inputDrv, outputNames] : drv.inputDrvs) {
|
||||||
auto outputHashes =
|
const auto outputHashes =
|
||||||
staticOutputHashes(store, store.readDerivation(inputDrv));
|
staticOutputHashes(store, store.readDerivation(inputDrv));
|
||||||
for (const auto & outputName : outputNames) {
|
for (const auto & outputName : outputNames) {
|
||||||
|
auto outputHash = get(outputHashes, outputName);
|
||||||
|
if (!outputHash)
|
||||||
|
throw Error(
|
||||||
|
"output '%s' of derivation '%s' isn't realised", outputName,
|
||||||
|
store.printStorePath(inputDrv));
|
||||||
auto thisRealisation = store.queryRealisation(
|
auto thisRealisation = store.queryRealisation(
|
||||||
DrvOutput{outputHashes.at(outputName), outputName});
|
DrvOutput{*outputHash, outputName});
|
||||||
if (!thisRealisation)
|
if (!thisRealisation)
|
||||||
throw Error(
|
throw Error(
|
||||||
"output '%s' of derivation '%s' isn't built", outputName,
|
"output '%s' of derivation '%s' isn't built", outputName,
|
||||||
|
|
|
@ -853,15 +853,15 @@ std::vector<BuildResult> RemoteStore::buildPathsWithResults(
|
||||||
|
|
||||||
OutputPathMap outputs;
|
OutputPathMap outputs;
|
||||||
auto drv = evalStore->readDerivation(bfd.drvPath);
|
auto drv = evalStore->readDerivation(bfd.drvPath);
|
||||||
auto outputHashes = staticOutputHashes(*evalStore, drv); // FIXME: expensive
|
const auto outputHashes = staticOutputHashes(*evalStore, drv); // FIXME: expensive
|
||||||
auto drvOutputs = drv.outputsAndOptPaths(*this);
|
const auto drvOutputs = drv.outputsAndOptPaths(*this);
|
||||||
for (auto & output : bfd.outputs) {
|
for (auto & output : bfd.outputs) {
|
||||||
if (!outputHashes.count(output))
|
auto outputHash = get(outputHashes, output);
|
||||||
|
if (!outputHash)
|
||||||
throw Error(
|
throw Error(
|
||||||
"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 =
|
auto outputId = DrvOutput{ *outputHash, output };
|
||||||
DrvOutput{outputHashes.at(output), output};
|
|
||||||
if (settings.isExperimentalFeatureEnabled(Xp::CaDerivations)) {
|
if (settings.isExperimentalFeatureEnabled(Xp::CaDerivations)) {
|
||||||
auto realisation =
|
auto realisation =
|
||||||
queryRealisation(outputId);
|
queryRealisation(outputId);
|
||||||
|
@ -874,13 +874,14 @@ std::vector<BuildResult> RemoteStore::buildPathsWithResults(
|
||||||
} else {
|
} else {
|
||||||
// If ca-derivations isn't enabled, assume that
|
// If ca-derivations isn't enabled, assume that
|
||||||
// the output path is statically known.
|
// the output path is statically known.
|
||||||
assert(drvOutputs.count(output));
|
const auto drvOutput = get(drvOutputs, output);
|
||||||
assert(drvOutputs.at(output).second);
|
assert(drvOutput);
|
||||||
|
assert(drvOutput->second);
|
||||||
res.builtOutputs.emplace(
|
res.builtOutputs.emplace(
|
||||||
outputId,
|
outputId,
|
||||||
Realisation {
|
Realisation {
|
||||||
.id = outputId,
|
.id = outputId,
|
||||||
.outPath = *drvOutputs.at(output).second
|
.outPath = *drvOutput->second,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1314,7 +1314,7 @@ static bool isNonUriPath(const std::string & spec) {
|
||||||
std::shared_ptr<Store> openFromNonUri(const std::string & uri, const Store::Params & params)
|
std::shared_ptr<Store> openFromNonUri(const std::string & uri, const Store::Params & params)
|
||||||
{
|
{
|
||||||
if (uri == "" || uri == "auto") {
|
if (uri == "" || uri == "auto") {
|
||||||
auto stateDir = get(params, "state").value_or(settings.nixStateDir);
|
auto stateDir = getOr(params, "state", settings.nixStateDir);
|
||||||
if (access(stateDir.c_str(), R_OK | W_OK) == 0)
|
if (access(stateDir.c_str(), R_OK | W_OK) == 0)
|
||||||
return std::make_shared<LocalStore>(params);
|
return std::make_shared<LocalStore>(params);
|
||||||
else if (pathExists(settings.nixDaemonSocketFile))
|
else if (pathExists(settings.nixDaemonSocketFile))
|
||||||
|
|
|
@ -35,7 +35,9 @@ const std::optional<ExperimentalFeature> parseExperimentalFeature(const std::str
|
||||||
|
|
||||||
std::string_view showExperimentalFeature(const ExperimentalFeature feature)
|
std::string_view showExperimentalFeature(const ExperimentalFeature feature)
|
||||||
{
|
{
|
||||||
return stringifiedXpFeatures.at(feature);
|
const auto ret = get(stringifiedXpFeatures, feature);
|
||||||
|
assert(ret);
|
||||||
|
return *ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::set<ExperimentalFeature> parseFeatures(const std::set<std::string> & rawFeatures)
|
std::set<ExperimentalFeature> parseFeatures(const std::set<std::string> & rawFeatures)
|
||||||
|
|
|
@ -548,7 +548,7 @@ namespace nix {
|
||||||
|
|
||||||
TEST(get, emptyContainer) {
|
TEST(get, emptyContainer) {
|
||||||
StringMap s = { };
|
StringMap s = { };
|
||||||
auto expected = std::nullopt;
|
auto expected = nullptr;
|
||||||
|
|
||||||
ASSERT_EQ(get(s, "one"), expected);
|
ASSERT_EQ(get(s, "one"), expected);
|
||||||
}
|
}
|
||||||
|
@ -559,7 +559,23 @@ namespace nix {
|
||||||
s["two"] = "er";
|
s["two"] = "er";
|
||||||
auto expected = "yi";
|
auto expected = "yi";
|
||||||
|
|
||||||
ASSERT_EQ(get(s, "one"), expected);
|
ASSERT_EQ(*get(s, "one"), expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(getOr, emptyContainer) {
|
||||||
|
StringMap s = { };
|
||||||
|
auto expected = "yi";
|
||||||
|
|
||||||
|
ASSERT_EQ(getOr(s, "one", "yi"), expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(getOr, getFromContainer) {
|
||||||
|
StringMap s;
|
||||||
|
s["one"] = "yi";
|
||||||
|
s["two"] = "er";
|
||||||
|
auto expected = "yi";
|
||||||
|
|
||||||
|
ASSERT_EQ(getOr(s, "one", "nope"), expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
|
|
|
@ -1586,6 +1586,20 @@ std::string stripIndentation(std::string_view s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const nlohmann::json * get(const nlohmann::json & map, const std::string & key)
|
||||||
|
{
|
||||||
|
auto i = map.find(key);
|
||||||
|
if (i == map.end()) return nullptr;
|
||||||
|
return &*i;
|
||||||
|
}
|
||||||
|
|
||||||
|
nlohmann::json * get(nlohmann::json & map, const std::string & key)
|
||||||
|
{
|
||||||
|
auto i = map.find(key);
|
||||||
|
if (i == map.end()) return nullptr;
|
||||||
|
return &*i;
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -543,13 +543,34 @@ std::string stripIndentation(std::string_view s);
|
||||||
|
|
||||||
/* Get a value for the specified key from an associate container. */
|
/* Get a value for the specified key from an associate container. */
|
||||||
template <class T>
|
template <class T>
|
||||||
std::optional<typename T::mapped_type> get(const T & map, const typename T::key_type & key)
|
const typename T::mapped_type * get(const T & map, const typename T::key_type & key)
|
||||||
{
|
{
|
||||||
auto i = map.find(key);
|
auto i = map.find(key);
|
||||||
if (i == map.end()) return {};
|
if (i == map.end()) return nullptr;
|
||||||
return std::optional<typename T::mapped_type>(i->second);
|
return &i->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
typename T::mapped_type * get(T & map, const typename T::key_type & key)
|
||||||
|
{
|
||||||
|
auto i = map.find(key);
|
||||||
|
if (i == map.end()) return nullptr;
|
||||||
|
return &i->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
const nlohmann::json * get(const nlohmann::json & map, const std::string & key);
|
||||||
|
nlohmann::json * get(nlohmann::json & map, const std::string & key);
|
||||||
|
|
||||||
|
/* Get a value for the specified key from an associate container, or a default value if the key isn't present. */
|
||||||
|
template <class T>
|
||||||
|
const typename T::mapped_type & getOr(T & map,
|
||||||
|
const typename T::key_type & key,
|
||||||
|
const typename T::mapped_type & defaultValue)
|
||||||
|
{
|
||||||
|
auto i = map.find(key);
|
||||||
|
if (i == map.end()) return defaultValue;
|
||||||
|
return i->second;
|
||||||
|
}
|
||||||
|
|
||||||
/* Remove and return the first item from a container. */
|
/* Remove and return the first item from a container. */
|
||||||
template <class T>
|
template <class T>
|
||||||
|
|
2
src/nix-build/nix-build.cc
Executable file → Normal file
2
src/nix-build/nix-build.cc
Executable file → Normal file
|
@ -440,7 +440,7 @@ static void main_nix_build(int argc, char * * argv)
|
||||||
env["NIX_STORE"] = store->storeDir;
|
env["NIX_STORE"] = store->storeDir;
|
||||||
env["NIX_BUILD_CORES"] = std::to_string(settings.buildCores);
|
env["NIX_BUILD_CORES"] = std::to_string(settings.buildCores);
|
||||||
|
|
||||||
auto passAsFile = tokenizeString<StringSet>(get(drv.env, "passAsFile").value_or(""));
|
auto passAsFile = tokenizeString<StringSet>(getOr(drv.env, "passAsFile", ""));
|
||||||
|
|
||||||
bool keepTmp = false;
|
bool keepTmp = false;
|
||||||
int fileNr = 0;
|
int fileNr = 0;
|
||||||
|
|
|
@ -176,7 +176,7 @@ int main(int argc, char ** argv)
|
||||||
impurePaths.insert(argv[2]);
|
impurePaths.insert(argv[2]);
|
||||||
else {
|
else {
|
||||||
auto drv = store->derivationFromPath(store->parseStorePath(argv[1]));
|
auto drv = store->derivationFromPath(store->parseStorePath(argv[1]));
|
||||||
impurePaths = tokenizeString<StringSet>(get(drv.env, "__impureHostDeps").value_or(""));
|
impurePaths = tokenizeString<StringSet>(getOr(drv.env, "__impureHostDeps", ""));
|
||||||
impurePaths.insert("/usr/lib/libSystem.dylib");
|
impurePaths.insert("/usr/lib/libSystem.dylib");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue