state commit

Change-Id: Ic3ef3f0477f15758d5bb1ce28b3a801bd5739496
This commit is contained in:
Qyriad 2024-06-19 18:44:16 -06:00
parent 85f282ef57
commit 8477702696
16 changed files with 300 additions and 55 deletions

View file

@ -45,6 +45,7 @@ std::pair<Value *, PosIdx> InstallableAttrPath::toValue(EvalState & state)
DerivedPathsWithInfo InstallableAttrPath::toDerivedPaths() DerivedPathsWithInfo InstallableAttrPath::toDerivedPaths()
{ {
notice("InstallableAttrPath::toDerivedPaths() START");
auto [v, pos] = toValue(*state); auto [v, pos] = toValue(*state);
if (std::optional derivedPathWithInfo = trySinglePathToDerivedPaths( if (std::optional derivedPathWithInfo = trySinglePathToDerivedPaths(

View file

@ -10,6 +10,7 @@ std::string InstallableDerivedPath::what() const
DerivedPathsWithInfo InstallableDerivedPath::toDerivedPaths() DerivedPathsWithInfo InstallableDerivedPath::toDerivedPaths()
{ {
notice("InstallableDerivedPath::toDerivedPaths() START");
return {{ return {{
.path = derivedPath, .path = derivedPath,
.info = make_ref<ExtraPathInfo>(), .info = make_ref<ExtraPathInfo>(),

View file

@ -421,6 +421,7 @@ ref<eval_cache::EvalCache> openEvalCache(
Installables SourceExprCommand::parseInstallables( Installables SourceExprCommand::parseInstallables(
ref<Store> store, std::vector<std::string> ss) ref<Store> store, std::vector<std::string> ss)
{ {
notice("SourceExprCommand::parseInstallables() START");
Installables result; Installables result;
if (file || expr) { if (file || expr) {
@ -448,8 +449,9 @@ Installables SourceExprCommand::parseInstallables(
auto [prefix, extendedOutputsSpec] = ExtendedOutputsSpec::parse(s); auto [prefix, extendedOutputsSpec] = ExtendedOutputsSpec::parse(s);
result.push_back( result.push_back(
make_ref<InstallableAttrPath>( make_ref<InstallableAttrPath>(
InstallableAttrPath::parse( InstallableAttrPath::parse(state, *this, vFile, std::move(prefix), std::move(extendedOutputsSpec))
state, *this, vFile, std::move(prefix), std::move(extendedOutputsSpec)))); )
);
} }
} else { } else {
@ -494,6 +496,8 @@ Installables SourceExprCommand::parseInstallables(
} }
} }
printTalkative("SourceExprCommand::parseInstallables() END");
return result; return result;
} }
@ -536,6 +540,7 @@ std::vector<BuiltPathWithResult> Installable::build(
const Installables & installables, const Installables & installables,
BuildMode bMode) BuildMode bMode)
{ {
notice("Installable::build() START");
std::vector<BuiltPathWithResult> res; std::vector<BuiltPathWithResult> res;
for (auto & [_, builtPathWithResult] : build2(evalStore, store, mode, installables, bMode)) for (auto & [_, builtPathWithResult] : build2(evalStore, store, mode, installables, bMode))
res.push_back(builtPathWithResult); res.push_back(builtPathWithResult);
@ -580,6 +585,7 @@ std::vector<std::pair<ref<Installable>, BuiltPathWithResult>> Installable::build
const Installables & installables, const Installables & installables,
BuildMode bMode) BuildMode bMode)
{ {
notice("Installable::build2() START");
if (mode == Realise::Nothing) if (mode == Realise::Nothing)
settings.readOnlyMode = true; settings.readOnlyMode = true;
@ -631,8 +637,10 @@ std::vector<std::pair<ref<Installable>, BuiltPathWithResult>> Installable::build
break; break;
case Realise::Outputs: { case Realise::Outputs: {
if (settings.printMissing) if (settings.printMissing) {
notice("printMissing() CALLING");
printMissing(store, pathsToBuild, lvlInfo); printMissing(store, pathsToBuild, lvlInfo);
}
auto buildResults = store->buildPathsWithResults(pathsToBuild, bMode, evalStore); auto buildResults = store->buildPathsWithResults(pathsToBuild, bMode, evalStore);
throwBuildErrors(buildResults, *store); throwBuildErrors(buildResults, *store);
@ -641,8 +649,9 @@ std::vector<std::pair<ref<Installable>, BuiltPathWithResult>> Installable::build
std::visit(overloaded { std::visit(overloaded {
[&](const DerivedPath::Built & bfd) { [&](const DerivedPath::Built & bfd) {
std::map<std::string, StorePath> outputs; std::map<std::string, StorePath> outputs;
for (auto & [outputName, realisation] : buildResult.builtOutputs) for (auto & [outputName, realisation] : buildResult.builtOutputs) {
outputs.emplace(outputName, realisation.outPath); outputs.emplace(outputName, realisation.outPath);
}
res.push_back({aux.installable, { res.push_back({aux.installable, {
.path = BuiltPath::Built { .path = BuiltPath::Built {
.drvPath = make_ref<SingleBuiltPath>(getBuiltPath(evalStore, store, *bfd.drvPath)), .drvPath = make_ref<SingleBuiltPath>(getBuiltPath(evalStore, store, *bfd.drvPath)),
@ -655,7 +664,8 @@ std::vector<std::pair<ref<Installable>, BuiltPathWithResult>> Installable::build
res.push_back({aux.installable, { res.push_back({aux.installable, {
.path = BuiltPath::Opaque { bo.path }, .path = BuiltPath::Opaque { bo.path },
.info = aux.info, .info = aux.info,
.result = buildResult}}); .result = buildResult
}});
}, },
}, buildResult.path.raw()); }, buildResult.path.raw());
} }
@ -799,6 +809,7 @@ std::vector<FlakeRef> RawInstallablesCommand::getFlakeRefsForCompletion()
void RawInstallablesCommand::run(ref<Store> store) void RawInstallablesCommand::run(ref<Store> store)
{ {
printTalkative("RawInstallablesCommand::run() START");
if (readFromStdIn && !isatty(STDIN_FILENO)) { if (readFromStdIn && !isatty(STDIN_FILENO)) {
std::string word; std::string word;
while (std::cin >> word) { while (std::cin >> word) {

View file

@ -1,10 +1,18 @@
#pragma once #pragma once
///@file ///@file
#include <sstream>
#include "error.hh"
#include "logging.hh"
#include "print.hh" #include "print.hh"
#include "eval.hh" #include "eval.hh"
#include "eval-error.hh" #include "eval-error.hh"
#include <boost/core/demangle.hpp>
#define TYPENAME(expr) (boost::core::demangle(typeid(expr).name()))
namespace nix { namespace nix {
/** /**
@ -80,26 +88,113 @@ Env & EvalState::allocEnv(size_t size)
return *env; return *env;
} }
template <typename T, typename ... Variants>
std::optional<std::reference_wrapper<T>> maybe_get(std::variant<Variants ...> & some_variant)
{
auto * maybe = std::get_if<T>(&some_variant);
if (maybe) {
return std::make_optional(std::ref(*maybe));
}
return std::nullopt;
}
template<typename T, typename ... Variants>
auto maybe_do(std::variant<Variants ...> & some_variant, auto && some_callable) -> std::optional<decltype(some_callable(*std::get_if<T>(&some_variant)))>
{
auto * maybe = std::get_if<T>(&some_variant);
if (maybe) {
return std::make_optional(some_callable(*maybe));
}
return std::nullopt;
}
[[gnu::always_inline]] [[gnu::always_inline]]
void EvalState::forceValue(Value & v, const PosIdx pos) void EvalState::forceValue(Value & v, const PosIdx pos)
{ {
//auto const maybeOrigin = maybe_get<SourcePath>(position.origin);
//if (maybeOrigin.has_value()) {
// auto const & origin = maybeOrigin.value().get();
//}
//
//if (auto const maybeOrigin = maybe_get<SourcePath>(position.origin)) {
// auto const & origin = maybeOrigin.value().get();
//}
//
//maybe_do<SourcePath>(position.origin, [&](SourcePath & origin) {
// return 5;
//});
//std::shared_ptr<Activity> act = nullptr;
//std::shared_ptr<std::string> actPath = nullptr;
std::optional<std::string> actPath = std::nullopt;
std::optional<Activity> optAct = std::nullopt;
std::optional<PushActivity> pushAct = std::nullopt;
auto position = positions[pos];
if (auto const * path = std::get_if<SourcePath>(&position.origin)) {
//std::string const pathStr = path->to_string();
//actPath = std::make_shared<std::string>(pathStr);
actPath.emplace(fmt("%s:%d", path->to_string(), position.line));
//optAct.emplace(
// *logger,
// lvlDebug,
// actUnknown,
// fmt("forcing '%s'", *actPath)
// //Logger::Fields{*actPath}
//);
//pushAct.emplace(optAct->id);
}
if (v.isThunk()) { if (v.isThunk()) {
Env * env = v.thunk.env; Env * env = v.thunk.env;
Expr & expr = *v.thunk.expr; Expr & expr = *v.thunk.expr;
std::optional<std::reference_wrapper<Activity>> actRef = std::nullopt;
if (actPath.has_value()) {
optAct.emplace(
*logger,
lvlDebug,
actEvaluating,
fmt("forcing '%s' in '%s'", TYPENAME(*v.thunk.expr), *actPath)
);
pushAct.emplace(optAct->id);
actRef.emplace(std::ref(optAct.value()));
}
try { try {
v.mkBlackhole(); v.mkBlackhole();
//checkInterrupt(); //checkInterrupt();
expr.eval(*this, *env, v); expr.eval(*this, *env, v, actRef);
} catch (...) { } catch (...) {
v.mkThunk(env, expr); v.mkThunk(env, expr);
tryFixupBlackHolePos(v, pos); tryFixupBlackHolePos(v, pos);
throw; throw;
} }
} else if (v.isApp()) {
if (v.app.left->isLambda() && v.app.left->lambda.fun->name) {
actPath.emplace(symbols[v.app.left->lambda.fun->name]);
optAct.emplace(
*logger,
lvlDebug,
actEvaluating,
fmt("calling '%s'", *actPath)
);
pushAct.emplace(optAct->id);
} }
else if (v.isApp()) //if (v.app.left->isLambda() && v.app.left->lambda.fun->name) {
// actPath = std::make_shared<std::string>(symbols[v.app.left->lambda.fun->name]);
// act = std::make_shared<Activity>(
// *logger,
// lvlTalkative,
// actUnknown,
// fmt("calling '%s'", *actPath),
// Logger::Fields{*actPath}
// );
//}
callFunction(*v.app.left, *v.app.right, v, pos); callFunction(*v.app.left, *v.app.right, v, pos);
} }
}
[[gnu::always_inline]] [[gnu::always_inline]]

View file

@ -1,6 +1,8 @@
#include "eval.hh" #include "eval.hh"
#include "error.hh"
#include "eval-settings.hh" #include "eval-settings.hh"
#include "hash.hh" #include "hash.hh"
#include "logging.hh"
#include "primops.hh" #include "primops.hh"
#include "print-options.hh" #include "print-options.hh"
#include "shared.hh" #include "shared.hh"
@ -21,6 +23,7 @@
#include <algorithm> #include <algorithm>
#include <chrono> #include <chrono>
#include <cstddef>
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
#include <cstring> #include <cstring>
@ -1114,7 +1117,45 @@ void EvalState::evalFile(const SourcePath & path_, Value & v, bool mustBeTrivial
return; return;
} }
debug("evaluating file '%1%'", resolvedPath); //debug("evaluating file '%1%'", resolvedPath);
std::string const pathstr = resolvedPath.to_string();
Activity evalAct(
*logger,
lvlDebug,
actUnknown,
fmt("evaluating file '%s'", pathstr)
);
PushActivity pushAct(evalAct.id);
//auto act = std::make_shared<Activity>(
// *logger,
// lvlTalkative,
// actUnknown,
// fmt("evaluating file '%s'", pathstr),
// Logger::Fields{pathstr}
//);
//PushActivity pact(act->id);
//for ([[maybe_unused]] auto const i : {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) {
//for ([[maybe_unused]] auto const i : std::ranges::views::iota(0, 100)) {
// std::this_thread::sleep_for(
// std::chrono::milliseconds(500)
// );
//}
//std::basic_ifstream<uint8_t> random("/dev/random", std::ios::binary);
//char volatile buffer[1024];
//for (auto const i : std::ranges::views::iota(0, 512)) {
// //std::vector<uint8_t>::size_type size = random.tellg();
// std::vector<uint8_t>::size_type size = 128;
// std::vector<uint8_t> rand_buffer(size, static_cast<uint8_t>(0));
// random.read(rand_buffer.data(), size);
// buffer[i] = rand_buffer.at(0);
// std::this_thread::sleep_for(std::chrono::milliseconds(1));
//}
//random.close();
//PushActivity pact(act->id);
//std::this_thread::sleep_for(std::chrono::milliseconds(50));
Expr * e = nullptr; Expr * e = nullptr;
auto j = fileParseCache.find(resolvedPath); auto j = fileParseCache.find(resolvedPath);
@ -1212,30 +1253,30 @@ inline void EvalState::evalAttrs(Env & env, Expr & e, Value & v, const PosIdx po
} }
void Expr::eval(EvalState & state, Env & env, Value & v) void Expr::eval(EvalState & state, Env & env, Value & v, std::optional<std::reference_wrapper<Activity>> act)
{ {
abort(); abort();
} }
void ExprInt::eval(EvalState & state, Env & env, Value & v) void ExprInt::eval(EvalState & state, Env & env, Value & v, std::optional<std::reference_wrapper<Activity>> act)
{ {
v = this->v; v = this->v;
} }
void ExprFloat::eval(EvalState & state, Env & env, Value & v) void ExprFloat::eval(EvalState & state, Env & env, Value & v, std::optional<std::reference_wrapper<Activity>> act)
{ {
v = this->v; v = this->v;
} }
void ExprString::eval(EvalState & state, Env & env, Value & v) void ExprString::eval(EvalState & state, Env & env, Value & v, std::optional<std::reference_wrapper<Activity>> act)
{ {
v = this->v; v = this->v;
} }
void ExprPath::eval(EvalState & state, Env & env, Value & v) void ExprPath::eval(EvalState & state, Env & env, Value & v, std::optional<std::reference_wrapper<Activity>> act)
{ {
v = this->v; v = this->v;
} }
@ -1253,7 +1294,7 @@ Env * ExprAttrs::buildInheritFromEnv(EvalState & state, Env & up)
return &inheritEnv; return &inheritEnv;
} }
void ExprAttrs::eval(EvalState & state, Env & env, Value & v) void ExprAttrs::eval(EvalState & state, Env & env, Value & v, std::optional<std::reference_wrapper<Activity>> act)
{ {
v.mkAttrs(state.buildBindings(attrs.size() + dynamicAttrs.size()).finish()); v.mkAttrs(state.buildBindings(attrs.size() + dynamicAttrs.size()).finish());
auto dynamicEnv = &env; auto dynamicEnv = &env;
@ -1344,11 +1385,16 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v)
} }
void ExprLet::eval(EvalState & state, Env & env, Value & v) void ExprLet::eval(EvalState & state, Env & env, Value & v, std::optional<std::reference_wrapper<Activity>> act)
{ {
auto const attrCount = attrs->attrs.size();
if (act.has_value()) {
Activity & activity = act->get();
activity.setExpected(actEvaluating, attrCount);
}
/* Create a new environment that contains the attributes in this /* Create a new environment that contains the attributes in this
`let'. */ `let'. */
Env & env2(state.allocEnv(attrs->attrs.size())); Env & env2(state.allocEnv(attrCount));
env2.up = &env; env2.up = &env;
Env * inheritEnv = attrs->inheritFromExprs ? attrs->buildInheritFromEnv(state, env2) : nullptr; Env * inheritEnv = attrs->inheritFromExprs ? attrs->buildInheritFromEnv(state, env2) : nullptr;
@ -1357,7 +1403,12 @@ void ExprLet::eval(EvalState & state, Env & env, Value & v)
while the inherited attributes are evaluated in the original while the inherited attributes are evaluated in the original
environment. */ environment. */
Displacement displ = 0; Displacement displ = 0;
size_t current = 0;
for (auto & i : attrs->attrs) { for (auto & i : attrs->attrs) {
if (act.has_value()) {
act->get().progress(current);
}
current += 1;
env2.values[displ++] = i.second.e->maybeThunk( env2.values[displ++] = i.second.e->maybeThunk(
state, state,
*i.second.chooseByKind(&env2, &env, inheritEnv)); *i.second.chooseByKind(&env2, &env, inheritEnv));
@ -1380,7 +1431,7 @@ void ExprLet::eval(EvalState & state, Env & env, Value & v)
} }
void ExprList::eval(EvalState & state, Env & env, Value & v) void ExprList::eval(EvalState & state, Env & env, Value & v, std::optional<std::reference_wrapper<Activity>> act)
{ {
state.mkList(v, elems.size()); state.mkList(v, elems.size());
for (auto [n, v2] : enumerate(v.listItems())) for (auto [n, v2] : enumerate(v.listItems()))
@ -1397,7 +1448,7 @@ Value * ExprList::maybeThunk(EvalState & state, Env & env)
} }
void ExprVar::eval(EvalState & state, Env & env, Value & v) void ExprVar::eval(EvalState & state, Env & env, Value & v, std::optional<std::reference_wrapper<Activity>> act)
{ {
Value * v2 = state.lookupVar(&env, *this, false); Value * v2 = state.lookupVar(&env, *this, false);
state.forceValue(*v2, pos); state.forceValue(*v2, pos);
@ -1424,7 +1475,7 @@ static std::string showAttrPath(EvalState & state, Env & env, const AttrPath & a
} }
void ExprSelect::eval(EvalState & state, Env & env, Value & v) void ExprSelect::eval(EvalState & state, Env & env, Value & v, std::optional<std::reference_wrapper<Activity>> act)
{ {
Value vTmp; Value vTmp;
PosIdx pos2; PosIdx pos2;
@ -1488,7 +1539,7 @@ void ExprSelect::eval(EvalState & state, Env & env, Value & v)
} }
void ExprOpHasAttr::eval(EvalState & state, Env & env, Value & v) void ExprOpHasAttr::eval(EvalState & state, Env & env, Value & v, std::optional<std::reference_wrapper<Activity>> act)
{ {
Value vTmp; Value vTmp;
Value * vAttrs = &vTmp; Value * vAttrs = &vTmp;
@ -1513,7 +1564,7 @@ void ExprOpHasAttr::eval(EvalState & state, Env & env, Value & v)
} }
void ExprLambda::eval(EvalState & state, Env & env, Value & v) void ExprLambda::eval(EvalState & state, Env & env, Value & v, std::optional<std::reference_wrapper<Activity>> act)
{ {
v.mkLambda(&env, this); v.mkLambda(&env, this);
} }
@ -1815,7 +1866,7 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value &
} }
void ExprCall::eval(EvalState & state, Env & env, Value & v) void ExprCall::eval(EvalState & state, Env & env, Value & v, std::optional<std::reference_wrapper<Activity>> act)
{ {
auto dts = state.debugRepl auto dts = state.debugRepl
? makeDebugTraceStacker( ? makeDebugTraceStacker(
@ -1838,9 +1889,18 @@ void ExprCall::eval(EvalState & state, Env & env, Value & v)
// 4: about 60 // 4: about 60
// 5: under 10 // 5: under 10
// This excluded attrset lambdas (`{...}:`). Contributions of mixed lambdas appears insignificant at ~150 total. // This excluded attrset lambdas (`{...}:`). Contributions of mixed lambdas appears insignificant at ~150 total.
if (act.has_value()) {
Activity & activity = act->get();
activity.setExpected(actEvaluating, args.size());
}
SmallValueVector<4> vArgs(args.size()); SmallValueVector<4> vArgs(args.size());
for (size_t i = 0; i < args.size(); ++i) for (size_t i = 0; i < args.size(); ++i) {
if (act.has_value()) {
Activity & activity = act->get();
activity.progress(i);
}
vArgs[i] = args[i]->maybeThunk(state, env); vArgs[i] = args[i]->maybeThunk(state, env);
}
state.callFunction(vFun, args.size(), vArgs.data(), v, pos); state.callFunction(vFun, args.size(), vArgs.data(), v, pos);
} }
@ -1904,7 +1964,7 @@ https://nixos.org/manual/nix/stable/language/constructs.html#functions.)", symbo
} }
void ExprWith::eval(EvalState & state, Env & env, Value & v) void ExprWith::eval(EvalState & state, Env & env, Value & v, std::optional<std::reference_wrapper<Activity>> act)
{ {
Env & env2(state.allocEnv(1)); Env & env2(state.allocEnv(1));
env2.up = &env; env2.up = &env;
@ -1914,14 +1974,14 @@ void ExprWith::eval(EvalState & state, Env & env, Value & v)
} }
void ExprIf::eval(EvalState & state, Env & env, Value & v) void ExprIf::eval(EvalState & state, Env & env, Value & v, std::optional<std::reference_wrapper<Activity>> act)
{ {
// We cheat in the parser, and pass the position of the condition as the position of the if itself. // We cheat in the parser, and pass the position of the condition as the position of the if itself.
(state.evalBool(env, *cond, pos, "while evaluating a branch condition") ? *then : *else_).eval(state, env, v); (state.evalBool(env, *cond, pos, "while evaluating a branch condition") ? *then : *else_).eval(state, env, v);
} }
void ExprAssert::eval(EvalState & state, Env & env, Value & v) void ExprAssert::eval(EvalState & state, Env & env, Value & v, std::optional<std::reference_wrapper<Activity>> act)
{ {
if (!state.evalBool(env, *cond, pos, "in the condition of the assert statement")) { if (!state.evalBool(env, *cond, pos, "in the condition of the assert statement")) {
std::ostringstream out; std::ostringstream out;
@ -1932,13 +1992,13 @@ void ExprAssert::eval(EvalState & state, Env & env, Value & v)
} }
void ExprOpNot::eval(EvalState & state, Env & env, Value & v) void ExprOpNot::eval(EvalState & state, Env & env, Value & v, std::optional<std::reference_wrapper<Activity>> act)
{ {
v.mkBool(!state.evalBool(env, *e, getPos(), "in the argument of the not operator")); // XXX: FIXME: ! v.mkBool(!state.evalBool(env, *e, getPos(), "in the argument of the not operator")); // XXX: FIXME: !
} }
void ExprOpEq::eval(EvalState & state, Env & env, Value & v) void ExprOpEq::eval(EvalState & state, Env & env, Value & v, std::optional<std::reference_wrapper<Activity>> act)
{ {
Value v1; e1->eval(state, env, v1); Value v1; e1->eval(state, env, v1);
Value v2; e2->eval(state, env, v2); Value v2; e2->eval(state, env, v2);
@ -1946,7 +2006,7 @@ void ExprOpEq::eval(EvalState & state, Env & env, Value & v)
} }
void ExprOpNEq::eval(EvalState & state, Env & env, Value & v) void ExprOpNEq::eval(EvalState & state, Env & env, Value & v, std::optional<std::reference_wrapper<Activity>> act)
{ {
Value v1; e1->eval(state, env, v1); Value v1; e1->eval(state, env, v1);
Value v2; e2->eval(state, env, v2); Value v2; e2->eval(state, env, v2);
@ -1954,25 +2014,25 @@ void ExprOpNEq::eval(EvalState & state, Env & env, Value & v)
} }
void ExprOpAnd::eval(EvalState & state, Env & env, Value & v) void ExprOpAnd::eval(EvalState & state, Env & env, Value & v, std::optional<std::reference_wrapper<Activity>> act)
{ {
v.mkBool(state.evalBool(env, *e1, pos, "in the left operand of the AND (&&) operator") && state.evalBool(env, *e2, pos, "in the right operand of the AND (&&) operator")); v.mkBool(state.evalBool(env, *e1, pos, "in the left operand of the AND (&&) operator") && state.evalBool(env, *e2, pos, "in the right operand of the AND (&&) operator"));
} }
void ExprOpOr::eval(EvalState & state, Env & env, Value & v) void ExprOpOr::eval(EvalState & state, Env & env, Value & v, std::optional<std::reference_wrapper<Activity>> act)
{ {
v.mkBool(state.evalBool(env, *e1, pos, "in the left operand of the OR (||) operator") || state.evalBool(env, *e2, pos, "in the right operand of the OR (||) operator")); v.mkBool(state.evalBool(env, *e1, pos, "in the left operand of the OR (||) operator") || state.evalBool(env, *e2, pos, "in the right operand of the OR (||) operator"));
} }
void ExprOpImpl::eval(EvalState & state, Env & env, Value & v) void ExprOpImpl::eval(EvalState & state, Env & env, Value & v, std::optional<std::reference_wrapper<Activity>> act)
{ {
v.mkBool(!state.evalBool(env, *e1, pos, "in the left operand of the IMPL (->) operator") || state.evalBool(env, *e2, pos, "in the right operand of the IMPL (->) operator")); v.mkBool(!state.evalBool(env, *e1, pos, "in the left operand of the IMPL (->) operator") || state.evalBool(env, *e2, pos, "in the right operand of the IMPL (->) operator"));
} }
void ExprOpUpdate::eval(EvalState & state, Env & env, Value & v) void ExprOpUpdate::eval(EvalState & state, Env & env, Value & v, std::optional<std::reference_wrapper<Activity>> act)
{ {
Value v1, v2; Value v1, v2;
state.evalAttrs(env, *e1, v1, pos, "in the left operand of the update (//) operator"); state.evalAttrs(env, *e1, v1, pos, "in the left operand of the update (//) operator");
@ -2010,7 +2070,7 @@ void ExprOpUpdate::eval(EvalState & state, Env & env, Value & v)
} }
void ExprOpConcatLists::eval(EvalState & state, Env & env, Value & v) void ExprOpConcatLists::eval(EvalState & state, Env & env, Value & v, std::optional<std::reference_wrapper<Activity>> act)
{ {
Value v1; e1->eval(state, env, v1); Value v1; e1->eval(state, env, v1);
Value v2; e2->eval(state, env, v2); Value v2; e2->eval(state, env, v2);
@ -2048,7 +2108,7 @@ void EvalState::concatLists(Value & v, size_t nrLists, Value * * lists, const Po
} }
void ExprConcatStrings::eval(EvalState & state, Env & env, Value & v) void ExprConcatStrings::eval(EvalState & state, Env & env, Value & v, std::optional<std::reference_wrapper<Activity>> act)
{ {
NixStringContext context; NixStringContext context;
std::vector<BackedStringView> s; std::vector<BackedStringView> s;
@ -2140,13 +2200,13 @@ void ExprConcatStrings::eval(EvalState & state, Env & env, Value & v)
} }
void ExprPos::eval(EvalState & state, Env & env, Value & v) void ExprPos::eval(EvalState & state, Env & env, Value & v, std::optional<std::reference_wrapper<Activity>> act)
{ {
state.mkPos(v, pos); state.mkPos(v, pos);
} }
void ExprBlackHole::eval(EvalState & state, Env & env, Value & v) void ExprBlackHole::eval(EvalState & state, Env & env, Value & v, std::optional<std::reference_wrapper<Activity>> act)
{ {
state.error<InfiniteRecursionError>("infinite recursion encountered") state.error<InfiniteRecursionError>("infinite recursion encountered")
.atPos(v.determinePos(noPos)) .atPos(v.determinePos(noPos))

View file

@ -1,7 +1,9 @@
#pragma once #pragma once
///@file ///@file
#include <functional>
#include <map> #include <map>
#include <optional>
#include <vector> #include <vector>
#include "value.hh" #include "value.hh"
@ -11,6 +13,7 @@
#include "eval-error.hh" #include "eval-error.hh"
#include "pos-idx.hh" #include "pos-idx.hh"
#include "pos-table.hh" #include "pos-table.hh"
#include "logging.hh"
namespace nix { namespace nix {
@ -59,7 +62,7 @@ public:
virtual void show(const SymbolTable & symbols, std::ostream & str) const; virtual void show(const SymbolTable & symbols, std::ostream & str) const;
virtual void bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> & env); virtual void bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> & env);
virtual void eval(EvalState & state, Env & env, Value & v); virtual void eval(EvalState & state, Env & env, Value & v, std::optional<std::reference_wrapper<Activity>> act = std::nullopt);
virtual Value * maybeThunk(EvalState & state, Env & env); virtual Value * maybeThunk(EvalState & state, Env & env);
virtual void setName(Symbol name); virtual void setName(Symbol name);
virtual PosIdx getPos() const { return noPos; } virtual PosIdx getPos() const { return noPos; }
@ -67,7 +70,7 @@ public:
#define COMMON_METHODS \ #define COMMON_METHODS \
void show(const SymbolTable & symbols, std::ostream & str) const override; \ void show(const SymbolTable & symbols, std::ostream & str) const override; \
void eval(EvalState & state, Env & env, Value & v) override; \ void eval(EvalState & state, Env & env, Value & v, std::optional<std::reference_wrapper<Activity>> act = std::nullopt) override; \
void bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> & env) override; void bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> & env) override;
struct ExprInt : Expr struct ExprInt : Expr
@ -406,7 +409,7 @@ struct ExprOpNot : Expr
{ \ { \
e1->bindVars(es, env); e2->bindVars(es, env); \ e1->bindVars(es, env); e2->bindVars(es, env); \
} \ } \
void eval(EvalState & state, Env & env, Value & v) override; \ void eval(EvalState & state, Env & env, Value & v, std::optional<std::reference_wrapper<Activity>> act = std::nullopt) override; \
PosIdx getPos() const override { return pos; } \ PosIdx getPos() const override { return pos; } \
}; };
@ -441,7 +444,7 @@ struct ExprPos : Expr
struct ExprBlackHole : Expr struct ExprBlackHole : Expr
{ {
void show(const SymbolTable & symbols, std::ostream & str) const override {} void show(const SymbolTable & symbols, std::ostream & str) const override {}
void eval(EvalState & state, Env & env, Value & v) override; void eval(EvalState & state, Env & env, Value & v, std::optional<std::reference_wrapper<Activity>> = std::nullopt) override;
void bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> & env) override {} void bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> & env) override {}
}; };

View file

@ -1,12 +1,14 @@
#include "archive.hh" #include "archive.hh"
#include "derivations.hh" #include "derivations.hh"
#include "downstream-placeholder.hh" #include "downstream-placeholder.hh"
#include "error.hh"
#include "eval-inline.hh" #include "eval-inline.hh"
#include "eval.hh" #include "eval.hh"
#include "eval-settings.hh" #include "eval-settings.hh"
#include "gc-small-vector.hh" #include "gc-small-vector.hh"
#include "globals.hh" #include "globals.hh"
#include "json-to-value.hh" #include "json-to-value.hh"
#include "logging.hh"
#include "names.hh" #include "names.hh"
#include "path-references.hh" #include "path-references.hh"
#include "processes.hh" #include "processes.hh"
@ -243,7 +245,24 @@ static void import(EvalState & state, const PosIdx pos, Value & vPath, Value * v
// No need to call staticEnv.sort(), because // No need to call staticEnv.sort(), because
// args[0]->attrs is already sorted. // args[0]->attrs is already sorted.
debug("evaluating file '%1%'", path); //debug("evaluating file '%1%'", path);
std::string const pathstr = path.to_string();
Activity importAct(
*logger,
lvlDebug,
actUnknown,
fmt("importing file '%s'", pathstr)
);
PushActivity pushAct(importAct.id);
//auto act = std::make_shared<Activity>(
// *logger,
// lvlTalkative,
// actUnknown,
// fmt("evaluating file '%s'", pathstr),
// Logger::Fields{pathstr}
//);
//PushActivity pact(act->id);
Expr & e = state.parseExprFromFile(resolveExprPath(path), staticEnv); Expr & e = state.parseExprFromFile(resolveExprPath(path), staticEnv);
e.eval(state, *env, v); e.eval(state, *env, v);

View file

@ -1,4 +1,5 @@
#include "progress-bar.hh" #include "progress-bar.hh"
#include "logging.hh"
#include "sync.hh" #include "sync.hh"
#include "store-api.hh" #include "store-api.hh"
#include "names.hh" #include "names.hh"
@ -188,31 +189,31 @@ public:
.parent = parent, .parent = parent,
.startTime = std::chrono::steady_clock::now() .startTime = std::chrono::steady_clock::now()
}); });
auto i = std::prev(state->activities.end()); auto lastAct = std::prev(state->activities.end());
state->its.emplace(act, i); state->its.emplace(act, lastAct);
state->activitiesByType[type].its.emplace(act, i); state->activitiesByType[type].its.emplace(act, lastAct);
if (type == actBuild) { if (type == actBuild) {
std::string name(storePathToName(getS(fields, 0))); std::string name(storePathToName(getS(fields, 0)));
if (name.ends_with(".drv")) if (name.ends_with(".drv"))
name = name.substr(0, name.size() - 4); name = name.substr(0, name.size() - 4);
i->s = fmt("building " ANSI_BOLD "%s" ANSI_NORMAL, name); lastAct->s = fmt("building " ANSI_BOLD "%s" ANSI_NORMAL, name);
auto machineName = getS(fields, 1); auto machineName = getS(fields, 1);
if (machineName != "") if (machineName != "")
i->s += fmt(" on " ANSI_BOLD "%s" ANSI_NORMAL, machineName); lastAct->s += fmt(" on " ANSI_BOLD "%s" ANSI_NORMAL, machineName);
// Used to be curRound and nrRounds, but the // Used to be curRound and nrRounds, but the
// implementation was broken for a long time. // implementation was broken for a long time.
if (getI(fields, 2) != 1 || getI(fields, 3) != 1) { if (getI(fields, 2) != 1 || getI(fields, 3) != 1) {
throw Error("log message indicated repeating builds, but this is not currently implemented"); throw Error("log message indicated repeating builds, but this is not currently implemented");
} }
i->name = DrvName(name).name; lastAct->name = DrvName(name).name;
} }
if (type == actSubstitute) { if (type == actSubstitute) {
auto name = storePathToName(getS(fields, 0)); auto name = storePathToName(getS(fields, 0));
auto sub = getS(fields, 1); auto sub = getS(fields, 1);
i->s = fmt( lastAct->s = fmt(
sub.starts_with("local") sub.starts_with("local")
? "copying " ANSI_BOLD "%s" ANSI_NORMAL " from %s" ? "copying " ANSI_BOLD "%s" ANSI_NORMAL " from %s"
: "fetching " ANSI_BOLD "%s" ANSI_NORMAL " from %s", : "fetching " ANSI_BOLD "%s" ANSI_NORMAL " from %s",
@ -223,19 +224,24 @@ public:
auto name = storePathToName(getS(fields, 0)); auto name = storePathToName(getS(fields, 0));
if (name.ends_with(".drv")) if (name.ends_with(".drv"))
name = name.substr(0, name.size() - 4); name = name.substr(0, name.size() - 4);
i->s = fmt("post-build " ANSI_BOLD "%s" ANSI_NORMAL, name); lastAct->s = fmt("post-build " ANSI_BOLD "%s" ANSI_NORMAL, name);
i->name = DrvName(name).name; lastAct->name = DrvName(name).name;
} }
if (type == actQueryPathInfo) { if (type == actQueryPathInfo) {
auto name = storePathToName(getS(fields, 0)); auto name = storePathToName(getS(fields, 0));
i->s = fmt("querying " ANSI_BOLD "%s" ANSI_NORMAL " on %s", name, getS(fields, 1)); lastAct->s = fmt("querying " ANSI_BOLD "%s" ANSI_NORMAL " on %s", name, getS(fields, 1));
} }
if ((type == actFileTransfer && hasAncestor(*state, actCopyPath, parent)) if ((type == actFileTransfer && hasAncestor(*state, actCopyPath, parent))
|| (type == actFileTransfer && hasAncestor(*state, actQueryPathInfo, parent)) || (type == actFileTransfer && hasAncestor(*state, actQueryPathInfo, parent))
|| (type == actCopyPath && hasAncestor(*state, actSubstitute, parent))) || (type == actCopyPath && hasAncestor(*state, actSubstitute, parent)))
i->visible = false; lastAct->visible = false;
//if (type == actEvaluating) {
// auto const path = getS(fields, 0);
// lastAct->s = fmt("evaluating " ANSI_BOLD "%s" ANSI_NORMAL, path);
//}
update(*state); update(*state);
} }
@ -407,7 +413,7 @@ public:
auto width = getWindowSize().second; auto width = getWindowSize().second;
if (width <= 0) width = std::numeric_limits<decltype(width)>::max(); if (width <= 0) width = std::numeric_limits<decltype(width)>::max();
writeToStderr("\r" + filterANSIEscapes(line, false, width) + ANSI_NORMAL + "\e[K"); writeToStderr("\r" + filterANSIEscapes(line, false, width) + ANSI_NORMAL + "\e[0K\r");
return nextWakeup; return nextWakeup;
} }
@ -489,6 +495,8 @@ public:
// FIXME: don't show "done" paths in green. // FIXME: don't show "done" paths in green.
showActivity(actVerifyPaths, "%s paths verified"); showActivity(actVerifyPaths, "%s paths verified");
showActivity(actEvaluating, "%s eval");
if (state.corruptedPaths) { if (state.corruptedPaths) {
if (!res.empty()) res += ", "; if (!res.empty()) res += ", ";
res += fmt(ANSI_RED "%d corrupted" ANSI_NORMAL, state.corruptedPaths); res += fmt(ANSI_RED "%d corrupted" ANSI_NORMAL, state.corruptedPaths);

View file

@ -1,5 +1,7 @@
#include "globals.hh" #include "globals.hh"
#include "shared.hh" #include "shared.hh"
#include "logging.hh"
#include "logging.hh"
#include "store-api.hh" #include "store-api.hh"
#include "gc-store.hh" #include "gc-store.hh"
#include "signals.hh" #include "signals.hh"
@ -282,6 +284,7 @@ void parseCmdLine(const std::string & programName, const Strings & args,
void printVersion(const std::string & programName) void printVersion(const std::string & programName)
{ {
std::cout << fmt("%1% (Lix, like Nix) %2%", programName, nixVersion) << std::endl; std::cout << fmt("%1% (Lix, like Nix) %2%", programName, nixVersion) << std::endl;
std::cout << "Verbosity: " << verbosityToString(verbosity) << std::endl;
if (verbosity > lvlInfo) { if (verbosity > lvlInfo) {
Strings cfg; Strings cfg;
#if HAVE_BOEHMGC #if HAVE_BOEHMGC

View file

@ -46,6 +46,7 @@ std::vector<KeyedBuildResult> Store::buildPathsWithResults(
BuildMode buildMode, BuildMode buildMode,
std::shared_ptr<Store> evalStore) std::shared_ptr<Store> evalStore)
{ {
notice("Store::buildPathsWithResults() START");
Worker worker(*this, evalStore ? *evalStore : *this); Worker worker(*this, evalStore ? *evalStore : *this);
Goals goals; Goals goals;

View file

@ -81,6 +81,7 @@ void Store::queryMissing(const std::vector<DerivedPath> & targets,
StorePathSet & willBuild_, StorePathSet & willSubstitute_, StorePathSet & unknown_, StorePathSet & willBuild_, StorePathSet & willSubstitute_, StorePathSet & unknown_,
uint64_t & downloadSize_, uint64_t & narSize_) uint64_t & downloadSize_, uint64_t & narSize_)
{ {
notice("Store::queryMissing() START");
Activity act(*logger, lvlDebug, actUnknown, "querying info about missing paths"); Activity act(*logger, lvlDebug, actUnknown, "querying info about missing paths");
downloadSize_ = narSize_ = 0; downloadSize_ = narSize_ = 0;

View file

@ -47,6 +47,28 @@ typedef enum {
Verbosity verbosityFromIntClamped(int val); Verbosity verbosityFromIntClamped(int val);
constexpr std::string_view verbosityToString(Verbosity lvl)
{
switch (lvl) {
case lvlError:
return "error";
case lvlWarn:
return "warn";
case lvlNotice:
return "notice";
case lvlInfo:
return "info";
case lvlTalkative:
return "talkative";
case lvlChatty:
return "chatty";
case lvlDebug:
return "debug";
case lvlVomit:
return "vomit";
}
}
/** /**
* The lines of code surrounding an error. * The lines of code surrounding an error.
*/ */

View file

@ -21,6 +21,7 @@ typedef enum {
actQueryPathInfo = 109, actQueryPathInfo = 109,
actPostBuildHook = 110, actPostBuildHook = 110,
actBuildWaiting = 111, actBuildWaiting = 111,
actEvaluating = 112,
} ActivityType; } ActivityType;
typedef enum { typedef enum {

View file

@ -154,6 +154,20 @@ constexpr auto enumerate(T && iterable)
return iterable_wrapper{ std::forward<T>(iterable) }; return iterable_wrapper{ std::forward<T>(iterable) };
} }
template<typename T>
concept NumericT = std::integral<T>;
/**
* A Python-like range() iterator.
*/
template<NumericT T>
constexpr auto numeric_range(T && end)
{
struct Iterator
{
size_t i;
};
}
/** /**
* C++17 std::visit boilerplate * C++17 std::visit boilerplate

View file

@ -1,5 +1,6 @@
#include "command.hh" #include "command.hh"
#include "common-args.hh" #include "common-args.hh"
#include "logging.hh"
#include "shared.hh" #include "shared.hh"
#include "store-api.hh" #include "store-api.hh"
#include "local-fs-store.hh" #include "local-fs-store.hh"
@ -115,6 +116,9 @@ struct CmdBuild : InstallablesCommand, MixDryRun, MixJSON, MixProfile
void run(ref<Store> store, Installables && installables) override void run(ref<Store> store, Installables && installables) override
{ {
printTalkative("CmdBuild::run() START");
logger->cout("Verbosity: %s", verbosityToString(nix::verbosity));
throw Exit(0);
if (dryRun) { if (dryRun) {
std::vector<DerivedPath> pathsToBuild; std::vector<DerivedPath> pathsToBuild;

View file

@ -499,6 +499,7 @@ void mainWrapped(int argc, char * * argv)
if (args.command->second->forceImpureByDefault() && !evalSettings.pureEval.overridden) { if (args.command->second->forceImpureByDefault() && !evalSettings.pureEval.overridden) {
evalSettings.pureEval = false; evalSettings.pureEval = false;
} }
printTalkative("args.command->second->run() END OF MAIN");
args.command->second->run(); args.command->second->run();
} }