1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-11-21 09:49:36 +01:00

Progress bar: Add a key to show what paths remain to be built/substituted

This commit is contained in:
Eelco Dolstra 2020-12-17 15:24:14 +01:00
parent 2392688a2d
commit ed80589a07
3 changed files with 74 additions and 20 deletions

View file

@ -69,6 +69,7 @@ private:
ActivityId parent; ActivityId parent;
std::optional<std::string> name; std::optional<std::string> name;
std::optional<std::chrono::time_point<std::chrono::steady_clock>> startTime; std::optional<std::chrono::time_point<std::chrono::steady_clock>> startTime;
PathSet buildsRemaining, substitutionsRemaining;
}; };
struct ActivitiesByType struct ActivitiesByType
@ -250,16 +251,49 @@ public:
resetHelp(*state); resetHelp(*state);
} else { } else {
state->helpShown = true; state->helpShown = true;
state->statusLines.insert_or_assign({idHelp, 0}, ""); size_t n = 0;
state->statusLines.insert_or_assign({idHelp, 1}, ANSI_BOLD "The following keys are available:"); state->statusLines.insert_or_assign({idHelp, n++}, "");
state->statusLines.insert_or_assign({idHelp, 2}, ANSI_BOLD " 'v' to increase verbosity."); state->statusLines.insert_or_assign({idHelp, n++}, ANSI_BOLD "The following keys are available:");
state->statusLines.insert_or_assign({idHelp, 3}, ANSI_BOLD " '-' to decrease verbosity."); state->statusLines.insert_or_assign({idHelp, n++}, ANSI_BOLD " 'v' to increase verbosity.");
state->statusLines.insert_or_assign({idHelp, 4}, ANSI_BOLD " 'l' to show build log output."); state->statusLines.insert_or_assign({idHelp, n++}, ANSI_BOLD " '-' to decrease verbosity.");
state->statusLines.insert_or_assign({idHelp, 5}, ANSI_BOLD " 'q' to quit."); state->statusLines.insert_or_assign({idHelp, n++}, ANSI_BOLD " 'l' to show build log output.");
state->statusLines.insert_or_assign({idHelp, 6}, ""); state->statusLines.insert_or_assign({idHelp, n++}, ANSI_BOLD " 'r' to show what paths remain to be built/substituted.");
state->statusLines.insert_or_assign({idHelp, n++}, ANSI_BOLD " 'h' to hide this help message.");
state->statusLines.insert_or_assign({idHelp, n++}, ANSI_BOLD " 'q' to quit.");
state->statusLines.insert_or_assign({idHelp, n++}, "");
} }
draw(*state); draw(*state);
} }
if (c == 'r') {
auto state(state_.lock());
PathSet buildsRemaining, substitutionsRemaining;
for (auto & act : state->activities) {
for (auto & path : act.buildsRemaining) buildsRemaining.insert(path);
for (auto & path : act.substitutionsRemaining) substitutionsRemaining.insert(path);
}
std::string msg;
// FIXME: sort by name?
if (!buildsRemaining.empty()) {
msg += fmt("\n" ANSI_BOLD "%d derivations remaining to be built:\n" ANSI_NORMAL, buildsRemaining.size());
for (auto & path : buildsRemaining)
msg += fmt(" • %s\n", path);
}
if (!substitutionsRemaining.empty()) {
msg += fmt("\n" ANSI_BOLD "%d paths remaining to be substituted:\n" ANSI_NORMAL, substitutionsRemaining.size());
for (auto & path : substitutionsRemaining)
msg += fmt(" • %s\n", path);
}
if (buildsRemaining.empty() && substitutionsRemaining.empty())
msg = "\n" ANSI_BOLD "Nothing left to be built or substituted.";
draw(*state, chomp(msg));
}
} }
}); });
@ -460,6 +494,10 @@ public:
{ {
auto state(state_.lock()); auto state(state_.lock());
auto i = state->its.find(act);
assert(i != state->its.end());
ActInfo & actInfo = *i->second;
if (type == resFileLinked) { if (type == resFileLinked) {
state->filesLinked++; state->filesLinked++;
state->bytesLinked += getI(fields, 0); state->bytesLinked += getI(fields, 0);
@ -469,8 +507,6 @@ public:
else if (type == resBuildLogLine || type == resPostBuildLogLine) { else if (type == resBuildLogLine || type == resPostBuildLogLine) {
auto lastLine = chomp(getS(fields, 0)); auto lastLine = chomp(getS(fields, 0));
if (!lastLine.empty()) { if (!lastLine.empty()) {
auto i = state->its.find(act);
assert(i != state->its.end());
i->second->lastLine = lastLine; i->second->lastLine = lastLine;
if (progressBarSettings.printBuildLogs) { if (progressBarSettings.printBuildLogs) {
auto suffix = "> "; auto suffix = "> ";
@ -494,16 +530,11 @@ public:
} }
else if (type == resSetPhase) { else if (type == resSetPhase) {
auto i = state->its.find(act);
assert(i != state->its.end());
i->second->phase = getS(fields, 0); i->second->phase = getS(fields, 0);
update(*state); update(*state);
} }
else if (type == resProgress) { else if (type == resProgress) {
auto i = state->its.find(act);
assert(i != state->its.end());
ActInfo & actInfo = *i->second;
if (!actInfo.ignored) { if (!actInfo.ignored) {
actInfo.done = getI(fields, 0); actInfo.done = getI(fields, 0);
actInfo.expected = getI(fields, 1); actInfo.expected = getI(fields, 1);
@ -514,9 +545,6 @@ public:
} }
else if (type == resSetExpected) { else if (type == resSetExpected) {
auto i = state->its.find(act);
assert(i != state->its.end());
ActInfo & actInfo = *i->second;
if (!actInfo.ignored) { if (!actInfo.ignored) {
auto type = (ActivityType) getI(fields, 0); auto type = (ActivityType) getI(fields, 0);
auto & j = actInfo.expectedByType[type]; auto & j = actInfo.expectedByType[type];
@ -526,6 +554,18 @@ public:
update(*state); update(*state);
} }
} }
else if (type == resExpectBuild)
actInfo.buildsRemaining.insert(getS(fields, 0));
else if (type == resUnexpectBuild)
actInfo.buildsRemaining.erase(getS(fields, 0));
else if (type == resExpectSubstitution)
actInfo.substitutionsRemaining.insert(getS(fields, 0));
else if (type == resUnexpectSubstitution)
actInfo.substitutionsRemaining.erase(getS(fields, 0));
} }
void update(State & state) void update(State & state)

View file

@ -103,12 +103,16 @@ static void removeGoal(std::shared_ptr<G> goal, std::map<StorePath, std::weak_pt
void Worker::removeGoal(GoalPtr goal) void Worker::removeGoal(GoalPtr goal)
{ {
if (auto drvGoal = std::dynamic_pointer_cast<DerivationGoal>(goal)) if (auto drvGoal = std::dynamic_pointer_cast<DerivationGoal>(goal)) {
act.result(resUnexpectBuild, store.printStorePath(drvGoal->drvPath));
nix::removeGoal(drvGoal, derivationGoals); nix::removeGoal(drvGoal, derivationGoals);
else if (auto subGoal = std::dynamic_pointer_cast<SubstitutionGoal>(goal)) }
else if (auto subGoal = std::dynamic_pointer_cast<SubstitutionGoal>(goal)) {
act.result(resUnexpectSubstitution, store.printStorePath(subGoal->storePath));
nix::removeGoal(subGoal, substitutionGoals); nix::removeGoal(subGoal, substitutionGoals);
else } else
assert(false); assert(false);
if (topGoals.find(goal) != topGoals.end()) { if (topGoals.find(goal) != topGoals.end()) {
topGoals.erase(goal); topGoals.erase(goal);
/* If a top-level goal failed, then kill all other goals /* If a top-level goal failed, then kill all other goals
@ -223,6 +227,12 @@ void Worker::run(const Goals & _topGoals)
uint64_t downloadSize, narSize; uint64_t downloadSize, narSize;
store.queryMissing(topPaths, willBuild, willSubstitute, unknown, downloadSize, narSize); store.queryMissing(topPaths, willBuild, willSubstitute, unknown, downloadSize, narSize);
for (auto & path : willBuild)
act.result(resExpectBuild, store.printStorePath(path));
for (auto & path : willSubstitute)
act.result(resExpectSubstitution, store.printStorePath(path));
debug("entered goal loop"); debug("entered goal loop");
while (1) { while (1) {

View file

@ -32,6 +32,10 @@ typedef enum {
resProgress = 105, resProgress = 105,
resSetExpected = 106, resSetExpected = 106,
resPostBuildLogLine = 107, resPostBuildLogLine = 107,
resExpectBuild = 108,
resUnexpectBuild = 109,
resExpectSubstitution = 110,
resUnexpectSubstitution = 111,
} ResultType; } ResultType;
typedef uint64_t ActivityId; typedef uint64_t ActivityId;