libcmd: pass EvalState& to installables

for the same reason the eval caches should not keep them as references,
only worse: installables cannot fully lose their reference member since
some types of installable (flakes -sigh-) need access to caches held by
their member reference. passing that around as well at all times is not
feasible; passing in EvalState& all the time is quite bad enough as is.

Change-Id: I05d438623b5ef10fc22e7e256b89447e61a0657d
This commit is contained in:
eldritch horrors
2024-12-03 20:38:41 +01:00
parent 81559ea8ad
commit ce698198f0
31 changed files with 172 additions and 151 deletions
+1 -1
View File
@@ -162,7 +162,7 @@ void BuiltPathsCommand::run(ref<Store> store, Installables && installables)
for (auto & p : store->queryAllValidPaths())
paths.emplace_back(BuiltPath::Opaque{p});
} else {
paths = Installable::toBuiltPaths(getEvalStore(), store, realiseMode, operateOn, installables);
paths = Installable::toBuiltPaths(*getEvalState(), getEvalStore(), store, realiseMode, operateOn, installables);
if (recursive) {
// XXX: This only computes the store path closure, ignoring
// intermediate realisations
+2 -2
View File
@@ -115,10 +115,10 @@ struct SourceExprCommand : virtual Args, MixFlakeOptions
SourceExprCommand();
Installables parseInstallables(
ref<Store> store, std::vector<std::string> ss);
EvalState & state, ref<Store> store, std::vector<std::string> ss);
ref<Installable> parseInstallable(
ref<Store> store, const std::string & installable);
EvalState & state, ref<Store> store, const std::string & installable);
virtual Strings getDefaultFlakeAttrPaths();
+10 -11
View File
@@ -24,21 +24,20 @@ InstallableAttrPath::InstallableAttrPath(
, extendedOutputsSpec(std::move(extendedOutputsSpec))
{ }
std::pair<Value *, PosIdx> InstallableAttrPath::toValue()
std::pair<Value *, PosIdx> InstallableAttrPath::toValue(EvalState & state)
{
auto [vRes, pos] = findAlongAttrPath(*state, attrPath, *cmd.getAutoArgs(*evaluator), **v);
state->forceValue(*vRes, pos);
auto [vRes, pos] = findAlongAttrPath(state, attrPath, *cmd.getAutoArgs(*evaluator), **v);
state.forceValue(*vRes, pos);
return {vRes, pos};
}
DerivedPathsWithInfo InstallableAttrPath::toDerivedPaths()
DerivedPathsWithInfo InstallableAttrPath::toDerivedPaths(EvalState & state)
{
auto [v, pos] = toValue();
auto [v, pos] = toValue(state);
if (std::optional derivedPathWithInfo = trySinglePathToDerivedPaths(
*v,
pos,
fmt("while evaluating the attribute '%s'", attrPath)))
state, *v, pos, fmt("while evaluating the attribute '%s'", attrPath)
))
{
return { *derivedPathWithInfo };
}
@@ -46,21 +45,21 @@ DerivedPathsWithInfo InstallableAttrPath::toDerivedPaths()
Bindings & autoArgs = *cmd.getAutoArgs(*evaluator);
DrvInfos drvInfos;
getDerivations(*state, *v, "", autoArgs, drvInfos, false);
getDerivations(state, *v, "", autoArgs, drvInfos, false);
// Backward compatibility hack: group results by drvPath. This
// helps keep .all output together.
std::map<StorePath, OutputsSpec> byDrvPath;
for (auto & drvInfo : drvInfos) {
auto drvPath = drvInfo.queryDrvPath(*state);
auto drvPath = drvInfo.queryDrvPath(state);
if (!drvPath)
throw Error("'%s' is not a derivation", what());
auto newOutputs = std::visit(overloaded {
[&](const ExtendedOutputsSpec::Default & d) -> OutputsSpec {
std::set<std::string> outputsToInstall;
for (auto & output : drvInfo.queryOutputs(*state, false, true))
for (auto & output : drvInfo.queryOutputs(state, false, true))
outputsToInstall.insert(output.first);
return OutputsSpec::Names { std::move(outputsToInstall) };
},
+2 -2
View File
@@ -28,9 +28,9 @@ class InstallableAttrPath : public InstallableValue
std::string what() const override { return attrPath; };
std::pair<Value *, PosIdx> toValue() override;
std::pair<Value *, PosIdx> toValue(EvalState & state) override;
DerivedPathsWithInfo toDerivedPaths() override;
DerivedPathsWithInfo toDerivedPaths(EvalState & state) override;
public:
+1 -1
View File
@@ -8,7 +8,7 @@ std::string InstallableDerivedPath::what() const
return derivedPath.to_string(*store);
}
DerivedPathsWithInfo InstallableDerivedPath::toDerivedPaths()
DerivedPathsWithInfo InstallableDerivedPath::toDerivedPaths(EvalState & state)
{
return {{
.path = derivedPath,
+1 -1
View File
@@ -16,7 +16,7 @@ struct InstallableDerivedPath : Installable
std::string what() const override;
DerivedPathsWithInfo toDerivedPaths() override;
DerivedPathsWithInfo toDerivedPaths(EvalState & state) override;
std::optional<StorePath> getStorePath() override;
+30 -31
View File
@@ -71,23 +71,22 @@ InstallableFlake::InstallableFlake(
throw UsageError("'--arg' and '--argstr' are incompatible with flakes");
}
DerivedPathsWithInfo InstallableFlake::toDerivedPaths()
DerivedPathsWithInfo InstallableFlake::toDerivedPaths(EvalState & state)
{
Activity act(*logger, lvlTalkative, actUnknown, fmt("evaluating derivation '%s'", what()));
auto attr = getCursor();
auto attr = getCursor(state);
auto attrPath = attr->getAttrPathStr(*state);
auto attrPath = attr->getAttrPathStr(state);
if (!attr->isDerivation(*state)) {
if (!attr->isDerivation(state)) {
// FIXME: use eval cache?
auto v = attr->forceValue(*state);
auto v = attr->forceValue(state);
if (std::optional derivedPathWithInfo = trySinglePathToDerivedPaths(
v,
noPos,
fmt("while evaluating the flake output attribute '%s'", attrPath)))
state, v, noPos, fmt("while evaluating the flake output attribute '%s'", attrPath)
))
{
return { *derivedPathWithInfo };
} else {
@@ -95,19 +94,19 @@ DerivedPathsWithInfo InstallableFlake::toDerivedPaths()
"expected flake output attribute '%s' to be a derivation or path but found %s: %s",
attrPath,
showType(v),
ValuePrinter(*this->state, v, errorPrintOptions)
ValuePrinter(state, v, errorPrintOptions)
);
}
}
auto drvPath = attr->forceDerivation(*state);
auto drvPath = attr->forceDerivation(state);
std::optional<NixInt::Inner> priority;
if (attr->maybeGetAttr(*state, "outputSpecified")) {
} else if (auto aMeta = attr->maybeGetAttr(*state, "meta")) {
if (auto aPriority = aMeta->maybeGetAttr(*state, "priority"))
priority = aPriority->getInt(*state).value;
if (attr->maybeGetAttr(state, "outputSpecified")) {
} else if (auto aMeta = attr->maybeGetAttr(state, "meta")) {
if (auto aPriority = aMeta->maybeGetAttr(state, "priority"))
priority = aPriority->getInt(state).value;
}
return {{
@@ -116,14 +115,14 @@ DerivedPathsWithInfo InstallableFlake::toDerivedPaths()
.outputs = std::visit(overloaded {
[&](const ExtendedOutputsSpec::Default & d) -> OutputsSpec {
std::set<std::string> outputsToInstall;
if (auto aOutputSpecified = attr->maybeGetAttr(*state, "outputSpecified")) {
if (aOutputSpecified->getBool(*state)) {
if (auto aOutputName = attr->maybeGetAttr(*state, "outputName"))
outputsToInstall = { aOutputName->getString(*state) };
if (auto aOutputSpecified = attr->maybeGetAttr(state, "outputSpecified")) {
if (aOutputSpecified->getBool(state)) {
if (auto aOutputName = attr->maybeGetAttr(state, "outputName"))
outputsToInstall = { aOutputName->getString(state) };
}
} else if (auto aMeta = attr->maybeGetAttr(*state, "meta")) {
if (auto aOutputsToInstall = aMeta->maybeGetAttr(*state, "outputsToInstall"))
for (auto & s : aOutputsToInstall->getListOfStrings(*state))
} else if (auto aMeta = attr->maybeGetAttr(state, "meta")) {
if (auto aOutputsToInstall = aMeta->maybeGetAttr(state, "outputsToInstall"))
for (auto & s : aOutputsToInstall->getListOfStrings(state))
outputsToInstall.insert(s);
}
@@ -145,20 +144,20 @@ DerivedPathsWithInfo InstallableFlake::toDerivedPaths()
},
ExtraPathInfoFlake::Flake {
.originalRef = flakeRef,
.lockedRef = getLockedFlake()->flake.lockedRef,
.lockedRef = getLockedFlake(state)->flake.lockedRef,
}),
}};
}
std::pair<Value *, PosIdx> InstallableFlake::toValue()
std::pair<Value *, PosIdx> InstallableFlake::toValue(EvalState & state)
{
return {&getCursor()->forceValue(*state), noPos};
return {&getCursor(state)->forceValue(state), noPos};
}
std::vector<ref<eval_cache::AttrCursor>>
InstallableFlake::getCursors()
InstallableFlake::getCursors(EvalState & state)
{
auto evalCache = openEvalCache(*evaluator, getLockedFlake());
auto evalCache = openEvalCache(*evaluator, getLockedFlake(state));
auto root = evalCache->getRoot();
@@ -170,7 +169,7 @@ InstallableFlake::getCursors()
for (auto & attrPath : attrPaths) {
debug("trying flake output attribute '%s'", attrPath);
auto attr = root->findAlongAttrPath(*state, parseAttrPath(attrPath));
auto attr = root->findAlongAttrPath(state, parseAttrPath(attrPath));
if (attr) {
res.push_back(ref(*attr));
} else {
@@ -188,20 +187,20 @@ InstallableFlake::getCursors()
return res;
}
std::shared_ptr<flake::LockedFlake> InstallableFlake::getLockedFlake() const
std::shared_ptr<flake::LockedFlake> InstallableFlake::getLockedFlake(EvalState & state) const
{
if (!_lockedFlake) {
flake::LockFlags lockFlagsApplyConfig = lockFlags;
// FIXME why this side effect?
lockFlagsApplyConfig.applyNixConfig = true;
_lockedFlake = std::make_shared<flake::LockedFlake>(lockFlake(*state, flakeRef, lockFlagsApplyConfig));
_lockedFlake = std::make_shared<flake::LockedFlake>(lockFlake(state, flakeRef, lockFlagsApplyConfig));
}
return _lockedFlake;
}
FlakeRef InstallableFlake::nixpkgsFlakeRef() const
FlakeRef InstallableFlake::nixpkgsFlakeRef(EvalState & state) const
{
auto lockedFlake = getLockedFlake();
auto lockedFlake = getLockedFlake(state);
if (auto nixpkgsInput = lockedFlake->lockFile.findInput({"nixpkgs"})) {
if (auto lockedNode = std::dynamic_pointer_cast<const flake::LockedNode>(nixpkgsInput)) {
+5 -5
View File
@@ -52,19 +52,19 @@ struct InstallableFlake : InstallableValue
std::vector<std::string> getActualAttrPaths();
DerivedPathsWithInfo toDerivedPaths() override;
DerivedPathsWithInfo toDerivedPaths(EvalState & state) override;
std::pair<Value *, PosIdx> toValue() override;
std::pair<Value *, PosIdx> toValue(EvalState & state) override;
/**
* Get a cursor to every attrpath in getActualAttrPaths() that
* exists. However if none exists, throw an exception.
*/
std::vector<ref<eval_cache::AttrCursor>> getCursors() override;
std::vector<ref<eval_cache::AttrCursor>> getCursors(EvalState & state) override;
std::shared_ptr<flake::LockedFlake> getLockedFlake() const;
std::shared_ptr<flake::LockedFlake> getLockedFlake(EvalState & state) const;
FlakeRef nixpkgsFlakeRef() const;
FlakeRef nixpkgsFlakeRef(EvalState & state) const;
};
/**
+9 -7
View File
@@ -5,20 +5,20 @@
namespace nix {
std::vector<ref<eval_cache::AttrCursor>>
InstallableValue::getCursors()
InstallableValue::getCursors(EvalState & state)
{
auto evalCache =
std::make_shared<nix::eval_cache::EvalCache>(std::nullopt,
[&]() { return toValue().first; });
[&](EvalState & state) { return toValue(state).first; });
return {evalCache->getRoot()};
}
ref<eval_cache::AttrCursor>
InstallableValue::getCursor()
InstallableValue::getCursor(EvalState & state)
{
/* Although getCursors should return at least one element, in case it doesn't,
bound check to avoid an undefined behavior for vector[0] */
return getCursors().at(0);
return getCursors(state).at(0);
}
static UsageError nonValueInstallable(Installable & installable)
@@ -42,10 +42,12 @@ ref<InstallableValue> InstallableValue::require(ref<Installable> installable)
return ref { castedInstallable };
}
std::optional<DerivedPathWithInfo> InstallableValue::trySinglePathToDerivedPaths(Value & v, const PosIdx pos, std::string_view errorCtx)
std::optional<DerivedPathWithInfo> InstallableValue::trySinglePathToDerivedPaths(
EvalState & state, Value & v, const PosIdx pos, std::string_view errorCtx
)
{
if (v.type() == nPath) {
auto storePath = fetchToStore(*state->store, v.path());
auto storePath = fetchToStore(*evaluator->store, v.path());
return {{
.path = DerivedPath::Opaque {
.path = std::move(storePath),
@@ -57,7 +59,7 @@ std::optional<DerivedPathWithInfo> InstallableValue::trySinglePathToDerivedPaths
else if (v.type() == nString) {
return {{
.path = DerivedPath::fromSingle(
state->coerceToSingleDerivedPath(pos, v, errorCtx)),
state.coerceToSingleDerivedPath(pos, v, errorCtx)),
.info = make_ref<ExtraPathInfo>(),
}};
}
+8 -6
View File
@@ -20,7 +20,7 @@ struct App
struct UnresolvedApp
{
App unresolved;
App resolve(ref<Store> evalStore, ref<Store> store);
App resolve(EvalState & state, ref<Store> evalStore, ref<Store> store);
};
/**
@@ -81,22 +81,22 @@ struct InstallableValue : Installable
virtual ~InstallableValue() { }
virtual std::pair<Value *, PosIdx> toValue() = 0;
virtual std::pair<Value *, PosIdx> toValue(EvalState & state) = 0;
/**
* Get a cursor to each value this Installable could refer to.
* However if none exists, throw exception instead of returning
* empty vector.
*/
virtual std::vector<ref<eval_cache::AttrCursor>> getCursors();
virtual std::vector<ref<eval_cache::AttrCursor>> getCursors(EvalState & state);
/**
* Get the first and most preferred cursor this Installable could
* refer to, or throw an exception if none exists.
*/
virtual ref<eval_cache::AttrCursor> getCursor();
virtual ref<eval_cache::AttrCursor> getCursor(EvalState & state);
UnresolvedApp toApp();
UnresolvedApp toApp(EvalState & state);
static InstallableValue & require(Installable & installable);
static ref<InstallableValue> require(ref<Installable> installable);
@@ -117,7 +117,9 @@ protected:
* @result A derived path (with empty info, for now) if the value
* matched the above criteria.
*/
std::optional<DerivedPathWithInfo> trySinglePathToDerivedPaths(Value & v, const PosIdx pos, std::string_view errorCtx);
std::optional<DerivedPathWithInfo> trySinglePathToDerivedPaths(
EvalState & state, Value & v, const PosIdx pos, std::string_view errorCtx
);
};
}
+31 -24
View File
@@ -371,9 +371,9 @@ void completeFlakeRef(AddCompletions & completions, ref<Store> store, std::strin
}
}
DerivedPathWithInfo Installable::toDerivedPath()
DerivedPathWithInfo Installable::toDerivedPath(EvalState & state)
{
auto buildables = toDerivedPaths();
auto buildables = toDerivedPaths(state);
if (buildables.size() != 1)
throw Error("installable '%s' evaluates to %d derivations, where only one is expected", what(), buildables.size());
return std::move(buildables[0]);
@@ -398,7 +398,7 @@ ref<eval_cache::EvalCache> openEvalCache(
auto fingerprint = evalSettings.useEvalCache && evalSettings.pureEval
? std::make_optional(lockedFlake->getFingerprint())
: std::nullopt;
auto rootLoader = [&state, lockedFlake]()
auto rootLoader = [lockedFlake](EvalState & state)
{
/* For testing whether the evaluation cache is
complete. */
@@ -424,7 +424,7 @@ ref<eval_cache::EvalCache> openEvalCache(
}
Installables SourceExprCommand::parseInstallables(
ref<Store> store, std::vector<std::string> ss)
EvalState & state, ref<Store> store, std::vector<std::string> ss)
{
Installables result;
@@ -438,18 +438,18 @@ Installables SourceExprCommand::parseInstallables(
getEvalState()->paths.allowedPaths.reset();
}
auto state = getEvalState();
auto vFile = state->mem.allocValue();
auto evaluator = getEvalState();
auto vFile = evaluator->mem.allocValue();
if (file == "-") {
auto & e = state->parseStdin();
state->eval(e, *vFile);
auto & e = evaluator->parseStdin();
state.eval(e, *vFile);
}
else if (file)
state->evalFile(lookupFileArg(*state, *file), *vFile);
state.evalFile(lookupFileArg(state, *file), *vFile);
else {
auto & e = state->parseExprFromString(*expr, CanonPath::fromCwd());
state->eval(e, *vFile);
auto & e = state.parseExprFromString(*expr, CanonPath::fromCwd());
state.eval(e, *vFile);
}
for (auto & s : ss) {
@@ -457,7 +457,7 @@ Installables SourceExprCommand::parseInstallables(
result.push_back(
make_ref<InstallableAttrPath>(
InstallableAttrPath::parse(
state, *this, vFile, std::move(prefix), std::move(extendedOutputsSpec))));
evaluator, *this, vFile, std::move(prefix), std::move(extendedOutputsSpec))));
}
} else {
@@ -506,9 +506,9 @@ Installables SourceExprCommand::parseInstallables(
}
ref<Installable> SourceExprCommand::parseInstallable(
ref<Store> store, const std::string & installable)
EvalState & state, ref<Store> store, const std::string & installable)
{
auto installables = parseInstallables(store, {installable});
auto installables = parseInstallables(state, store, {installable});
assert(installables.size() == 1);
return installables.front();
}
@@ -538,6 +538,7 @@ static SingleBuiltPath getBuiltPath(ref<Store> evalStore, ref<Store> store, cons
}
std::vector<BuiltPathWithResult> Installable::build(
EvalState & state,
ref<Store> evalStore,
ref<Store> store,
Realise mode,
@@ -545,7 +546,7 @@ std::vector<BuiltPathWithResult> Installable::build(
BuildMode bMode)
{
std::vector<BuiltPathWithResult> res;
for (auto & [_, builtPathWithResult] : build2(evalStore, store, mode, installables, bMode))
for (auto & [_, builtPathWithResult] : build2(state, evalStore, store, mode, installables, bMode))
res.push_back(builtPathWithResult);
return res;
}
@@ -582,6 +583,7 @@ static void throwBuildErrors(
}
std::vector<std::pair<ref<Installable>, BuiltPathWithResult>> Installable::build2(
EvalState & state,
ref<Store> evalStore,
ref<Store> store,
Realise mode,
@@ -601,7 +603,7 @@ std::vector<std::pair<ref<Installable>, BuiltPathWithResult>> Installable::build
std::map<DerivedPath, std::vector<Aux>> backmap;
for (auto & i : installables) {
for (auto b : i->toDerivedPaths()) {
for (auto b : i->toDerivedPaths(state)) {
pathsToBuild.push_back(b.path);
backmap[b.path].push_back({.info = b.info, .installable = i});
}
@@ -680,6 +682,7 @@ std::vector<std::pair<ref<Installable>, BuiltPathWithResult>> Installable::build
}
BuiltPaths Installable::toBuiltPaths(
EvalState & state,
ref<Store> evalStore,
ref<Store> store,
Realise mode,
@@ -688,7 +691,7 @@ BuiltPaths Installable::toBuiltPaths(
{
if (operateOn == OperateOn::Output) {
BuiltPaths res;
for (auto & p : Installable::build(evalStore, store, mode, installables))
for (auto & p : Installable::build(state, evalStore, store, mode, installables))
res.push_back(p.path);
return res;
} else {
@@ -696,20 +699,21 @@ BuiltPaths Installable::toBuiltPaths(
settings.readOnlyMode = true;
BuiltPaths res;
for (auto & drvPath : Installable::toDerivations(store, installables, true))
for (auto & drvPath : Installable::toDerivations(state, store, installables, true))
res.emplace_back(BuiltPath::Opaque{drvPath});
return res;
}
}
StorePathSet Installable::toStorePathSet(
EvalState & state,
ref<Store> evalStore,
ref<Store> store,
Realise mode, OperateOn operateOn,
const Installables & installables)
{
StorePathSet outPaths;
for (auto & path : toBuiltPaths(evalStore, store, mode, operateOn, installables)) {
for (auto & path : toBuiltPaths(state, evalStore, store, mode, operateOn, installables)) {
auto thisOutPaths = path.outPaths();
outPaths.insert(thisOutPaths.begin(), thisOutPaths.end());
}
@@ -717,13 +721,14 @@ StorePathSet Installable::toStorePathSet(
}
StorePaths Installable::toStorePaths(
EvalState & state,
ref<Store> evalStore,
ref<Store> store,
Realise mode, OperateOn operateOn,
const Installables & installables)
{
StorePaths outPaths;
for (auto & path : toBuiltPaths(evalStore, store, mode, operateOn, installables)) {
for (auto & path : toBuiltPaths(state, evalStore, store, mode, operateOn, installables)) {
auto thisOutPaths = path.outPaths();
outPaths.insert(outPaths.end(), thisOutPaths.begin(), thisOutPaths.end());
}
@@ -731,12 +736,13 @@ StorePaths Installable::toStorePaths(
}
StorePath Installable::toStorePath(
EvalState & state,
ref<Store> evalStore,
ref<Store> store,
Realise mode, OperateOn operateOn,
ref<Installable> installable)
{
auto paths = toStorePathSet(evalStore, store, mode, operateOn, {installable});
auto paths = toStorePathSet(state, evalStore, store, mode, operateOn, {installable});
if (paths.size() != 1)
throw Error("argument '%s' should evaluate to one store path", installable->what());
@@ -745,6 +751,7 @@ StorePath Installable::toStorePath(
}
StorePathSet Installable::toDerivations(
EvalState & state,
ref<Store> store,
const Installables & installables,
bool useDeriver)
@@ -752,7 +759,7 @@ StorePathSet Installable::toDerivations(
StorePathSet drvPaths;
for (const auto & i : installables)
for (const auto & b : i->toDerivedPaths())
for (const auto & b : i->toDerivedPaths(state))
std::visit(overloaded {
[&](const DerivedPath::Opaque & bo) {
drvPaths.insert(
@@ -829,7 +836,7 @@ std::vector<FlakeRef> InstallableCommand::getFlakeRefsForCompletion()
void InstallablesCommand::run(ref<Store> store, std::vector<std::string> && rawInstallables)
{
auto installables = parseInstallables(store, rawInstallables);
auto installables = parseInstallables(*getEvalState(), store, rawInstallables);
run(store, std::move(installables));
}
@@ -846,7 +853,7 @@ InstallableCommand::InstallableCommand()
void InstallableCommand::run(ref<Store> store)
{
auto installable = parseInstallable(store, _installable);
auto installable = parseInstallable(*getEvalState(), store, _installable);
run(store, std::move(installable));
}
+10 -2
View File
@@ -1,6 +1,7 @@
#pragma once
///@file
#include "lix/libexpr/eval.hh"
#include "lix/libstore/path.hh"
#include "lix/libstore/outputs-spec.hh"
#include "lix/libstore/derived-path.hh"
@@ -127,7 +128,7 @@ struct Installable
*
* This is the main method of this class
*/
virtual DerivedPathsWithInfo toDerivedPaths() = 0;
virtual DerivedPathsWithInfo toDerivedPaths(EvalState & state) = 0;
/**
* A convenience wrapper of the above for when we expect an
@@ -137,7 +138,7 @@ struct Installable
* If no or multiple \ref DerivedPath "derived paths" are produced,
* and error is raised.
*/
DerivedPathWithInfo toDerivedPath();
DerivedPathWithInfo toDerivedPath(EvalState & state);
/**
* Return a value only if this installable is a store path or a
@@ -152,6 +153,7 @@ struct Installable
}
static std::vector<BuiltPathWithResult> build(
EvalState & state,
ref<Store> evalStore,
ref<Store> store,
Realise mode,
@@ -159,6 +161,7 @@ struct Installable
BuildMode bMode = bmNormal);
static std::vector<std::pair<ref<Installable>, BuiltPathWithResult>> build2(
EvalState & state,
ref<Store> evalStore,
ref<Store> store,
Realise mode,
@@ -166,6 +169,7 @@ struct Installable
BuildMode bMode = bmNormal);
static std::set<StorePath> toStorePathSet(
EvalState & state,
ref<Store> evalStore,
ref<Store> store,
Realise mode,
@@ -173,6 +177,7 @@ struct Installable
const Installables & installables);
static std::vector<StorePath> toStorePaths(
EvalState & state,
ref<Store> evalStore,
ref<Store> store,
Realise mode,
@@ -180,6 +185,7 @@ struct Installable
const Installables & installables);
static StorePath toStorePath(
EvalState & state,
ref<Store> evalStore,
ref<Store> store,
Realise mode,
@@ -187,11 +193,13 @@ struct Installable
ref<Installable> installable);
static std::set<StorePath> toDerivations(
EvalState & state,
ref<Store> store,
const Installables & installables,
bool useDeriver = false);
static BuiltPaths toBuiltPaths(
EvalState & state,
ref<Store> evalStore,
ref<Store> store,
Realise mode,
+3 -3
View File
@@ -340,11 +340,11 @@ EvalCache::EvalCache(
{
}
Value * EvalCache::getRootValue()
Value * EvalCache::getRootValue(EvalState & state)
{
if (!value) {
debug("getting root value");
value = allocRootValue(rootLoader());
value = allocRootValue(rootLoader(state));
}
return *value;
}
@@ -387,7 +387,7 @@ Value & AttrCursor::getValue(EvalState & state)
throw Error("attribute '%s' is unexpectedly missing", getAttrPathStr(state));
_value = allocRootValue(attr->value);
} else
_value = allocRootValue(root->getRootValue());
_value = allocRootValue(root->getRootValue(state));
}
return **_value;
}
+2 -2
View File
@@ -13,7 +13,7 @@ namespace nix::eval_cache {
struct AttrDb;
class AttrCursor;
typedef std::function<Value *()> RootLoader;
typedef std::function<Value *(EvalState &)> RootLoader;
/**
* EvalState with caching support. Historically this was part of EvalState,
@@ -43,7 +43,7 @@ class EvalCache : public std::enable_shared_from_this<EvalCache>
RootLoader rootLoader;
RootValue value;
Value * getRootValue();
Value * getRootValue(EvalState & state);
public:
+18 -18
View File
@@ -51,21 +51,21 @@ std::string resolveString(
return rewriteStrings(toResolve, rewrites);
}
UnresolvedApp InstallableValue::toApp()
UnresolvedApp InstallableValue::toApp(EvalState & state)
{
auto cursor = getCursor();
auto attrPath = cursor->getAttrPath(*state);
auto cursor = getCursor(state);
auto attrPath = cursor->getAttrPath(state);
auto type = cursor->getAttr(*state, "type")->getString(*state);
auto type = cursor->getAttr(state, "type")->getString(state);
std::string expected = !attrPath.empty() &&
(attrPath[0] == "apps" || attrPath[0] == "defaultApp")
? "app" : "derivation";
if (type != expected)
throw Error("attribute '%s' should have type '%s'", cursor->getAttrPathStr(*state), expected);
throw Error("attribute '%s' should have type '%s'", cursor->getAttrPathStr(state), expected);
if (type == "app") {
auto [program, context] = cursor->getAttr(*state, "program")->getStringWithContext(*state);
auto [program, context] = cursor->getAttr(state, "program")->getStringWithContext(state);
std::vector<DerivedPath> context2;
for (auto & c : context) {
@@ -98,18 +98,18 @@ UnresolvedApp InstallableValue::toApp()
}
else if (type == "derivation") {
auto drvPath = cursor->forceDerivation(*state);
auto outPath = cursor->getAttr(*state, "outPath")->getString(*state);
auto outputName = cursor->getAttr(*state, "outputName")->getString(*state);
auto name = cursor->getAttr(*state, "name")->getString(*state);
auto aPname = cursor->maybeGetAttr(*state, "pname");
auto aMeta = cursor->maybeGetAttr(*state, "meta");
auto aMainProgram = aMeta ? aMeta->maybeGetAttr(*state, "mainProgram") : nullptr;
auto drvPath = cursor->forceDerivation(state);
auto outPath = cursor->getAttr(state, "outPath")->getString(state);
auto outputName = cursor->getAttr(state, "outputName")->getString(state);
auto name = cursor->getAttr(state, "name")->getString(state);
auto aPname = cursor->maybeGetAttr(state, "pname");
auto aMeta = cursor->maybeGetAttr(state, "meta");
auto aMainProgram = aMeta ? aMeta->maybeGetAttr(state, "mainProgram") : nullptr;
auto mainProgram =
aMainProgram
? aMainProgram->getString(*state)
? aMainProgram->getString(state)
: aPname
? aPname->getString(*state)
? aPname->getString(state)
: DrvName(name).name;
auto program = outPath + "/bin/" + mainProgram;
return UnresolvedApp { App {
@@ -122,11 +122,11 @@ UnresolvedApp InstallableValue::toApp()
}
else
throw Error("attribute '%s' has unsupported type '%s'", cursor->getAttrPathStr(*state), type);
throw Error("attribute '%s' has unsupported type '%s'", cursor->getAttrPathStr(state), type);
}
// FIXME: move to libcmd
App UnresolvedApp::resolve(ref<Store> evalStore, ref<Store> store)
App UnresolvedApp::resolve(EvalState & state, ref<Store> evalStore, ref<Store> store)
{
auto res = unresolved;
@@ -136,7 +136,7 @@ App UnresolvedApp::resolve(ref<Store> evalStore, ref<Store> store)
installableContext.push_back(
make_ref<InstallableDerivedPath>(store, DerivedPath { ctxElt }));
auto builtContext = Installable::build(evalStore, store, Realise::Outputs, installableContext);
auto builtContext = Installable::build(state, evalStore, store, Realise::Outputs, installableContext);
res.program = resolveString(*store, unresolved.program, builtContext);
if (!store->isInStore(res.program))
throw Error("app program '%s' is not in the Nix store", res.program);
+4 -2
View File
@@ -114,11 +114,13 @@ struct CmdBuild : InstallablesCommand, MixDryRun, MixJSON, MixProfile
void run(ref<Store> store, Installables && installables) override
{
auto state = getEvalState();
if (dryRun) {
std::vector<DerivedPath> pathsToBuild;
for (auto & i : installables)
for (auto & b : i->toDerivedPaths())
for (auto & b : i->toDerivedPaths(*state))
pathsToBuild.push_back(b.path);
printMissing(store, pathsToBuild, lvlError);
@@ -130,7 +132,7 @@ struct CmdBuild : InstallablesCommand, MixDryRun, MixJSON, MixProfile
}
auto buildables = Installable::build(
getEvalStore(), store,
*state, getEvalStore(), store,
Realise::Outputs,
installables,
repair ? bmRepair : buildMode);
+2 -2
View File
@@ -78,7 +78,7 @@ struct CmdBundle : InstallableCommand
auto const installableValue = InstallableValue::require(installable);
auto val = installableValue->toValue().first;
auto val = installableValue->toValue(*evalState).first;
auto [bundlerFlakeRef, bundlerName, extendedOutputsSpec] = parseFlakeRefWithFragmentAndExtendedOutputsSpec(bundler, absPath("."));
const flake::LockFlags lockFlags{ .writeLockFile = false };
@@ -92,7 +92,7 @@ struct CmdBundle : InstallableCommand
};
auto vRes = evaluator->mem.allocValue();
evalState->callFunction(*bundler.toValue().first, *val, *vRes, noPos);
evalState->callFunction(*bundler.toValue(*evalState).first, *val, *vRes, noPos);
if (!evalState->isDerivation(*vRes))
throw Error("the bundler '%s' does not produce a derivation", bundler.what());
+1 -1
View File
@@ -41,7 +41,7 @@ struct CmdShowDerivation : InstallablesCommand
void run(ref<Store> store, Installables && installables) override
{
auto drvPaths = Installable::toDerivations(store, installables, true);
auto drvPaths = Installable::toDerivations(*getEvalState(), store, installables, true);
if (recursive) {
StorePathSet closure;
+6 -6
View File
@@ -364,9 +364,9 @@ struct Common : InstallableCommand, MixProfile
/* Substitute redirects. */
for (auto & [installable_, dir_] : redirects) {
auto dir = absPath(dir_);
auto installable = parseInstallable(store, installable_);
auto installable = parseInstallable(*getEvalState(), store, installable_);
auto builtPaths = Installable::toStorePathSet(
getEvalStore(), store, Realise::Nothing, OperateOn::Output, {installable});
*getEvalState(), getEvalStore(), store, Realise::Nothing, OperateOn::Output, {installable});
for (auto & path: builtPaths) {
auto from = store->printStorePath(path);
if (script.find(from) == std::string::npos)
@@ -444,7 +444,7 @@ struct Common : InstallableCommand, MixProfile
if (path && path->to_string().ends_with("-env"))
return *path;
else {
auto drvs = Installable::toDerivations(store, {installable});
auto drvs = Installable::toDerivations(*getEvalState(), store, {installable});
if (drvs.size() != 1)
throw Error("'%s' needs to evaluate to a single derivation, but it evaluated to %d derivations",
@@ -607,7 +607,7 @@ struct CmdDevelop : Common, MixEnvironment
auto nixpkgs = defaultNixpkgsFlakeRef();
if (auto * i = dynamic_cast<const InstallableFlake *>(&*installable))
nixpkgs = i->nixpkgsFlakeRef();
nixpkgs = i->nixpkgsFlakeRef(*state);
auto bashInstallable = make_ref<InstallableFlake>(
this,
@@ -621,7 +621,7 @@ struct CmdDevelop : Common, MixEnvironment
bool found = false;
for (auto & path : Installable::toStorePathSet(getEvalStore(), store, Realise::Outputs, OperateOn::Output, {bashInstallable})) {
for (auto & path : Installable::toStorePathSet(*state, getEvalStore(), store, Realise::Outputs, OperateOn::Output, {bashInstallable})) {
auto s = store->printStorePath(path) + "/bin/bash";
if (pathExists(s)) {
shell = s;
@@ -651,7 +651,7 @@ struct CmdDevelop : Common, MixEnvironment
// chdir if installable is a flake of type git+file or path
auto installableFlake = installable.dynamic_pointer_cast<InstallableFlake>();
if (installableFlake) {
auto sourcePath = installableFlake->getLockedFlake()->flake.resolvedRef.input.getSourcePath();
auto sourcePath = installableFlake->getLockedFlake(*getEvalState())->flake.resolvedRef.input.getSourcePath();
if (sourcePath) {
if (chdir(sourcePath->c_str()) == -1) {
throw SysError("chdir to '%s' failed", *sourcePath);
+5 -4
View File
@@ -124,10 +124,11 @@ struct CmdDiffClosures : SourceExprCommand, MixOperateOnOptions
void run(ref<Store> store) override
{
auto before = parseInstallable(store, _before);
auto beforePath = Installable::toStorePath(getEvalStore(), store, Realise::Outputs, operateOn, before);
auto after = parseInstallable(store, _after);
auto afterPath = Installable::toStorePath(getEvalStore(), store, Realise::Outputs, operateOn, after);
auto state = getEvalState();
auto before = parseInstallable(*state, store, _before);
auto beforePath = Installable::toStorePath(*state, getEvalStore(), store, Realise::Outputs, operateOn, before);
auto after = parseInstallable(*state, store, _after);
auto afterPath = Installable::toStorePath(*state, getEvalStore(), store, Realise::Outputs, operateOn, after);
printClosureDiff(store, beforePath, afterPath, "");
}
};
+1 -1
View File
@@ -33,7 +33,7 @@ struct CmdEdit : InstallableCommand
auto const installableValue = InstallableValue::require(installable);
const auto [file, line] = [&] {
auto [v, pos] = installableValue->toValue();
auto [v, pos] = installableValue->toValue(*state);
try {
return findPackageFilename(*state, *v, installable->what());
+1 -1
View File
@@ -64,7 +64,7 @@ struct CmdEval : MixJSON, InstallableCommand, MixReadOnlyOption
auto evaluator = getEvalState();
auto state = evaluator;
auto [v, pos] = installableValue->toValue();
auto [v, pos] = installableValue->toValue(*state);
NixStringContext context;
if (apply) {
+1 -1
View File
@@ -864,7 +864,7 @@ struct CmdFlakeInitCommon : virtual Args, EvalCommand
defaultTemplateAttrPathsPrefixes,
lockFlags);
auto cursor = installable.getCursor();
auto cursor = installable.getCursor(*evalState);
auto templateDirAttr = cursor->getAttr(*evalState, "path");
auto templateDir = templateDirAttr->getString(*evalState);
+2 -2
View File
@@ -32,9 +32,9 @@ struct CmdFmt : SourceExprCommand {
auto evalState = getEvalState();
auto evalStore = getEvalStore();
auto installable_ = parseInstallable(store, ".");
auto installable_ = parseInstallable(*evalState, store, ".");
auto & installable = InstallableValue::require(*installable_);
auto app = installable.toApp().resolve(evalStore, store);
auto app = installable.toApp(*evalState).resolve(*evalState, evalStore, store);
Strings programArgs{app.program};
+1 -1
View File
@@ -30,7 +30,7 @@ struct CmdLog : InstallableCommand
subs.push_front(store);
auto b = installable->toDerivedPath();
auto b = installable->toDerivedPath(*getEvalState());
// For compat with CLI today, TODO revisit
auto oneUp = std::visit(overloaded {
+3 -3
View File
@@ -73,7 +73,7 @@ struct CmdProfileInstall : InstallablesCommand, MixDefaultProfile
auto builtPaths = builtPathsPerInstallable(
Installable::build2(
getEvalStore(), store, Realise::Outputs, installables, bmNormal));
*getEvalState(), getEvalStore(), store, Realise::Outputs, installables, bmNormal));
for (auto & installable : installables) {
ProfileElement element;
@@ -343,7 +343,7 @@ struct CmdProfileUpgrade : virtual SourceExprCommand, MixDefaultProfile, MixProf
lockFlags
);
auto derivedPaths = installable->toDerivedPaths();
auto derivedPaths = installable->toDerivedPaths(*getEvalState());
if (derivedPaths.empty()) {
continue;
}
@@ -393,7 +393,7 @@ struct CmdProfileUpgrade : virtual SourceExprCommand, MixDefaultProfile, MixProf
auto builtPaths = builtPathsPerInstallable(
Installable::build2(
getEvalStore(), store, Realise::Outputs, installables, bmNormal));
*getEvalState(), getEvalStore(), store, Realise::Outputs, installables, bmNormal));
for (size_t i = 0; i < installables.size(); ++i) {
auto & installable = installables.at(i);
+3 -3
View File
@@ -66,13 +66,13 @@ struct CmdRepl : RawInstallablesCommand
auto evaluator = getEvalState();
auto state = evaluator;
auto getValues = [&]()->AbstractNixRepl::AnnotatedValues{
auto installables = parseInstallables(store, rawInstallables);
auto installables = parseInstallables(*state, store, rawInstallables);
AbstractNixRepl::AnnotatedValues values;
for (auto & installable_: installables){
auto & installable = InstallableValue::require(*installable_);
auto what = installable.what();
if (file){
auto [val, pos] = installable.toValue();
auto [val, pos] = installable.toValue(*state);
auto what = installable.what();
state->forceValue(*val, pos);
auto autoArgs = getAutoArgs(*evaluator);
@@ -81,7 +81,7 @@ struct CmdRepl : RawInstallablesCommand
state->forceValue(*valPost, pos);
values.push_back( {valPost, what });
} else {
auto [val, pos] = installable.toValue();
auto [val, pos] = installable.toValue(*state);
values.push_back( {val, what} );
}
}
+2 -2
View File
@@ -111,7 +111,7 @@ struct CmdShell : InstallablesCommand, MixEnvironment
void run(ref<Store> store, Installables && installables) override
{
auto outPaths = Installable::toStorePaths(getEvalStore(), store, Realise::Outputs, OperateOn::Output, installables);
auto outPaths = Installable::toStorePaths(*getEvalState(), getEvalStore(), store, Realise::Outputs, OperateOn::Output, installables);
auto accessor = store->getFSAccessor();
@@ -205,7 +205,7 @@ struct CmdRun : InstallableCommand
auto installableValue = InstallableValue::require(installable);
lockFlags.applyNixConfig = true;
auto app = installableValue->toApp().resolve(getEvalStore(), store);
auto app = installableValue->toApp(*state).resolve(*state, getEvalStore(), store);
Strings allArgs{app.program};
for (auto & i : args) allArgs.push_back(i);
+1 -1
View File
@@ -193,7 +193,7 @@ struct CmdSearch : InstallableCommand, MixJSON
}
};
for (auto & cursor : installableValue->getCursors())
for (auto & cursor : installableValue->getCursors(*state))
visit(*cursor, cursor->getAttrPath(*state), true);
if (json)
+1 -1
View File
@@ -31,7 +31,7 @@ struct CmdCopyLog : virtual CopyCommand, virtual InstallablesCommand
auto dstStore = getDstStore();
auto & dstLogStore = require<LogStore>(*dstStore);
for (auto & drvPath : Installable::toDerivations(getEvalStore(), installables, true)) {
for (auto & drvPath : Installable::toDerivations(*getEvalState(), getEvalStore(), installables, true)) {
if (auto log = srcLogStore.getBuildLog(drvPath))
dstLogStore.addBuildLog(drvPath, *log);
else
+5 -4
View File
@@ -76,8 +76,9 @@ struct CmdWhyDepends : SourceExprCommand, MixOperateOnOptions
void run(ref<Store> store) override
{
auto package = parseInstallable(store, _package);
auto packagePath = Installable::toStorePath(getEvalStore(), store, Realise::Outputs, operateOn, package);
auto state = getEvalState();
auto package = parseInstallable(*state, store, _package);
auto packagePath = Installable::toStorePath(*state, getEvalStore(), store, Realise::Outputs, operateOn, package);
/* We don't need to build `dependency`. We try to get the store
* path if it's already known, and if not, then it's not a dependency.
@@ -89,10 +90,10 @@ struct CmdWhyDepends : SourceExprCommand, MixOperateOnOptions
* derivation which hasn't been built), then `package` did not need it
* to build.
*/
auto dependency = parseInstallable(store, _dependency);
auto dependency = parseInstallable(*state, store, _dependency);
auto optDependencyPath = [&]() -> std::optional<StorePath> {
try {
return {Installable::toStorePath(getEvalStore(), store, Realise::Derivation, operateOn, dependency)};
return {Installable::toStorePath(*state, getEvalStore(), store, Realise::Derivation, operateOn, dependency)};
} catch (MissingRealisation &) {
return std::nullopt;
}