[PATCH] progress: Add time remaining for long tasks

timeless timeless at gmail.com
Sun Nov 14 20:13:48 CST 2010


# HG changeset patch
# User timeless <timeless at gmail.com>
# Date 1289786978 21600
# Node ID a862577669b427374281d19f2002e4e08141db77
# Parent  8cb0269e8d999af6f6f95b7e2c1e633b9083b33b
progress: Add time remaining for long tasks

diff --git a/hgext/progress.py b/hgext/progress.py
--- a/hgext/progress.py
+++ b/hgext/progress.py
@@ -46,6 +46,7 @@ num characters, or ``+<num>`` for the fi
 import sys
 import time
 
+from mercurial.i18n import _
 from mercurial import util
 
 def spacejoin(*args):
@@ -64,6 +65,7 @@ class progbar(object):
         self.topics = []
         self.topicstates = {}
         self.pendingtopics = {}
+        self.starttimes = {}
         self.printed = False
         self.lastprint = time.time() + float(self.ui.config(
             'progress', 'delay', default=3))
@@ -74,10 +76,10 @@ class progbar(object):
             'progress', 'format',
             default=['topic', 'bar', 'number'])
 
-    def show(self, topic, pos, item, unit, total):
+    def show(self, now, tuple):
         if not shouldprint(self.ui):
             return
-        tuple = (topic, pos, item, unit, total)
+        (topic, pos, item, unit, total) = tuple
         if self.printed == tuple:
             # don't double-print progress information, otherwise
             # possible in the case of unwinding the topic stack
@@ -128,6 +130,23 @@ class progbar(object):
                 used += len(tail) + 1
             progwidth = termwidth - used - 3
             if total and pos <= total:
+                if pos > 0:
+                    elapsed = now - self.starttimes[topic]
+                    if elapsed > float(
+                        self.ui.config('progress', 'estimate', default=2)):
+                        seconds = (elapsed * (total - pos)) // pos + 1
+                        minutes = seconds // 60
+                        if minutes < 10:
+                            seconds -= minutes * 60
+                            remaining = _("%dm%02d") % (minutes, seconds)
+                        else:
+                            # we're going to ignore seconds in this case
+                            minutes += 1
+                            hours = minutes // 60
+                            minutes -= hours * 60
+                            remaining = _("%dh%02d") % (hours, minutes)
+                        progwidth -= len(remaining) + 1
+                        tail = spacejoin(tail, remaining)
                 amt = pos * progwidth // total
                 bar = '=' * (amt - 1)
                 if amt > 0:
@@ -171,6 +190,7 @@ class progbar(object):
         now = time.time()
         if pos is None:
             self.pendingtopics.pop(topic, None)
+            self.starttimes.pop(topic, None)
             if self.topics and self.topics[0] == topic and self.printed:
                 self.complete()
                 self.resetstate()
@@ -187,12 +207,14 @@ class progbar(object):
                     return
             if topic not in self.topics:
                 self.pendingtopics[topic] = 0
+                self.starttimes[topic] = now
                 self.topics.append(topic)
             self.topicstates[topic] = pos, item, unit, total
         if now - self.lastprint >= self.refresh and self.topics:
             self.lastprint = now
             curtopic = self.topics[-1]
-            self.show(curtopic, *self.topicstates[curtopic])
+            tuple = (curtopic,) + self.topicstates[curtopic]
+            self.show(now, tuple)
 
 def uisetup(ui):
     class progressui(ui.__class__):


More information about the Mercurial-devel mailing list