##// END OF EJS Templates
progress: stop getting stuck in a nested topic during a long inner step...
Augie Fackler -
r19619:4694ccd5 default
parent child Browse files
Show More
@@ -1,296 +1,303
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 software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 """show progress bars for some actions
8 """show progress bars for some actions
9
9
10 This extension uses the progress information logged by hg commands
10 This extension uses the progress information logged by hg commands
11 to draw progress bars that are as informative as possible. Some progress
11 to draw progress bars that are as informative as possible. Some progress
12 bars only offer indeterminate information, while others have a definite
12 bars only offer indeterminate information, while others have a definite
13 end point.
13 end point.
14
14
15 The following settings are available::
15 The following settings are available::
16
16
17 [progress]
17 [progress]
18 delay = 3 # number of seconds (float) before showing the progress bar
18 delay = 3 # number of seconds (float) before showing the progress bar
19 changedelay = 1 # changedelay: minimum delay before showing a new topic.
19 changedelay = 1 # changedelay: minimum delay before showing a new topic.
20 # If set to less than 3 * refresh, that value will
20 # If set to less than 3 * refresh, that value will
21 # be used instead.
21 # be used instead.
22 refresh = 0.1 # time in seconds between refreshes of the progress bar
22 refresh = 0.1 # time in seconds between refreshes of the progress bar
23 format = topic bar number estimate # format of the progress bar
23 format = topic bar number estimate # format of the progress bar
24 width = <none> # if set, the maximum width of the progress information
24 width = <none> # if set, the maximum width of the progress information
25 # (that is, min(width, term width) will be used)
25 # (that is, min(width, term width) will be used)
26 clear-complete = True # clear the progress bar after it's done
26 clear-complete = True # clear the progress bar after it's done
27 disable = False # if true, don't show a progress bar
27 disable = False # if true, don't show a progress bar
28 assume-tty = False # if true, ALWAYS show a progress bar, unless
28 assume-tty = False # if true, ALWAYS show a progress bar, unless
29 # disable is given
29 # disable is given
30
30
31 Valid entries for the format field are topic, bar, number, unit,
31 Valid entries for the format field are topic, bar, number, unit,
32 estimate, speed, and item. item defaults to the last 20 characters of
32 estimate, speed, and item. item defaults to the last 20 characters of
33 the item, but this can be changed by adding either ``-<num>`` which
33 the item, but this can be changed by adding either ``-<num>`` which
34 would take the last num characters, or ``+<num>`` for the first num
34 would take the last num characters, or ``+<num>`` for the first num
35 characters.
35 characters.
36 """
36 """
37
37
38 import sys
38 import sys
39 import time
39 import time
40
40
41 from mercurial.i18n import _
41 from mercurial.i18n import _
42 testedwith = 'internal'
42 testedwith = 'internal'
43
43
44 def spacejoin(*args):
44 def spacejoin(*args):
45 return ' '.join(s for s in args if s)
45 return ' '.join(s for s in args if s)
46
46
47 def shouldprint(ui):
47 def shouldprint(ui):
48 return not ui.plain() and (ui._isatty(sys.stderr) or
48 return not ui.plain() and (ui._isatty(sys.stderr) or
49 ui.configbool('progress', 'assume-tty'))
49 ui.configbool('progress', 'assume-tty'))
50
50
51 def fmtremaining(seconds):
51 def fmtremaining(seconds):
52 if seconds < 60:
52 if seconds < 60:
53 # i18n: format XX seconds as "XXs"
53 # i18n: format XX seconds as "XXs"
54 return _("%02ds") % (seconds)
54 return _("%02ds") % (seconds)
55 minutes = seconds // 60
55 minutes = seconds // 60
56 if minutes < 60:
56 if minutes < 60:
57 seconds -= minutes * 60
57 seconds -= minutes * 60
58 # i18n: format X minutes and YY seconds as "XmYYs"
58 # i18n: format X minutes and YY seconds as "XmYYs"
59 return _("%dm%02ds") % (minutes, seconds)
59 return _("%dm%02ds") % (minutes, seconds)
60 # we're going to ignore seconds in this case
60 # we're going to ignore seconds in this case
61 minutes += 1
61 minutes += 1
62 hours = minutes // 60
62 hours = minutes // 60
63 minutes -= hours * 60
63 minutes -= hours * 60
64 if hours < 30:
64 if hours < 30:
65 # i18n: format X hours and YY minutes as "XhYYm"
65 # i18n: format X hours and YY minutes as "XhYYm"
66 return _("%dh%02dm") % (hours, minutes)
66 return _("%dh%02dm") % (hours, minutes)
67 # we're going to ignore minutes in this case
67 # we're going to ignore minutes in this case
68 hours += 1
68 hours += 1
69 days = hours // 24
69 days = hours // 24
70 hours -= days * 24
70 hours -= days * 24
71 if days < 15:
71 if days < 15:
72 # i18n: format X days and YY hours as "XdYYh"
72 # i18n: format X days and YY hours as "XdYYh"
73 return _("%dd%02dh") % (days, hours)
73 return _("%dd%02dh") % (days, hours)
74 # we're going to ignore hours in this case
74 # we're going to ignore hours in this case
75 days += 1
75 days += 1
76 weeks = days // 7
76 weeks = days // 7
77 days -= weeks * 7
77 days -= weeks * 7
78 if weeks < 55:
78 if weeks < 55:
79 # i18n: format X weeks and YY days as "XwYYd"
79 # i18n: format X weeks and YY days as "XwYYd"
80 return _("%dw%02dd") % (weeks, days)
80 return _("%dw%02dd") % (weeks, days)
81 # we're going to ignore days and treat a year as 52 weeks
81 # we're going to ignore days and treat a year as 52 weeks
82 weeks += 1
82 weeks += 1
83 years = weeks // 52
83 years = weeks // 52
84 weeks -= years * 52
84 weeks -= years * 52
85 # i18n: format X years and YY weeks as "XyYYw"
85 # i18n: format X years and YY weeks as "XyYYw"
86 return _("%dy%02dw") % (years, weeks)
86 return _("%dy%02dw") % (years, weeks)
87
87
88 class progbar(object):
88 class progbar(object):
89 def __init__(self, ui):
89 def __init__(self, ui):
90 self.ui = ui
90 self.ui = ui
91 self.resetstate()
91 self.resetstate()
92
92
93 def resetstate(self):
93 def resetstate(self):
94 self.topics = []
94 self.topics = []
95 self.topicstates = {}
95 self.topicstates = {}
96 self.starttimes = {}
96 self.starttimes = {}
97 self.startvals = {}
97 self.startvals = {}
98 self.printed = False
98 self.printed = False
99 self.lastprint = time.time() + float(self.ui.config(
99 self.lastprint = time.time() + float(self.ui.config(
100 'progress', 'delay', default=3))
100 'progress', 'delay', default=3))
101 self.lasttopic = None
101 self.lasttopic = None
102 self.indetcount = 0
102 self.indetcount = 0
103 self.refresh = float(self.ui.config(
103 self.refresh = float(self.ui.config(
104 'progress', 'refresh', default=0.1))
104 'progress', 'refresh', default=0.1))
105 self.changedelay = max(3 * self.refresh,
105 self.changedelay = max(3 * self.refresh,
106 float(self.ui.config(
106 float(self.ui.config(
107 'progress', 'changedelay', default=1)))
107 'progress', 'changedelay', default=1)))
108 self.order = self.ui.configlist(
108 self.order = self.ui.configlist(
109 'progress', 'format',
109 'progress', 'format',
110 default=['topic', 'bar', 'number', 'estimate'])
110 default=['topic', 'bar', 'number', 'estimate'])
111
111
112 def show(self, now, topic, pos, item, unit, total):
112 def show(self, now, topic, pos, item, unit, total):
113 if not shouldprint(self.ui):
113 if not shouldprint(self.ui):
114 return
114 return
115 termwidth = self.width()
115 termwidth = self.width()
116 self.printed = True
116 self.printed = True
117 head = ''
117 head = ''
118 needprogress = False
118 needprogress = False
119 tail = ''
119 tail = ''
120 for indicator in self.order:
120 for indicator in self.order:
121 add = ''
121 add = ''
122 if indicator == 'topic':
122 if indicator == 'topic':
123 add = topic
123 add = topic
124 elif indicator == 'number':
124 elif indicator == 'number':
125 if total:
125 if total:
126 add = ('% ' + str(len(str(total))) +
126 add = ('% ' + str(len(str(total))) +
127 's/%s') % (pos, total)
127 's/%s') % (pos, total)
128 else:
128 else:
129 add = str(pos)
129 add = str(pos)
130 elif indicator.startswith('item') and item:
130 elif indicator.startswith('item') and item:
131 slice = 'end'
131 slice = 'end'
132 if '-' in indicator:
132 if '-' in indicator:
133 wid = int(indicator.split('-')[1])
133 wid = int(indicator.split('-')[1])
134 elif '+' in indicator:
134 elif '+' in indicator:
135 slice = 'beginning'
135 slice = 'beginning'
136 wid = int(indicator.split('+')[1])
136 wid = int(indicator.split('+')[1])
137 else:
137 else:
138 wid = 20
138 wid = 20
139 if slice == 'end':
139 if slice == 'end':
140 add = item[-wid:]
140 add = item[-wid:]
141 else:
141 else:
142 add = item[:wid]
142 add = item[:wid]
143 add += (wid - len(add)) * ' '
143 add += (wid - len(add)) * ' '
144 elif indicator == 'bar':
144 elif indicator == 'bar':
145 add = ''
145 add = ''
146 needprogress = True
146 needprogress = True
147 elif indicator == 'unit' and unit:
147 elif indicator == 'unit' and unit:
148 add = unit
148 add = unit
149 elif indicator == 'estimate':
149 elif indicator == 'estimate':
150 add = self.estimate(topic, pos, total, now)
150 add = self.estimate(topic, pos, total, now)
151 elif indicator == 'speed':
151 elif indicator == 'speed':
152 add = self.speed(topic, pos, unit, now)
152 add = self.speed(topic, pos, unit, now)
153 if not needprogress:
153 if not needprogress:
154 head = spacejoin(head, add)
154 head = spacejoin(head, add)
155 else:
155 else:
156 tail = spacejoin(tail, add)
156 tail = spacejoin(tail, add)
157 if needprogress:
157 if needprogress:
158 used = 0
158 used = 0
159 if head:
159 if head:
160 used += len(head) + 1
160 used += len(head) + 1
161 if tail:
161 if tail:
162 used += len(tail) + 1
162 used += len(tail) + 1
163 progwidth = termwidth - used - 3
163 progwidth = termwidth - used - 3
164 if total and pos <= total:
164 if total and pos <= total:
165 amt = pos * progwidth // total
165 amt = pos * progwidth // total
166 bar = '=' * (amt - 1)
166 bar = '=' * (amt - 1)
167 if amt > 0:
167 if amt > 0:
168 bar += '>'
168 bar += '>'
169 bar += ' ' * (progwidth - amt)
169 bar += ' ' * (progwidth - amt)
170 else:
170 else:
171 progwidth -= 3
171 progwidth -= 3
172 self.indetcount += 1
172 self.indetcount += 1
173 # mod the count by twice the width so we can make the
173 # mod the count by twice the width so we can make the
174 # cursor bounce between the right and left sides
174 # cursor bounce between the right and left sides
175 amt = self.indetcount % (2 * progwidth)
175 amt = self.indetcount % (2 * progwidth)
176 amt -= progwidth
176 amt -= progwidth
177 bar = (' ' * int(progwidth - abs(amt)) + '<=>' +
177 bar = (' ' * int(progwidth - abs(amt)) + '<=>' +
178 ' ' * int(abs(amt)))
178 ' ' * int(abs(amt)))
179 prog = ''.join(('[', bar , ']'))
179 prog = ''.join(('[', bar , ']'))
180 out = spacejoin(head, prog, tail)
180 out = spacejoin(head, prog, tail)
181 else:
181 else:
182 out = spacejoin(head, tail)
182 out = spacejoin(head, tail)
183 sys.stderr.write('\r' + out[:termwidth])
183 sys.stderr.write('\r' + out[:termwidth])
184 self.lasttopic = topic
184 self.lasttopic = topic
185 sys.stderr.flush()
185 sys.stderr.flush()
186
186
187 def clear(self):
187 def clear(self):
188 if not shouldprint(self.ui):
188 if not shouldprint(self.ui):
189 return
189 return
190 sys.stderr.write('\r%s\r' % (' ' * self.width()))
190 sys.stderr.write('\r%s\r' % (' ' * self.width()))
191
191
192 def complete(self):
192 def complete(self):
193 if not shouldprint(self.ui):
193 if not shouldprint(self.ui):
194 return
194 return
195 if self.ui.configbool('progress', 'clear-complete', default=True):
195 if self.ui.configbool('progress', 'clear-complete', default=True):
196 self.clear()
196 self.clear()
197 else:
197 else:
198 sys.stderr.write('\n')
198 sys.stderr.write('\n')
199 sys.stderr.flush()
199 sys.stderr.flush()
200
200
201 def width(self):
201 def width(self):
202 tw = self.ui.termwidth()
202 tw = self.ui.termwidth()
203 return min(int(self.ui.config('progress', 'width', default=tw)), tw)
203 return min(int(self.ui.config('progress', 'width', default=tw)), tw)
204
204
205 def estimate(self, topic, pos, total, now):
205 def estimate(self, topic, pos, total, now):
206 if total is None:
206 if total is None:
207 return ''
207 return ''
208 initialpos = self.startvals[topic]
208 initialpos = self.startvals[topic]
209 target = total - initialpos
209 target = total - initialpos
210 delta = pos - initialpos
210 delta = pos - initialpos
211 if delta > 0:
211 if delta > 0:
212 elapsed = now - self.starttimes[topic]
212 elapsed = now - self.starttimes[topic]
213 if elapsed > float(
213 if elapsed > float(
214 self.ui.config('progress', 'estimate', default=2)):
214 self.ui.config('progress', 'estimate', default=2)):
215 seconds = (elapsed * (target - delta)) // delta + 1
215 seconds = (elapsed * (target - delta)) // delta + 1
216 return fmtremaining(seconds)
216 return fmtremaining(seconds)
217 return ''
217 return ''
218
218
219 def speed(self, topic, pos, unit, now):
219 def speed(self, topic, pos, unit, now):
220 initialpos = self.startvals[topic]
220 initialpos = self.startvals[topic]
221 delta = pos - initialpos
221 delta = pos - initialpos
222 elapsed = now - self.starttimes[topic]
222 elapsed = now - self.starttimes[topic]
223 if elapsed > float(
223 if elapsed > float(
224 self.ui.config('progress', 'estimate', default=2)):
224 self.ui.config('progress', 'estimate', default=2)):
225 return _('%d %s/sec') % (delta / elapsed, unit)
225 return _('%d %s/sec') % (delta / elapsed, unit)
226 return ''
226 return ''
227
227
228 def progress(self, topic, pos, item='', unit='', total=None):
228 def progress(self, topic, pos, item='', unit='', total=None):
229 now = time.time()
229 now = time.time()
230 if pos is None:
230 if pos is None:
231 self.starttimes.pop(topic, None)
231 self.starttimes.pop(topic, None)
232 self.startvals.pop(topic, None)
232 self.startvals.pop(topic, None)
233 self.topicstates.pop(topic, None)
233 self.topicstates.pop(topic, None)
234 # reset the progress bar if this is the outermost topic
234 # reset the progress bar if this is the outermost topic
235 if self.topics and self.topics[0] == topic and self.printed:
235 if self.topics and self.topics[0] == topic and self.printed:
236 self.complete()
236 self.complete()
237 self.resetstate()
237 self.resetstate()
238 # truncate the list of topics assuming all topics within
238 # truncate the list of topics assuming all topics within
239 # this one are also closed
239 # this one are also closed
240 if topic in self.topics:
240 if topic in self.topics:
241 self.topics = self.topics[:self.topics.index(topic)]
241 self.topics = self.topics[:self.topics.index(topic)]
242 # reset the last topic to the one we just unwound to,
243 # so that higher-level topics will be stickier than
244 # lower-level topics
245 if self.topics:
246 self.lasttopic = self.topics[-1]
247 else:
248 self.lasttopic = None
242 else:
249 else:
243 if topic not in self.topics:
250 if topic not in self.topics:
244 self.starttimes[topic] = now
251 self.starttimes[topic] = now
245 self.startvals[topic] = pos
252 self.startvals[topic] = pos
246 self.topics.append(topic)
253 self.topics.append(topic)
247 self.topicstates[topic] = pos, item, unit, total
254 self.topicstates[topic] = pos, item, unit, total
248 if now - self.lastprint >= self.refresh and self.topics:
255 if now - self.lastprint >= self.refresh and self.topics:
249 if (self.lasttopic is None # first time we printed
256 if (self.lasttopic is None # first time we printed
250 # not a topic change
257 # not a topic change
251 or topic == self.lasttopic
258 or topic == self.lasttopic
252 # it's been long enough we should print anyway
259 # it's been long enough we should print anyway
253 or now - self.lastprint >= self.changedelay):
260 or now - self.lastprint >= self.changedelay):
254 self.lastprint = now
261 self.lastprint = now
255 self.show(now, topic, *self.topicstates[topic])
262 self.show(now, topic, *self.topicstates[topic])
256
263
257 _singleton = None
264 _singleton = None
258
265
259 def uisetup(ui):
266 def uisetup(ui):
260 global _singleton
267 global _singleton
261 class progressui(ui.__class__):
268 class progressui(ui.__class__):
262 _progbar = None
269 _progbar = None
263
270
264 def _quiet(self):
271 def _quiet(self):
265 return self.debugflag or self.quiet
272 return self.debugflag or self.quiet
266
273
267 def progress(self, *args, **opts):
274 def progress(self, *args, **opts):
268 if not self._quiet():
275 if not self._quiet():
269 self._progbar.progress(*args, **opts)
276 self._progbar.progress(*args, **opts)
270 return super(progressui, self).progress(*args, **opts)
277 return super(progressui, self).progress(*args, **opts)
271
278
272 def write(self, *args, **opts):
279 def write(self, *args, **opts):
273 if not self._quiet() and self._progbar.printed:
280 if not self._quiet() and self._progbar.printed:
274 self._progbar.clear()
281 self._progbar.clear()
275 return super(progressui, self).write(*args, **opts)
282 return super(progressui, self).write(*args, **opts)
276
283
277 def write_err(self, *args, **opts):
284 def write_err(self, *args, **opts):
278 if not self._quiet() and self._progbar.printed:
285 if not self._quiet() and self._progbar.printed:
279 self._progbar.clear()
286 self._progbar.clear()
280 return super(progressui, self).write_err(*args, **opts)
287 return super(progressui, self).write_err(*args, **opts)
281
288
282 # Apps that derive a class from ui.ui() can use
289 # Apps that derive a class from ui.ui() can use
283 # setconfig('progress', 'disable', 'True') to disable this extension
290 # setconfig('progress', 'disable', 'True') to disable this extension
284 if ui.configbool('progress', 'disable'):
291 if ui.configbool('progress', 'disable'):
285 return
292 return
286 if shouldprint(ui) and not ui.debugflag and not ui.quiet:
293 if shouldprint(ui) and not ui.debugflag and not ui.quiet:
287 ui.__class__ = progressui
294 ui.__class__ = progressui
288 # we instantiate one globally shared progress bar to avoid
295 # we instantiate one globally shared progress bar to avoid
289 # competing progress bars when multiple UI objects get created
296 # competing progress bars when multiple UI objects get created
290 if not progressui._progbar:
297 if not progressui._progbar:
291 if _singleton is None:
298 if _singleton is None:
292 _singleton = progbar(ui)
299 _singleton = progbar(ui)
293 progressui._progbar = _singleton
300 progressui._progbar = _singleton
294
301
295 def reposetup(ui, repo):
302 def reposetup(ui, repo):
296 uisetup(repo.ui)
303 uisetup(repo.ui)
@@ -1,208 +1,239
1
1
2 $ cat > loop.py <<EOF
2 $ cat > loop.py <<EOF
3 > from mercurial import commands
3 > from mercurial import commands
4 > import time
5 > class incrementingtime(object):
6 > def __init__(self):
7 > self._time = 0.0
8 > def __call__(self):
9 > self._time += 0.25
10 > return self._time
11 > time.time = incrementingtime()
4 >
12 >
5 > def loop(ui, loops, **opts):
13 > def loop(ui, loops, **opts):
6 > loops = int(loops)
14 > loops = int(loops)
7 > total = None
15 > total = None
8 > if loops >= 0:
16 > if loops >= 0:
9 > total = loops
17 > total = loops
10 > if opts.get('total', None):
18 > if opts.get('total', None):
11 > total = int(opts.get('total'))
19 > total = int(opts.get('total'))
12 > nested = False
20 > nested = False
13 > if opts.get('nested', None):
21 > if opts.get('nested', None):
14 > nested = True
22 > nested = True
15 > loops = abs(loops)
23 > loops = abs(loops)
16 >
24 >
17 > for i in range(loops):
25 > for i in range(loops):
18 > ui.progress('loop', i, 'loop.%d' % i, 'loopnum', total)
26 > ui.progress('loop', i, 'loop.%d' % i, 'loopnum', total)
19 > if opts.get('parallel'):
27 > if opts.get('parallel'):
20 > ui.progress('other', i, 'other.%d' % i, 'othernum', total)
28 > ui.progress('other', i, 'other.%d' % i, 'othernum', total)
21 > if nested:
29 > if nested:
22 > for j in range(2):
30 > nested_steps = 2
23 > ui.progress('nested', j, 'nested.%d' % j, 'nestnum', 2)
31 > if i and i % 4 == 0:
24 > ui.progress('nested', None, 'nested.done', 'nestnum', 2)
32 > nested_steps = 5
33 > for j in range(nested_steps):
34 > ui.progress(
35 > 'nested', j, 'nested.%d' % j, 'nestnum', nested_steps)
36 > ui.progress(
37 > 'nested', None, 'nested.done', 'nestnum', nested_steps)
25 > ui.progress('loop', None, 'loop.done', 'loopnum', total)
38 > ui.progress('loop', None, 'loop.done', 'loopnum', total)
26 >
39 >
27 > commands.norepo += " loop"
40 > commands.norepo += " loop"
28 >
41 >
29 > cmdtable = {
42 > cmdtable = {
30 > "loop": (loop, [('', 'total', '', 'override for total'),
43 > "loop": (loop, [('', 'total', '', 'override for total'),
31 > ('', 'nested', False, 'show nested results'),
44 > ('', 'nested', False, 'show nested results'),
32 > ('', 'parallel', False, 'show parallel sets of results'),
45 > ('', 'parallel', False, 'show parallel sets of results'),
33 > ],
46 > ],
34 > 'hg loop LOOPS'),
47 > 'hg loop LOOPS'),
35 > }
48 > }
36 > EOF
49 > EOF
37
50
38 $ cp $HGRCPATH $HGRCPATH.orig
51 $ cp $HGRCPATH $HGRCPATH.orig
39 $ echo "[extensions]" >> $HGRCPATH
52 $ echo "[extensions]" >> $HGRCPATH
40 $ echo "progress=" >> $HGRCPATH
53 $ echo "progress=" >> $HGRCPATH
41 $ echo "loop=`pwd`/loop.py" >> $HGRCPATH
54 $ echo "loop=`pwd`/loop.py" >> $HGRCPATH
42 $ echo "[progress]" >> $HGRCPATH
55 $ echo "[progress]" >> $HGRCPATH
43 $ echo "format = topic bar number" >> $HGRCPATH
56 $ echo "format = topic bar number" >> $HGRCPATH
44 $ echo "assume-tty=1" >> $HGRCPATH
57 $ echo "assume-tty=1" >> $HGRCPATH
45 $ echo "width=60" >> $HGRCPATH
58 $ echo "width=60" >> $HGRCPATH
46
59
47 test default params, display nothing because of delay
60 test default params, display nothing because of delay
48
61
49 $ hg -y loop 3
62 $ hg -y loop 3
50 $ echo "delay=0" >> $HGRCPATH
63 $ echo "delay=0" >> $HGRCPATH
51 $ echo "refresh=0" >> $HGRCPATH
64 $ echo "refresh=0" >> $HGRCPATH
52
65
53 test with delay=0, refresh=0
66 test with delay=0, refresh=0
54
67
55 $ hg -y loop 3
68 $ hg -y loop 3
56 \r (no-eol) (esc)
69 \r (no-eol) (esc)
57 loop [ ] 0/3\r (no-eol) (esc)
70 loop [ ] 0/3\r (no-eol) (esc)
58 loop [===============> ] 1/3\r (no-eol) (esc)
71 loop [===============> ] 1/3\r (no-eol) (esc)
59 loop [===============================> ] 2/3\r (no-eol) (esc)
72 loop [===============================> ] 2/3\r (no-eol) (esc)
60 \r (no-eol) (esc)
73 \r (no-eol) (esc)
61
74
62
75
63 test nested short-lived topics (which shouldn't display with nestdelay):
76 test nested short-lived topics (which shouldn't display with nestdelay):
64
77
65 $ hg -y loop 3 --nested
78 $ hg -y loop 3 --nested
66 \r (no-eol) (esc)
79 \r (no-eol) (esc)
67 loop [ ] 0/3\r (no-eol) (esc)
80 loop [ ] 0/3\r (no-eol) (esc)
68 loop [===============> ] 1/3\r (no-eol) (esc)
81 loop [===============> ] 1/3\r (no-eol) (esc)
69 loop [===============================> ] 2/3\r (no-eol) (esc)
82 loop [===============================> ] 2/3\r (no-eol) (esc)
70 \r (no-eol) (esc)
83 \r (no-eol) (esc)
71
84
85 Test nested long-lived topic which has the same name as a short-lived
86 peer. We shouldn't get stuck showing the short-lived inner steps, and
87 should go back to skipping the inner steps when the slow nested step
88 finishes.
89
90 $ hg -y loop 7 --nested
91 \r (no-eol) (esc)
92 loop [ ] 0/7\r (no-eol) (esc)
93 loop [=====> ] 1/7\r (no-eol) (esc)
94 loop [============> ] 2/7\r (no-eol) (esc)
95 loop [===================> ] 3/7\r (no-eol) (esc)
96 loop [==========================> ] 4/7\r (no-eol) (esc)
97 nested [==========================> ] 3/5\r (no-eol) (esc)
98 nested [===================================> ] 4/5\r (no-eol) (esc)
99 loop [=================================> ] 5/7\r (no-eol) (esc)
100 loop [========================================> ] 6/7\r (no-eol) (esc)
101 \r (no-eol) (esc)
102
72
103
73 $ hg --config progress.changedelay=0 -y loop 3 --nested
104 $ hg --config progress.changedelay=0 -y loop 3 --nested
74 \r (no-eol) (esc)
105 \r (no-eol) (esc)
75 loop [ ] 0/3\r (no-eol) (esc)
106 loop [ ] 0/3\r (no-eol) (esc)
76 nested [ ] 0/2\r (no-eol) (esc)
107 nested [ ] 0/2\r (no-eol) (esc)
77 nested [======================> ] 1/2\r (no-eol) (esc)
108 nested [======================> ] 1/2\r (no-eol) (esc)
78 loop [===============> ] 1/3\r (no-eol) (esc)
109 loop [===============> ] 1/3\r (no-eol) (esc)
79 nested [ ] 0/2\r (no-eol) (esc)
110 nested [ ] 0/2\r (no-eol) (esc)
80 nested [======================> ] 1/2\r (no-eol) (esc)
111 nested [======================> ] 1/2\r (no-eol) (esc)
81 loop [===============================> ] 2/3\r (no-eol) (esc)
112 loop [===============================> ] 2/3\r (no-eol) (esc)
82 nested [ ] 0/2\r (no-eol) (esc)
113 nested [ ] 0/2\r (no-eol) (esc)
83 nested [======================> ] 1/2\r (no-eol) (esc)
114 nested [======================> ] 1/2\r (no-eol) (esc)
84 \r (no-eol) (esc)
115 \r (no-eol) (esc)
85
116
86
117
87 test two topics being printed in parallel (as when we're doing a local
118 test two topics being printed in parallel (as when we're doing a local
88 --pull clone, where you get the unbundle and bundle progress at the
119 --pull clone, where you get the unbundle and bundle progress at the
89 same time):
120 same time):
90 $ hg loop 3 --parallel
121 $ hg loop 3 --parallel
91 \r (no-eol) (esc)
122 \r (no-eol) (esc)
92 loop [ ] 0/3\r (no-eol) (esc)
123 loop [ ] 0/3\r (no-eol) (esc)
93 loop [===============> ] 1/3\r (no-eol) (esc)
124 loop [===============> ] 1/3\r (no-eol) (esc)
94 loop [===============================> ] 2/3\r (no-eol) (esc)
125 loop [===============================> ] 2/3\r (no-eol) (esc)
95 \r (no-eol) (esc)
126 \r (no-eol) (esc)
96 test refresh is taken in account
127 test refresh is taken in account
97
128
98 $ hg -y --config progress.refresh=100 loop 3
129 $ hg -y --config progress.refresh=100 loop 3
99
130
100 test format options 1
131 test format options 1
101
132
102 $ hg -y --config 'progress.format=number topic item+2' loop 2
133 $ hg -y --config 'progress.format=number topic item+2' loop 2
103 \r (no-eol) (esc)
134 \r (no-eol) (esc)
104 0/2 loop lo\r (no-eol) (esc)
135 0/2 loop lo\r (no-eol) (esc)
105 1/2 loop lo\r (no-eol) (esc)
136 1/2 loop lo\r (no-eol) (esc)
106 \r (no-eol) (esc)
137 \r (no-eol) (esc)
107
138
108 test format options 2
139 test format options 2
109
140
110 $ hg -y --config 'progress.format=number item-3 bar' loop 2
141 $ hg -y --config 'progress.format=number item-3 bar' loop 2
111 \r (no-eol) (esc)
142 \r (no-eol) (esc)
112 0/2 p.0 [ ]\r (no-eol) (esc)
143 0/2 p.0 [ ]\r (no-eol) (esc)
113 1/2 p.1 [=======================> ]\r (no-eol) (esc)
144 1/2 p.1 [=======================> ]\r (no-eol) (esc)
114 \r (no-eol) (esc)
145 \r (no-eol) (esc)
115
146
116 test format options and indeterminate progress
147 test format options and indeterminate progress
117
148
118 $ hg -y --config 'progress.format=number item bar' loop -- -2
149 $ hg -y --config 'progress.format=number item bar' loop -- -2
119 \r (no-eol) (esc)
150 \r (no-eol) (esc)
120 0 loop.0 [ <=> ]\r (no-eol) (esc)
151 0 loop.0 [ <=> ]\r (no-eol) (esc)
121 1 loop.1 [ <=> ]\r (no-eol) (esc)
152 1 loop.1 [ <=> ]\r (no-eol) (esc)
122 \r (no-eol) (esc)
153 \r (no-eol) (esc)
123
154
124 make sure things don't fall over if count > total
155 make sure things don't fall over if count > total
125
156
126 $ hg -y loop --total 4 6
157 $ hg -y loop --total 4 6
127 \r (no-eol) (esc)
158 \r (no-eol) (esc)
128 loop [ ] 0/4\r (no-eol) (esc)
159 loop [ ] 0/4\r (no-eol) (esc)
129 loop [===========> ] 1/4\r (no-eol) (esc)
160 loop [===========> ] 1/4\r (no-eol) (esc)
130 loop [=======================> ] 2/4\r (no-eol) (esc)
161 loop [=======================> ] 2/4\r (no-eol) (esc)
131 loop [===================================> ] 3/4\r (no-eol) (esc)
162 loop [===================================> ] 3/4\r (no-eol) (esc)
132 loop [===============================================>] 4/4\r (no-eol) (esc)
163 loop [===============================================>] 4/4\r (no-eol) (esc)
133 loop [ <=> ] 5/4\r (no-eol) (esc)
164 loop [ <=> ] 5/4\r (no-eol) (esc)
134 \r (no-eol) (esc)
165 \r (no-eol) (esc)
135
166
136 test immediate progress completion
167 test immediate progress completion
137
168
138 $ hg -y loop 0
169 $ hg -y loop 0
139
170
140 test delay time estimates
171 test delay time estimates
141
172
142 $ cat > mocktime.py <<EOF
173 $ cat > mocktime.py <<EOF
143 > import os
174 > import os
144 > import time
175 > import time
145 >
176 >
146 > class mocktime(object):
177 > class mocktime(object):
147 > def __init__(self, increment):
178 > def __init__(self, increment):
148 > self.time = 0
179 > self.time = 0
149 > self.increment = increment
180 > self.increment = increment
150 > def __call__(self):
181 > def __call__(self):
151 > self.time += self.increment
182 > self.time += self.increment
152 > return self.time
183 > return self.time
153 >
184 >
154 > def uisetup(ui):
185 > def uisetup(ui):
155 > time.time = mocktime(int(os.environ.get('MOCKTIME', '11')))
186 > time.time = mocktime(int(os.environ.get('MOCKTIME', '11')))
156 > EOF
187 > EOF
157
188
158 $ cp $HGRCPATH.orig $HGRCPATH
189 $ cp $HGRCPATH.orig $HGRCPATH
159 $ echo "[extensions]" >> $HGRCPATH
190 $ echo "[extensions]" >> $HGRCPATH
160 $ echo "mocktime=`pwd`/mocktime.py" >> $HGRCPATH
191 $ echo "mocktime=`pwd`/mocktime.py" >> $HGRCPATH
161 $ echo "progress=" >> $HGRCPATH
192 $ echo "progress=" >> $HGRCPATH
162 $ echo "loop=`pwd`/loop.py" >> $HGRCPATH
193 $ echo "loop=`pwd`/loop.py" >> $HGRCPATH
163 $ echo "[progress]" >> $HGRCPATH
194 $ echo "[progress]" >> $HGRCPATH
164 $ echo "assume-tty=1" >> $HGRCPATH
195 $ echo "assume-tty=1" >> $HGRCPATH
165 $ echo "delay=25" >> $HGRCPATH
196 $ echo "delay=25" >> $HGRCPATH
166 $ echo "width=60" >> $HGRCPATH
197 $ echo "width=60" >> $HGRCPATH
167
198
168 $ hg -y loop 8
199 $ hg -y loop 8
169 \r (no-eol) (esc)
200 \r (no-eol) (esc)
170 loop [=========> ] 2/8 1m07s\r (no-eol) (esc)
201 loop [=========> ] 2/8 1m07s\r (no-eol) (esc)
171 loop [===============> ] 3/8 56s\r (no-eol) (esc)
202 loop [===============> ] 3/8 56s\r (no-eol) (esc)
172 loop [=====================> ] 4/8 45s\r (no-eol) (esc)
203 loop [=====================> ] 4/8 45s\r (no-eol) (esc)
173 loop [==========================> ] 5/8 34s\r (no-eol) (esc)
204 loop [==========================> ] 5/8 34s\r (no-eol) (esc)
174 loop [================================> ] 6/8 23s\r (no-eol) (esc)
205 loop [================================> ] 6/8 23s\r (no-eol) (esc)
175 loop [=====================================> ] 7/8 12s\r (no-eol) (esc)
206 loop [=====================================> ] 7/8 12s\r (no-eol) (esc)
176 \r (no-eol) (esc)
207 \r (no-eol) (esc)
177
208
178 $ MOCKTIME=10000 hg -y loop 4
209 $ MOCKTIME=10000 hg -y loop 4
179 \r (no-eol) (esc)
210 \r (no-eol) (esc)
180 loop [ ] 0/4\r (no-eol) (esc)
211 loop [ ] 0/4\r (no-eol) (esc)
181 loop [=========> ] 1/4 8h21m\r (no-eol) (esc)
212 loop [=========> ] 1/4 8h21m\r (no-eol) (esc)
182 loop [====================> ] 2/4 5h34m\r (no-eol) (esc)
213 loop [====================> ] 2/4 5h34m\r (no-eol) (esc)
183 loop [==============================> ] 3/4 2h47m\r (no-eol) (esc)
214 loop [==============================> ] 3/4 2h47m\r (no-eol) (esc)
184 \r (no-eol) (esc)
215 \r (no-eol) (esc)
185
216
186 $ MOCKTIME=1000000 hg -y loop 4
217 $ MOCKTIME=1000000 hg -y loop 4
187 \r (no-eol) (esc)
218 \r (no-eol) (esc)
188 loop [ ] 0/4\r (no-eol) (esc)
219 loop [ ] 0/4\r (no-eol) (esc)
189 loop [=========> ] 1/4 5w00d\r (no-eol) (esc)
220 loop [=========> ] 1/4 5w00d\r (no-eol) (esc)
190 loop [====================> ] 2/4 3w03d\r (no-eol) (esc)
221 loop [====================> ] 2/4 3w03d\r (no-eol) (esc)
191 loop [=============================> ] 3/4 11d14h\r (no-eol) (esc)
222 loop [=============================> ] 3/4 11d14h\r (no-eol) (esc)
192 \r (no-eol) (esc)
223 \r (no-eol) (esc)
193
224
194
225
195 $ MOCKTIME=14000000 hg -y loop 4
226 $ MOCKTIME=14000000 hg -y loop 4
196 \r (no-eol) (esc)
227 \r (no-eol) (esc)
197 loop [ ] 0/4\r (no-eol) (esc)
228 loop [ ] 0/4\r (no-eol) (esc)
198 loop [=========> ] 1/4 1y18w\r (no-eol) (esc)
229 loop [=========> ] 1/4 1y18w\r (no-eol) (esc)
199 loop [===================> ] 2/4 46w03d\r (no-eol) (esc)
230 loop [===================> ] 2/4 46w03d\r (no-eol) (esc)
200 loop [=============================> ] 3/4 23w02d\r (no-eol) (esc)
231 loop [=============================> ] 3/4 23w02d\r (no-eol) (esc)
201 \r (no-eol) (esc)
232 \r (no-eol) (esc)
202
233
203 Time estimates should not fail when there's no end point:
234 Time estimates should not fail when there's no end point:
204 $ hg -y loop -- -4
235 $ hg -y loop -- -4
205 \r (no-eol) (esc)
236 \r (no-eol) (esc)
206 loop [ <=> ] 2\r (no-eol) (esc)
237 loop [ <=> ] 2\r (no-eol) (esc)
207 loop [ <=> ] 3\r (no-eol) (esc)
238 loop [ <=> ] 3\r (no-eol) (esc)
208 \r (no-eol) (esc)
239 \r (no-eol) (esc)
General Comments 0
You need to be logged in to leave comments. Login now