Mercurial > hg-stable
comparison hgext/hbisect.py @ 2348:1772852d7d14
better ui for the bisect extension
(and update to i18n)
author | Benoit Boissinot <benoit.boissinot@ens-lyon.org> |
---|---|
date | Fri, 26 May 2006 22:17:43 +0200 |
parents | e7de4dd43472 |
children | 07026da25ed8 |
comparison
equal
deleted
inserted
replaced
2347:5b178298b7f4 | 2348:1772852d7d14 |
---|---|
4 # Inspired by git bisect, extension skeleton taken from mq.py. | 4 # Inspired by git bisect, extension skeleton taken from mq.py. |
5 # | 5 # |
6 # This software may be used and distributed according to the terms | 6 # This software may be used and distributed according to the terms |
7 # of the GNU General Public License, incorporated herein by reference. | 7 # of the GNU General Public License, incorporated herein by reference. |
8 | 8 |
9 from mercurial.i18n import gettext as _ | |
9 from mercurial.demandload import demandload | 10 from mercurial.demandload import demandload |
10 demandload(globals(), "os sys sets mercurial:hg,util") | 11 demandload(globals(), "os sys sets mercurial:hg,util,commands") |
11 | 12 |
12 versionstr = "0.0.3" | 13 versionstr = "0.0.3" |
13 | 14 |
14 def lookup_rev(ui, repo, rev=None): | 15 def lookup_rev(ui, repo, rev=None): |
15 """returns rev or the checked-out revision if rev is None""" | 16 """returns rev or the checked-out revision if rev is None""" |
16 if not rev is None: | 17 if not rev is None: |
17 return repo.lookup(rev) | 18 return repo.lookup(rev) |
18 parents = [p for p in repo.dirstate.parents() if p != hg.nullid] | 19 parents = [p for p in repo.dirstate.parents() if p != hg.nullid] |
19 if len(parents) != 1: | 20 if len(parents) != 1: |
20 ui.warn("unexpected number of parents\n") | 21 raise util.Abort(_("unexpected number of parents, " |
21 ui.warn("please commit or revert\n") | 22 "please commit or revert")) |
22 sys.exit(1) | |
23 return parents.pop() | 23 return parents.pop() |
24 | 24 |
25 def check_clean(ui, repo): | 25 def check_clean(ui, repo): |
26 modified, added, removed, deleted, unknown = repo.changes() | 26 modified, added, removed, deleted, unknown = repo.changes() |
27 if modified or added or removed: | 27 if modified or added or removed: |
62 f.write(hg.hex(self.badrev) + "\n") | 62 f.write(hg.hex(self.badrev) + "\n") |
63 | 63 |
64 def init(self): | 64 def init(self): |
65 """start a new bisection""" | 65 """start a new bisection""" |
66 if os.path.isdir(self.path): | 66 if os.path.isdir(self.path): |
67 self.ui.warn("bisect directory already exists\n") | 67 raise util.Abort(_("bisect directory already exists\n")) |
68 return 1 | |
69 os.mkdir(self.path) | 68 os.mkdir(self.path) |
70 check_clean(self.ui, self.repo) | 69 check_clean(self.ui, self.repo) |
71 return 0 | 70 return 0 |
72 | 71 |
73 def reset(self): | 72 def reset(self): |
135 for p in parents: | 134 for p in parents: |
136 d[p][0] += 1 | 135 d[p][0] += 1 |
137 return d | 136 return d |
138 | 137 |
139 if head in stop: | 138 if head in stop: |
140 self.ui.warn("Unconsistent state, %s is good and bad\n" | 139 raise util.Abort(_("Unconsistent state, %s:%s is good and bad") |
141 % hg.hex(head)) | 140 % (cl.rev(head), hg.short(head))) |
142 sys.exit(1) | |
143 n_child = num_children(head) | 141 n_child = num_children(head) |
144 for i in xrange(cl.rev(head)+1): | 142 for i in xrange(cl.rev(head)+1): |
145 n = cl.node(i) | 143 n = cl.node(i) |
146 parents = [p for p in cl.parents(n) if p != hg.nullid] | 144 parents = [p for p in cl.parents(n) if p != hg.nullid] |
147 for p in parents: | 145 for p in parents: |
158 n_child[n] = len(n_child[n][1]) | 156 n_child[n] = len(n_child[n][1]) |
159 return anc, n_child | 157 return anc, n_child |
160 | 158 |
161 def next(self): | 159 def next(self): |
162 if not self.badrev: | 160 if not self.badrev: |
163 self.ui.warn("You should give at least one bad\n") | 161 raise util.Abort(_("You should give at least one bad revision")) |
164 sys.exit(1) | |
165 if not self.goodrevs: | 162 if not self.goodrevs: |
166 self.ui.warn("No good revision given\n") | 163 self.ui.warn(_("No good revision given\n")) |
167 self.ui.warn("Assuming the first revision is good\n") | 164 self.ui.warn(_("Marking the first revision as good\n")) |
168 ancestors, num_ancestors = self.__ancestors_and_nb_ancestors( | 165 ancestors, num_ancestors = self.__ancestors_and_nb_ancestors( |
169 self.badrev) | 166 self.badrev) |
170 tot = len(ancestors) | 167 tot = len(ancestors) |
171 if tot == 1: | 168 if tot == 1: |
172 if ancestors.pop() != self.badrev: | 169 if ancestors.pop() != self.badrev: |
173 self.ui.warn("Could not find the first bad revision\n") | 170 raise util.Abort(_("Could not find the first bad revision")) |
174 sys.exit(1) | 171 self.ui.write(_("The first bad revision is:\n")) |
175 self.ui.write( | 172 displayer = commands.show_changeset(self.ui, self.repo, {}) |
176 "The first bad revision is: %s\n" % hg.hex(self.badrev)) | 173 displayer.show(changenode=self.badrev) |
177 sys.exit(0) | 174 return None |
178 self.ui.write("%d revisions left\n" % tot) | |
179 best_rev = None | 175 best_rev = None |
180 best_len = -1 | 176 best_len = -1 |
181 for n in ancestors: | 177 for n in ancestors: |
182 l = num_ancestors[n] | 178 l = num_ancestors[n] |
183 l = min(l, tot - l) | 179 l = min(l, tot - l) |
184 if l > best_len: | 180 if l > best_len: |
185 best_len = l | 181 best_len = l |
186 best_rev = n | 182 best_rev = n |
183 assert best_rev is not None | |
184 nb_tests = 0 | |
185 q, r = divmod(tot, 2) | |
186 while q: | |
187 nb_tests += 1 | |
188 q, r = divmod(q, 2) | |
189 msg = _("Testing changeset %s:%s (%s changesets remaining, " | |
190 "~%s tests)\n") % (self.repo.changelog.rev(best_rev), | |
191 hg.short(best_rev), tot, nb_tests) | |
192 self.ui.write(msg) | |
187 return best_rev | 193 return best_rev |
188 | 194 |
189 def autonext(self): | 195 def autonext(self): |
190 """find and update to the next revision to test""" | 196 """find and update to the next revision to test""" |
191 check_clean(self.ui, self.repo) | 197 check_clean(self.ui, self.repo) |
192 rev = self.next() | 198 rev = self.next() |
193 self.ui.write("Now testing %s\n" % hg.hex(rev)) | 199 if rev is not None: |
194 return self.repo.update(rev, force=True) | 200 return self.repo.update(rev, force=True) |
195 | 201 |
196 def good(self, rev): | 202 def good(self, rev): |
197 self.goodrevs.append(rev) | 203 self.goodrevs.append(rev) |
198 | 204 |
199 def autogood(self, rev=None): | 205 def autogood(self, rev=None): |
200 """mark revision as good and update to the next revision to test""" | 206 """mark revision as good and update to the next revision to test""" |
201 check_clean(self.ui, self.repo) | 207 check_clean(self.ui, self.repo) |
202 rev = lookup_rev(self.ui, self.repo, rev) | 208 rev = lookup_rev(self.ui, self.repo, rev) |
203 self.good(rev) | 209 self.good(rev) |
204 if self.badrev: | 210 if self.badrev: |
205 self.autonext() | 211 return self.autonext() |
206 | 212 |
207 def bad(self, rev): | 213 def bad(self, rev): |
208 self.badrev = rev | 214 self.badrev = rev |
209 | 215 |
210 def autobad(self, rev=None): | 216 def autobad(self, rev=None): |
234 ui.write("it is bad\n") | 240 ui.write("it is bad\n") |
235 else: | 241 else: |
236 b.good(new_rev) | 242 b.good(new_rev) |
237 ui.write("it is good\n") | 243 ui.write("it is good\n") |
238 anc = b.ancestors() | 244 anc = b.ancestors() |
239 repo.update(new_rev, force=True) | 245 #repo.update(new_rev, force=True) |
240 for v in anc: | 246 for v in anc: |
241 if v != rev: | 247 if v != rev: |
242 ui.warn("fail to found cset! :(\n") | 248 ui.warn("fail to found cset! :(\n") |
243 return 1 | 249 return 1 |
244 ui.write("Found bad cset: %s\n" % hg.hex(b.badrev)) | 250 ui.write("Found bad cset: %s\n" % hg.hex(b.badrev)) |
256 doc = cmdtable[cmd][0].__doc__ | 262 doc = cmdtable[cmd][0].__doc__ |
257 synopsis = cmdtable[cmd][2] | 263 synopsis = cmdtable[cmd][2] |
258 ui.write(synopsis + "\n") | 264 ui.write(synopsis + "\n") |
259 ui.write("\n" + doc + "\n") | 265 ui.write("\n" + doc + "\n") |
260 return | 266 return |
261 ui.write("list of subcommands for the bisect extension\n\n") | 267 ui.write(_("list of subcommands for the bisect extension\n\n")) |
262 cmds = cmdtable.keys() | 268 cmds = cmdtable.keys() |
263 cmds.sort() | 269 cmds.sort() |
264 m = max([len(c) for c in cmds]) | 270 m = max([len(c) for c in cmds]) |
265 for cmd in cmds: | 271 for cmd in cmds: |
266 doc = cmdtable[cmd][0].__doc__.splitlines(0)[0].rstrip() | 272 doc = cmdtable[cmd][0].__doc__.splitlines(0)[0].rstrip() |
267 ui.write(" %-*s %s\n" % (m, cmd, doc)) | 273 ui.write(" %-*s %s\n" % (m, cmd, doc)) |
268 | 274 |
269 b = bisect(ui, repo) | 275 b = bisect(ui, repo) |
270 bisectcmdtable = { | 276 bisectcmdtable = { |
271 "init": (b.init, 0, "hg bisect init"), | 277 "init": (b.init, 0, _("hg bisect init")), |
272 "bad": (b.autobad, 1, "hg bisect bad [<rev>]"), | 278 "bad": (b.autobad, 1, _("hg bisect bad [<rev>]")), |
273 "good": (b.autogood, 1, "hg bisect good [<rev>]"), | 279 "good": (b.autogood, 1, _("hg bisect good [<rev>]")), |
274 "next": (b.autonext, 0, "hg bisect next"), | 280 "next": (b.autonext, 0, _("hg bisect next")), |
275 "reset": (b.reset, 0, "hg bisect reset"), | 281 "reset": (b.reset, 0, _("hg bisect reset")), |
276 "help": (help_, 1, "hg bisect help [<subcommand>]"), | 282 "help": (help_, 1, _("hg bisect help [<subcommand>]")), |
277 } | 283 } |
278 | 284 |
279 if not bisectcmdtable.has_key(cmd): | 285 if not bisectcmdtable.has_key(cmd): |
280 ui.warn("bisect: Unknown sub-command\n") | 286 ui.warn(_("bisect: Unknown sub-command\n")) |
281 return help_() | 287 return help_() |
282 if len(args) > bisectcmdtable[cmd][1]: | 288 if len(args) > bisectcmdtable[cmd][1]: |
283 ui.warn("bisect: Too many arguments\n") | 289 ui.warn(_("bisect: Too many arguments\n")) |
284 return help_() | 290 return help_() |
285 return bisectcmdtable[cmd][0](*args) | 291 return bisectcmdtable[cmd][0](*args) |
286 | 292 |
287 cmdtable = { | 293 cmdtable = { |
288 "bisect": (bisect_run, [], "hg bisect [help|init|reset|next|good|bad]"), | 294 "bisect": (bisect_run, [], _("hg bisect [help|init|reset|next|good|bad]")), |
289 #"bisect-test": (test, [], "hg bisect-test rev"), | 295 #"bisect-test": (test, [], "hg bisect-test rev"), |
290 } | 296 } |