Mercurial > hg
annotate hgext/progress.py @ 13369:69238d0ca60f stable
mq: catch attempt to qpush to an earlier patch (issue2587)
We can't assume that all pushable patches early in the series have already been
applied. If a hg qselect is done while you already have patches applied, some
patches with guards may now be pushable, even though they come earlier in the
series.
So instead of checking only applied patches, explicitly check where we are in
the series against the position of the patch we want to qpush to.
author | Afuna <afunamatata@gmail.com> |
---|---|
date | Sat, 12 Feb 2011 16:08:41 +0800 |
parents | c52c629ce19e |
children | f139f34ba330 |
rev | line source |
---|---|
10434 | 1 # progress.py show progress bars for some actions |
2 # | |
3 # Copyright (C) 2010 Augie Fackler <durin42@gmail.com> | |
4 # | |
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 | |
7 # Free Software Foundation; either version 2 of the License, or (at your | |
8 # option) any later version. | |
9 # | |
10 # This program is distributed in the hope that it will be useful, but | |
11 # WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General | |
13 # Public License for more details. | |
14 # | |
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., | |
17 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 | |
19 """show progress bars for some actions | |
20 | |
10450 | 21 This extension uses the progress information logged by hg commands |
22 to draw progress bars that are as informative as possible. Some progress | |
10434 | 23 bars only offer indeterminate information, while others have a definite |
24 end point. | |
25 | |
26 The following settings are available:: | |
27 | |
28 [progress] | |
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 | |
31 format = topic bar number # format of the progress bar | |
32 width = <none> # if set, the maximum width of the progress information | |
33 # (that is, min(width, term width) will be used) | |
34 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
|
35 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
|
36 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
|
37 # disable is given |
10434 | 38 |
10471
132eb7128ad5
progress: use inline literals in help string
Martin Geisler <mg@lazybytes.net>
parents:
10464
diff
changeset
|
39 Valid entries for the format field are topic, bar, number, unit, and |
132eb7128ad5
progress: use inline literals in help string
Martin Geisler <mg@lazybytes.net>
parents:
10464
diff
changeset
|
40 item. item defaults to the last 20 characters of the item, but this |
132eb7128ad5
progress: use inline literals in help string
Martin Geisler <mg@lazybytes.net>
parents:
10464
diff
changeset
|
41 can be changed by adding either ``-<num>`` which would take the last |
132eb7128ad5
progress: use inline literals in help string
Martin Geisler <mg@lazybytes.net>
parents:
10464
diff
changeset
|
42 num characters, or ``+<num>`` for the first num characters. |
10434 | 43 """ |
44 | |
45 import sys | |
46 import time | |
47 | |
48 from mercurial import util | |
49 | |
50 def spacejoin(*args): | |
10452
59f8fff4f887
progress: simplify spacejoin()
Brodie Rao <me+hg@dackz.net>
parents:
10450
diff
changeset
|
51 return ' '.join(s for s in args if s) |
10434 | 52 |
11458
ec21d91c79b3
progress: check stderr.isatty() before each print
Augie Fackler <durin42@gmail.com>
parents:
10891
diff
changeset
|
53 def shouldprint(ui): |
12654
646eb9337c87
progress: make sure stderr has isatty before calling (issue2191)
Augie Fackler <durin42@gmail.com>
parents:
11555
diff
changeset
|
54 return (getattr(sys.stderr, 'isatty', None) and |
646eb9337c87
progress: make sure stderr has isatty before calling (issue2191)
Augie Fackler <durin42@gmail.com>
parents:
11555
diff
changeset
|
55 (sys.stderr.isatty() or ui.configbool('progress', 'assume-tty'))) |
11458
ec21d91c79b3
progress: check stderr.isatty() before each print
Augie Fackler <durin42@gmail.com>
parents:
10891
diff
changeset
|
56 |
10434 | 57 class progbar(object): |
58 def __init__(self, ui): | |
59 self.ui = ui | |
60 self.resetstate() | |
61 | |
62 def resetstate(self): | |
63 self.topics = [] | |
64 self.printed = False | |
65 self.lastprint = time.time() + float(self.ui.config( | |
66 'progress', 'delay', default=3)) | |
67 self.indetcount = 0 | |
68 self.refresh = float(self.ui.config( | |
69 'progress', 'refresh', default=0.1)) | |
70 self.order = self.ui.configlist( | |
71 'progress', 'format', | |
72 default=['topic', 'bar', 'number']) | |
73 | |
74 def show(self, topic, pos, item, unit, total): | |
11458
ec21d91c79b3
progress: check stderr.isatty() before each print
Augie Fackler <durin42@gmail.com>
parents:
10891
diff
changeset
|
75 if not shouldprint(self.ui): |
ec21d91c79b3
progress: check stderr.isatty() before each print
Augie Fackler <durin42@gmail.com>
parents:
10891
diff
changeset
|
76 return |
10434 | 77 termwidth = self.width() |
78 self.printed = True | |
79 head = '' | |
80 needprogress = False | |
81 tail = '' | |
82 for indicator in self.order: | |
83 add = '' | |
84 if indicator == 'topic': | |
85 add = topic | |
86 elif indicator == 'number': | |
87 if total: | |
88 add = ('% ' + str(len(str(total))) + | |
89 's/%s') % (pos, total) | |
90 else: | |
91 add = str(pos) | |
92 elif indicator.startswith('item') and item: | |
93 slice = 'end' | |
94 if '-' in indicator: | |
95 wid = int(indicator.split('-')[1]) | |
96 elif '+' in indicator: | |
97 slice = 'beginning' | |
98 wid = int(indicator.split('+')[1]) | |
99 else: | |
100 wid = 20 | |
101 if slice == 'end': | |
102 add = item[-wid:] | |
103 else: | |
104 add = item[:wid] | |
105 add += (wid - len(add)) * ' ' | |
106 elif indicator == 'bar': | |
107 add = '' | |
108 needprogress = True | |
109 elif indicator == 'unit' and unit: | |
110 add = unit | |
111 if not needprogress: | |
112 head = spacejoin(head, add) | |
113 else: | |
114 tail = spacejoin(add, tail) | |
115 if needprogress: | |
116 used = 0 | |
117 if head: | |
118 used += len(head) + 1 | |
119 if tail: | |
120 used += len(tail) + 1 | |
121 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
|
122 if total and pos <= total: |
10434 | 123 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
|
124 bar = '=' * (amt - 1) |
7edc649f9f7e
progress: make determinate bar more like wget progress bar
Brodie Rao <me+hg@dackz.net>
parents:
10452
diff
changeset
|
125 if amt > 0: |
7edc649f9f7e
progress: make determinate bar more like wget progress bar
Brodie Rao <me+hg@dackz.net>
parents:
10452
diff
changeset
|
126 bar += '>' |
7edc649f9f7e
progress: make determinate bar more like wget progress bar
Brodie Rao <me+hg@dackz.net>
parents:
10452
diff
changeset
|
127 bar += ' ' * (progwidth - amt) |
10434 | 128 else: |
129 progwidth -= 3 | |
130 self.indetcount += 1 | |
131 # mod the count by twice the width so we can make the | |
132 # cursor bounce between the right and left sides | |
133 amt = self.indetcount % (2 * progwidth) | |
134 amt -= progwidth | |
135 bar = (' ' * int(progwidth - abs(amt)) + '<=>' + | |
136 ' ' * int(abs(amt))) | |
137 prog = ''.join(('[', bar , ']')) | |
138 out = spacejoin(head, prog, tail) | |
139 else: | |
140 out = spacejoin(head, tail) | |
10788
ca6ba6cac6cd
progress: use stderr instead of stdout; check stderr.isatty()
Augie Fackler <durin42@gmail.com>
parents:
10656
diff
changeset
|
141 sys.stderr.write('\r' + out[:termwidth]) |
ca6ba6cac6cd
progress: use stderr instead of stdout; check stderr.isatty()
Augie Fackler <durin42@gmail.com>
parents:
10656
diff
changeset
|
142 sys.stderr.flush() |
10434 | 143 |
144 def clear(self): | |
11458
ec21d91c79b3
progress: check stderr.isatty() before each print
Augie Fackler <durin42@gmail.com>
parents:
10891
diff
changeset
|
145 if not shouldprint(self.ui): |
ec21d91c79b3
progress: check stderr.isatty() before each print
Augie Fackler <durin42@gmail.com>
parents:
10891
diff
changeset
|
146 return |
10788
ca6ba6cac6cd
progress: use stderr instead of stdout; check stderr.isatty()
Augie Fackler <durin42@gmail.com>
parents:
10656
diff
changeset
|
147 sys.stderr.write('\r%s\r' % (' ' * self.width())) |
10434 | 148 |
10439
509f4ed56509
progress: correctly handle empty progress topic
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10434
diff
changeset
|
149 def complete(self): |
11458
ec21d91c79b3
progress: check stderr.isatty() before each print
Augie Fackler <durin42@gmail.com>
parents:
10891
diff
changeset
|
150 if not shouldprint(self.ui): |
ec21d91c79b3
progress: check stderr.isatty() before each print
Augie Fackler <durin42@gmail.com>
parents:
10891
diff
changeset
|
151 return |
10439
509f4ed56509
progress: correctly handle empty progress topic
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10434
diff
changeset
|
152 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
|
153 self.clear() |
509f4ed56509
progress: correctly handle empty progress topic
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10434
diff
changeset
|
154 else: |
10788
ca6ba6cac6cd
progress: use stderr instead of stdout; check stderr.isatty()
Augie Fackler <durin42@gmail.com>
parents:
10656
diff
changeset
|
155 sys.stderr.write('\n') |
ca6ba6cac6cd
progress: use stderr instead of stdout; check stderr.isatty()
Augie Fackler <durin42@gmail.com>
parents:
10656
diff
changeset
|
156 sys.stderr.flush() |
10439
509f4ed56509
progress: correctly handle empty progress topic
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10434
diff
changeset
|
157 |
10434 | 158 def width(self): |
12689
c52c629ce19e
termwidth: move to ui.ui from util
Augie Fackler <durin42@gmail.com>
parents:
12654
diff
changeset
|
159 tw = self.ui.termwidth() |
10434 | 160 return min(int(self.ui.config('progress', 'width', default=tw)), tw) |
161 | |
11555
d8d0fc3988ca
color/progress: subclass ui instead of using wrapfunction (issue2096)
Brodie Rao <brodie@bitheap.org>
parents:
11458
diff
changeset
|
162 def progress(self, topic, pos, item='', unit='', total=None): |
10439
509f4ed56509
progress: correctly handle empty progress topic
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10434
diff
changeset
|
163 if pos is None: |
509f4ed56509
progress: correctly handle empty progress topic
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10434
diff
changeset
|
164 if self.topics and self.topics[-1] == topic and self.printed: |
509f4ed56509
progress: correctly handle empty progress topic
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10434
diff
changeset
|
165 self.complete() |
10441
dc0d1ca2d378
progress: only reset state if finishing progress for the current topic
Augie Fackler <durin42@gmail.com>
parents:
10439
diff
changeset
|
166 self.resetstate() |
10439
509f4ed56509
progress: correctly handle empty progress topic
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10434
diff
changeset
|
167 else: |
509f4ed56509
progress: correctly handle empty progress topic
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10434
diff
changeset
|
168 if topic not in self.topics: |
509f4ed56509
progress: correctly handle empty progress topic
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10434
diff
changeset
|
169 self.topics.append(topic) |
509f4ed56509
progress: correctly handle empty progress topic
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10434
diff
changeset
|
170 now = time.time() |
10464
149ad0a3ec91
progress: make progress.refresh=0 always display the progress line
Patrick Mezard <pmezard@gmail.com>
parents:
10463
diff
changeset
|
171 if (now - self.lastprint >= self.refresh |
149ad0a3ec91
progress: make progress.refresh=0 always display the progress line
Patrick Mezard <pmezard@gmail.com>
parents:
10463
diff
changeset
|
172 and topic == self.topics[-1]): |
10439
509f4ed56509
progress: correctly handle empty progress topic
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10434
diff
changeset
|
173 self.lastprint = now |
509f4ed56509
progress: correctly handle empty progress topic
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10434
diff
changeset
|
174 self.show(topic, pos, item, unit, total) |
10434 | 175 |
176 def uisetup(ui): | |
11555
d8d0fc3988ca
color/progress: subclass ui instead of using wrapfunction (issue2096)
Brodie Rao <brodie@bitheap.org>
parents:
11458
diff
changeset
|
177 class progressui(ui.__class__): |
d8d0fc3988ca
color/progress: subclass ui instead of using wrapfunction (issue2096)
Brodie Rao <brodie@bitheap.org>
parents:
11458
diff
changeset
|
178 _progbar = None |
d8d0fc3988ca
color/progress: subclass ui instead of using wrapfunction (issue2096)
Brodie Rao <brodie@bitheap.org>
parents:
11458
diff
changeset
|
179 |
d8d0fc3988ca
color/progress: subclass ui instead of using wrapfunction (issue2096)
Brodie Rao <brodie@bitheap.org>
parents:
11458
diff
changeset
|
180 def progress(self, *args, **opts): |
d8d0fc3988ca
color/progress: subclass ui instead of using wrapfunction (issue2096)
Brodie Rao <brodie@bitheap.org>
parents:
11458
diff
changeset
|
181 self._progbar.progress(*args, **opts) |
d8d0fc3988ca
color/progress: subclass ui instead of using wrapfunction (issue2096)
Brodie Rao <brodie@bitheap.org>
parents:
11458
diff
changeset
|
182 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
|
183 |
d8d0fc3988ca
color/progress: subclass ui instead of using wrapfunction (issue2096)
Brodie Rao <brodie@bitheap.org>
parents:
11458
diff
changeset
|
184 def write(self, *args, **opts): |
d8d0fc3988ca
color/progress: subclass ui instead of using wrapfunction (issue2096)
Brodie Rao <brodie@bitheap.org>
parents:
11458
diff
changeset
|
185 if self._progbar.printed: |
d8d0fc3988ca
color/progress: subclass ui instead of using wrapfunction (issue2096)
Brodie Rao <brodie@bitheap.org>
parents:
11458
diff
changeset
|
186 self._progbar.clear() |
d8d0fc3988ca
color/progress: subclass ui instead of using wrapfunction (issue2096)
Brodie Rao <brodie@bitheap.org>
parents:
11458
diff
changeset
|
187 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
|
188 |
d8d0fc3988ca
color/progress: subclass ui instead of using wrapfunction (issue2096)
Brodie Rao <brodie@bitheap.org>
parents:
11458
diff
changeset
|
189 def write_err(self, *args, **opts): |
d8d0fc3988ca
color/progress: subclass ui instead of using wrapfunction (issue2096)
Brodie Rao <brodie@bitheap.org>
parents:
11458
diff
changeset
|
190 if self._progbar.printed: |
d8d0fc3988ca
color/progress: subclass ui instead of using wrapfunction (issue2096)
Brodie Rao <brodie@bitheap.org>
parents:
11458
diff
changeset
|
191 self._progbar.clear() |
d8d0fc3988ca
color/progress: subclass ui instead of using wrapfunction (issue2096)
Brodie Rao <brodie@bitheap.org>
parents:
11458
diff
changeset
|
192 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
|
193 |
10540
dd9d057465c1
progress: provide an explicit disable method for developers
Steve Borho <steve@borho.org>
parents:
10523
diff
changeset
|
194 # 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
|
195 # 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
|
196 if ui.configbool('progress', 'disable'): |
dd9d057465c1
progress: provide an explicit disable method for developers
Steve Borho <steve@borho.org>
parents:
10523
diff
changeset
|
197 return |
11458
ec21d91c79b3
progress: check stderr.isatty() before each print
Augie Fackler <durin42@gmail.com>
parents:
10891
diff
changeset
|
198 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
|
199 ui.__class__ = progressui |
10434 | 200 # we instantiate one globally shared progress bar to avoid |
201 # 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
|
202 if not progressui._progbar: |
d8d0fc3988ca
color/progress: subclass ui instead of using wrapfunction (issue2096)
Brodie Rao <brodie@bitheap.org>
parents:
11458
diff
changeset
|
203 progressui._progbar = progbar(ui) |
10434 | 204 |
205 def reposetup(ui, repo): | |
206 uisetup(repo.ui) |