From 8477702696547f44cae148bccc487171ca95c692 Mon Sep 17 00:00:00 2001 From: Qyriad Date: Wed, 19 Jun 2024 18:44:16 -0600 Subject: [PATCH] state commit Change-Id: Ic3ef3f0477f15758d5bb1ce28b3a801bd5739496 --- src/libcmd/installable-attr-path.cc | 1 + src/libcmd/installable-derived-path.cc | 1 + src/libcmd/installables.cc | 21 +++-- src/libexpr/eval-inline.hh | 101 ++++++++++++++++++++- src/libexpr/eval.cc | 120 ++++++++++++++++++------- src/libexpr/nixexpr.hh | 11 ++- src/libexpr/primops.cc | 21 ++++- src/libmain/progress-bar.cc | 32 ++++--- src/libmain/shared.cc | 3 + src/libstore/build/entry-points.cc | 1 + src/libstore/misc.cc | 1 + src/libutil/error.hh | 22 +++++ src/libutil/logging.hh | 1 + src/libutil/types.hh | 14 +++ src/nix/build.cc | 4 + src/nix/main.cc | 1 + 16 files changed, 300 insertions(+), 55 deletions(-) diff --git a/src/libcmd/installable-attr-path.cc b/src/libcmd/installable-attr-path.cc index eb15fecc3..f86bf205d 100644 --- a/src/libcmd/installable-attr-path.cc +++ b/src/libcmd/installable-attr-path.cc @@ -45,6 +45,7 @@ std::pair InstallableAttrPath::toValue(EvalState & state) DerivedPathsWithInfo InstallableAttrPath::toDerivedPaths() { + notice("InstallableAttrPath::toDerivedPaths() START"); auto [v, pos] = toValue(*state); if (std::optional derivedPathWithInfo = trySinglePathToDerivedPaths( diff --git a/src/libcmd/installable-derived-path.cc b/src/libcmd/installable-derived-path.cc index 4d1f83a1c..36d861113 100644 --- a/src/libcmd/installable-derived-path.cc +++ b/src/libcmd/installable-derived-path.cc @@ -10,6 +10,7 @@ std::string InstallableDerivedPath::what() const DerivedPathsWithInfo InstallableDerivedPath::toDerivedPaths() { + notice("InstallableDerivedPath::toDerivedPaths() START"); return {{ .path = derivedPath, .info = make_ref(), diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc index a10214561..c59d137b5 100644 --- a/src/libcmd/installables.cc +++ b/src/libcmd/installables.cc @@ -421,6 +421,7 @@ ref openEvalCache( Installables SourceExprCommand::parseInstallables( ref store, std::vector ss) { + notice("SourceExprCommand::parseInstallables() START"); Installables result; if (file || expr) { @@ -448,8 +449,9 @@ Installables SourceExprCommand::parseInstallables( auto [prefix, extendedOutputsSpec] = ExtendedOutputsSpec::parse(s); result.push_back( make_ref( - InstallableAttrPath::parse( - state, *this, vFile, std::move(prefix), std::move(extendedOutputsSpec)))); + InstallableAttrPath::parse(state, *this, vFile, std::move(prefix), std::move(extendedOutputsSpec)) + ) + ); } } else { @@ -494,6 +496,8 @@ Installables SourceExprCommand::parseInstallables( } } + printTalkative("SourceExprCommand::parseInstallables() END"); + return result; } @@ -536,6 +540,7 @@ std::vector Installable::build( const Installables & installables, BuildMode bMode) { + notice("Installable::build() START"); std::vector res; for (auto & [_, builtPathWithResult] : build2(evalStore, store, mode, installables, bMode)) res.push_back(builtPathWithResult); @@ -580,6 +585,7 @@ std::vector, BuiltPathWithResult>> Installable::build const Installables & installables, BuildMode bMode) { + notice("Installable::build2() START"); if (mode == Realise::Nothing) settings.readOnlyMode = true; @@ -631,8 +637,10 @@ std::vector, BuiltPathWithResult>> Installable::build break; case Realise::Outputs: { - if (settings.printMissing) + if (settings.printMissing) { + notice("printMissing() CALLING"); printMissing(store, pathsToBuild, lvlInfo); + } auto buildResults = store->buildPathsWithResults(pathsToBuild, bMode, evalStore); throwBuildErrors(buildResults, *store); @@ -641,8 +649,9 @@ std::vector, BuiltPathWithResult>> Installable::build std::visit(overloaded { [&](const DerivedPath::Built & bfd) { std::map outputs; - for (auto & [outputName, realisation] : buildResult.builtOutputs) + for (auto & [outputName, realisation] : buildResult.builtOutputs) { outputs.emplace(outputName, realisation.outPath); + } res.push_back({aux.installable, { .path = BuiltPath::Built { .drvPath = make_ref(getBuiltPath(evalStore, store, *bfd.drvPath)), @@ -655,7 +664,8 @@ std::vector, BuiltPathWithResult>> Installable::build res.push_back({aux.installable, { .path = BuiltPath::Opaque { bo.path }, .info = aux.info, - .result = buildResult}}); + .result = buildResult + }}); }, }, buildResult.path.raw()); } @@ -799,6 +809,7 @@ std::vector RawInstallablesCommand::getFlakeRefsForCompletion() void RawInstallablesCommand::run(ref store) { + printTalkative("RawInstallablesCommand::run() START"); if (readFromStdIn && !isatty(STDIN_FILENO)) { std::string word; while (std::cin >> word) { diff --git a/src/libexpr/eval-inline.hh b/src/libexpr/eval-inline.hh index 94d4c55ef..0d2b05fa6 100644 --- a/src/libexpr/eval-inline.hh +++ b/src/libexpr/eval-inline.hh @@ -1,10 +1,18 @@ #pragma once ///@file +#include + +#include "error.hh" +#include "logging.hh" #include "print.hh" #include "eval.hh" #include "eval-error.hh" +#include + +#define TYPENAME(expr) (boost::core::demangle(typeid(expr).name())) + namespace nix { /** @@ -80,25 +88,112 @@ Env & EvalState::allocEnv(size_t size) return *env; } +template +std::optional> maybe_get(std::variant & some_variant) +{ + auto * maybe = std::get_if(&some_variant); + if (maybe) { + return std::make_optional(std::ref(*maybe)); + } + return std::nullopt; +} + +template +auto maybe_do(std::variant & some_variant, auto && some_callable) -> std::optional(&some_variant)))> +{ + auto * maybe = std::get_if(&some_variant); + if (maybe) { + return std::make_optional(some_callable(*maybe)); + } + return std::nullopt; +} + [[gnu::always_inline]] void EvalState::forceValue(Value & v, const PosIdx pos) { + //auto const maybeOrigin = maybe_get(position.origin); + //if (maybeOrigin.has_value()) { + // auto const & origin = maybeOrigin.value().get(); + //} + // + //if (auto const maybeOrigin = maybe_get(position.origin)) { + // auto const & origin = maybeOrigin.value().get(); + //} + // + //maybe_do(position.origin, [&](SourcePath & origin) { + // return 5; + //}); + //std::shared_ptr act = nullptr; + + //std::shared_ptr actPath = nullptr; + + std::optional actPath = std::nullopt; + std::optional optAct = std::nullopt; + std::optional pushAct = std::nullopt; + + auto position = positions[pos]; + + if (auto const * path = std::get_if(&position.origin)) { + //std::string const pathStr = path->to_string(); + //actPath = std::make_shared(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()) { Env * env = v.thunk.env; Expr & expr = *v.thunk.expr; + std::optional> 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 { v.mkBlackhole(); //checkInterrupt(); - expr.eval(*this, *env, v); + expr.eval(*this, *env, v, actRef); } catch (...) { v.mkThunk(env, expr); tryFixupBlackHolePos(v, pos); throw; } - } - else if (v.isApp()) + } 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); + } + //if (v.app.left->isLambda() && v.app.left->lambda.fun->name) { + // actPath = std::make_shared(symbols[v.app.left->lambda.fun->name]); + // act = std::make_shared( + // *logger, + // lvlTalkative, + // actUnknown, + // fmt("calling '%s'", *actPath), + // Logger::Fields{*actPath} + // ); + //} callFunction(*v.app.left, *v.app.right, v, pos); + } } diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 9bd27e22d..b3de7d7f3 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -1,6 +1,8 @@ #include "eval.hh" +#include "error.hh" #include "eval-settings.hh" #include "hash.hh" +#include "logging.hh" #include "primops.hh" #include "print-options.hh" #include "shared.hh" @@ -21,6 +23,7 @@ #include #include +#include #include #include #include @@ -1114,7 +1117,45 @@ void EvalState::evalFile(const SourcePath & path_, Value & v, bool mustBeTrivial 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( + // *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 random("/dev/random", std::ios::binary); + //char volatile buffer[1024]; + //for (auto const i : std::ranges::views::iota(0, 512)) { + // //std::vector::size_type size = random.tellg(); + // std::vector::size_type size = 128; + // std::vector rand_buffer(size, static_cast(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; 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> act) { abort(); } -void ExprInt::eval(EvalState & state, Env & env, Value & v) +void ExprInt::eval(EvalState & state, Env & env, Value & v, std::optional> act) { v = this->v; } -void ExprFloat::eval(EvalState & state, Env & env, Value & v) +void ExprFloat::eval(EvalState & state, Env & env, Value & v, std::optional> act) { v = this->v; } -void ExprString::eval(EvalState & state, Env & env, Value & v) +void ExprString::eval(EvalState & state, Env & env, Value & v, std::optional> act) { v = this->v; } -void ExprPath::eval(EvalState & state, Env & env, Value & v) +void ExprPath::eval(EvalState & state, Env & env, Value & v, std::optional> act) { v = this->v; } @@ -1253,7 +1294,7 @@ Env * ExprAttrs::buildInheritFromEnv(EvalState & state, Env & up) return &inheritEnv; } -void ExprAttrs::eval(EvalState & state, Env & env, Value & v) +void ExprAttrs::eval(EvalState & state, Env & env, Value & v, std::optional> act) { v.mkAttrs(state.buildBindings(attrs.size() + dynamicAttrs.size()).finish()); 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> 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 `let'. */ - Env & env2(state.allocEnv(attrs->attrs.size())); + Env & env2(state.allocEnv(attrCount)); env2.up = &env; 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 environment. */ Displacement displ = 0; + size_t current = 0; for (auto & i : attrs->attrs) { + if (act.has_value()) { + act->get().progress(current); + } + current += 1; env2.values[displ++] = i.second.e->maybeThunk( state, *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> act) { state.mkList(v, elems.size()); 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> act) { Value * v2 = state.lookupVar(&env, *this, false); 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> act) { Value vTmp; 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> act) { Value 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> act) { 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> act) { auto dts = state.debugRepl ? makeDebugTraceStacker( @@ -1838,9 +1889,18 @@ void ExprCall::eval(EvalState & state, Env & env, Value & v) // 4: about 60 // 5: under 10 // 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()); - 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); + } 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> act) { Env & env2(state.allocEnv(1)); 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> act) { // 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); } -void ExprAssert::eval(EvalState & state, Env & env, Value & v) +void ExprAssert::eval(EvalState & state, Env & env, Value & v, std::optional> act) { if (!state.evalBool(env, *cond, pos, "in the condition of the assert statement")) { 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> act) { 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> act) { Value v1; e1->eval(state, env, v1); 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> act) { Value v1; e1->eval(state, env, v1); 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> 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")); } -void ExprOpOr::eval(EvalState & state, Env & env, Value & v) +void ExprOpOr::eval(EvalState & state, Env & env, Value & v, std::optional> 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")); } -void ExprOpImpl::eval(EvalState & state, Env & env, Value & v) +void ExprOpImpl::eval(EvalState & state, Env & env, Value & v, std::optional> 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")); } -void ExprOpUpdate::eval(EvalState & state, Env & env, Value & v) +void ExprOpUpdate::eval(EvalState & state, Env & env, Value & v, std::optional> act) { Value v1, v2; 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> act) { Value v1; e1->eval(state, env, v1); 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> act) { NixStringContext context; std::vector 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> act) { state.mkPos(v, pos); } -void ExprBlackHole::eval(EvalState & state, Env & env, Value & v) +void ExprBlackHole::eval(EvalState & state, Env & env, Value & v, std::optional> act) { state.error("infinite recursion encountered") .atPos(v.determinePos(noPos)) diff --git a/src/libexpr/nixexpr.hh b/src/libexpr/nixexpr.hh index 45d44d1d1..ff331da16 100644 --- a/src/libexpr/nixexpr.hh +++ b/src/libexpr/nixexpr.hh @@ -1,7 +1,9 @@ #pragma once ///@file +#include #include +#include #include #include "value.hh" @@ -11,6 +13,7 @@ #include "eval-error.hh" #include "pos-idx.hh" #include "pos-table.hh" +#include "logging.hh" namespace nix { @@ -59,7 +62,7 @@ public: virtual void show(const SymbolTable & symbols, std::ostream & str) const; virtual void bindVars(EvalState & es, const std::shared_ptr & env); - virtual void eval(EvalState & state, Env & env, Value & v); + virtual void eval(EvalState & state, Env & env, Value & v, std::optional> act = std::nullopt); virtual Value * maybeThunk(EvalState & state, Env & env); virtual void setName(Symbol name); virtual PosIdx getPos() const { return noPos; } @@ -67,7 +70,7 @@ public: #define COMMON_METHODS \ 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> act = std::nullopt) override; \ void bindVars(EvalState & es, const std::shared_ptr & env) override; struct ExprInt : Expr @@ -406,7 +409,7 @@ struct ExprOpNot : Expr { \ 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> act = std::nullopt) override; \ PosIdx getPos() const override { return pos; } \ }; @@ -441,7 +444,7 @@ struct ExprPos : Expr struct ExprBlackHole : Expr { 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::nullopt) override; void bindVars(EvalState & es, const std::shared_ptr & env) override {} }; diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index 20851da70..56b311fd7 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -1,12 +1,14 @@ #include "archive.hh" #include "derivations.hh" #include "downstream-placeholder.hh" +#include "error.hh" #include "eval-inline.hh" #include "eval.hh" #include "eval-settings.hh" #include "gc-small-vector.hh" #include "globals.hh" #include "json-to-value.hh" +#include "logging.hh" #include "names.hh" #include "path-references.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 // 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( + // *logger, + // lvlTalkative, + // actUnknown, + // fmt("evaluating file '%s'", pathstr), + // Logger::Fields{pathstr} + //); + //PushActivity pact(act->id); Expr & e = state.parseExprFromFile(resolveExprPath(path), staticEnv); e.eval(state, *env, v); diff --git a/src/libmain/progress-bar.cc b/src/libmain/progress-bar.cc index d83b09cd4..b7ad07abf 100644 --- a/src/libmain/progress-bar.cc +++ b/src/libmain/progress-bar.cc @@ -1,4 +1,5 @@ #include "progress-bar.hh" +#include "logging.hh" #include "sync.hh" #include "store-api.hh" #include "names.hh" @@ -188,31 +189,31 @@ public: .parent = parent, .startTime = std::chrono::steady_clock::now() }); - auto i = std::prev(state->activities.end()); - state->its.emplace(act, i); - state->activitiesByType[type].its.emplace(act, i); + auto lastAct = std::prev(state->activities.end()); + state->its.emplace(act, lastAct); + state->activitiesByType[type].its.emplace(act, lastAct); if (type == actBuild) { std::string name(storePathToName(getS(fields, 0))); if (name.ends_with(".drv")) 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); 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 // implementation was broken for a long time. if (getI(fields, 2) != 1 || getI(fields, 3) != 1) { 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) { auto name = storePathToName(getS(fields, 0)); auto sub = getS(fields, 1); - i->s = fmt( + lastAct->s = fmt( sub.starts_with("local") ? "copying " 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)); if (name.ends_with(".drv")) name = name.substr(0, name.size() - 4); - i->s = fmt("post-build " ANSI_BOLD "%s" ANSI_NORMAL, name); - i->name = DrvName(name).name; + lastAct->s = fmt("post-build " ANSI_BOLD "%s" ANSI_NORMAL, name); + lastAct->name = DrvName(name).name; } if (type == actQueryPathInfo) { 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)) || (type == actFileTransfer && hasAncestor(*state, actQueryPathInfo, 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); } @@ -407,7 +413,7 @@ public: auto width = getWindowSize().second; if (width <= 0) width = std::numeric_limits::max(); - writeToStderr("\r" + filterANSIEscapes(line, false, width) + ANSI_NORMAL + "\e[K"); + writeToStderr("\r" + filterANSIEscapes(line, false, width) + ANSI_NORMAL + "\e[0K\r"); return nextWakeup; } @@ -489,6 +495,8 @@ public: // FIXME: don't show "done" paths in green. showActivity(actVerifyPaths, "%s paths verified"); + showActivity(actEvaluating, "%s eval"); + if (state.corruptedPaths) { if (!res.empty()) res += ", "; res += fmt(ANSI_RED "%d corrupted" ANSI_NORMAL, state.corruptedPaths); diff --git a/src/libmain/shared.cc b/src/libmain/shared.cc index f99777a20..c7c18fd8d 100644 --- a/src/libmain/shared.cc +++ b/src/libmain/shared.cc @@ -1,5 +1,7 @@ #include "globals.hh" #include "shared.hh" +#include "logging.hh" +#include "logging.hh" #include "store-api.hh" #include "gc-store.hh" #include "signals.hh" @@ -282,6 +284,7 @@ void parseCmdLine(const std::string & programName, const Strings & args, void printVersion(const std::string & programName) { std::cout << fmt("%1% (Lix, like Nix) %2%", programName, nixVersion) << std::endl; + std::cout << "Verbosity: " << verbosityToString(verbosity) << std::endl; if (verbosity > lvlInfo) { Strings cfg; #if HAVE_BOEHMGC diff --git a/src/libstore/build/entry-points.cc b/src/libstore/build/entry-points.cc index d4bead28e..e0d46985e 100644 --- a/src/libstore/build/entry-points.cc +++ b/src/libstore/build/entry-points.cc @@ -46,6 +46,7 @@ std::vector Store::buildPathsWithResults( BuildMode buildMode, std::shared_ptr evalStore) { + notice("Store::buildPathsWithResults() START"); Worker worker(*this, evalStore ? *evalStore : *this); Goals goals; diff --git a/src/libstore/misc.cc b/src/libstore/misc.cc index a63a28482..875168749 100644 --- a/src/libstore/misc.cc +++ b/src/libstore/misc.cc @@ -81,6 +81,7 @@ void Store::queryMissing(const std::vector & targets, StorePathSet & willBuild_, StorePathSet & willSubstitute_, StorePathSet & unknown_, uint64_t & downloadSize_, uint64_t & narSize_) { + notice("Store::queryMissing() START"); Activity act(*logger, lvlDebug, actUnknown, "querying info about missing paths"); downloadSize_ = narSize_ = 0; diff --git a/src/libutil/error.hh b/src/libutil/error.hh index 06dfba0df..92acbbf60 100644 --- a/src/libutil/error.hh +++ b/src/libutil/error.hh @@ -47,6 +47,28 @@ typedef enum { 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. */ diff --git a/src/libutil/logging.hh b/src/libutil/logging.hh index 64be8bc62..28e93667f 100644 --- a/src/libutil/logging.hh +++ b/src/libutil/logging.hh @@ -21,6 +21,7 @@ typedef enum { actQueryPathInfo = 109, actPostBuildHook = 110, actBuildWaiting = 111, + actEvaluating = 112, } ActivityType; typedef enum { diff --git a/src/libutil/types.hh b/src/libutil/types.hh index 4974634d8..150398b9c 100644 --- a/src/libutil/types.hh +++ b/src/libutil/types.hh @@ -154,6 +154,20 @@ constexpr auto enumerate(T && iterable) return iterable_wrapper{ std::forward(iterable) }; } +template +concept NumericT = std::integral; +/** + * A Python-like range() iterator. + */ +template +constexpr auto numeric_range(T && end) +{ + struct Iterator + { + size_t i; + + }; +} /** * C++17 std::visit boilerplate diff --git a/src/nix/build.cc b/src/nix/build.cc index 479100186..1f5d11714 100644 --- a/src/nix/build.cc +++ b/src/nix/build.cc @@ -1,5 +1,6 @@ #include "command.hh" #include "common-args.hh" +#include "logging.hh" #include "shared.hh" #include "store-api.hh" #include "local-fs-store.hh" @@ -115,6 +116,9 @@ struct CmdBuild : InstallablesCommand, MixDryRun, MixJSON, MixProfile void run(ref store, Installables && installables) override { + printTalkative("CmdBuild::run() START"); + logger->cout("Verbosity: %s", verbosityToString(nix::verbosity)); + throw Exit(0); if (dryRun) { std::vector pathsToBuild; diff --git a/src/nix/main.cc b/src/nix/main.cc index 55f8d59ba..f31cc4544 100644 --- a/src/nix/main.cc +++ b/src/nix/main.cc @@ -499,6 +499,7 @@ void mainWrapped(int argc, char * * argv) if (args.command->second->forceImpureByDefault() && !evalSettings.pureEval.overridden) { evalSettings.pureEval = false; } + printTalkative("args.command->second->run() END OF MAIN"); args.command->second->run(); }