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;
std::optional<std::string> name;
std::optional<std::chrono::time_point<std::chrono::steady_clock>> startTime;
PathSet buildsRemaining, substitutionsRemaining;
};
struct ActivitiesByType
@ -250,16 +251,49 @@ public:
resetHelp(*state);
} else {
state->helpShown = true;
state->statusLines.insert_or_assign({idHelp, 0}, "");
state->statusLines.insert_or_assign({idHelp, 1}, ANSI_BOLD "The following keys are available:");
state->statusLines.insert_or_assign({idHelp, 2}, ANSI_BOLD " 'v' to increase verbosity.");
state->statusLines.insert_or_assign({idHelp, 3}, ANSI_BOLD " '-' to decrease verbosity.");
state->statusLines.insert_or_assign({idHelp, 4}, ANSI_BOLD " 'l' to show build log output.");
state->statusLines.insert_or_assign({idHelp, 5}, ANSI_BOLD " 'q' to quit.");
state->statusLines.insert_or_assign({idHelp, 6}, "");
size_t n = 0;
state->statusLines.insert_or_assign({idHelp, n++}, "");
state->statusLines.insert_or_assign({idHelp, n++}, ANSI_BOLD "The following keys are available:");
state->statusLines.insert_or_assign({idHelp, n++}, ANSI_BOLD " 'v' to increase verbosity.");
state->statusLines.insert_or_assign({idHelp, n++}, ANSI_BOLD " '-' to decrease verbosity.");
state->statusLines.insert_or_assign({idHelp, n++}, ANSI_BOLD " 'l' to show build log output.");
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);
}
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 i = state->its.find(act);
assert(i != state->its.end());
ActInfo & actInfo = *i->second;
if (type == resFileLinked) {
state->filesLinked++;
state->bytesLinked += getI(fields, 0);
@ -469,8 +507,6 @@ public:
else if (type == resBuildLogLine || type == resPostBuildLogLine) {
auto lastLine = chomp(getS(fields, 0));
if (!lastLine.empty()) {
auto i = state->its.find(act);
assert(i != state->its.end());
i->second->lastLine = lastLine;
if (progressBarSettings.printBuildLogs) {
auto suffix = "> ";
@ -494,16 +530,11 @@ public:
}
else if (type == resSetPhase) {
auto i = state->its.find(act);
assert(i != state->its.end());
i->second->phase = getS(fields, 0);
update(*state);
}
else if (type == resProgress) {
auto i = state->its.find(act);
assert(i != state->its.end());
ActInfo & actInfo = *i->second;
if (!actInfo.ignored) {
actInfo.done = getI(fields, 0);
actInfo.expected = getI(fields, 1);
@ -514,9 +545,6 @@ public:
}
else if (type == resSetExpected) {
auto i = state->its.find(act);
assert(i != state->its.end());
ActInfo & actInfo = *i->second;
if (!actInfo.ignored) {
auto type = (ActivityType) getI(fields, 0);
auto & j = actInfo.expectedByType[type];
@ -526,6 +554,18 @@ public:
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)

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)
{
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);
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);
else
} else
assert(false);
if (topGoals.find(goal) != topGoals.end()) {
topGoals.erase(goal);
/* 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;
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");
while (1) {

View file

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