##// END OF EJS Templates
progress: don't compute estimate without a total...
Augie Fackler -
r13154:e11c14f1 default
parent child Browse files
Show More
@@ -1,252 +1,254
1 # progress.py show progress bars for some actions
1 # progress.py show progress bars for some actions
2 #
2 #
3 # Copyright (C) 2010 Augie Fackler <durin42@gmail.com>
3 # Copyright (C) 2010 Augie Fackler <durin42@gmail.com>
4 #
4 #
5 # This program is free software; you can redistribute it and/or modify it
5 # This program is free software; you can redistribute it and/or modify it
6 # under the terms of the GNU General Public License as published by the
6 # under the terms of the GNU General Public License as published by the
7 # Free Software Foundation; either version 2 of the License, or (at your
7 # Free Software Foundation; either version 2 of the License, or (at your
8 # option) any later version.
8 # option) any later version.
9 #
9 #
10 # This program is distributed in the hope that it will be useful, but
10 # This program is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
13 # Public License for more details.
13 # Public License for more details.
14 #
14 #
15 # You should have received a copy of the GNU General Public License along
15 # You should have received a copy of the GNU General Public License along
16 # with this program; if not, write to the Free Software Foundation, Inc.,
16 # with this program; if not, write to the Free Software Foundation, Inc.,
17 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18
18
19 """show progress bars for some actions
19 """show progress bars for some actions
20
20
21 This extension uses the progress information logged by hg commands
21 This extension uses the progress information logged by hg commands
22 to draw progress bars that are as informative as possible. Some progress
22 to draw progress bars that are as informative as possible. Some progress
23 bars only offer indeterminate information, while others have a definite
23 bars only offer indeterminate information, while others have a definite
24 end point.
24 end point.
25
25
26 The following settings are available::
26 The following settings are available::
27
27
28 [progress]
28 [progress]
29 delay = 3 # number of seconds (float) before showing the progress bar
29 delay = 3 # number of seconds (float) before showing the progress bar
30 refresh = 0.1 # time in seconds between refreshes of the progress bar
30 refresh = 0.1 # time in seconds between refreshes of the progress bar
31 format = topic bar number estimate # format of the progress bar
31 format = topic bar number estimate # format of the progress bar
32 width = <none> # if set, the maximum width of the progress information
32 width = <none> # if set, the maximum width of the progress information
33 # (that is, min(width, term width) will be used)
33 # (that is, min(width, term width) will be used)
34 clear-complete = True # clear the progress bar after it's done
34 clear-complete = True # clear the progress bar after it's done
35 disable = False # if true, don't show a progress bar
35 disable = False # if true, don't show a progress bar
36 assume-tty = False # if true, ALWAYS show a progress bar, unless
36 assume-tty = False # if true, ALWAYS show a progress bar, unless
37 # disable is given
37 # disable is given
38
38
39 Valid entries for the format field are topic, bar, number, unit,
39 Valid entries for the format field are topic, bar, number, unit,
40 estimate, and item. item defaults to the last 20 characters of the
40 estimate, and item. item defaults to the last 20 characters of the
41 item, but this can be changed by adding either ``-<num>`` which would
41 item, but this can be changed by adding either ``-<num>`` which would
42 take the last num characters, or ``+<num>`` for the first num
42 take the last num characters, or ``+<num>`` for the first num
43 characters.
43 characters.
44 """
44 """
45
45
46 import sys
46 import sys
47 import time
47 import time
48
48
49 from mercurial.i18n import _
49 from mercurial.i18n import _
50 from mercurial import util
50 from mercurial import util
51
51
52 def spacejoin(*args):
52 def spacejoin(*args):
53 return ' '.join(s for s in args if s)
53 return ' '.join(s for s in args if s)
54
54
55 def shouldprint(ui):
55 def shouldprint(ui):
56 return (getattr(sys.stderr, 'isatty', None) and
56 return (getattr(sys.stderr, 'isatty', None) and
57 (sys.stderr.isatty() or ui.configbool('progress', 'assume-tty')))
57 (sys.stderr.isatty() or ui.configbool('progress', 'assume-tty')))
58
58
59 def fmtremaining(seconds):
59 def fmtremaining(seconds):
60 if seconds < 60:
60 if seconds < 60:
61 # i18n: format XX seconds as "XXs"
61 # i18n: format XX seconds as "XXs"
62 return _("%02ds") % (seconds)
62 return _("%02ds") % (seconds)
63 minutes = seconds // 60
63 minutes = seconds // 60
64 if minutes < 60:
64 if minutes < 60:
65 seconds -= minutes * 60
65 seconds -= minutes * 60
66 # i18n: format X minutes and YY seconds as "XmYYs"
66 # i18n: format X minutes and YY seconds as "XmYYs"
67 return _("%dm%02ds") % (minutes, seconds)
67 return _("%dm%02ds") % (minutes, seconds)
68 # we're going to ignore seconds in this case
68 # we're going to ignore seconds in this case
69 minutes += 1
69 minutes += 1
70 hours = minutes // 60
70 hours = minutes // 60
71 minutes -= hours * 60
71 minutes -= hours * 60
72 # i18n: format X hours and YY minutes as "XhYYm"
72 # i18n: format X hours and YY minutes as "XhYYm"
73 return _("%dh%02dm") % (hours, minutes)
73 return _("%dh%02dm") % (hours, minutes)
74
74
75 class progbar(object):
75 class progbar(object):
76 def __init__(self, ui):
76 def __init__(self, ui):
77 self.ui = ui
77 self.ui = ui
78 self.resetstate()
78 self.resetstate()
79
79
80 def resetstate(self):
80 def resetstate(self):
81 self.topics = []
81 self.topics = []
82 self.topicstates = {}
82 self.topicstates = {}
83 self.starttimes = {}
83 self.starttimes = {}
84 self.startvals = {}
84 self.startvals = {}
85 self.printed = False
85 self.printed = False
86 self.lastprint = time.time() + float(self.ui.config(
86 self.lastprint = time.time() + float(self.ui.config(
87 'progress', 'delay', default=3))
87 'progress', 'delay', default=3))
88 self.indetcount = 0
88 self.indetcount = 0
89 self.refresh = float(self.ui.config(
89 self.refresh = float(self.ui.config(
90 'progress', 'refresh', default=0.1))
90 'progress', 'refresh', default=0.1))
91 self.order = self.ui.configlist(
91 self.order = self.ui.configlist(
92 'progress', 'format',
92 'progress', 'format',
93 default=['topic', 'bar', 'number', 'estimate'])
93 default=['topic', 'bar', 'number', 'estimate'])
94
94
95 def show(self, now, topic, pos, item, unit, total):
95 def show(self, now, topic, pos, item, unit, total):
96 if not shouldprint(self.ui):
96 if not shouldprint(self.ui):
97 return
97 return
98 termwidth = self.width()
98 termwidth = self.width()
99 self.printed = True
99 self.printed = True
100 head = ''
100 head = ''
101 needprogress = False
101 needprogress = False
102 tail = ''
102 tail = ''
103 for indicator in self.order:
103 for indicator in self.order:
104 add = ''
104 add = ''
105 if indicator == 'topic':
105 if indicator == 'topic':
106 add = topic
106 add = topic
107 elif indicator == 'number':
107 elif indicator == 'number':
108 if total:
108 if total:
109 add = ('% ' + str(len(str(total))) +
109 add = ('% ' + str(len(str(total))) +
110 's/%s') % (pos, total)
110 's/%s') % (pos, total)
111 else:
111 else:
112 add = str(pos)
112 add = str(pos)
113 elif indicator.startswith('item') and item:
113 elif indicator.startswith('item') and item:
114 slice = 'end'
114 slice = 'end'
115 if '-' in indicator:
115 if '-' in indicator:
116 wid = int(indicator.split('-')[1])
116 wid = int(indicator.split('-')[1])
117 elif '+' in indicator:
117 elif '+' in indicator:
118 slice = 'beginning'
118 slice = 'beginning'
119 wid = int(indicator.split('+')[1])
119 wid = int(indicator.split('+')[1])
120 else:
120 else:
121 wid = 20
121 wid = 20
122 if slice == 'end':
122 if slice == 'end':
123 add = item[-wid:]
123 add = item[-wid:]
124 else:
124 else:
125 add = item[:wid]
125 add = item[:wid]
126 add += (wid - len(add)) * ' '
126 add += (wid - len(add)) * ' '
127 elif indicator == 'bar':
127 elif indicator == 'bar':
128 add = ''
128 add = ''
129 needprogress = True
129 needprogress = True
130 elif indicator == 'unit' and unit:
130 elif indicator == 'unit' and unit:
131 add = unit
131 add = unit
132 elif indicator == 'estimate':
132 elif indicator == 'estimate':
133 add = self.estimate(topic, pos, total, now)
133 add = self.estimate(topic, pos, total, now)
134 if not needprogress:
134 if not needprogress:
135 head = spacejoin(head, add)
135 head = spacejoin(head, add)
136 else:
136 else:
137 tail = spacejoin(tail, add)
137 tail = spacejoin(tail, add)
138 if needprogress:
138 if needprogress:
139 used = 0
139 used = 0
140 if head:
140 if head:
141 used += len(head) + 1
141 used += len(head) + 1
142 if tail:
142 if tail:
143 used += len(tail) + 1
143 used += len(tail) + 1
144 progwidth = termwidth - used - 3
144 progwidth = termwidth - used - 3
145 if total and pos <= total:
145 if total and pos <= total:
146 amt = pos * progwidth // total
146 amt = pos * progwidth // total
147 bar = '=' * (amt - 1)
147 bar = '=' * (amt - 1)
148 if amt > 0:
148 if amt > 0:
149 bar += '>'
149 bar += '>'
150 bar += ' ' * (progwidth - amt)
150 bar += ' ' * (progwidth - amt)
151 else:
151 else:
152 progwidth -= 3
152 progwidth -= 3
153 self.indetcount += 1
153 self.indetcount += 1
154 # mod the count by twice the width so we can make the
154 # mod the count by twice the width so we can make the
155 # cursor bounce between the right and left sides
155 # cursor bounce between the right and left sides
156 amt = self.indetcount % (2 * progwidth)
156 amt = self.indetcount % (2 * progwidth)
157 amt -= progwidth
157 amt -= progwidth
158 bar = (' ' * int(progwidth - abs(amt)) + '<=>' +
158 bar = (' ' * int(progwidth - abs(amt)) + '<=>' +
159 ' ' * int(abs(amt)))
159 ' ' * int(abs(amt)))
160 prog = ''.join(('[', bar , ']'))
160 prog = ''.join(('[', bar , ']'))
161 out = spacejoin(head, prog, tail)
161 out = spacejoin(head, prog, tail)
162 else:
162 else:
163 out = spacejoin(head, tail)
163 out = spacejoin(head, tail)
164 sys.stderr.write('\r' + out[:termwidth])
164 sys.stderr.write('\r' + out[:termwidth])
165 sys.stderr.flush()
165 sys.stderr.flush()
166
166
167 def clear(self):
167 def clear(self):
168 if not shouldprint(self.ui):
168 if not shouldprint(self.ui):
169 return
169 return
170 sys.stderr.write('\r%s\r' % (' ' * self.width()))
170 sys.stderr.write('\r%s\r' % (' ' * self.width()))
171
171
172 def complete(self):
172 def complete(self):
173 if not shouldprint(self.ui):
173 if not shouldprint(self.ui):
174 return
174 return
175 if self.ui.configbool('progress', 'clear-complete', default=True):
175 if self.ui.configbool('progress', 'clear-complete', default=True):
176 self.clear()
176 self.clear()
177 else:
177 else:
178 sys.stderr.write('\n')
178 sys.stderr.write('\n')
179 sys.stderr.flush()
179 sys.stderr.flush()
180
180
181 def width(self):
181 def width(self):
182 tw = self.ui.termwidth()
182 tw = self.ui.termwidth()
183 return min(int(self.ui.config('progress', 'width', default=tw)), tw)
183 return min(int(self.ui.config('progress', 'width', default=tw)), tw)
184
184
185 def estimate(self, topic, pos, total, now):
185 def estimate(self, topic, pos, total, now):
186 if total is None:
187 return ''
186 initialpos = self.startvals[topic]
188 initialpos = self.startvals[topic]
187 target = total - initialpos
189 target = total - initialpos
188 delta = pos - initialpos
190 delta = pos - initialpos
189 if delta > 0:
191 if delta > 0:
190 elapsed = now - self.starttimes[topic]
192 elapsed = now - self.starttimes[topic]
191 if elapsed > float(
193 if elapsed > float(
192 self.ui.config('progress', 'estimate', default=2)):
194 self.ui.config('progress', 'estimate', default=2)):
193 seconds = (elapsed * (target - delta)) // delta + 1
195 seconds = (elapsed * (target - delta)) // delta + 1
194 return fmtremaining(seconds)
196 return fmtremaining(seconds)
195 return ''
197 return ''
196
198
197 def progress(self, topic, pos, item='', unit='', total=None):
199 def progress(self, topic, pos, item='', unit='', total=None):
198 now = time.time()
200 now = time.time()
199 if pos is None:
201 if pos is None:
200 self.starttimes.pop(topic, None)
202 self.starttimes.pop(topic, None)
201 self.startvals.pop(topic, None)
203 self.startvals.pop(topic, None)
202 self.topicstates.pop(topic, None)
204 self.topicstates.pop(topic, None)
203 # reset the progress bar if this is the outermost topic
205 # reset the progress bar if this is the outermost topic
204 if self.topics and self.topics[0] == topic and self.printed:
206 if self.topics and self.topics[0] == topic and self.printed:
205 self.complete()
207 self.complete()
206 self.resetstate()
208 self.resetstate()
207 # truncate the list of topics assuming all topics within
209 # truncate the list of topics assuming all topics within
208 # this one are also closed
210 # this one are also closed
209 if topic in self.topics:
211 if topic in self.topics:
210 self.topics = self.topics[:self.topics.index(topic)]
212 self.topics = self.topics[:self.topics.index(topic)]
211 else:
213 else:
212 if topic not in self.topics:
214 if topic not in self.topics:
213 self.starttimes[topic] = now
215 self.starttimes[topic] = now
214 self.startvals[topic] = pos
216 self.startvals[topic] = pos
215 self.topics.append(topic)
217 self.topics.append(topic)
216 self.topicstates[topic] = pos, item, unit, total
218 self.topicstates[topic] = pos, item, unit, total
217 if now - self.lastprint >= self.refresh and self.topics:
219 if now - self.lastprint >= self.refresh and self.topics:
218 self.lastprint = now
220 self.lastprint = now
219 current = self.topics[-1]
221 current = self.topics[-1]
220 self.show(now, topic, *self.topicstates[topic])
222 self.show(now, topic, *self.topicstates[topic])
221
223
222 def uisetup(ui):
224 def uisetup(ui):
223 class progressui(ui.__class__):
225 class progressui(ui.__class__):
224 _progbar = None
226 _progbar = None
225
227
226 def progress(self, *args, **opts):
228 def progress(self, *args, **opts):
227 self._progbar.progress(*args, **opts)
229 self._progbar.progress(*args, **opts)
228 return super(progressui, self).progress(*args, **opts)
230 return super(progressui, self).progress(*args, **opts)
229
231
230 def write(self, *args, **opts):
232 def write(self, *args, **opts):
231 if self._progbar.printed:
233 if self._progbar.printed:
232 self._progbar.clear()
234 self._progbar.clear()
233 return super(progressui, self).write(*args, **opts)
235 return super(progressui, self).write(*args, **opts)
234
236
235 def write_err(self, *args, **opts):
237 def write_err(self, *args, **opts):
236 if self._progbar.printed:
238 if self._progbar.printed:
237 self._progbar.clear()
239 self._progbar.clear()
238 return super(progressui, self).write_err(*args, **opts)
240 return super(progressui, self).write_err(*args, **opts)
239
241
240 # Apps that derive a class from ui.ui() can use
242 # Apps that derive a class from ui.ui() can use
241 # setconfig('progress', 'disable', 'True') to disable this extension
243 # setconfig('progress', 'disable', 'True') to disable this extension
242 if ui.configbool('progress', 'disable'):
244 if ui.configbool('progress', 'disable'):
243 return
245 return
244 if shouldprint(ui) and not ui.debugflag and not ui.quiet:
246 if shouldprint(ui) and not ui.debugflag and not ui.quiet:
245 ui.__class__ = progressui
247 ui.__class__ = progressui
246 # we instantiate one globally shared progress bar to avoid
248 # we instantiate one globally shared progress bar to avoid
247 # competing progress bars when multiple UI objects get created
249 # competing progress bars when multiple UI objects get created
248 if not progressui._progbar:
250 if not progressui._progbar:
249 progressui._progbar = progbar(ui)
251 progressui._progbar = progbar(ui)
250
252
251 def reposetup(ui, repo):
253 def reposetup(ui, repo):
252 uisetup(repo.ui)
254 uisetup(repo.ui)
@@ -1,143 +1,149
1
1
2 $ cat > loop.py <<EOF
2 $ cat > loop.py <<EOF
3 > from mercurial import commands
3 > from mercurial import commands
4 >
4 >
5 > def loop(ui, loops, **opts):
5 > def loop(ui, loops, **opts):
6 > loops = int(loops)
6 > loops = int(loops)
7 > total = None
7 > total = None
8 > if loops >= 0:
8 > if loops >= 0:
9 > total = loops
9 > total = loops
10 > if opts.get('total', None):
10 > if opts.get('total', None):
11 > total = int(opts.get('total'))
11 > total = int(opts.get('total'))
12 > loops = abs(loops)
12 > loops = abs(loops)
13 >
13 >
14 > for i in range(loops):
14 > for i in range(loops):
15 > ui.progress('loop', i, 'loop.%d' % i, 'loopnum', total)
15 > ui.progress('loop', i, 'loop.%d' % i, 'loopnum', total)
16 > ui.progress('loop', None, 'loop.done', 'loopnum', total)
16 > ui.progress('loop', None, 'loop.done', 'loopnum', total)
17 >
17 >
18 > commands.norepo += " loop"
18 > commands.norepo += " loop"
19 >
19 >
20 > cmdtable = {
20 > cmdtable = {
21 > "loop": (loop, [('', 'total', '', 'override for total')],
21 > "loop": (loop, [('', 'total', '', 'override for total')],
22 > 'hg loop LOOPS'),
22 > 'hg loop LOOPS'),
23 > }
23 > }
24 > EOF
24 > EOF
25
25
26 $ echo "[extensions]" >> $HGRCPATH
26 $ echo "[extensions]" >> $HGRCPATH
27 $ echo "progress=" >> $HGRCPATH
27 $ echo "progress=" >> $HGRCPATH
28 $ echo "loop=`pwd`/loop.py" >> $HGRCPATH
28 $ echo "loop=`pwd`/loop.py" >> $HGRCPATH
29 $ echo "[progress]" >> $HGRCPATH
29 $ echo "[progress]" >> $HGRCPATH
30 $ echo "format = topic bar number" >> $HGRCPATH
30 $ echo "format = topic bar number" >> $HGRCPATH
31 $ echo "assume-tty=1" >> $HGRCPATH
31 $ echo "assume-tty=1" >> $HGRCPATH
32 $ echo "width=60" >> $HGRCPATH
32 $ echo "width=60" >> $HGRCPATH
33
33
34 test default params, display nothing because of delay
34 test default params, display nothing because of delay
35
35
36 $ hg -y loop 3 2>&1 | $TESTDIR/filtercr.py
36 $ hg -y loop 3 2>&1 | $TESTDIR/filtercr.py
37
37
38 $ echo "delay=0" >> $HGRCPATH
38 $ echo "delay=0" >> $HGRCPATH
39 $ echo "refresh=0" >> $HGRCPATH
39 $ echo "refresh=0" >> $HGRCPATH
40
40
41 test with delay=0, refresh=0
41 test with delay=0, refresh=0
42
42
43 $ hg -y loop 3 2>&1 | $TESTDIR/filtercr.py
43 $ hg -y loop 3 2>&1 | $TESTDIR/filtercr.py
44
44
45 loop [ ] 0/3
45 loop [ ] 0/3
46 loop [===============> ] 1/3
46 loop [===============> ] 1/3
47 loop [===============================> ] 2/3
47 loop [===============================> ] 2/3
48 \r (esc)
48 \r (esc)
49
49
50 test refresh is taken in account
50 test refresh is taken in account
51
51
52 $ hg -y --config progress.refresh=100 loop 3 2>&1 | $TESTDIR/filtercr.py
52 $ hg -y --config progress.refresh=100 loop 3 2>&1 | $TESTDIR/filtercr.py
53
53
54
54
55 test format options 1
55 test format options 1
56
56
57 $ hg -y --config 'progress.format=number topic item+2' loop 2 2>&1 \
57 $ hg -y --config 'progress.format=number topic item+2' loop 2 2>&1 \
58 > | $TESTDIR/filtercr.py
58 > | $TESTDIR/filtercr.py
59
59
60 0/2 loop lo
60 0/2 loop lo
61 1/2 loop lo
61 1/2 loop lo
62 \r (esc)
62 \r (esc)
63
63
64 test format options 2
64 test format options 2
65
65
66 $ hg -y --config 'progress.format=number item-3 bar' loop 2 2>&1 \
66 $ hg -y --config 'progress.format=number item-3 bar' loop 2 2>&1 \
67 > | $TESTDIR/filtercr.py
67 > | $TESTDIR/filtercr.py
68
68
69 0/2 p.0 [ ]
69 0/2 p.0 [ ]
70 1/2 p.1 [=======================> ]
70 1/2 p.1 [=======================> ]
71 \r (esc)
71 \r (esc)
72
72
73 test format options and indeterminate progress
73 test format options and indeterminate progress
74
74
75 $ hg -y --config 'progress.format=number item bar' loop -- -2 2>&1 \
75 $ hg -y --config 'progress.format=number item bar' loop -- -2 2>&1 \
76 > | $TESTDIR/filtercr.py
76 > | $TESTDIR/filtercr.py
77
77
78 0 loop.0 [ <=> ]
78 0 loop.0 [ <=> ]
79 1 loop.1 [ <=> ]
79 1 loop.1 [ <=> ]
80 \r (esc)
80 \r (esc)
81
81
82 make sure things don't fall over if count > total
82 make sure things don't fall over if count > total
83
83
84 $ hg -y loop --total 4 6 2>&1 | $TESTDIR/filtercr.py
84 $ hg -y loop --total 4 6 2>&1 | $TESTDIR/filtercr.py
85
85
86 loop [ ] 0/4
86 loop [ ] 0/4
87 loop [===========> ] 1/4
87 loop [===========> ] 1/4
88 loop [=======================> ] 2/4
88 loop [=======================> ] 2/4
89 loop [===================================> ] 3/4
89 loop [===================================> ] 3/4
90 loop [===============================================>] 4/4
90 loop [===============================================>] 4/4
91 loop [ <=> ] 5/4
91 loop [ <=> ] 5/4
92 \r (esc)
92 \r (esc)
93
93
94 test immediate progress completion
94 test immediate progress completion
95
95
96 $ hg -y loop 0 2>&1 | $TESTDIR/filtercr.py
96 $ hg -y loop 0 2>&1 | $TESTDIR/filtercr.py
97
97
98
98
99 test delay time estimates
99 test delay time estimates
100
100
101 $ cat > mocktime.py <<EOF
101 $ cat > mocktime.py <<EOF
102 > import os
102 > import os
103 > import time
103 > import time
104 >
104 >
105 > class mocktime(object):
105 > class mocktime(object):
106 > def __init__(self, increment):
106 > def __init__(self, increment):
107 > self.time = 0
107 > self.time = 0
108 > self.increment = increment
108 > self.increment = increment
109 > def __call__(self):
109 > def __call__(self):
110 > self.time += self.increment
110 > self.time += self.increment
111 > return self.time
111 > return self.time
112 >
112 >
113 > def uisetup(ui):
113 > def uisetup(ui):
114 > time.time = mocktime(int(os.environ.get('MOCKTIME', '11')))
114 > time.time = mocktime(int(os.environ.get('MOCKTIME', '11')))
115 > EOF
115 > EOF
116
116
117 $ echo "[extensions]" > $HGRCPATH
117 $ echo "[extensions]" > $HGRCPATH
118 $ echo "mocktime=`pwd`/mocktime.py" >> $HGRCPATH
118 $ echo "mocktime=`pwd`/mocktime.py" >> $HGRCPATH
119 $ echo "progress=" >> $HGRCPATH
119 $ echo "progress=" >> $HGRCPATH
120 $ echo "loop=`pwd`/loop.py" >> $HGRCPATH
120 $ echo "loop=`pwd`/loop.py" >> $HGRCPATH
121 $ echo "[progress]" >> $HGRCPATH
121 $ echo "[progress]" >> $HGRCPATH
122 $ echo "assume-tty=1" >> $HGRCPATH
122 $ echo "assume-tty=1" >> $HGRCPATH
123 $ echo "delay=25" >> $HGRCPATH
123 $ echo "delay=25" >> $HGRCPATH
124 $ echo "width=60" >> $HGRCPATH
124 $ echo "width=60" >> $HGRCPATH
125
125
126 $ hg -y loop 8 2>&1 | python $TESTDIR/filtercr.py
126 $ hg -y loop 8 2>&1 | python $TESTDIR/filtercr.py
127
127
128 loop [=========> ] 2/8 1m07s
128 loop [=========> ] 2/8 1m07s
129 loop [===============> ] 3/8 56s
129 loop [===============> ] 3/8 56s
130 loop [=====================> ] 4/8 45s
130 loop [=====================> ] 4/8 45s
131 loop [==========================> ] 5/8 34s
131 loop [==========================> ] 5/8 34s
132 loop [================================> ] 6/8 23s
132 loop [================================> ] 6/8 23s
133 loop [=====================================> ] 7/8 12s
133 loop [=====================================> ] 7/8 12s
134 \r (esc)
134 \r (esc)
135
135
136 $ MOCKTIME=10000 hg -y loop 4 2>&1 | python $TESTDIR/filtercr.py
136 $ MOCKTIME=10000 hg -y loop 4 2>&1 | python $TESTDIR/filtercr.py
137
137
138 loop [ ] 0/4
138 loop [ ] 0/4
139 loop [=========> ] 1/4 8h21m
139 loop [=========> ] 1/4 8h21m
140 loop [====================> ] 2/4 5h34m
140 loop [====================> ] 2/4 5h34m
141 loop [==============================> ] 3/4 2h47m
141 loop [==============================> ] 3/4 2h47m
142 \r (esc)
142 \r (esc)
143
143
144 Time estimates should not fail when there's no end point:
145 $ hg -y loop -- -4 2>&1 | python $TESTDIR/filtercr.py
146
147 loop [ <=> ] 2
148 loop [ <=> ] 3
149 \r (esc)
General Comments 0
You need to be logged in to leave comments. Login now