Mercurial > hg
annotate hgext/progress.py @ 18993:0fd0612dc855
annotate: increase refcount of each revisions correctly (issue3841)
Before this patch, refcount (managed in "needed") of parents of each
revisions in "visit" is increased, only when parent is not annotated
yet (examined by "p not in hist").
But this causes less refcount of the revision like "A" in the tree
below ("A" is assumed as the second parent of "C"):
A --- B --- C
\ /
\-----/
Steps of annotation for "C" in this case are shown below:
1. for "C"
1.1 increase refcount of "B"
1.2 increase refcount of "A" (=> 1)
1.3 defer annotation for "C"
2. for "A"
2.1 annotate for "A" (=> put result into "hist[A]")
2.2 clear "pcache[A]" ("pcache[A] = []")
3. for "B"
3.1 not increase refcount of "A", because "A not in hist" is False
3.2 annotate for "B"
3.3 decrease refcount of "A" (=> 0)
3.4 delete "hist[A]", even though "A" is still needed by "C"
3.5 clear "pcache[B]"
4. for "C", again
4.1 not increase refcount of "B", because "B not in hist" is False
4.2 increase refcount of "A" (=> 1)
4.3 defer annotation for "C"
5. for "A", again
5.1 annotate for "A" (=> put result into "hist[A]", again)
5.2 clear "pcache[A]"
6. for "C", once again
6.1 not increase refcount of "B", because "B not in hist" is False
6.2 not increase refcount of "A", because "A not in hist" is False
6.3 annotate for "C"
6.4 decrease refcount of "A", and delete "hist[A]"
6.5 decrease refcount of "B", and delete "hist[B]"
6.6 clear "pcache[C]"
At step (5.1), annotation for "A" mis-recognizes that all lines are
created at "A", because "pcache[A]" already cleared at step (2.2)
prevents from scanning ancestors of "A".
So, annotation for "C" or its descendants loses information about "A"
or its ancestors.
The root cause of this problem is that refcount of "A" is decreased at
step (3.3), even though it isn't increased at step (3.1).
To increase refcount correctly, this patch increases refcount of each
parents of each revisions:
- regardless of "p not in hist" or not, and
- only once for each revisions in "visit" (by "not pcached")
In fact, this problem should occur only on legacy repositories in
which a filelog includes the merging between the revision and its
ancestor (as the second parent), because:
- tree is scanned in depth-first
without such merging, revisions in "visit" refer different
revisions as parent each other
- recent Mercurial doesn't allow such merging
changelog and manifest can include such merging someway, but
filelogs can't, because "localrepository._filecommit()" converts
such merging request to linear history.
This patch tests merging cases below: these cases are from filelog of
"mercurial/commands.py" in the repository of Mercurial itself.
- both parents are same
10 --- 11 --- 12
\_/
filelogrev: changesetid:
10 00ea3613f82c
11 fc4a6e5b5812
12 4f802588cdfb
- the second parent is also ancestor of the first one
37 --- 38 --- 39 --- 40
\________/
filelogrev: changesetid:
37 f8d56da6ac8f
38 38919e1c254d
39 d3400605d246
40 f06a4a3b86a7
author | FUJIWARA Katsunori <foozy@lares.dti.ne.jp> |
---|---|
date | Fri, 29 Mar 2013 22:57:16 +0900 |
parents | 9cca7b70f8df |
children | b4744c3b991e |
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 | |
40 | |
13131
c9ae7e096994
progress: Add estimated time remaining for long tasks
timeless <timeless@gmail.com>
parents:
13130
diff
changeset
|
41 from mercurial.i18n import _ |
16743
38caf405d010
hgext: mark all first-party extensions as such
Augie Fackler <raf@durin42.com>
parents:
16676
diff
changeset
|
42 testedwith = 'internal' |
10434 | 43 |
44 def spacejoin(*args): | |
10452
59f8fff4f887
progress: simplify spacejoin()
Brodie Rao <me+hg@dackz.net>
parents:
10450
diff
changeset
|
45 return ' '.join(s for s in args if s) |
10434 | 46 |
11458
ec21d91c79b3
progress: check stderr.isatty() before each print
Augie Fackler <durin42@gmail.com>
parents:
10891
diff
changeset
|
47 def shouldprint(ui): |
16753 | 48 return ui._isatty(sys.stderr) or ui.configbool('progress', 'assume-tty') |
11458
ec21d91c79b3
progress: check stderr.isatty() before each print
Augie Fackler <durin42@gmail.com>
parents:
10891
diff
changeset
|
49 |
13132
24e3349cba8e
progress: refactor for readability and show XXs instead of 0mXXs.
Augie Fackler <durin42@gmail.com>
parents:
13131
diff
changeset
|
50 def fmtremaining(seconds): |
24e3349cba8e
progress: refactor for readability and show XXs instead of 0mXXs.
Augie Fackler <durin42@gmail.com>
parents:
13131
diff
changeset
|
51 if seconds < 60: |
13139
f4dd6aa16805
progress: explain format strings to translators
Martin Geisler <mg@aragost.com>
parents:
13132
diff
changeset
|
52 # 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
|
53 return _("%02ds") % (seconds) |
24e3349cba8e
progress: refactor for readability and show XXs instead of 0mXXs.
Augie Fackler <durin42@gmail.com>
parents:
13131
diff
changeset
|
54 minutes = seconds // 60 |
24e3349cba8e
progress: refactor for readability and show XXs instead of 0mXXs.
Augie Fackler <durin42@gmail.com>
parents:
13131
diff
changeset
|
55 if minutes < 60: |
24e3349cba8e
progress: refactor for readability and show XXs instead of 0mXXs.
Augie Fackler <durin42@gmail.com>
parents:
13131
diff
changeset
|
56 seconds -= minutes * 60 |
13139
f4dd6aa16805
progress: explain format strings to translators
Martin Geisler <mg@aragost.com>
parents:
13132
diff
changeset
|
57 # 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
|
58 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
|
59 # 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
|
60 minutes += 1 |
24e3349cba8e
progress: refactor for readability and show XXs instead of 0mXXs.
Augie Fackler <durin42@gmail.com>
parents:
13131
diff
changeset
|
61 hours = minutes // 60 |
24e3349cba8e
progress: refactor for readability and show XXs instead of 0mXXs.
Augie Fackler <durin42@gmail.com>
parents:
13131
diff
changeset
|
62 minutes -= hours * 60 |
13236
3f299f5d9a29
progress: handle days, weeks and years
timeless <timeless@gmail.com>
parents:
13154
diff
changeset
|
63 if hours < 30: |
3f299f5d9a29
progress: handle days, weeks and years
timeless <timeless@gmail.com>
parents:
13154
diff
changeset
|
64 # i18n: format X hours and YY minutes as "XhYYm" |
3f299f5d9a29
progress: handle days, weeks and years
timeless <timeless@gmail.com>
parents:
13154
diff
changeset
|
65 return _("%dh%02dm") % (hours, minutes) |
3f299f5d9a29
progress: handle days, weeks and years
timeless <timeless@gmail.com>
parents:
13154
diff
changeset
|
66 # we're going to ignore minutes in this case |
3f299f5d9a29
progress: handle days, weeks and years
timeless <timeless@gmail.com>
parents:
13154
diff
changeset
|
67 hours += 1 |
3f299f5d9a29
progress: handle days, weeks and years
timeless <timeless@gmail.com>
parents:
13154
diff
changeset
|
68 days = hours // 24 |
3f299f5d9a29
progress: handle days, weeks and years
timeless <timeless@gmail.com>
parents:
13154
diff
changeset
|
69 hours -= days * 24 |
3f299f5d9a29
progress: handle days, weeks and years
timeless <timeless@gmail.com>
parents:
13154
diff
changeset
|
70 if days < 15: |
3f299f5d9a29
progress: handle days, weeks and years
timeless <timeless@gmail.com>
parents:
13154
diff
changeset
|
71 # i18n: format X days and YY hours as "XdYYh" |
3f299f5d9a29
progress: handle days, weeks and years
timeless <timeless@gmail.com>
parents:
13154
diff
changeset
|
72 return _("%dd%02dh") % (days, hours) |
3f299f5d9a29
progress: handle days, weeks and years
timeless <timeless@gmail.com>
parents:
13154
diff
changeset
|
73 # we're going to ignore hours in this case |
3f299f5d9a29
progress: handle days, weeks and years
timeless <timeless@gmail.com>
parents:
13154
diff
changeset
|
74 days += 1 |
3f299f5d9a29
progress: handle days, weeks and years
timeless <timeless@gmail.com>
parents:
13154
diff
changeset
|
75 weeks = days // 7 |
3f299f5d9a29
progress: handle days, weeks and years
timeless <timeless@gmail.com>
parents:
13154
diff
changeset
|
76 days -= weeks * 7 |
3f299f5d9a29
progress: handle days, weeks and years
timeless <timeless@gmail.com>
parents:
13154
diff
changeset
|
77 if weeks < 55: |
3f299f5d9a29
progress: handle days, weeks and years
timeless <timeless@gmail.com>
parents:
13154
diff
changeset
|
78 # i18n: format X weeks and YY days as "XwYYd" |
3f299f5d9a29
progress: handle days, weeks and years
timeless <timeless@gmail.com>
parents:
13154
diff
changeset
|
79 return _("%dw%02dd") % (weeks, days) |
3f299f5d9a29
progress: handle days, weeks and years
timeless <timeless@gmail.com>
parents:
13154
diff
changeset
|
80 # 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
|
81 weeks += 1 |
3f299f5d9a29
progress: handle days, weeks and years
timeless <timeless@gmail.com>
parents:
13154
diff
changeset
|
82 years = weeks // 52 |
3f299f5d9a29
progress: handle days, weeks and years
timeless <timeless@gmail.com>
parents:
13154
diff
changeset
|
83 weeks -= years * 52 |
3f299f5d9a29
progress: handle days, weeks and years
timeless <timeless@gmail.com>
parents:
13154
diff
changeset
|
84 # i18n: format X years and YY weeks as "XyYYw" |
3f299f5d9a29
progress: handle days, weeks and years
timeless <timeless@gmail.com>
parents:
13154
diff
changeset
|
85 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
|
86 |
10434 | 87 class progbar(object): |
88 def __init__(self, ui): | |
89 self.ui = ui | |
90 self.resetstate() | |
91 | |
92 def resetstate(self): | |
93 self.topics = [] | |
13130
f139f34ba330
progress: react more reasonably to nested progress topics
Augie Fackler <durin42@gmail.com>
parents:
12689
diff
changeset
|
94 self.topicstates = {} |
13131
c9ae7e096994
progress: Add estimated time remaining for long tasks
timeless <timeless@gmail.com>
parents:
13130
diff
changeset
|
95 self.starttimes = {} |
c9ae7e096994
progress: Add estimated time remaining for long tasks
timeless <timeless@gmail.com>
parents:
13130
diff
changeset
|
96 self.startvals = {} |
10434 | 97 self.printed = False |
98 self.lastprint = time.time() + float(self.ui.config( | |
99 'progress', 'delay', default=3)) | |
14838
5d261fd00446
progress: add a changedelay to prevent parallel topics from flapping (issue2698)
Augie Fackler <durin42@gmail.com>
parents:
14837
diff
changeset
|
100 self.lasttopic = None |
10434 | 101 self.indetcount = 0 |
102 self.refresh = float(self.ui.config( | |
103 '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
|
104 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
|
105 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
|
106 'progress', 'changedelay', default=1))) |
10434 | 107 self.order = self.ui.configlist( |
108 'progress', 'format', | |
13148
ab5fcc473fd1
progress: include time estimate as part of the default progress format
Augie Fackler <durin42@gmail.com>
parents:
13147
diff
changeset
|
109 default=['topic', 'bar', 'number', 'estimate']) |
10434 | 110 |
13131
c9ae7e096994
progress: Add estimated time remaining for long tasks
timeless <timeless@gmail.com>
parents:
13130
diff
changeset
|
111 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
|
112 if not shouldprint(self.ui): |
ec21d91c79b3
progress: check stderr.isatty() before each print
Augie Fackler <durin42@gmail.com>
parents:
10891
diff
changeset
|
113 return |
10434 | 114 termwidth = self.width() |
115 self.printed = True | |
116 head = '' | |
117 needprogress = False | |
118 tail = '' | |
119 for indicator in self.order: | |
120 add = '' | |
121 if indicator == 'topic': | |
122 add = topic | |
123 elif indicator == 'number': | |
124 if total: | |
125 add = ('% ' + str(len(str(total))) + | |
126 's/%s') % (pos, total) | |
127 else: | |
128 add = str(pos) | |
129 elif indicator.startswith('item') and item: | |
130 slice = 'end' | |
131 if '-' in indicator: | |
132 wid = int(indicator.split('-')[1]) | |
133 elif '+' in indicator: | |
134 slice = 'beginning' | |
135 wid = int(indicator.split('+')[1]) | |
136 else: | |
137 wid = 20 | |
138 if slice == 'end': | |
139 add = item[-wid:] | |
140 else: | |
141 add = item[:wid] | |
142 add += (wid - len(add)) * ' ' | |
143 elif indicator == 'bar': | |
144 add = '' | |
145 needprogress = True | |
146 elif indicator == 'unit' and unit: | |
147 add = unit | |
13147
082f5be788d9
progress: only show time estimate when progress format contains 'estimate'
Augie Fackler <durin42@gmail.com>
parents:
13146
diff
changeset
|
148 elif indicator == 'estimate': |
082f5be788d9
progress: only show time estimate when progress format contains 'estimate'
Augie Fackler <durin42@gmail.com>
parents:
13146
diff
changeset
|
149 add = self.estimate(topic, pos, total, now) |
14280
98e4d3914c2e
progress: add speed format
Martin Geisler <mg@aragost.com>
parents:
14247
diff
changeset
|
150 elif indicator == 'speed': |
98e4d3914c2e
progress: add speed format
Martin Geisler <mg@aragost.com>
parents:
14247
diff
changeset
|
151 add = self.speed(topic, pos, unit, now) |
10434 | 152 if not needprogress: |
153 head = spacejoin(head, add) | |
154 else: | |
13146
43575c67add3
progress: fix adding format elements after the progress bar
Augie Fackler <durin42@gmail.com>
parents:
13139
diff
changeset
|
155 tail = spacejoin(tail, add) |
10434 | 156 if needprogress: |
157 used = 0 | |
158 if head: | |
159 used += len(head) + 1 | |
160 if tail: | |
161 used += len(tail) + 1 | |
162 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
|
163 if total and pos <= total: |
10434 | 164 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
|
165 bar = '=' * (amt - 1) |
7edc649f9f7e
progress: make determinate bar more like wget progress bar
Brodie Rao <me+hg@dackz.net>
parents:
10452
diff
changeset
|
166 if amt > 0: |
7edc649f9f7e
progress: make determinate bar more like wget progress bar
Brodie Rao <me+hg@dackz.net>
parents:
10452
diff
changeset
|
167 bar += '>' |
7edc649f9f7e
progress: make determinate bar more like wget progress bar
Brodie Rao <me+hg@dackz.net>
parents:
10452
diff
changeset
|
168 bar += ' ' * (progwidth - amt) |
10434 | 169 else: |
170 progwidth -= 3 | |
171 self.indetcount += 1 | |
172 # mod the count by twice the width so we can make the | |
173 # cursor bounce between the right and left sides | |
174 amt = self.indetcount % (2 * progwidth) | |
175 amt -= progwidth | |
176 bar = (' ' * int(progwidth - abs(amt)) + '<=>' + | |
177 ' ' * int(abs(amt))) | |
178 prog = ''.join(('[', bar , ']')) | |
179 out = spacejoin(head, prog, tail) | |
180 else: | |
181 out = spacejoin(head, tail) | |
10788
ca6ba6cac6cd
progress: use stderr instead of stdout; check stderr.isatty()
Augie Fackler <durin42@gmail.com>
parents:
10656
diff
changeset
|
182 sys.stderr.write('\r' + out[:termwidth]) |
14838
5d261fd00446
progress: add a changedelay to prevent parallel topics from flapping (issue2698)
Augie Fackler <durin42@gmail.com>
parents:
14837
diff
changeset
|
183 self.lasttopic = topic |
10788
ca6ba6cac6cd
progress: use stderr instead of stdout; check stderr.isatty()
Augie Fackler <durin42@gmail.com>
parents:
10656
diff
changeset
|
184 sys.stderr.flush() |
10434 | 185 |
186 def clear(self): | |
11458
ec21d91c79b3
progress: check stderr.isatty() before each print
Augie Fackler <durin42@gmail.com>
parents:
10891
diff
changeset
|
187 if not shouldprint(self.ui): |
ec21d91c79b3
progress: check stderr.isatty() before each print
Augie Fackler <durin42@gmail.com>
parents:
10891
diff
changeset
|
188 return |
10788
ca6ba6cac6cd
progress: use stderr instead of stdout; check stderr.isatty()
Augie Fackler <durin42@gmail.com>
parents:
10656
diff
changeset
|
189 sys.stderr.write('\r%s\r' % (' ' * self.width())) |
10434 | 190 |
10439
509f4ed56509
progress: correctly handle empty progress topic
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10434
diff
changeset
|
191 def complete(self): |
11458
ec21d91c79b3
progress: check stderr.isatty() before each print
Augie Fackler <durin42@gmail.com>
parents:
10891
diff
changeset
|
192 if not shouldprint(self.ui): |
ec21d91c79b3
progress: check stderr.isatty() before each print
Augie Fackler <durin42@gmail.com>
parents:
10891
diff
changeset
|
193 return |
10439
509f4ed56509
progress: correctly handle empty progress topic
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10434
diff
changeset
|
194 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
|
195 self.clear() |
509f4ed56509
progress: correctly handle empty progress topic
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10434
diff
changeset
|
196 else: |
10788
ca6ba6cac6cd
progress: use stderr instead of stdout; check stderr.isatty()
Augie Fackler <durin42@gmail.com>
parents:
10656
diff
changeset
|
197 sys.stderr.write('\n') |
ca6ba6cac6cd
progress: use stderr instead of stdout; check stderr.isatty()
Augie Fackler <durin42@gmail.com>
parents:
10656
diff
changeset
|
198 sys.stderr.flush() |
10439
509f4ed56509
progress: correctly handle empty progress topic
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10434
diff
changeset
|
199 |
10434 | 200 def width(self): |
12689
c52c629ce19e
termwidth: move to ui.ui from util
Augie Fackler <durin42@gmail.com>
parents:
12654
diff
changeset
|
201 tw = self.ui.termwidth() |
10434 | 202 return min(int(self.ui.config('progress', 'width', default=tw)), tw) |
203 | |
13147
082f5be788d9
progress: only show time estimate when progress format contains 'estimate'
Augie Fackler <durin42@gmail.com>
parents:
13146
diff
changeset
|
204 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
|
205 if total is None: |
e11c14f14491
progress: don't compute estimate without a total
Augie Fackler <durin42@gmail.com>
parents:
13148
diff
changeset
|
206 return '' |
13147
082f5be788d9
progress: only show time estimate when progress format contains 'estimate'
Augie Fackler <durin42@gmail.com>
parents:
13146
diff
changeset
|
207 initialpos = self.startvals[topic] |
082f5be788d9
progress: only show time estimate when progress format contains 'estimate'
Augie Fackler <durin42@gmail.com>
parents:
13146
diff
changeset
|
208 target = total - initialpos |
082f5be788d9
progress: only show time estimate when progress format contains 'estimate'
Augie Fackler <durin42@gmail.com>
parents:
13146
diff
changeset
|
209 delta = pos - initialpos |
082f5be788d9
progress: only show time estimate when progress format contains 'estimate'
Augie Fackler <durin42@gmail.com>
parents:
13146
diff
changeset
|
210 if delta > 0: |
082f5be788d9
progress: only show time estimate when progress format contains 'estimate'
Augie Fackler <durin42@gmail.com>
parents:
13146
diff
changeset
|
211 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
|
212 if elapsed > float( |
082f5be788d9
progress: only show time estimate when progress format contains 'estimate'
Augie Fackler <durin42@gmail.com>
parents:
13146
diff
changeset
|
213 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
|
214 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
|
215 return fmtremaining(seconds) |
082f5be788d9
progress: only show time estimate when progress format contains 'estimate'
Augie Fackler <durin42@gmail.com>
parents:
13146
diff
changeset
|
216 return '' |
082f5be788d9
progress: only show time estimate when progress format contains 'estimate'
Augie Fackler <durin42@gmail.com>
parents:
13146
diff
changeset
|
217 |
14280
98e4d3914c2e
progress: add speed format
Martin Geisler <mg@aragost.com>
parents:
14247
diff
changeset
|
218 def speed(self, topic, pos, unit, now): |
98e4d3914c2e
progress: add speed format
Martin Geisler <mg@aragost.com>
parents:
14247
diff
changeset
|
219 initialpos = self.startvals[topic] |
98e4d3914c2e
progress: add speed format
Martin Geisler <mg@aragost.com>
parents:
14247
diff
changeset
|
220 delta = pos - initialpos |
98e4d3914c2e
progress: add speed format
Martin Geisler <mg@aragost.com>
parents:
14247
diff
changeset
|
221 elapsed = now - self.starttimes[topic] |
98e4d3914c2e
progress: add speed format
Martin Geisler <mg@aragost.com>
parents:
14247
diff
changeset
|
222 if elapsed > float( |
98e4d3914c2e
progress: add speed format
Martin Geisler <mg@aragost.com>
parents:
14247
diff
changeset
|
223 self.ui.config('progress', 'estimate', default=2)): |
98e4d3914c2e
progress: add speed format
Martin Geisler <mg@aragost.com>
parents:
14247
diff
changeset
|
224 return _('%d %s/sec') % (delta / elapsed, unit) |
98e4d3914c2e
progress: add speed format
Martin Geisler <mg@aragost.com>
parents:
14247
diff
changeset
|
225 return '' |
98e4d3914c2e
progress: add speed format
Martin Geisler <mg@aragost.com>
parents:
14247
diff
changeset
|
226 |
11555
d8d0fc3988ca
color/progress: subclass ui instead of using wrapfunction (issue2096)
Brodie Rao <brodie@bitheap.org>
parents:
11458
diff
changeset
|
227 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
|
228 now = time.time() |
10439
509f4ed56509
progress: correctly handle empty progress topic
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10434
diff
changeset
|
229 if pos is None: |
13131
c9ae7e096994
progress: Add estimated time remaining for long tasks
timeless <timeless@gmail.com>
parents:
13130
diff
changeset
|
230 self.starttimes.pop(topic, None) |
c9ae7e096994
progress: Add estimated time remaining for long tasks
timeless <timeless@gmail.com>
parents:
13130
diff
changeset
|
231 self.startvals.pop(topic, None) |
13130
f139f34ba330
progress: react more reasonably to nested progress topics
Augie Fackler <durin42@gmail.com>
parents:
12689
diff
changeset
|
232 self.topicstates.pop(topic, None) |
f139f34ba330
progress: react more reasonably to nested progress topics
Augie Fackler <durin42@gmail.com>
parents:
12689
diff
changeset
|
233 # reset the progress bar if this is the outermost topic |
f139f34ba330
progress: react more reasonably to nested progress topics
Augie Fackler <durin42@gmail.com>
parents:
12689
diff
changeset
|
234 if self.topics and self.topics[0] == topic and self.printed: |
10439
509f4ed56509
progress: correctly handle empty progress topic
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10434
diff
changeset
|
235 self.complete() |
10441
dc0d1ca2d378
progress: only reset state if finishing progress for the current topic
Augie Fackler <durin42@gmail.com>
parents:
10439
diff
changeset
|
236 self.resetstate() |
13130
f139f34ba330
progress: react more reasonably to nested progress topics
Augie Fackler <durin42@gmail.com>
parents:
12689
diff
changeset
|
237 # truncate the list of topics assuming all topics within |
f139f34ba330
progress: react more reasonably to nested progress topics
Augie Fackler <durin42@gmail.com>
parents:
12689
diff
changeset
|
238 # this one are also closed |
f139f34ba330
progress: react more reasonably to nested progress topics
Augie Fackler <durin42@gmail.com>
parents:
12689
diff
changeset
|
239 if topic in self.topics: |
16676
654b9e1966f7
progress: fix indentation
Martin Geisler <mg@lazybytes.net>
parents:
15772
diff
changeset
|
240 self.topics = self.topics[:self.topics.index(topic)] |
10439
509f4ed56509
progress: correctly handle empty progress topic
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10434
diff
changeset
|
241 else: |
509f4ed56509
progress: correctly handle empty progress topic
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10434
diff
changeset
|
242 if topic not in self.topics: |
13131
c9ae7e096994
progress: Add estimated time remaining for long tasks
timeless <timeless@gmail.com>
parents:
13130
diff
changeset
|
243 self.starttimes[topic] = now |
c9ae7e096994
progress: Add estimated time remaining for long tasks
timeless <timeless@gmail.com>
parents:
13130
diff
changeset
|
244 self.startvals[topic] = pos |
10439
509f4ed56509
progress: correctly handle empty progress topic
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10434
diff
changeset
|
245 self.topics.append(topic) |
13130
f139f34ba330
progress: react more reasonably to nested progress topics
Augie Fackler <durin42@gmail.com>
parents:
12689
diff
changeset
|
246 self.topicstates[topic] = pos, item, unit, total |
f139f34ba330
progress: react more reasonably to nested progress topics
Augie Fackler <durin42@gmail.com>
parents:
12689
diff
changeset
|
247 if now - self.lastprint >= self.refresh and self.topics: |
14838
5d261fd00446
progress: add a changedelay to prevent parallel topics from flapping (issue2698)
Augie Fackler <durin42@gmail.com>
parents:
14837
diff
changeset
|
248 if (self.lasttopic is None # first time we printed |
5d261fd00446
progress: add a changedelay to prevent parallel topics from flapping (issue2698)
Augie Fackler <durin42@gmail.com>
parents:
14837
diff
changeset
|
249 # not a topic change |
5d261fd00446
progress: add a changedelay to prevent parallel topics from flapping (issue2698)
Augie Fackler <durin42@gmail.com>
parents:
14837
diff
changeset
|
250 or topic == self.lasttopic |
5d261fd00446
progress: add a changedelay to prevent parallel topics from flapping (issue2698)
Augie Fackler <durin42@gmail.com>
parents:
14837
diff
changeset
|
251 # it's been long enough we should print anyway |
5d261fd00446
progress: add a changedelay to prevent parallel topics from flapping (issue2698)
Augie Fackler <durin42@gmail.com>
parents:
14837
diff
changeset
|
252 or now - self.lastprint >= self.changedelay): |
5d261fd00446
progress: add a changedelay to prevent parallel topics from flapping (issue2698)
Augie Fackler <durin42@gmail.com>
parents:
14837
diff
changeset
|
253 self.lastprint = now |
5d261fd00446
progress: add a changedelay to prevent parallel topics from flapping (issue2698)
Augie Fackler <durin42@gmail.com>
parents:
14837
diff
changeset
|
254 self.show(now, topic, *self.topicstates[topic]) |
10434 | 255 |
14837
ec4ba216ddef
progress: make progress bar a singleton to avoid double-progress ui bugs
Augie Fackler <durin42@gmail.com>
parents:
14836
diff
changeset
|
256 _singleton = None |
ec4ba216ddef
progress: make progress bar a singleton to avoid double-progress ui bugs
Augie Fackler <durin42@gmail.com>
parents:
14836
diff
changeset
|
257 |
10434 | 258 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
|
259 global _singleton |
11555
d8d0fc3988ca
color/progress: subclass ui instead of using wrapfunction (issue2096)
Brodie Rao <brodie@bitheap.org>
parents:
11458
diff
changeset
|
260 class progressui(ui.__class__): |
d8d0fc3988ca
color/progress: subclass ui instead of using wrapfunction (issue2096)
Brodie Rao <brodie@bitheap.org>
parents:
11458
diff
changeset
|
261 _progbar = None |
d8d0fc3988ca
color/progress: subclass ui instead of using wrapfunction (issue2096)
Brodie Rao <brodie@bitheap.org>
parents:
11458
diff
changeset
|
262 |
15662
06671371e634
progress: check for ui.quiet and ui.debugflag before we write
David Soria Parra <dsp@php.net>
parents:
14838
diff
changeset
|
263 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
|
264 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
|
265 |
11555
d8d0fc3988ca
color/progress: subclass ui instead of using wrapfunction (issue2096)
Brodie Rao <brodie@bitheap.org>
parents:
11458
diff
changeset
|
266 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
|
267 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
|
268 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
|
269 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
|
270 |
d8d0fc3988ca
color/progress: subclass ui instead of using wrapfunction (issue2096)
Brodie Rao <brodie@bitheap.org>
parents:
11458
diff
changeset
|
271 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
|
272 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
|
273 self._progbar.clear() |
d8d0fc3988ca
color/progress: subclass ui instead of using wrapfunction (issue2096)
Brodie Rao <brodie@bitheap.org>
parents:
11458
diff
changeset
|
274 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
|
275 |
d8d0fc3988ca
color/progress: subclass ui instead of using wrapfunction (issue2096)
Brodie Rao <brodie@bitheap.org>
parents:
11458
diff
changeset
|
276 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
|
277 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
|
278 self._progbar.clear() |
d8d0fc3988ca
color/progress: subclass ui instead of using wrapfunction (issue2096)
Brodie Rao <brodie@bitheap.org>
parents:
11458
diff
changeset
|
279 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
|
280 |
10540
dd9d057465c1
progress: provide an explicit disable method for developers
Steve Borho <steve@borho.org>
parents:
10523
diff
changeset
|
281 # 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
|
282 # 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
|
283 if ui.configbool('progress', 'disable'): |
dd9d057465c1
progress: provide an explicit disable method for developers
Steve Borho <steve@borho.org>
parents:
10523
diff
changeset
|
284 return |
11458
ec21d91c79b3
progress: check stderr.isatty() before each print
Augie Fackler <durin42@gmail.com>
parents:
10891
diff
changeset
|
285 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
|
286 ui.__class__ = progressui |
10434 | 287 # we instantiate one globally shared progress bar to avoid |
288 # 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
|
289 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
|
290 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
|
291 _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
|
292 progressui._progbar = _singleton |
10434 | 293 |
294 def reposetup(ui, repo): | |
295 uisetup(repo.ui) |