about summary refs log tree commit diff
path: root/src/nix/progress-bar.cc
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2017-08-25T15·49+0200
committerEelco Dolstra <edolstra@gmail.com>2017-08-25T15·49+0200
commitc137c0a5ebc0d58c53f86986ab66967ac8629cbe (patch)
tree38e01bef5549985449a4c911c1444758d585335f /src/nix/progress-bar.cc
parentf194629f96d4bdbded897e7e88ac0d03211c959d (diff)
Allow activities to be nested
In particular, this allows more relevant activities ("substituting X")
to supersede inferior ones ("downloading X").
Diffstat (limited to 'src/nix/progress-bar.cc')
-rw-r--r--src/nix/progress-bar.cc28
1 files changed, 26 insertions, 2 deletions
diff --git a/src/nix/progress-bar.cc b/src/nix/progress-bar.cc
index 17d7109e7165..1b597433b30e 100644
--- a/src/nix/progress-bar.cc
+++ b/src/nix/progress-bar.cc
@@ -73,6 +73,8 @@ private:
         uint64_t running = 0;
         uint64_t failed = 0;
         std::map<ActivityType, uint64_t> expectedByType;
+        bool visible = true;
+        ActivityId parent;
     };
 
     struct ActivitiesByType
@@ -125,7 +127,7 @@ public:
     }
 
     void startActivity(ActivityId act, ActivityType type, const std::string & s,
-        const Fields & fields) override
+        const Fields & fields, ActivityId parent) override
     {
         auto state(state_.lock());
 
@@ -133,6 +135,7 @@ public:
         auto i = std::prev(state->activities.end());
         i->s = s;
         i->type = type;
+        i->parent = parent;
         state->its.emplace(act, i);
         state->activitiesByType[type].its.emplace(act, i);
 
@@ -143,9 +146,30 @@ public:
             i->s = fmt("building " ANSI_BOLD "%s" ANSI_NORMAL, name);
         }
 
+        if (type == actSubstitute) {
+            auto name = storePathToName(getS(fields, 0));
+            i->s = fmt("fetching " ANSI_BOLD "%s" ANSI_NORMAL " from %s", name, getS(fields, 1));
+        }
+
+        if ((type == actDownload && hasAncestor(*state, actCopyPath, parent))
+            || (type == actCopyPath && hasAncestor(*state, actSubstitute, parent)))
+            i->visible = false;
+
         update(*state);
     }
 
+    /* Check whether an activity has an ancestore with the specified
+       type. */
+    bool hasAncestor(State & state, ActivityType type, ActivityId act)
+    {
+        while (act != 0) {
+            auto i = state.its.find(act);
+            if (i == state.its.end()) break;
+            if (i->second->type == type) return true;
+        }
+        return false;
+    }
+
     void stopActivity(ActivityId act) override
     {
         auto state(state_.lock());
@@ -253,7 +277,7 @@ public:
             if (!status.empty()) line += " ";
             auto i = state.activities.rbegin();
 
-            while (i != state.activities.rend() && i->s.empty() && i->s2.empty())
+            while (i != state.activities.rend() && (!i->visible || (i->s.empty() && i->s2.empty())))
                 ++i;
 
             if (i != state.activities.rend()) {