/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
0.62.1 by Jelmer Vernooij
Lazy load plugin.
1
# Copyright (C) 2006-2011 Canonical Ltd
2
#
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
6656.2.1 by Jelmer Vernooij
Integrate bisect command into core.
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
0.62.1 by Jelmer Vernooij
Lazy load plugin.
16
17
"""bisect command implementations."""
18
6625.4.4 by Jelmer Vernooij
Drop meta file.
19
from __future__ import absolute_import
20
0.62.1 by Jelmer Vernooij
Lazy load plugin.
21
import sys
6656.2.3 by Jelmer Vernooij
Merge trunk.
22
from .controldir import ControlDir
6656.2.1 by Jelmer Vernooij
Integrate bisect command into core.
23
from . import revision as _mod_revision
24
from .commands import Command
25
from .errors import BzrCommandError
26
from .option import Option
27
from .trace import note
0.62.1 by Jelmer Vernooij
Lazy load plugin.
28
6681.2.2 by Jelmer Vernooij
Use controldir API in bisect.
29
BISECT_INFO_PATH = "bisect"
30
BISECT_REV_PATH = "bisect_revid"
0.62.1 by Jelmer Vernooij
Lazy load plugin.
31
32
33
class BisectCurrent(object):
34
    """Bisect class for managing the current revision."""
35
6681.2.2 by Jelmer Vernooij
Use controldir API in bisect.
36
    def __init__(self, controldir, filename=BISECT_REV_PATH):
0.62.1 by Jelmer Vernooij
Lazy load plugin.
37
        self._filename = filename
6681.2.2 by Jelmer Vernooij
Use controldir API in bisect.
38
        self._controldir = controldir
6681.2.1 by Jelmer Vernooij
Rename more uses of bzrdir to controldir.
39
        self._branch = self._controldir.open_branch()
6681.2.2 by Jelmer Vernooij
Use controldir API in bisect.
40
        if self._controldir.control_transport.has(filename):
41
            self._revid = self._controldir.control_transport.get_bytes(
42
                filename).strip()
0.62.1 by Jelmer Vernooij
Lazy load plugin.
43
        else:
6681.2.1 by Jelmer Vernooij
Rename more uses of bzrdir to controldir.
44
            self._revid = self._branch.last_revision()
0.62.1 by Jelmer Vernooij
Lazy load plugin.
45
46
    def _save(self):
47
        """Save the current revision."""
6681.2.2 by Jelmer Vernooij
Use controldir API in bisect.
48
        self._controldir.control_transport.put_bytes(
7027.3.1 by Jelmer Vernooij
Fix bisect.
49
            self._filename, self._revid + b"\n")
0.62.1 by Jelmer Vernooij
Lazy load plugin.
50
51
    def get_current_revid(self):
52
        """Return the current revision id."""
53
        return self._revid
54
55
    def get_current_revno(self):
56
        """Return the current revision number as a tuple."""
6997.6.8 by Jelmer Vernooij
Fix tests.
57
        return self._branch.revision_id_to_dotted_revno(self._revid)
0.62.1 by Jelmer Vernooij
Lazy load plugin.
58
59
    def get_parent_revids(self):
60
        """Return the IDs of the current revision's predecessors."""
6681.2.1 by Jelmer Vernooij
Rename more uses of bzrdir to controldir.
61
        repo = self._branch.repository
6754.8.4 by Jelmer Vernooij
Use new context stuff.
62
        with repo.lock_read():
63
            retval = repo.get_parent_map([self._revid]).get(self._revid, None)
0.62.1 by Jelmer Vernooij
Lazy load plugin.
64
        return retval
65
66
    def is_merge_point(self):
67
        """Is the current revision a merge point?"""
68
        return len(self.get_parent_revids()) > 1
69
6833.2.1 by Jelmer Vernooij
Avoid writing to sys.stdout directly.
70
    def show_rev_log(self, outf):
0.62.1 by Jelmer Vernooij
Lazy load plugin.
71
        """Write the current revision's log entry to a file."""
6681.2.1 by Jelmer Vernooij
Rename more uses of bzrdir to controldir.
72
        rev = self._branch.repository.get_revision(self._revid)
0.62.1 by Jelmer Vernooij
Lazy load plugin.
73
        revno = ".".join([str(x) for x in self.get_current_revno()])
6833.2.1 by Jelmer Vernooij
Avoid writing to sys.stdout directly.
74
        outf.write("On revision %s (%s):\n%s\n" % (revno, rev.revision_id,
75
                                                   rev.message))
0.62.1 by Jelmer Vernooij
Lazy load plugin.
76
77
    def switch(self, revid):
78
        """Switch the current revision to the given revid."""
6681.2.1 by Jelmer Vernooij
Rename more uses of bzrdir to controldir.
79
        working = self._controldir.open_workingtree()
0.62.1 by Jelmer Vernooij
Lazy load plugin.
80
        if isinstance(revid, int):
6681.2.1 by Jelmer Vernooij
Rename more uses of bzrdir to controldir.
81
            revid = self._branch.get_rev_id(revid)
0.62.1 by Jelmer Vernooij
Lazy load plugin.
82
        elif isinstance(revid, list):
83
            revid = revid[0].in_history(working.branch).rev_id
84
        working.revert(None, working.branch.repository.revision_tree(revid),
85
                       False)
86
        self._revid = revid
87
        self._save()
88
89
    def reset(self):
90
        """Revert bisection, setting the working tree to normal."""
6681.2.1 by Jelmer Vernooij
Rename more uses of bzrdir to controldir.
91
        working = self._controldir.open_workingtree()
0.62.1 by Jelmer Vernooij
Lazy load plugin.
92
        last_rev = working.branch.last_revision()
93
        rev_tree = working.branch.repository.revision_tree(last_rev)
94
        working.revert(None, rev_tree, False)
6681.2.2 by Jelmer Vernooij
Use controldir API in bisect.
95
        if self._controldir.control_transport.has(BISECT_REV_PATH):
96
            self._controldir.control_transport.delete(BISECT_REV_PATH)
0.62.1 by Jelmer Vernooij
Lazy load plugin.
97
98
99
class BisectLog(object):
100
    """Bisect log file handler."""
101
6681.2.2 by Jelmer Vernooij
Use controldir API in bisect.
102
    def __init__(self, controldir, filename=BISECT_INFO_PATH):
0.62.1 by Jelmer Vernooij
Lazy load plugin.
103
        self._items = []
6681.2.2 by Jelmer Vernooij
Use controldir API in bisect.
104
        self._current = BisectCurrent(controldir)
105
        self._controldir = controldir
106
        self._branch = None
0.62.1 by Jelmer Vernooij
Lazy load plugin.
107
        self._high_revid = None
108
        self._low_revid = None
109
        self._middle_revid = None
110
        self._filename = filename
111
        self.load()
112
113
    def _open_for_read(self):
114
        """Open log file for reading."""
115
        if self._filename:
6681.2.2 by Jelmer Vernooij
Use controldir API in bisect.
116
            return self._controldir.control_transport.get(self._filename)
0.62.1 by Jelmer Vernooij
Lazy load plugin.
117
        else:
118
            return sys.stdin
119
6681.2.1 by Jelmer Vernooij
Rename more uses of bzrdir to controldir.
120
    def _load_tree(self):
0.62.1 by Jelmer Vernooij
Lazy load plugin.
121
        """Load bzr information."""
6681.2.2 by Jelmer Vernooij
Use controldir API in bisect.
122
        if not self._branch:
6681.2.1 by Jelmer Vernooij
Rename more uses of bzrdir to controldir.
123
            self._branch = self._controldir.open_branch()
0.62.1 by Jelmer Vernooij
Lazy load plugin.
124
7143.11.1 by Jelmer Vernooij
Remove some unused imports.
125
    def _find_range_and_middle(self, branch_last_rev=None):
0.62.1 by Jelmer Vernooij
Lazy load plugin.
126
        """Find the current revision range, and the midpoint."""
6681.2.1 by Jelmer Vernooij
Rename more uses of bzrdir to controldir.
127
        self._load_tree()
0.62.1 by Jelmer Vernooij
Lazy load plugin.
128
        self._middle_revid = None
129
130
        if not branch_last_rev:
6681.2.1 by Jelmer Vernooij
Rename more uses of bzrdir to controldir.
131
            last_revid = self._branch.last_revision()
0.62.1 by Jelmer Vernooij
Lazy load plugin.
132
        else:
133
            last_revid = branch_last_rev
134
6681.2.1 by Jelmer Vernooij
Rename more uses of bzrdir to controldir.
135
        repo = self._branch.repository
6754.8.4 by Jelmer Vernooij
Use new context stuff.
136
        with repo.lock_read():
0.63.1 by Thomi Richards
Use graph.iter_lefthand_ancestry instead of repo.iter_reverse_revision_history.
137
            graph = repo.get_graph()
7143.15.3 by Jelmer Vernooij
Fix pep8 issues in breezy.git.
138
            rev_sequence = graph.iter_lefthand_ancestry(
139
                last_revid, (_mod_revision.NULL_REVISION,))
0.62.1 by Jelmer Vernooij
Lazy load plugin.
140
            high_revid = None
141
            low_revid = None
142
            between_revs = []
143
            for revision in rev_sequence:
144
                between_revs.insert(0, revision)
145
                matches = [x[1] for x in self._items
146
                           if x[0] == revision and x[1] in ('yes', 'no')]
147
                if not matches:
148
                    continue
149
                if len(matches) > 1:
150
                    raise RuntimeError("revision %s duplicated" % revision)
151
                if matches[0] == "yes":
152
                    high_revid = revision
153
                    between_revs = []
154
                elif matches[0] == "no":
155
                    low_revid = revision
156
                    del between_revs[0]
157
                    break
158
159
            if not high_revid:
160
                high_revid = last_revid
161
            if not low_revid:
6681.2.1 by Jelmer Vernooij
Rename more uses of bzrdir to controldir.
162
                low_revid = self._branch.get_rev_id(1)
0.62.1 by Jelmer Vernooij
Lazy load plugin.
163
164
        # The spread must include the high revision, to bias
165
        # odd numbers of intervening revisions towards the high
166
        # side.
167
168
        spread = len(between_revs) + 1
169
        if spread < 2:
170
            middle_index = 0
171
        else:
7027.3.3 by Jelmer Vernooij
Add some more bees; support writing both bytes and unicode strings in build_tree_contents.
172
            middle_index = (spread // 2) - 1
0.62.1 by Jelmer Vernooij
Lazy load plugin.
173
174
        if len(between_revs) > 0:
175
            self._middle_revid = between_revs[middle_index]
176
        else:
177
            self._middle_revid = high_revid
178
179
        self._high_revid = high_revid
180
        self._low_revid = low_revid
181
182
    def _switch_wc_to_revno(self, revno, outf):
183
        """Move the working tree to the given revno."""
184
        self._current.switch(revno)
6833.2.1 by Jelmer Vernooij
Avoid writing to sys.stdout directly.
185
        self._current.show_rev_log(outf=outf)
0.62.1 by Jelmer Vernooij
Lazy load plugin.
186
187
    def _set_status(self, revid, status):
188
        """Set the bisect status for the given revid."""
189
        if not self.is_done():
0.63.1 by Thomi Richards
Use graph.iter_lefthand_ancestry instead of repo.iter_reverse_revision_history.
190
            if status != "done" and revid in [x[0] for x in self._items
0.62.1 by Jelmer Vernooij
Lazy load plugin.
191
                                              if x[1] in ['yes', 'no']]:
192
                raise RuntimeError("attempting to add revid %s twice" % revid)
193
            self._items.append((revid, status))
194
195
    def change_file_name(self, filename):
196
        """Switch log files."""
197
        self._filename = filename
198
199
    def load(self):
200
        """Load the bisection log."""
201
        self._items = []
6681.2.2 by Jelmer Vernooij
Use controldir API in bisect.
202
        if self._controldir.control_transport.has(self._filename):
0.62.1 by Jelmer Vernooij
Lazy load plugin.
203
            revlog = self._open_for_read()
204
            for line in revlog:
205
                (revid, status) = line.split()
7027.3.1 by Jelmer Vernooij
Fix bisect.
206
                self._items.append((revid, status.decode('ascii')))
0.62.1 by Jelmer Vernooij
Lazy load plugin.
207
208
    def save(self):
209
        """Save the bisection log."""
7027.3.1 by Jelmer Vernooij
Fix bisect.
210
        contents = b''.join(
211
            (b"%s %s\n" % (revid, status.encode('ascii')))
6681.2.2 by Jelmer Vernooij
Use controldir API in bisect.
212
            for (revid, status) in self._items)
213
        if self._filename:
214
            self._controldir.control_transport.put_bytes(
215
                self._filename, contents)
216
        else:
217
            sys.stdout.write(contents)
0.62.1 by Jelmer Vernooij
Lazy load plugin.
218
219
    def is_done(self):
220
        """Report whether we've found the right revision."""
221
        return len(self._items) > 0 and self._items[-1][1] == "done"
222
223
    def set_status_from_revspec(self, revspec, status):
224
        """Set the bisection status for the revision in revspec."""
6681.2.1 by Jelmer Vernooij
Rename more uses of bzrdir to controldir.
225
        self._load_tree()
226
        revid = revspec[0].in_history(self._branch).rev_id
0.62.1 by Jelmer Vernooij
Lazy load plugin.
227
        self._set_status(revid, status)
228
229
    def set_current(self, status):
230
        """Set the current revision to the given bisection status."""
231
        self._set_status(self._current.get_current_revid(), status)
232
233
    def is_merge_point(self, revid):
234
        return len(self.get_parent_revids(revid)) > 1
235
236
    def get_parent_revids(self, revid):
6681.2.1 by Jelmer Vernooij
Rename more uses of bzrdir to controldir.
237
        repo = self._branch.repository
6754.8.4 by Jelmer Vernooij
Use new context stuff.
238
        with repo.lock_read():
0.62.1 by Jelmer Vernooij
Lazy load plugin.
239
            retval = repo.get_parent_map([revid]).get(revid, None)
240
        return retval
241
242
    def bisect(self, outf):
243
        """Using the current revision's status, do a bisection."""
244
        self._find_range_and_middle()
245
        # If we've found the "final" revision, check for a
246
        # merge point.
7143.15.2 by Jelmer Vernooij
Run autopep8.
247
        while ((self._middle_revid == self._high_revid or
248
                self._middle_revid == self._low_revid) and
249
                self.is_merge_point(self._middle_revid)):
0.62.1 by Jelmer Vernooij
Lazy load plugin.
250
            for parent in self.get_parent_revids(self._middle_revid):
251
                if parent == self._low_revid:
252
                    continue
253
                else:
254
                    self._find_range_and_middle(parent)
255
                    break
256
        self._switch_wc_to_revno(self._middle_revid, outf)
257
        if self._middle_revid == self._high_revid or \
258
           self._middle_revid == self._low_revid:
259
            self.set_current("done")
260
261
262
class cmd_bisect(Command):
263
    """Find an interesting commit using a binary search.
264
265
    Bisecting, in a nutshell, is a way to find the commit at which
266
    some testable change was made, such as the introduction of a bug
267
    or feature.  By identifying a version which did not have the
268
    interesting change and a later version which did, a developer
269
    can test for the presence of the change at various points in
270
    the history, eventually ending up at the precise commit when
271
    the change was first introduced.
272
273
    This command uses subcommands to implement the search, each
274
    of which changes the state of the bisection.  The
275
    subcommands are:
276
6656.2.1 by Jelmer Vernooij
Integrate bisect command into core.
277
    brz bisect start
0.62.1 by Jelmer Vernooij
Lazy load plugin.
278
        Start a bisect, possibly clearing out a previous bisect.
279
6656.2.1 by Jelmer Vernooij
Integrate bisect command into core.
280
    brz bisect yes [-r rev]
0.62.1 by Jelmer Vernooij
Lazy load plugin.
281
        The specified revision (or the current revision, if not given)
282
        has the characteristic we're looking for,
283
6656.2.1 by Jelmer Vernooij
Integrate bisect command into core.
284
    brz bisect no [-r rev]
0.62.1 by Jelmer Vernooij
Lazy load plugin.
285
        The specified revision (or the current revision, if not given)
286
        does not have the characteristic we're looking for,
287
6656.2.1 by Jelmer Vernooij
Integrate bisect command into core.
288
    brz bisect move -r rev
0.62.1 by Jelmer Vernooij
Lazy load plugin.
289
        Switch to a different revision manually.  Use if the bisect
290
        algorithm chooses a revision that is not suitable.  Try to
291
        move as little as possible.
292
6656.2.1 by Jelmer Vernooij
Integrate bisect command into core.
293
    brz bisect reset
0.62.1 by Jelmer Vernooij
Lazy load plugin.
294
        Clear out a bisection in progress.
295
6656.2.1 by Jelmer Vernooij
Integrate bisect command into core.
296
    brz bisect log [-o file]
0.62.1 by Jelmer Vernooij
Lazy load plugin.
297
        Output a log of the current bisection to standard output, or
298
        to the specified file.
299
6656.2.1 by Jelmer Vernooij
Integrate bisect command into core.
300
    brz bisect replay <logfile>
0.62.1 by Jelmer Vernooij
Lazy load plugin.
301
        Replay a previously-saved bisect log, forgetting any bisection
302
        that might be in progress.
303
6656.2.1 by Jelmer Vernooij
Integrate bisect command into core.
304
    brz bisect run <script>
0.62.1 by Jelmer Vernooij
Lazy load plugin.
305
        Bisect automatically using <script> to determine 'yes' or 'no'.
306
        <script> should exit with:
307
           0 for yes
308
           125 for unknown (like build failed so we could not test)
309
           anything else for no
310
    """
311
312
    takes_args = ['subcommand', 'args*']
313
    takes_options = [Option('output', short_name='o',
7479.2.1 by Jelmer Vernooij
Drop python2 support.
314
                            help='Write log to this file.', type=str),
6681.2.2 by Jelmer Vernooij
Use controldir API in bisect.
315
                     'revision', 'directory']
0.62.1 by Jelmer Vernooij
Lazy load plugin.
316
6681.2.2 by Jelmer Vernooij
Use controldir API in bisect.
317
    def _check(self, controldir):
0.62.1 by Jelmer Vernooij
Lazy load plugin.
318
        """Check preconditions for most operations to work."""
6681.2.2 by Jelmer Vernooij
Use controldir API in bisect.
319
        if not controldir.control_transport.has(BISECT_INFO_PATH):
0.62.1 by Jelmer Vernooij
Lazy load plugin.
320
            raise BzrCommandError("No bisection in progress.")
321
6681.2.2 by Jelmer Vernooij
Use controldir API in bisect.
322
    def _set_state(self, controldir, revspec, state):
0.62.1 by Jelmer Vernooij
Lazy load plugin.
323
        """Set the state of the given revspec and bisecting.
324
325
        Returns boolean indicating if bisection is done."""
6681.2.2 by Jelmer Vernooij
Use controldir API in bisect.
326
        bisect_log = BisectLog(controldir)
0.62.1 by Jelmer Vernooij
Lazy load plugin.
327
        if bisect_log.is_done():
328
            note("No further bisection is possible.\n")
6833.2.1 by Jelmer Vernooij
Avoid writing to sys.stdout directly.
329
            bisect_log._current.show_rev_log(outf=self.outf)
0.62.1 by Jelmer Vernooij
Lazy load plugin.
330
            return True
331
332
        if revspec:
333
            bisect_log.set_status_from_revspec(revspec, state)
334
        else:
335
            bisect_log.set_current(state)
336
        bisect_log.bisect(self.outf)
337
        bisect_log.save()
338
        return False
339
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
340
    def run(self, subcommand, args_list, directory='.', revision=None,
341
            output=None):
0.62.1 by Jelmer Vernooij
Lazy load plugin.
342
        """Handle the bisect command."""
343
344
        log_fn = None
345
        if subcommand in ('yes', 'no', 'move') and revision:
346
            pass
347
        elif subcommand in ('replay', ) and args_list and len(args_list) == 1:
348
            log_fn = args_list[0]
349
        elif subcommand in ('move', ) and not revision:
350
            raise BzrCommandError(
351
                "The 'bisect move' command requires a revision.")
352
        elif subcommand in ('run', ):
353
            run_script = args_list[0]
354
        elif args_list or revision:
355
            raise BzrCommandError(
356
                "Improper arguments to bisect " + subcommand)
357
6681.2.2 by Jelmer Vernooij
Use controldir API in bisect.
358
        controldir, _ = ControlDir.open_containing(directory)
359
0.62.1 by Jelmer Vernooij
Lazy load plugin.
360
        # Dispatch.
361
        if subcommand == "start":
6681.2.2 by Jelmer Vernooij
Use controldir API in bisect.
362
            self.start(controldir)
0.62.1 by Jelmer Vernooij
Lazy load plugin.
363
        elif subcommand == "yes":
6681.2.2 by Jelmer Vernooij
Use controldir API in bisect.
364
            self.yes(controldir, revision)
0.62.1 by Jelmer Vernooij
Lazy load plugin.
365
        elif subcommand == "no":
6681.2.2 by Jelmer Vernooij
Use controldir API in bisect.
366
            self.no(controldir, revision)
0.62.1 by Jelmer Vernooij
Lazy load plugin.
367
        elif subcommand == "move":
6681.2.2 by Jelmer Vernooij
Use controldir API in bisect.
368
            self.move(controldir, revision)
0.62.1 by Jelmer Vernooij
Lazy load plugin.
369
        elif subcommand == "reset":
6681.2.2 by Jelmer Vernooij
Use controldir API in bisect.
370
            self.reset(controldir)
0.62.1 by Jelmer Vernooij
Lazy load plugin.
371
        elif subcommand == "log":
6681.2.2 by Jelmer Vernooij
Use controldir API in bisect.
372
            self.log(controldir, output)
0.62.1 by Jelmer Vernooij
Lazy load plugin.
373
        elif subcommand == "replay":
6681.2.2 by Jelmer Vernooij
Use controldir API in bisect.
374
            self.replay(controldir, log_fn)
0.62.1 by Jelmer Vernooij
Lazy load plugin.
375
        elif subcommand == "run":
6681.2.2 by Jelmer Vernooij
Use controldir API in bisect.
376
            self.run_bisect(controldir, run_script)
0.62.1 by Jelmer Vernooij
Lazy load plugin.
377
        else:
378
            raise BzrCommandError(
379
                "Unknown bisect command: " + subcommand)
380
6681.2.2 by Jelmer Vernooij
Use controldir API in bisect.
381
    def reset(self, controldir):
0.62.1 by Jelmer Vernooij
Lazy load plugin.
382
        """Reset the bisect state to no state."""
6681.2.2 by Jelmer Vernooij
Use controldir API in bisect.
383
        self._check(controldir)
384
        BisectCurrent(controldir).reset()
385
        controldir.control_transport.delete(BISECT_INFO_PATH)
0.62.1 by Jelmer Vernooij
Lazy load plugin.
386
6681.2.2 by Jelmer Vernooij
Use controldir API in bisect.
387
    def start(self, controldir):
0.62.1 by Jelmer Vernooij
Lazy load plugin.
388
        """Reset the bisect state, then prepare for a new bisection."""
6681.2.2 by Jelmer Vernooij
Use controldir API in bisect.
389
        if controldir.control_transport.has(BISECT_INFO_PATH):
390
            BisectCurrent(controldir).reset()
391
            controldir.control_transport.delete(BISECT_INFO_PATH)
0.62.1 by Jelmer Vernooij
Lazy load plugin.
392
6681.2.2 by Jelmer Vernooij
Use controldir API in bisect.
393
        bisect_log = BisectLog(controldir)
0.62.1 by Jelmer Vernooij
Lazy load plugin.
394
        bisect_log.set_current("start")
395
        bisect_log.save()
396
6681.2.2 by Jelmer Vernooij
Use controldir API in bisect.
397
    def yes(self, controldir, revspec):
0.62.1 by Jelmer Vernooij
Lazy load plugin.
398
        """Mark that a given revision has the state we're looking for."""
6681.2.2 by Jelmer Vernooij
Use controldir API in bisect.
399
        self._set_state(controldir, revspec, "yes")
0.62.1 by Jelmer Vernooij
Lazy load plugin.
400
6681.2.2 by Jelmer Vernooij
Use controldir API in bisect.
401
    def no(self, controldir, revspec):
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
402
        """Mark a given revision as wrong."""
6681.2.2 by Jelmer Vernooij
Use controldir API in bisect.
403
        self._set_state(controldir, revspec, "no")
0.62.1 by Jelmer Vernooij
Lazy load plugin.
404
6681.2.2 by Jelmer Vernooij
Use controldir API in bisect.
405
    def move(self, controldir, revspec):
0.62.1 by Jelmer Vernooij
Lazy load plugin.
406
        """Move to a different revision manually."""
6681.2.2 by Jelmer Vernooij
Use controldir API in bisect.
407
        current = BisectCurrent(controldir)
0.62.1 by Jelmer Vernooij
Lazy load plugin.
408
        current.switch(revspec)
6835 by Jelmer Vernooij
Merge lp:~jelmer/brz/268573-outf
409
        current.show_rev_log(outf=self.outf)
0.62.1 by Jelmer Vernooij
Lazy load plugin.
410
6681.2.2 by Jelmer Vernooij
Use controldir API in bisect.
411
    def log(self, controldir, filename):
0.62.1 by Jelmer Vernooij
Lazy load plugin.
412
        """Write the current bisect log to a file."""
6681.2.2 by Jelmer Vernooij
Use controldir API in bisect.
413
        self._check(controldir)
414
        bisect_log = BisectLog(controldir)
0.62.1 by Jelmer Vernooij
Lazy load plugin.
415
        bisect_log.change_file_name(filename)
416
        bisect_log.save()
417
6681.2.2 by Jelmer Vernooij
Use controldir API in bisect.
418
    def replay(self, controldir, filename):
0.62.1 by Jelmer Vernooij
Lazy load plugin.
419
        """Apply the given log file to a clean state, so the state is
420
        exactly as it was when the log was saved."""
6681.2.2 by Jelmer Vernooij
Use controldir API in bisect.
421
        if controldir.control_transport.has(BISECT_INFO_PATH):
422
            BisectCurrent(controldir).reset()
423
            controldir.control_transport.delete(BISECT_INFO_PATH)
424
        bisect_log = BisectLog(controldir, filename)
425
        bisect_log.change_file_name(BISECT_INFO_PATH)
0.62.1 by Jelmer Vernooij
Lazy load plugin.
426
        bisect_log.save()
427
428
        bisect_log.bisect(self.outf)
429
6681.2.2 by Jelmer Vernooij
Use controldir API in bisect.
430
    def run_bisect(self, controldir, script):
0.62.1 by Jelmer Vernooij
Lazy load plugin.
431
        import subprocess
432
        note("Starting bisect.")
6681.2.2 by Jelmer Vernooij
Use controldir API in bisect.
433
        self.start(controldir)
0.62.1 by Jelmer Vernooij
Lazy load plugin.
434
        while True:
435
            try:
436
                process = subprocess.Popen(script, shell=True)
437
                process.wait()
438
                retcode = process.returncode
439
                if retcode == 0:
6681.2.2 by Jelmer Vernooij
Use controldir API in bisect.
440
                    done = self._set_state(controldir, None, 'yes')
0.62.1 by Jelmer Vernooij
Lazy load plugin.
441
                elif retcode == 125:
442
                    break
443
                else:
6681.2.2 by Jelmer Vernooij
Use controldir API in bisect.
444
                    done = self._set_state(controldir, None, 'no')
0.62.1 by Jelmer Vernooij
Lazy load plugin.
445
                if done:
446
                    break
447
            except RuntimeError:
448
                break