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