Mercurial > hg
annotate hgext/progress.py @ 24653:83f6c4733ecc
windows: allow readpipe() to actually read data out of the pipe
It appears that the read() in readpipe() never actually ran before (in
test-ssh.t anyway). A print of the size returned from os.fstat() is 0 for every
single print output in test-ssh.t, so the data in the pipe ends up being read
later instead of when it is available. This is the same problem as Linux, as
mentioned in 331cbf088c4c.
There are several places in the Windows SSH tests where the order of local
output vs remote output differ from the other platforms. This only fixes one of
those cases (and interstingly, not the one added in order to test 331cbf088c4c),
so there is more investigation needed. However, without this patch, test-ssh.t
also has this diff:
--- c:/Users/Matt/Projects/hg/tests/test-ssh.t
+++ c:/Users/Matt/Projects/hg/tests/test-ssh.t.err
@@ -397,11 +397,11 @@
$ hg push --ssh "sh ../ssh.sh"
pushing to ssh://user@dummy/*/remote (glob)
searching for changes
- remote: Permission denied
- remote: abort: prechangegroup.hg-ssh hook failed
- remote: Permission denied
- remote: pushkey-abort: prepushkey.hg-ssh hook failed
updating 6c0482d977a3 to public failed!
+ remote: Permission denied
+ remote: abort: prechangegroup.hg-ssh hook failed
+ remote: Permission denied
+ remote: pushkey-abort: prepushkey.hg-ssh hook failed
[1]
$ cd ..
Output with this change was stable over 600+ runs of test-ssh.t. I initially
tried a background thread to read the pipe[1], but this was simpler and the test
results were exactly the same. I also tried SetNamedPipeHandleState(), but the
PIPE_NOWAIT is for compatibility with LANMAN 2.0, not for async I/O (the results
were identical though).
[1] http://eyalarubas.com/python-subproc-nonblock.html
author | Matt Harbison <matt_harbison@yahoo.com> |
---|---|
date | Tue, 07 Apr 2015 22:31:36 -0400 |
parents | 5502bd79d052 |
children | 80c5b2666a96 |
rev | line source |
---|---|
10434 | 1 # progress.py show progress bars for some actions |
2 # | |
3 # Copyright (C) 2010 Augie Fackler <durin42@gmail.com> | |
4 # | |
15772
83a140752239
progress: Use the same GPL boilerplate as most hg files
Augie Fackler <durin42@gmail.com>
parents:
15662
diff
changeset
|
5 # This software may be used and distributed according to the terms of the |
83a140752239
progress: Use the same GPL boilerplate as most hg files
Augie Fackler <durin42@gmail.com>
parents:
15662
diff
changeset
|
6 # GNU General Public License version 2 or any later version. |
10434 | 7 |
8 """show progress bars for some actions | |
9 | |
10450 | 10 This extension uses the progress information logged by hg commands |
11 to draw progress bars that are as informative as possible. Some progress | |
10434 | 12 bars only offer indeterminate information, while others have a definite |
13 end point. | |
14 | |
15 The following settings are available:: | |
16 | |
17 [progress] | |
18 delay = 3 # number of seconds (float) before showing the progress bar | |
14838
5d261fd00446
progress: add a changedelay to prevent parallel topics from flapping (issue2698)
Augie Fackler <durin42@gmail.com>
parents:
14837
diff
changeset
|
19 changedelay = 1 # changedelay: minimum delay before showing a new topic. |
5d261fd00446
progress: add a changedelay to prevent parallel topics from flapping (issue2698)
Augie Fackler <durin42@gmail.com>
parents:
14837
diff
changeset
|
20 # If set to less than 3 * refresh, that value will |
5d261fd00446
progress: add a changedelay to prevent parallel topics from flapping (issue2698)
Augie Fackler <durin42@gmail.com>
parents:
14837
diff
changeset
|
21 # be used instead. |
10434 | 22 refresh = 0.1 # time in seconds between refreshes of the progress bar |
13148
ab5fcc473fd1
progress: include time estimate as part of the default progress format
Augie Fackler <durin42@gmail.com>
parents:
13147
diff
changeset
|
23 format = topic bar number estimate # format of the progress bar |
10434 | 24 width = <none> # if set, the maximum width of the progress information |
25 # (that is, min(width, term width) will be used) | |
26 clear-complete = True # clear the progress bar after it's done | |
10656
f6ee02933af9
progress: document progress.disable config option
Augie Fackler <durin42@gmail.com>
parents:
10594
diff
changeset
|
27 disable = False # if true, don't show a progress bar |
10788
ca6ba6cac6cd
progress: use stderr instead of stdout; check stderr.isatty()
Augie Fackler <durin42@gmail.com>
parents:
10656
diff
changeset
|
28 assume-tty = False # if true, ALWAYS show a progress bar, unless |
ca6ba6cac6cd
progress: use stderr instead of stdout; check stderr.isatty()
Augie Fackler <durin42@gmail.com>
parents:
10656
diff
changeset
|
29 # disable is given |
10434 | 30 |
13147
082f5be788d9
progress: only show time estimate when progress format contains 'estimate'
Augie Fackler <durin42@gmail.com>
parents:
13146
diff
changeset
|
31 Valid entries for the format field are topic, bar, number, unit, |
14280
98e4d3914c2e
progress: add speed format
Martin Geisler <mg@aragost.com>
parents:
14247
diff
changeset
|
32 estimate, speed, and item. item defaults to the last 20 characters of |
98e4d3914c2e
progress: add speed format
Martin Geisler <mg@aragost.com>
parents:
14247
diff
changeset
|
33 the item, but this can be changed by adding either ``-<num>`` which |
98e4d3914c2e
progress: add speed format
Martin Geisler <mg@aragost.com>
parents:
14247
diff
changeset
|
34 would take the last num characters, or ``+<num>`` for the first num |
13147
082f5be788d9
progress: only show time estimate when progress format contains 'estimate'
Augie Fackler <durin42@gmail.com>
parents:
13146
diff
changeset
|
35 characters. |
10434 | 36 """ |
37 | |
38 import sys | |
39 import time | |
23908
5502bd79d052
progress: add a lock to prepare for introducing a thread
Solomon Matthews <smat@fb.com>
parents:
23907
diff
changeset
|
40 import threading |
10434 | 41 |
13131
c9ae7e096994
progress: Add estimated time remaining for long tasks
timeless <timeless@gmail.com>
parents:
13130
diff
changeset
|
42 from mercurial.i18n import _ |
16743
38caf405d010
hgext: mark all first-party extensions as such
Augie Fackler <raf@durin42.com>
parents:
16676
diff
changeset
|
43 testedwith = 'internal' |
10434 | 44 |
21859
be4270d27a7e
progress: use 'encoding.trim' to trim output line correctly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
19619
diff
changeset
|
45 from mercurial import encoding |
be4270d27a7e
progress: use 'encoding.trim' to trim output line correctly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
19619
diff
changeset
|
46 |
10434 | 47 def spacejoin(*args): |
10452
59f8fff4f887
progress: simplify spacejoin()
Brodie Rao <me+hg@dackz.net>
parents:
10450
diff
changeset
|
48 return ' '.join(s for s in args if s) |
10434 | 49 |
11458
ec21d91c79b3
progress: check stderr.isatty() before each print
Augie Fackler <durin42@gmail.com>
parents:
10891
diff
changeset
|
50 def shouldprint(ui): |
19404 | 51 return not ui.plain() and (ui._isatty(sys.stderr) or |
52 ui.configbool('progress', 'assume-tty')) | |
11458
ec21d91c79b3
progress: check stderr.isatty() before each print
Augie Fackler <durin42@gmail.com>
parents:
10891
diff
changeset
|
53 |
13132
24e3349cba8e
progress: refactor for readability and show XXs instead of 0mXXs.
Augie Fackler <durin42@gmail.com>
parents:
13131
diff
changeset
|
54 def fmtremaining(seconds): |
24e3349cba8e
progress: refactor for readability and show XXs instead of 0mXXs.
Augie Fackler <durin42@gmail.com>
parents:
13131
diff
changeset
|
55 if seconds < 60: |
13139
f4dd6aa16805
progress: explain format strings to translators
Martin Geisler <mg@aragost.com>
parents:
13132
diff
changeset
|
56 # i18n: format XX seconds as "XXs" |
13132
24e3349cba8e
progress: refactor for readability and show XXs instead of 0mXXs.
Augie Fackler <durin42@gmail.com>
parents:
13131
diff
changeset
|
57 return _("%02ds") % (seconds) |
24e3349cba8e
progress: refactor for readability and show XXs instead of 0mXXs.
Augie Fackler <durin42@gmail.com>
parents:
13131
diff
changeset
|
58 minutes = seconds // 60 |
24e3349cba8e
progress: refactor for readability and show XXs instead of 0mXXs.
Augie Fackler <durin42@gmail.com>
parents:
13131
diff
changeset
|
59 if minutes < 60: |
24e3349cba8e
progress: refactor for readability and show XXs instead of 0mXXs.
Augie Fackler <durin42@gmail.com>
parents:
13131
diff
changeset
|
60 seconds -= minutes * 60 |
13139
f4dd6aa16805
progress: explain format strings to translators
Martin Geisler <mg@aragost.com>
parents:
13132
diff
changeset
|
61 # i18n: format X minutes and YY seconds as "XmYYs" |
13132
24e3349cba8e
progress: refactor for readability and show XXs instead of 0mXXs.
Augie Fackler <durin42@gmail.com>
parents:
13131
diff
changeset
|
62 return _("%dm%02ds") % (minutes, seconds) |
24e3349cba8e
progress: refactor for readability and show XXs instead of 0mXXs.
Augie Fackler <durin42@gmail.com>
parents:
13131
diff
changeset
|
63 # we're going to ignore seconds in this case |
24e3349cba8e
progress: refactor for readability and show XXs instead of 0mXXs.
Augie Fackler <durin42@gmail.com>
parents:
13131
diff
changeset
|
64 minutes += 1 |
24e3349cba8e
progress: refactor for readability and show XXs instead of 0mXXs.
Augie Fackler <durin42@gmail.com>
parents:
13131
diff
changeset
|
65 hours = minutes // 60 |
24e3349cba8e
progress: refactor for readability and show XXs instead of 0mXXs.
Augie Fackler <durin42@gmail.com>
parents:
13131
diff
changeset
|
66 minutes -= hours * 60 |
13236
3f299f5d9a29
progress: handle days, weeks and years
timeless <timeless@gmail.com>
parents:
13154
diff
changeset
|
67 if hours < 30: |
3f299f5d9a29
progress: handle days, weeks and years
timeless <timeless@gmail.com>
parents:
13154
diff
changeset
|
68 # i18n: format X hours and YY minutes as "XhYYm" |
3f299f5d9a29
progress: handle days, weeks and years
timeless <timeless@gmail.com>
parents:
13154
diff
changeset
|
69 return _("%dh%02dm") % (hours, minutes) |
3f299f5d9a29
progress: handle days, weeks and years
timeless <timeless@gmail.com>
parents:
13154
diff
changeset
|
70 # we're going to ignore minutes in this case |
3f299f5d9a29
progress: handle days, weeks and years
timeless <timeless@gmail.com>
parents:
13154
diff
changeset
|
71 hours += 1 |
3f299f5d9a29
progress: handle days, weeks and years
timeless <timeless@gmail.com>
parents:
13154
diff
changeset
|
72 days = hours // 24 |
3f299f5d9a29
progress: handle days, weeks and years
timeless <timeless@gmail.com>
parents:
13154
diff
changeset
|
73 hours -= days * 24 |
3f299f5d9a29
progress: handle days, weeks and years
timeless <timeless@gmail.com>
parents:
13154
diff
changeset
|
74 if days < 15: |
3f299f5d9a29
progress: handle days, weeks and years
timeless <timeless@gmail.com>
parents:
13154
diff
changeset
|
75 # i18n: format X days and YY hours as "XdYYh" |
3f299f5d9a29
progress: handle days, weeks and years
timeless <timeless@gmail.com>
parents:
13154
diff
changeset
|
76 return _("%dd%02dh") % (days, hours) |
3f299f5d9a29
progress: handle days, weeks and years
timeless <timeless@gmail.com>
parents:
13154
diff
changeset
|
77 # we're going to ignore hours in this case |
3f299f5d9a29
progress: handle days, weeks and years
timeless <timeless@gmail.com>
parents:
13154
diff
changeset
|
78 days += 1 |
3f299f5d9a29
progress: handle days, weeks and years
timeless <timeless@gmail.com>
parents:
13154
diff
changeset
|
79 weeks = days // 7 |
3f299f5d9a29
progress: handle days, weeks and years
timeless <timeless@gmail.com>
parents:
13154
diff
changeset
|
80 days -= weeks * 7 |
3f299f5d9a29
progress: handle days, weeks and years
timeless <timeless@gmail.com>
parents:
13154
diff
changeset
|
81 if weeks < 55: |
3f299f5d9a29
progress: handle days, weeks and years
timeless <timeless@gmail.com>
parents:
13154
diff
changeset
|
82 # i18n: format X weeks and YY days as "XwYYd" |
3f299f5d9a29
progress: handle days, weeks and years
timeless <timeless@gmail.com>
parents:
13154
diff
changeset
|
83 return _("%dw%02dd") % (weeks, days) |
3f299f5d9a29
progress: handle days, weeks and years
timeless <timeless@gmail.com>
parents:
13154
diff
changeset
|
84 # we're going to ignore days and treat a year as 52 weeks |
3f299f5d9a29
progress: handle days, weeks and years
timeless <timeless@gmail.com>
parents:
13154
diff
changeset
|
85 weeks += 1 |
3f299f5d9a29
progress: handle days, weeks and years
timeless <timeless@gmail.com>
parents:
13154
diff
changeset
|
86 years = weeks // 52 |
3f299f5d9a29
progress: handle days, weeks and years
timeless <timeless@gmail.com>
parents:
13154
diff
changeset
|
87 weeks -= years * 52 |
3f299f5d9a29
progress: handle days, weeks and years
timeless <timeless@gmail.com>
parents:
13154
diff
changeset
|
88 # i18n: format X years and YY weeks as "XyYYw" |
3f299f5d9a29
progress: handle days, weeks and years
timeless <timeless@gmail.com>
parents:
13154
diff
changeset
|
89 return _("%dy%02dw") % (years, weeks) |
13132
24e3349cba8e
progress: refactor for readability and show XXs instead of 0mXXs.
Augie Fackler <durin42@gmail.com>
parents:
13131
diff
changeset
|
90 |
10434 | 91 class progbar(object): |
92 def __init__(self, ui): | |
93 self.ui = ui | |
23908
5502bd79d052
progress: add a lock to prepare for introducing a thread
Solomon Matthews <smat@fb.com>
parents:
23907
diff
changeset
|
94 self._refreshlock = threading.Lock() |
10434 | 95 self.resetstate() |
96 | |
97 def resetstate(self): | |
98 self.topics = [] | |
13130
f139f34ba330
progress: react more reasonably to nested progress topics
Augie Fackler <durin42@gmail.com>
parents:
12689
diff
changeset
|
99 self.topicstates = {} |
13131
c9ae7e096994
progress: Add estimated time remaining for long tasks
timeless <timeless@gmail.com>
parents:
13130
diff
changeset
|
100 self.starttimes = {} |
c9ae7e096994
progress: Add estimated time remaining for long tasks
timeless <timeless@gmail.com>
parents:
13130
diff
changeset
|
101 self.startvals = {} |
10434 | 102 self.printed = False |
103 self.lastprint = time.time() + float(self.ui.config( | |
104 'progress', 'delay', default=3)) | |
23906
e0ae0a4e4c7b
progress: move current topic to member variable
Solomon Matthews <smat@fb.com>
parents:
23905
diff
changeset
|
105 self.curtopic = None |
14838
5d261fd00446
progress: add a changedelay to prevent parallel topics from flapping (issue2698)
Augie Fackler <durin42@gmail.com>
parents:
14837
diff
changeset
|
106 self.lasttopic = None |
10434 | 107 self.indetcount = 0 |
108 self.refresh = float(self.ui.config( | |
109 'progress', 'refresh', default=0.1)) | |
14838
5d261fd00446
progress: add a changedelay to prevent parallel topics from flapping (issue2698)
Augie Fackler <durin42@gmail.com>
parents:
14837
diff
changeset
|
110 self.changedelay = max(3 * self.refresh, |
5d261fd00446
progress: add a changedelay to prevent parallel topics from flapping (issue2698)
Augie Fackler <durin42@gmail.com>
parents:
14837
diff
changeset
|
111 float(self.ui.config( |
5d261fd00446
progress: add a changedelay to prevent parallel topics from flapping (issue2698)
Augie Fackler <durin42@gmail.com>
parents:
14837
diff
changeset
|
112 'progress', 'changedelay', default=1))) |
10434 | 113 self.order = self.ui.configlist( |
114 'progress', 'format', | |
13148
ab5fcc473fd1
progress: include time estimate as part of the default progress format
Augie Fackler <durin42@gmail.com>
parents:
13147
diff
changeset
|
115 default=['topic', 'bar', 'number', 'estimate']) |
10434 | 116 |
13131
c9ae7e096994
progress: Add estimated time remaining for long tasks
timeless <timeless@gmail.com>
parents:
13130
diff
changeset
|
117 def show(self, now, topic, pos, item, unit, total): |
11458
ec21d91c79b3
progress: check stderr.isatty() before each print
Augie Fackler <durin42@gmail.com>
parents:
10891
diff
changeset
|
118 if not shouldprint(self.ui): |
ec21d91c79b3
progress: check stderr.isatty() before each print
Augie Fackler <durin42@gmail.com>
parents:
10891
diff
changeset
|
119 return |
10434 | 120 termwidth = self.width() |
121 self.printed = True | |
122 head = '' | |
123 needprogress = False | |
124 tail = '' | |
125 for indicator in self.order: | |
126 add = '' | |
127 if indicator == 'topic': | |
128 add = topic | |
129 elif indicator == 'number': | |
130 if total: | |
131 add = ('% ' + str(len(str(total))) + | |
132 's/%s') % (pos, total) | |
133 else: | |
134 add = str(pos) | |
135 elif indicator.startswith('item') and item: | |
136 slice = 'end' | |
137 if '-' in indicator: | |
138 wid = int(indicator.split('-')[1]) | |
139 elif '+' in indicator: | |
140 slice = 'beginning' | |
141 wid = int(indicator.split('+')[1]) | |
142 else: | |
143 wid = 20 | |
144 if slice == 'end': | |
21862
ba7f75e7f4e5
progress: use 'encoding.trim' to trim items in output line correctly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
21860
diff
changeset
|
145 add = encoding.trim(item, wid, leftside=True) |
10434 | 146 else: |
21862
ba7f75e7f4e5
progress: use 'encoding.trim' to trim items in output line correctly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
21860
diff
changeset
|
147 add = encoding.trim(item, wid) |
21863
f9c91c638378
progress: use 'encoding.colwidth' to get column width of items correctly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
21862
diff
changeset
|
148 add += (wid - encoding.colwidth(add)) * ' ' |
10434 | 149 elif indicator == 'bar': |
150 add = '' | |
151 needprogress = True | |
152 elif indicator == 'unit' and unit: | |
153 add = unit | |
13147
082f5be788d9
progress: only show time estimate when progress format contains 'estimate'
Augie Fackler <durin42@gmail.com>
parents:
13146
diff
changeset
|
154 elif indicator == 'estimate': |
082f5be788d9
progress: only show time estimate when progress format contains 'estimate'
Augie Fackler <durin42@gmail.com>
parents:
13146
diff
changeset
|
155 add = self.estimate(topic, pos, total, now) |
14280
98e4d3914c2e
progress: add speed format
Martin Geisler <mg@aragost.com>
parents:
14247
diff
changeset
|
156 elif indicator == 'speed': |
98e4d3914c2e
progress: add speed format
Martin Geisler <mg@aragost.com>
parents:
14247
diff
changeset
|
157 add = self.speed(topic, pos, unit, now) |
10434 | 158 if not needprogress: |
159 head = spacejoin(head, add) | |
160 else: | |
13146
43575c67add3
progress: fix adding format elements after the progress bar
Augie Fackler <durin42@gmail.com>
parents:
13139
diff
changeset
|
161 tail = spacejoin(tail, add) |
10434 | 162 if needprogress: |
163 used = 0 | |
164 if head: | |
21860
e382cf9ec30b
progress: use 'encoding.colwidth' to get column width of output line correctly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
21859
diff
changeset
|
165 used += encoding.colwidth(head) + 1 |
10434 | 166 if tail: |
21860
e382cf9ec30b
progress: use 'encoding.colwidth' to get column width of output line correctly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
21859
diff
changeset
|
167 used += encoding.colwidth(tail) + 1 |
10434 | 168 progwidth = termwidth - used - 3 |
10891
83af68e38be3
progress: fall back to indeterminate progress if position is >= total
Augie Fackler <durin42@gmail.com>
parents:
10815
diff
changeset
|
169 if total and pos <= total: |
10434 | 170 amt = pos * progwidth // total |
10453
7edc649f9f7e
progress: make determinate bar more like wget progress bar
Brodie Rao <me+hg@dackz.net>
parents:
10452
diff
changeset
|
171 bar = '=' * (amt - 1) |
7edc649f9f7e
progress: make determinate bar more like wget progress bar
Brodie Rao <me+hg@dackz.net>
parents:
10452
diff
changeset
|
172 if amt > 0: |
7edc649f9f7e
progress: make determinate bar more like wget progress bar
Brodie Rao <me+hg@dackz.net>
parents:
10452
diff
changeset
|
173 bar += '>' |
7edc649f9f7e
progress: make determinate bar more like wget progress bar
Brodie Rao <me+hg@dackz.net>
parents:
10452
diff
changeset
|
174 bar += ' ' * (progwidth - amt) |
10434 | 175 else: |
176 progwidth -= 3 | |
177 self.indetcount += 1 | |
178 # mod the count by twice the width so we can make the | |
179 # cursor bounce between the right and left sides | |
180 amt = self.indetcount % (2 * progwidth) | |
181 amt -= progwidth | |
182 bar = (' ' * int(progwidth - abs(amt)) + '<=>' + | |
183 ' ' * int(abs(amt))) | |
184 prog = ''.join(('[', bar , ']')) | |
185 out = spacejoin(head, prog, tail) | |
186 else: | |
187 out = spacejoin(head, tail) | |
21859
be4270d27a7e
progress: use 'encoding.trim' to trim output line correctly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
19619
diff
changeset
|
188 sys.stderr.write('\r' + encoding.trim(out, termwidth)) |
14838
5d261fd00446
progress: add a changedelay to prevent parallel topics from flapping (issue2698)
Augie Fackler <durin42@gmail.com>
parents:
14837
diff
changeset
|
189 self.lasttopic = topic |
10788
ca6ba6cac6cd
progress: use stderr instead of stdout; check stderr.isatty()
Augie Fackler <durin42@gmail.com>
parents:
10656
diff
changeset
|
190 sys.stderr.flush() |
10434 | 191 |
192 def clear(self): | |
11458
ec21d91c79b3
progress: check stderr.isatty() before each print
Augie Fackler <durin42@gmail.com>
parents:
10891
diff
changeset
|
193 if not shouldprint(self.ui): |
ec21d91c79b3
progress: check stderr.isatty() before each print
Augie Fackler <durin42@gmail.com>
parents:
10891
diff
changeset
|
194 return |
10788
ca6ba6cac6cd
progress: use stderr instead of stdout; check stderr.isatty()
Augie Fackler <durin42@gmail.com>
parents:
10656
diff
changeset
|
195 sys.stderr.write('\r%s\r' % (' ' * self.width())) |
10434 | 196 |
10439
509f4ed56509
progress: correctly handle empty progress topic
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10434
diff
changeset
|
197 def complete(self): |
11458
ec21d91c79b3
progress: check stderr.isatty() before each print
Augie Fackler <durin42@gmail.com>
parents:
10891
diff
changeset
|
198 if not shouldprint(self.ui): |
ec21d91c79b3
progress: check stderr.isatty() before each print
Augie Fackler <durin42@gmail.com>
parents:
10891
diff
changeset
|
199 return |
10439
509f4ed56509
progress: correctly handle empty progress topic
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10434
diff
changeset
|
200 if self.ui.configbool('progress', 'clear-complete', default=True): |
509f4ed56509
progress: correctly handle empty progress topic
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10434
diff
changeset
|
201 self.clear() |
509f4ed56509
progress: correctly handle empty progress topic
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10434
diff
changeset
|
202 else: |
10788
ca6ba6cac6cd
progress: use stderr instead of stdout; check stderr.isatty()
Augie Fackler <durin42@gmail.com>
parents:
10656
diff
changeset
|
203 sys.stderr.write('\n') |
ca6ba6cac6cd
progress: use stderr instead of stdout; check stderr.isatty()
Augie Fackler <durin42@gmail.com>
parents:
10656
diff
changeset
|
204 sys.stderr.flush() |
10439
509f4ed56509
progress: correctly handle empty progress topic
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10434
diff
changeset
|
205 |
10434 | 206 def width(self): |
12689
c52c629ce19e
termwidth: move to ui.ui from util
Augie Fackler <durin42@gmail.com>
parents:
12654
diff
changeset
|
207 tw = self.ui.termwidth() |
10434 | 208 return min(int(self.ui.config('progress', 'width', default=tw)), tw) |
209 | |
13147
082f5be788d9
progress: only show time estimate when progress format contains 'estimate'
Augie Fackler <durin42@gmail.com>
parents:
13146
diff
changeset
|
210 def estimate(self, topic, pos, total, now): |
13154
e11c14f14491
progress: don't compute estimate without a total
Augie Fackler <durin42@gmail.com>
parents:
13148
diff
changeset
|
211 if total is None: |
e11c14f14491
progress: don't compute estimate without a total
Augie Fackler <durin42@gmail.com>
parents:
13148
diff
changeset
|
212 return '' |
13147
082f5be788d9
progress: only show time estimate when progress format contains 'estimate'
Augie Fackler <durin42@gmail.com>
parents:
13146
diff
changeset
|
213 initialpos = self.startvals[topic] |
082f5be788d9
progress: only show time estimate when progress format contains 'estimate'
Augie Fackler <durin42@gmail.com>
parents:
13146
diff
changeset
|
214 target = total - initialpos |
082f5be788d9
progress: only show time estimate when progress format contains 'estimate'
Augie Fackler <durin42@gmail.com>
parents:
13146
diff
changeset
|
215 delta = pos - initialpos |
082f5be788d9
progress: only show time estimate when progress format contains 'estimate'
Augie Fackler <durin42@gmail.com>
parents:
13146
diff
changeset
|
216 if delta > 0: |
082f5be788d9
progress: only show time estimate when progress format contains 'estimate'
Augie Fackler <durin42@gmail.com>
parents:
13146
diff
changeset
|
217 elapsed = now - self.starttimes[topic] |
082f5be788d9
progress: only show time estimate when progress format contains 'estimate'
Augie Fackler <durin42@gmail.com>
parents:
13146
diff
changeset
|
218 if elapsed > float( |
082f5be788d9
progress: only show time estimate when progress format contains 'estimate'
Augie Fackler <durin42@gmail.com>
parents:
13146
diff
changeset
|
219 self.ui.config('progress', 'estimate', default=2)): |
082f5be788d9
progress: only show time estimate when progress format contains 'estimate'
Augie Fackler <durin42@gmail.com>
parents:
13146
diff
changeset
|
220 seconds = (elapsed * (target - delta)) // delta + 1 |
082f5be788d9
progress: only show time estimate when progress format contains 'estimate'
Augie Fackler <durin42@gmail.com>
parents:
13146
diff
changeset
|
221 return fmtremaining(seconds) |
082f5be788d9
progress: only show time estimate when progress format contains 'estimate'
Augie Fackler <durin42@gmail.com>
parents:
13146
diff
changeset
|
222 return '' |
082f5be788d9
progress: only show time estimate when progress format contains 'estimate'
Augie Fackler <durin42@gmail.com>
parents:
13146
diff
changeset
|
223 |
14280
98e4d3914c2e
progress: add speed format
Martin Geisler <mg@aragost.com>
parents:
14247
diff
changeset
|
224 def speed(self, topic, pos, unit, now): |
98e4d3914c2e
progress: add speed format
Martin Geisler <mg@aragost.com>
parents:
14247
diff
changeset
|
225 initialpos = self.startvals[topic] |
98e4d3914c2e
progress: add speed format
Martin Geisler <mg@aragost.com>
parents:
14247
diff
changeset
|
226 delta = pos - initialpos |
98e4d3914c2e
progress: add speed format
Martin Geisler <mg@aragost.com>
parents:
14247
diff
changeset
|
227 elapsed = now - self.starttimes[topic] |
98e4d3914c2e
progress: add speed format
Martin Geisler <mg@aragost.com>
parents:
14247
diff
changeset
|
228 if elapsed > float( |
98e4d3914c2e
progress: add speed format
Martin Geisler <mg@aragost.com>
parents:
14247
diff
changeset
|
229 self.ui.config('progress', 'estimate', default=2)): |
98e4d3914c2e
progress: add speed format
Martin Geisler <mg@aragost.com>
parents:
14247
diff
changeset
|
230 return _('%d %s/sec') % (delta / elapsed, unit) |
98e4d3914c2e
progress: add speed format
Martin Geisler <mg@aragost.com>
parents:
14247
diff
changeset
|
231 return '' |
98e4d3914c2e
progress: add speed format
Martin Geisler <mg@aragost.com>
parents:
14247
diff
changeset
|
232 |
23907
63c7783a5928
progress: move update check into helper method
Solomon Matthews <smat@fb.com>
parents:
23906
diff
changeset
|
233 def _oktoprint(self, now): |
63c7783a5928
progress: move update check into helper method
Solomon Matthews <smat@fb.com>
parents:
23906
diff
changeset
|
234 '''Check if conditions are met to print - e.g. changedelay elapsed''' |
63c7783a5928
progress: move update check into helper method
Solomon Matthews <smat@fb.com>
parents:
23906
diff
changeset
|
235 if (self.lasttopic is None # first time we printed |
63c7783a5928
progress: move update check into helper method
Solomon Matthews <smat@fb.com>
parents:
23906
diff
changeset
|
236 # not a topic change |
63c7783a5928
progress: move update check into helper method
Solomon Matthews <smat@fb.com>
parents:
23906
diff
changeset
|
237 or self.curtopic == self.lasttopic |
63c7783a5928
progress: move update check into helper method
Solomon Matthews <smat@fb.com>
parents:
23906
diff
changeset
|
238 # it's been long enough we should print anyway |
63c7783a5928
progress: move update check into helper method
Solomon Matthews <smat@fb.com>
parents:
23906
diff
changeset
|
239 or now - self.lastprint >= self.changedelay): |
63c7783a5928
progress: move update check into helper method
Solomon Matthews <smat@fb.com>
parents:
23906
diff
changeset
|
240 return True |
63c7783a5928
progress: move update check into helper method
Solomon Matthews <smat@fb.com>
parents:
23906
diff
changeset
|
241 else: |
63c7783a5928
progress: move update check into helper method
Solomon Matthews <smat@fb.com>
parents:
23906
diff
changeset
|
242 return False |
63c7783a5928
progress: move update check into helper method
Solomon Matthews <smat@fb.com>
parents:
23906
diff
changeset
|
243 |
11555
d8d0fc3988ca
color/progress: subclass ui instead of using wrapfunction (issue2096)
Brodie Rao <brodie@bitheap.org>
parents:
11458
diff
changeset
|
244 def progress(self, topic, pos, item='', unit='', total=None): |
13131
c9ae7e096994
progress: Add estimated time remaining for long tasks
timeless <timeless@gmail.com>
parents:
13130
diff
changeset
|
245 now = time.time() |
23908
5502bd79d052
progress: add a lock to prepare for introducing a thread
Solomon Matthews <smat@fb.com>
parents:
23907
diff
changeset
|
246 self._refreshlock.acquire() |
23905
8b5b963ba95a
progress: add try/finally to make the diffs for the next commit more readable
Solomon Matthews <smat@fb.com>
parents:
21863
diff
changeset
|
247 try: |
8b5b963ba95a
progress: add try/finally to make the diffs for the next commit more readable
Solomon Matthews <smat@fb.com>
parents:
21863
diff
changeset
|
248 if pos is None: |
8b5b963ba95a
progress: add try/finally to make the diffs for the next commit more readable
Solomon Matthews <smat@fb.com>
parents:
21863
diff
changeset
|
249 self.starttimes.pop(topic, None) |
8b5b963ba95a
progress: add try/finally to make the diffs for the next commit more readable
Solomon Matthews <smat@fb.com>
parents:
21863
diff
changeset
|
250 self.startvals.pop(topic, None) |
8b5b963ba95a
progress: add try/finally to make the diffs for the next commit more readable
Solomon Matthews <smat@fb.com>
parents:
21863
diff
changeset
|
251 self.topicstates.pop(topic, None) |
8b5b963ba95a
progress: add try/finally to make the diffs for the next commit more readable
Solomon Matthews <smat@fb.com>
parents:
21863
diff
changeset
|
252 # reset the progress bar if this is the outermost topic |
8b5b963ba95a
progress: add try/finally to make the diffs for the next commit more readable
Solomon Matthews <smat@fb.com>
parents:
21863
diff
changeset
|
253 if self.topics and self.topics[0] == topic and self.printed: |
8b5b963ba95a
progress: add try/finally to make the diffs for the next commit more readable
Solomon Matthews <smat@fb.com>
parents:
21863
diff
changeset
|
254 self.complete() |
8b5b963ba95a
progress: add try/finally to make the diffs for the next commit more readable
Solomon Matthews <smat@fb.com>
parents:
21863
diff
changeset
|
255 self.resetstate() |
8b5b963ba95a
progress: add try/finally to make the diffs for the next commit more readable
Solomon Matthews <smat@fb.com>
parents:
21863
diff
changeset
|
256 # truncate the list of topics assuming all topics within |
8b5b963ba95a
progress: add try/finally to make the diffs for the next commit more readable
Solomon Matthews <smat@fb.com>
parents:
21863
diff
changeset
|
257 # this one are also closed |
8b5b963ba95a
progress: add try/finally to make the diffs for the next commit more readable
Solomon Matthews <smat@fb.com>
parents:
21863
diff
changeset
|
258 if topic in self.topics: |
8b5b963ba95a
progress: add try/finally to make the diffs for the next commit more readable
Solomon Matthews <smat@fb.com>
parents:
21863
diff
changeset
|
259 self.topics = self.topics[:self.topics.index(topic)] |
8b5b963ba95a
progress: add try/finally to make the diffs for the next commit more readable
Solomon Matthews <smat@fb.com>
parents:
21863
diff
changeset
|
260 # reset the last topic to the one we just unwound to, |
8b5b963ba95a
progress: add try/finally to make the diffs for the next commit more readable
Solomon Matthews <smat@fb.com>
parents:
21863
diff
changeset
|
261 # so that higher-level topics will be stickier than |
8b5b963ba95a
progress: add try/finally to make the diffs for the next commit more readable
Solomon Matthews <smat@fb.com>
parents:
21863
diff
changeset
|
262 # lower-level topics |
8b5b963ba95a
progress: add try/finally to make the diffs for the next commit more readable
Solomon Matthews <smat@fb.com>
parents:
21863
diff
changeset
|
263 if self.topics: |
8b5b963ba95a
progress: add try/finally to make the diffs for the next commit more readable
Solomon Matthews <smat@fb.com>
parents:
21863
diff
changeset
|
264 self.lasttopic = self.topics[-1] |
8b5b963ba95a
progress: add try/finally to make the diffs for the next commit more readable
Solomon Matthews <smat@fb.com>
parents:
21863
diff
changeset
|
265 else: |
8b5b963ba95a
progress: add try/finally to make the diffs for the next commit more readable
Solomon Matthews <smat@fb.com>
parents:
21863
diff
changeset
|
266 self.lasttopic = None |
8b5b963ba95a
progress: add try/finally to make the diffs for the next commit more readable
Solomon Matthews <smat@fb.com>
parents:
21863
diff
changeset
|
267 else: |
8b5b963ba95a
progress: add try/finally to make the diffs for the next commit more readable
Solomon Matthews <smat@fb.com>
parents:
21863
diff
changeset
|
268 if topic not in self.topics: |
8b5b963ba95a
progress: add try/finally to make the diffs for the next commit more readable
Solomon Matthews <smat@fb.com>
parents:
21863
diff
changeset
|
269 self.starttimes[topic] = now |
8b5b963ba95a
progress: add try/finally to make the diffs for the next commit more readable
Solomon Matthews <smat@fb.com>
parents:
21863
diff
changeset
|
270 self.startvals[topic] = pos |
8b5b963ba95a
progress: add try/finally to make the diffs for the next commit more readable
Solomon Matthews <smat@fb.com>
parents:
21863
diff
changeset
|
271 self.topics.append(topic) |
8b5b963ba95a
progress: add try/finally to make the diffs for the next commit more readable
Solomon Matthews <smat@fb.com>
parents:
21863
diff
changeset
|
272 self.topicstates[topic] = pos, item, unit, total |
23906
e0ae0a4e4c7b
progress: move current topic to member variable
Solomon Matthews <smat@fb.com>
parents:
23905
diff
changeset
|
273 self.curtopic = topic |
23905
8b5b963ba95a
progress: add try/finally to make the diffs for the next commit more readable
Solomon Matthews <smat@fb.com>
parents:
21863
diff
changeset
|
274 if now - self.lastprint >= self.refresh and self.topics: |
23907
63c7783a5928
progress: move update check into helper method
Solomon Matthews <smat@fb.com>
parents:
23906
diff
changeset
|
275 if self._oktoprint(now): |
23905
8b5b963ba95a
progress: add try/finally to make the diffs for the next commit more readable
Solomon Matthews <smat@fb.com>
parents:
21863
diff
changeset
|
276 self.lastprint = now |
8b5b963ba95a
progress: add try/finally to make the diffs for the next commit more readable
Solomon Matthews <smat@fb.com>
parents:
21863
diff
changeset
|
277 self.show(now, topic, *self.topicstates[topic]) |
8b5b963ba95a
progress: add try/finally to make the diffs for the next commit more readable
Solomon Matthews <smat@fb.com>
parents:
21863
diff
changeset
|
278 finally: |
23908
5502bd79d052
progress: add a lock to prepare for introducing a thread
Solomon Matthews <smat@fb.com>
parents:
23907
diff
changeset
|
279 self._refreshlock.release() |
10434 | 280 |
14837
ec4ba216ddef
progress: make progress bar a singleton to avoid double-progress ui bugs
Augie Fackler <durin42@gmail.com>
parents:
14836
diff
changeset
|
281 _singleton = None |
ec4ba216ddef
progress: make progress bar a singleton to avoid double-progress ui bugs
Augie Fackler <durin42@gmail.com>
parents:
14836
diff
changeset
|
282 |
10434 | 283 def uisetup(ui): |
14837
ec4ba216ddef
progress: make progress bar a singleton to avoid double-progress ui bugs
Augie Fackler <durin42@gmail.com>
parents:
14836
diff
changeset
|
284 global _singleton |
11555
d8d0fc3988ca
color/progress: subclass ui instead of using wrapfunction (issue2096)
Brodie Rao <brodie@bitheap.org>
parents:
11458
diff
changeset
|
285 class progressui(ui.__class__): |
d8d0fc3988ca
color/progress: subclass ui instead of using wrapfunction (issue2096)
Brodie Rao <brodie@bitheap.org>
parents:
11458
diff
changeset
|
286 _progbar = None |
d8d0fc3988ca
color/progress: subclass ui instead of using wrapfunction (issue2096)
Brodie Rao <brodie@bitheap.org>
parents:
11458
diff
changeset
|
287 |
15662
06671371e634
progress: check for ui.quiet and ui.debugflag before we write
David Soria Parra <dsp@php.net>
parents:
14838
diff
changeset
|
288 def _quiet(self): |
06671371e634
progress: check for ui.quiet and ui.debugflag before we write
David Soria Parra <dsp@php.net>
parents:
14838
diff
changeset
|
289 return self.debugflag or self.quiet |
06671371e634
progress: check for ui.quiet and ui.debugflag before we write
David Soria Parra <dsp@php.net>
parents:
14838
diff
changeset
|
290 |
11555
d8d0fc3988ca
color/progress: subclass ui instead of using wrapfunction (issue2096)
Brodie Rao <brodie@bitheap.org>
parents:
11458
diff
changeset
|
291 def progress(self, *args, **opts): |
15662
06671371e634
progress: check for ui.quiet and ui.debugflag before we write
David Soria Parra <dsp@php.net>
parents:
14838
diff
changeset
|
292 if not self._quiet(): |
06671371e634
progress: check for ui.quiet and ui.debugflag before we write
David Soria Parra <dsp@php.net>
parents:
14838
diff
changeset
|
293 self._progbar.progress(*args, **opts) |
11555
d8d0fc3988ca
color/progress: subclass ui instead of using wrapfunction (issue2096)
Brodie Rao <brodie@bitheap.org>
parents:
11458
diff
changeset
|
294 return super(progressui, self).progress(*args, **opts) |
d8d0fc3988ca
color/progress: subclass ui instead of using wrapfunction (issue2096)
Brodie Rao <brodie@bitheap.org>
parents:
11458
diff
changeset
|
295 |
d8d0fc3988ca
color/progress: subclass ui instead of using wrapfunction (issue2096)
Brodie Rao <brodie@bitheap.org>
parents:
11458
diff
changeset
|
296 def write(self, *args, **opts): |
15662
06671371e634
progress: check for ui.quiet and ui.debugflag before we write
David Soria Parra <dsp@php.net>
parents:
14838
diff
changeset
|
297 if not self._quiet() and self._progbar.printed: |
11555
d8d0fc3988ca
color/progress: subclass ui instead of using wrapfunction (issue2096)
Brodie Rao <brodie@bitheap.org>
parents:
11458
diff
changeset
|
298 self._progbar.clear() |
d8d0fc3988ca
color/progress: subclass ui instead of using wrapfunction (issue2096)
Brodie Rao <brodie@bitheap.org>
parents:
11458
diff
changeset
|
299 return super(progressui, self).write(*args, **opts) |
d8d0fc3988ca
color/progress: subclass ui instead of using wrapfunction (issue2096)
Brodie Rao <brodie@bitheap.org>
parents:
11458
diff
changeset
|
300 |
d8d0fc3988ca
color/progress: subclass ui instead of using wrapfunction (issue2096)
Brodie Rao <brodie@bitheap.org>
parents:
11458
diff
changeset
|
301 def write_err(self, *args, **opts): |
15662
06671371e634
progress: check for ui.quiet and ui.debugflag before we write
David Soria Parra <dsp@php.net>
parents:
14838
diff
changeset
|
302 if not self._quiet() and self._progbar.printed: |
11555
d8d0fc3988ca
color/progress: subclass ui instead of using wrapfunction (issue2096)
Brodie Rao <brodie@bitheap.org>
parents:
11458
diff
changeset
|
303 self._progbar.clear() |
d8d0fc3988ca
color/progress: subclass ui instead of using wrapfunction (issue2096)
Brodie Rao <brodie@bitheap.org>
parents:
11458
diff
changeset
|
304 return super(progressui, self).write_err(*args, **opts) |
d8d0fc3988ca
color/progress: subclass ui instead of using wrapfunction (issue2096)
Brodie Rao <brodie@bitheap.org>
parents:
11458
diff
changeset
|
305 |
10540
dd9d057465c1
progress: provide an explicit disable method for developers
Steve Borho <steve@borho.org>
parents:
10523
diff
changeset
|
306 # Apps that derive a class from ui.ui() can use |
dd9d057465c1
progress: provide an explicit disable method for developers
Steve Borho <steve@borho.org>
parents:
10523
diff
changeset
|
307 # setconfig('progress', 'disable', 'True') to disable this extension |
dd9d057465c1
progress: provide an explicit disable method for developers
Steve Borho <steve@borho.org>
parents:
10523
diff
changeset
|
308 if ui.configbool('progress', 'disable'): |
dd9d057465c1
progress: provide an explicit disable method for developers
Steve Borho <steve@borho.org>
parents:
10523
diff
changeset
|
309 return |
11458
ec21d91c79b3
progress: check stderr.isatty() before each print
Augie Fackler <durin42@gmail.com>
parents:
10891
diff
changeset
|
310 if shouldprint(ui) and not ui.debugflag and not ui.quiet: |
11555
d8d0fc3988ca
color/progress: subclass ui instead of using wrapfunction (issue2096)
Brodie Rao <brodie@bitheap.org>
parents:
11458
diff
changeset
|
311 ui.__class__ = progressui |
10434 | 312 # we instantiate one globally shared progress bar to avoid |
313 # competing progress bars when multiple UI objects get created | |
11555
d8d0fc3988ca
color/progress: subclass ui instead of using wrapfunction (issue2096)
Brodie Rao <brodie@bitheap.org>
parents:
11458
diff
changeset
|
314 if not progressui._progbar: |
14837
ec4ba216ddef
progress: make progress bar a singleton to avoid double-progress ui bugs
Augie Fackler <durin42@gmail.com>
parents:
14836
diff
changeset
|
315 if _singleton is None: |
ec4ba216ddef
progress: make progress bar a singleton to avoid double-progress ui bugs
Augie Fackler <durin42@gmail.com>
parents:
14836
diff
changeset
|
316 _singleton = progbar(ui) |
ec4ba216ddef
progress: make progress bar a singleton to avoid double-progress ui bugs
Augie Fackler <durin42@gmail.com>
parents:
14836
diff
changeset
|
317 progressui._progbar = _singleton |
10434 | 318 |
319 def reposetup(ui, repo): | |
320 uisetup(repo.ui) |