~gary/tarmac/fix693595

« back to all changes in this revision

Viewing changes to tarmac/bin/commands.py

  • Committer: Gary Poster
  • Date: 2010-12-23 18:28:32 UTC
  • Revision ID: gary.poster@canonical.com-20101223182832-t8fiby7u45rjo3be
fix bug 693595 by making commit plugins able to cancel a merge.  Correct some logic errors along the way, revealed by this work.

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
import httplib2
3
3
import logging
4
4
import os
5
 
import time
6
5
 
7
6
from bzrlib.commands import Command
8
7
from bzrlib.help import help_commands
15
14
from tarmac.log import set_up_debug_logging, set_up_logging
16
15
from tarmac.exceptions import TarmacCommandError, TarmacMergeError
17
16
from tarmac.plugin import load_plugins
18
 
from tarmac.pidfile import get_pid, make_pidfile
 
17
from tarmac.pidfile import make_pidfile, remove_pidfile, PidfileExistsError
19
18
 
20
19
 
21
20
class TarmacCommand(Command):
237
236
    """
238
237
 
239
238
    def _do_merges(self, branch_url, imply_commit_message):
240
 
        existing_pid = get_pid()
241
 
        if existing_pid is None:
 
239
        try:
242
240
            make_pidfile()
243
 
        else:
244
 
            # Check how long the lock has been there.
245
 
            lock_creation_time = os.stat(self.config.PID_FILE)[-1]
246
 
            now = time.time()
247
 
            locked_period = now - lock_creation_time
248
 
            # If the locked_period is greater than the allowed, it probably 
249
 
            # means the test suite is stuck.
250
 
            message = 'Tarmac lock file in place for %d seconds, PID: %d'
251
 
            if locked_period > int(self.config.allowed_lock_period):
252
 
                self.logger.info(message % (locked_period, get_pid()))
253
 
                raise TarmacCommandError(message % (locked_period, get_pid()))
 
241
        except PidfileExistsError, e:
 
242
            message = "Is there another instance of Tarmac Running?  %s" % e
 
243
            if e.lifetime > int(self.config.allowed_lock_period):
 
244
                # If the locked_period is greater than the allowed, it
 
245
                # probably means the test suite is stuck.
 
246
                self.logger.info(message)
 
247
                raise TarmacCommandError(message)
254
248
            else:
255
 
                self.logger.info(message % (locked_period, get_pid()))
 
249
                self.logger.info(message)
256
250
                return
257
 
 
258
 
        target = Branch.create(
259
 
            self.launchpad.branches.getByUrl(url=branch_url), self.config,
260
 
            imply_commit_message=imply_commit_message)
261
 
 
262
 
        if not target.get_merge_proposals():
263
 
            return
264
 
 
265
 
        self.logger.debug('Firing tarmac_pre_merge hook')
266
 
        tarmac_hooks['tarmac_pre_merge'].fire(self, target)
267
 
 
268
251
        try:
269
 
            # revno to restore to if bundle merge fails.
270
 
            restore_revno = target.tree.branch.revno() + 1
271
 
            results = target.merge_branches()
272
 
            # Use a set to collect the proposals. We don't want
273
 
            # duplicates since results generator will return the (source,
274
 
            # proposal) tuple twice, once for each pre and post commit hook.
275
 
            collected_proposals = set()
276
 
            while True:
277
 
                try:
278
 
                    (hook, source, proposal) = results.next()
279
 
                    collected_proposals.add((source, proposal))
280
 
                    self._fire_merge_hook(
281
 
                        results, hook, target, source, proposal)
282
 
                except StopIteration:
283
 
                    break
284
 
            tarmac_hooks['tarmac_bundle_merge'].fire(
285
 
                self, target, restore_revno, collected_proposals)
286
 
 
287
 
        # This except is here because we need the else and can't have it
288
 
        # without an except as well.
289
 
        except:
290
 
            raise
291
 
        else:
292
 
            self.logger.debug('Firing tarmac_post_merge hook')
293
 
            tarmac_hooks['tarmac_post_merge'].fire(self, target)
294
 
            # Push target.tree.branch to location branch_url.
295
 
            target.push()
 
252
            target = Branch.create(
 
253
                self.launchpad.branches.getByUrl(url=branch_url), self.config,
 
254
                imply_commit_message=imply_commit_message)
 
255
 
 
256
            if not target.get_merge_proposals():
 
257
                return
 
258
 
 
259
            self.logger.debug('Firing tarmac_pre_merge hook')
 
260
            tarmac_hooks['tarmac_pre_merge'].fire(self, target)
 
261
 
 
262
            try:
 
263
                # revno to restore to if bundle merge fails.
 
264
                restore_revno = target.tree.branch.revno() + 1
 
265
                results = target.merge_branches()
 
266
                collected_proposals = []
 
267
                while True:
 
268
                    try:
 
269
                        (hook, source, proposal) = results.next()
 
270
                        if hook == 'tarmac_post_commit':
 
271
                            # We only want the proposals that have not been
 
272
                            # rejected.
 
273
                            collected_proposals.append((source, proposal))
 
274
                        self._fire_merge_hook(
 
275
                            results, hook, target, source, proposal)
 
276
                    except StopIteration:
 
277
                        break
 
278
                if collected_proposals:
 
279
                    # We actually have something to do!
 
280
                    # This hook is expected to raise an exception if
 
281
                    # tests fail. The hook is probably the one found in
 
282
                    # plugins/bundlecommand.py.
 
283
                    tarmac_hooks['tarmac_bundle_merge'].fire(
 
284
                        self, target, restore_revno, collected_proposals)
 
285
                    self.logger.debug('Firing tarmac_post_merge hook')
 
286
                    tarmac_hooks['tarmac_post_merge'].fire(self, target)
 
287
                    # Push target.tree.branch to location branch_url.
 
288
                    target.push()
 
289
            finally:
 
290
                target.cleanup()
296
291
        finally:
297
 
            target.cleanup()
 
292
            remove_pidfile()