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