about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libstore/build.cc46
-rw-r--r--src/libutil/logging.hh12
-rw-r--r--src/nix/progress-bar.cc27
3 files changed, 56 insertions, 29 deletions
diff --git a/src/libstore/build.cc b/src/libstore/build.cc
index 59013c0349b8..92626738ab27 100644
--- a/src/libstore/build.cc
+++ b/src/libstore/build.cc
@@ -2401,6 +2401,19 @@ struct BuilderLogger : Logger
 
     BuilderLogger(Logger & prevLogger) : prevLogger(prevLogger) { }
 
+    void addFields(nlohmann::json & json, const Fields & fields)
+    {
+        if (fields.empty()) return;
+        auto & arr = json["fields"] = nlohmann::json::array();
+        for (auto & f : fields)
+            if (f.type == Logger::Field::tInt)
+                arr.push_back(f.i);
+            else if (f.type == Logger::Field::tString)
+                arr.push_back(f.s);
+            else
+                abort();
+    }
+
     void log(Verbosity lvl, const FormatOrString & fs) override
     {
         prevLogger.log(lvl, fs);
@@ -2414,7 +2427,8 @@ struct BuilderLogger : Logger
         json["id"] = act;
         json["type"] = type;
         json["text"] = s;
-        // FIXME: handle fields, parent
+        addFields(json, fields);
+        // FIXME: handle parent
         log(lvlError, "@nix " + json.dump());
     }
 
@@ -2426,15 +2440,13 @@ struct BuilderLogger : Logger
         log(lvlError, "@nix " + json.dump());
     }
 
-    void progress(ActivityId act, uint64_t done = 0, uint64_t expected = 0, uint64_t running = 0, uint64_t failed = 0) override
+    void result(ActivityId act, ResultType type, const Fields & fields) override
     {
         nlohmann::json json;
-        json["action"] = "progress";
+        json["action"] = "result";
         json["id"] = act;
-        json["done"] = done;
-        json["expected"] = expected;
-        json["running"] = running;
-        json["failed"] = failed;
+        json["type"] = type;
+        addFields(json, fields);
         log(lvlError, "@nix " + json.dump());
     }
 };
@@ -3299,6 +3311,20 @@ void DerivationGoal::handleEOF(int fd)
 }
 
 
+static Logger::Fields getFields(nlohmann::json & json)
+{
+    Logger::Fields fields;
+    for (auto & f : json) {
+        if (f.type() == nlohmann::json::value_t::number_unsigned)
+            fields.emplace_back(Logger::Field(f.get<uint64_t>()));
+        else if (f.type() == nlohmann::json::value_t::string)
+            fields.emplace_back(Logger::Field(f.get<std::string>()));
+        else throw Error("unsupported JSON type %d", (int) f.type());
+    }
+    return fields;
+}
+
+
 void DerivationGoal::flushLine()
 {
     if (hasPrefix(currentLogLine, "@nix ")) {
@@ -3313,16 +3339,16 @@ void DerivationGoal::flushLine()
                 if (type == actDownload)
                     builderActivities.emplace(std::piecewise_construct,
                         std::forward_as_tuple(json["id"]),
-                        std::forward_as_tuple(*logger, type, json["text"], Logger::Fields{}, act->id));
+                        std::forward_as_tuple(*logger, type, json["text"], getFields(json["fields"]), act->id));
             }
 
             else if (action == "stop")
                 builderActivities.erase((ActivityId) json["id"]);
 
-            else if (action == "progress") {
+            else if (action == "result") {
                 auto i = builderActivities.find((ActivityId) json["id"]);
                 if (i != builderActivities.end())
-                    i->second.progress(json.value("done", 0), json.value("expected", 0), json.value("running", 0), json.value("failed", 0));
+                    i->second.result((ResultType) json["type"], getFields(json["fields"]));
             }
 
             else if (action == "setPhase") {
diff --git a/src/libutil/logging.hh b/src/libutil/logging.hh
index 57157dce15cc..4b1f3b5f70cf 100644
--- a/src/libutil/logging.hh
+++ b/src/libutil/logging.hh
@@ -32,6 +32,7 @@ typedef enum {
     resUntrustedPath = 102,
     resCorruptedPath = 103,
     resSetPhase = 104,
+    resProgress = 105,
 } ResultType;
 
 typedef uint64_t ActivityId;
@@ -71,8 +72,6 @@ public:
 
     virtual void stopActivity(ActivityId act) { };
 
-    virtual void progress(ActivityId act, uint64_t done = 0, uint64_t expected = 0, uint64_t running = 0, uint64_t failed = 0) { };
-
     virtual void setExpected(ActivityId act, ActivityType type, uint64_t expected) { };
 
     virtual void result(ActivityId act, ResultType type, const Fields & fields) { };
@@ -95,16 +94,21 @@ struct Activity
     { logger.stopActivity(id); }
 
     void progress(uint64_t done = 0, uint64_t expected = 0, uint64_t running = 0, uint64_t failed = 0) const
-    { logger.progress(id, done, expected, running, failed); }
+    { result(resProgress, done, expected, running, failed); }
 
     void setExpected(ActivityType type2, uint64_t expected) const
     { logger.setExpected(id, type2, expected); }
 
     template<typename... Args>
-    void result(ResultType type, const Args & ... args)
+    void result(ResultType type, const Args & ... args) const
     {
         Logger::Fields fields;
         nop{(fields.emplace_back(Logger::Field(args)), 1)...};
+        result(type, fields);
+    }
+
+    void result(ResultType type, const Logger::Fields & fields) const
+    {
         logger.result(id, type, fields);
     }
 
diff --git a/src/nix/progress-bar.cc b/src/nix/progress-bar.cc
index f638c7cfb198..054127f6277e 100644
--- a/src/nix/progress-bar.cc
+++ b/src/nix/progress-bar.cc
@@ -192,21 +192,6 @@ public:
         update(*state);
     }
 
-    void progress(ActivityId act, uint64_t done = 0, uint64_t expected = 0, uint64_t running = 0, uint64_t failed = 0) override
-    {
-        auto state(state_.lock());
-
-        auto i = state->its.find(act);
-        assert(i != state->its.end());
-        ActInfo & actInfo = *i->second;
-        actInfo.done = done;
-        actInfo.expected = expected;
-        actInfo.running = running;
-        actInfo.failed = failed;
-
-        update(*state);
-    }
-
     void setExpected(ActivityId act, ActivityType type, uint64_t expected) override
     {
         auto state(state_.lock());
@@ -260,6 +245,18 @@ public:
             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;
+            actInfo.done = getI(fields, 0);
+            actInfo.expected = getI(fields, 1);
+            actInfo.running = getI(fields, 2);
+            actInfo.failed = getI(fields, 3);
+            update(*state);
         }
     }