forked from lix-project/lix
parent
706f482216
commit
619cfa9fec
|
@ -1,4 +1,6 @@
|
|||
#include "progress-bar.hh"
|
||||
#include "escape-string.hh"
|
||||
#include "logging.hh"
|
||||
#include "sync.hh"
|
||||
#include "store-api.hh"
|
||||
#include "names.hh"
|
||||
|
@ -39,13 +41,14 @@ static std::string_view storePathToName(std::string_view path)
|
|||
// 100 years ought to be enough for anyone (yet sufficiently smaller than max() to not cause signed integer overflow).
|
||||
constexpr const auto A_LONG_TIME = std::chrono::duration_cast<std::chrono::milliseconds>(100 * 365 * 86400s);
|
||||
|
||||
class ProgressBar : public Logger
|
||||
{
|
||||
private:
|
||||
|
||||
struct ActInfo
|
||||
{
|
||||
std::string s, lastLine, phase;
|
||||
struct ActInfo
|
||||
{
|
||||
using TimePoint = std::chrono::time_point<std::chrono::steady_clock>;
|
||||
|
||||
std::string s;
|
||||
std::string lastLine;
|
||||
std::string phase;
|
||||
ActivityType type = actUnknown;
|
||||
uint64_t done = 0;
|
||||
uint64_t expected = 0;
|
||||
|
@ -55,32 +58,68 @@ private:
|
|||
bool visible = true;
|
||||
ActivityId parent;
|
||||
std::optional<std::string> name;
|
||||
std::chrono::time_point<std::chrono::steady_clock> startTime;
|
||||
};
|
||||
TimePoint startTime;
|
||||
|
||||
struct ActivitiesByType
|
||||
std::string to_string() const
|
||||
{
|
||||
std::map<ActivityId, std::list<ActInfo>::iterator> its;
|
||||
EscapeStringOptions escapeOptions{
|
||||
.escapeNonPrinting = true,
|
||||
};
|
||||
auto const escapedS = escapeString(s, escapeOptions);
|
||||
auto const escapedLastLine = escapeString(lastLine, escapeOptions);
|
||||
auto const escapedPhase = escapeString(phase, escapeOptions);
|
||||
auto const typeS = activityTypeToString(type);
|
||||
|
||||
return fmt(
|
||||
"ActInfo {\n s = %s,\n lastLine = %s,\n phase = %s,\n type = %s,\n done = %d\n expected = %d,\n running = %d,\n failed = %d,\n parent = %d,\n name = %s,\n}",
|
||||
escapedS,
|
||||
escapedLastLine,
|
||||
escapedPhase,
|
||||
typeS,
|
||||
done,
|
||||
expected,
|
||||
running,
|
||||
failed,
|
||||
parent,
|
||||
name.value_or("<nullopt>")
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
using ActInfoIterator = std::list<ActInfo>::iterator;
|
||||
|
||||
struct ActivitiesByType
|
||||
{
|
||||
std::map<ActivityId, ActInfoIterator> its;
|
||||
uint64_t done = 0;
|
||||
uint64_t expected = 0;
|
||||
uint64_t failed = 0;
|
||||
};
|
||||
};
|
||||
|
||||
struct State
|
||||
{
|
||||
struct BarState
|
||||
{
|
||||
std::list<ActInfo> activities;
|
||||
std::map<ActivityId, std::list<ActInfo>::iterator> its;
|
||||
std::map<ActivityId, ActInfoIterator> its;
|
||||
|
||||
std::map<ActivityType, ActivitiesByType> activitiesByType;
|
||||
|
||||
uint64_t filesLinked = 0, bytesLinked = 0;
|
||||
|
||||
uint64_t corruptedPaths = 0, untrustedPaths = 0;
|
||||
uint64_t filesLinked = 0;
|
||||
uint64_t bytesLinked = 0;
|
||||
uint64_t corruptedPaths = 0;
|
||||
uint64_t untrustedPaths = 0;
|
||||
|
||||
bool active = true;
|
||||
bool paused = false;
|
||||
bool haveUpdate = true;
|
||||
};
|
||||
};
|
||||
|
||||
class ProgressBar : public Logger
|
||||
{
|
||||
private:
|
||||
|
||||
//using ActInfo = ActInfo;
|
||||
using ActivitiesByType = ActivitiesByType;
|
||||
using State = BarState;
|
||||
|
||||
Sync<State> state_;
|
||||
|
||||
|
@ -415,6 +454,13 @@ public:
|
|||
std::string getStatus(State & state)
|
||||
{
|
||||
constexpr auto MiB = 1024.0 * 1024.0;
|
||||
//this->cout("getStatus(): we have %d activities", state.activities.size());
|
||||
//std::cerr << "\ngetStatus(): we have " << state.activities.size() << "\n";
|
||||
|
||||
if (!state.activities.empty()) {
|
||||
ActInfo const & firstActivity = state.activities.front();
|
||||
std::cerr << "\ngetStatus(): " << firstActivity.to_string() << "\n";
|
||||
}
|
||||
|
||||
std::string res;
|
||||
|
||||
|
@ -433,21 +479,49 @@ public:
|
|||
std::string s;
|
||||
|
||||
if (running || done || expected || failed) {
|
||||
if (running)
|
||||
if (expected != 0)
|
||||
s = fmt(ANSI_BLUE + numberFmt + ANSI_NORMAL "/" ANSI_GREEN + numberFmt + ANSI_NORMAL "/" + numberFmt,
|
||||
running / unit, done / unit, expected / unit);
|
||||
else
|
||||
s = fmt(ANSI_BLUE + numberFmt + ANSI_NORMAL "/" ANSI_GREEN + numberFmt + ANSI_NORMAL,
|
||||
running / unit, done / unit);
|
||||
else if (expected != done)
|
||||
if (expected != 0)
|
||||
s = fmt(ANSI_GREEN + numberFmt + ANSI_NORMAL "/" + numberFmt,
|
||||
done / unit, expected / unit);
|
||||
else
|
||||
s = fmt(ANSI_GREEN + numberFmt + ANSI_NORMAL, done / unit);
|
||||
else
|
||||
s = fmt(done ? ANSI_GREEN + numberFmt + ANSI_NORMAL : numberFmt, done / unit);
|
||||
if (running) {
|
||||
if (expected != 0) {
|
||||
auto const runningPart = fmt(numberFmt, running / unit);
|
||||
auto const donePart = fmt(numberFmt, done / unit);
|
||||
auto const expectedPart = fmt(numberFmt, expected / unit);
|
||||
s = fmt(
|
||||
ANSI_BLUE "%s" ANSI_NORMAL "/" ANSI_GREEN "%s" ANSI_NORMAL "/%s",
|
||||
runningPart,
|
||||
donePart,
|
||||
expectedPart
|
||||
);
|
||||
} else {
|
||||
auto const runningPart = fmt(numberFmt, running / unit);
|
||||
auto const donePart = fmt(numberFmt, done / unit);
|
||||
s = fmt(
|
||||
ANSI_BLUE "%s" ANSI_NORMAL "/" ANSI_GREEN "%s" ANSI_NORMAL,
|
||||
runningPart,
|
||||
donePart
|
||||
);
|
||||
}
|
||||
} else if (expected != done) {
|
||||
if (expected != 0) {
|
||||
auto const donePart = fmt(numberFmt, done / unit);
|
||||
auto const expectedPart = fmt(numberFmt, expected / unit);
|
||||
s = fmt(
|
||||
ANSI_GREEN "%s" ANSI_NORMAL "/%s",
|
||||
donePart,
|
||||
expectedPart
|
||||
);
|
||||
} else {
|
||||
auto const donePart = fmt(numberFmt, done / unit);
|
||||
s = fmt(ANSI_GREEN "%s" ANSI_NORMAL, donePart);
|
||||
}
|
||||
} else {
|
||||
auto const donePart = fmt(numberFmt, done / unit);
|
||||
|
||||
// We only color if `done` is non-zero.
|
||||
if (done) {
|
||||
s = concatStrings(ANSI_GREEN, donePart, ANSI_NORMAL);
|
||||
} else {
|
||||
s = donePart;
|
||||
}
|
||||
}
|
||||
s = fmt(itemFmt, s);
|
||||
|
||||
if (failed)
|
||||
|
@ -458,10 +532,10 @@ public:
|
|||
};
|
||||
|
||||
auto showActivity = [&](ActivityType type, const std::string & itemFmt, const std::string & numberFmt = "%d", double unit = 1) {
|
||||
auto s = renderActivity(type, itemFmt, numberFmt, unit);
|
||||
if (s.empty()) return;
|
||||
auto rendered = renderActivity(type, itemFmt, numberFmt, unit);
|
||||
if (rendered.empty()) return;
|
||||
if (!res.empty()) res += ", ";
|
||||
res += s;
|
||||
res += rendered;
|
||||
};
|
||||
|
||||
showActivity(actBuilds, "%s built");
|
||||
|
|
|
@ -23,6 +23,38 @@ typedef enum {
|
|||
actBuildWaiting = 111,
|
||||
} ActivityType;
|
||||
|
||||
constexpr std::string_view activityTypeToString(ActivityType const & actType)
|
||||
{
|
||||
switch (actType) {
|
||||
case actUnknown:
|
||||
return "Unknown";
|
||||
case actCopyPath:
|
||||
return "CopyPath";
|
||||
case actFileTransfer:
|
||||
return "FileTransfer";
|
||||
case actRealise:
|
||||
return "Realise";
|
||||
case actCopyPaths:
|
||||
return "CopyPaths";
|
||||
case actBuilds:
|
||||
return "Builds";
|
||||
case actBuild:
|
||||
return "Build";
|
||||
case actOptimiseStore:
|
||||
return "OptimiseStore";
|
||||
case actVerifyPaths:
|
||||
return "VerifyPaths";
|
||||
case actSubstitute:
|
||||
return "Substitute";
|
||||
case actQueryPathInfo:
|
||||
return "QueryPathInfo";
|
||||
case actPostBuildHook:
|
||||
return "PostBuildHook";
|
||||
case actBuildWaiting:
|
||||
return "BuildWaiting";
|
||||
}
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
resFileLinked = 100,
|
||||
resBuildLogLine = 101,
|
||||
|
|
Loading…
Reference in a new issue