Ticket #946: bzr_buildbot.patch

File bzr_buildbot.patch, 6.4 KB (added by tom.prince, 8 years ago)

Uniffied diff version

  • master/contrib/bzr_buildbot.py

    diff --git a/master/contrib/bzr_buildbot.py b/master/contrib/bzr_buildbot.py
    index 5f84fb9..a639511 100644
    a b import twisted.internet.reactor 
    113113import twisted.internet.selectreactor
    114114import twisted.internet.task
    115115import twisted.internet.threads
    116 import twisted.python.log
     116from twisted.python import log
    117117import twisted.spread.pb
     118import datetime
    118119
    119120
    120121#############################################################################
    def generate_change(branch, 
    126127                    blame_merge_author=False):
    127128    """Return a dict of information about a change to the branch.
    128129
    129     Dict has keys of "files", "who", "comments", and "revision", as used by
     130    Dict has keys of "files", "author", "when_timestamp", "comments", and "revision", as used by
    130131    the buildbot Change (and the PBChangeSource).
    131132
    132133    If only the branch is given, the most recent change is returned.
    def generate_change(branch, 
    138139    bzr hooks usually provide this information.
    139140
    140141    blame_merge_author means that the author of the merged branch is
    141     identified as the "who", not the person who committed the branch itself.
     142    identified as the "author", not the person who committed the branch itself.
    142143    This is typically used for PQM.
    143144    """
    144     change = {} # files, who, comments, revision; NOT branch (= branch.nick)
     145    change = {} # files, author, when_timestamp, comments, revision; NOT branch (= branch.nick)
    145146    if new_revno is None:
    146147        new_revno = branch.revno()
    147148    if new_revid is None:
    def generate_change(branch, 
    155156    new_rev = repository.get_revision(new_revid)
    156157    if blame_merge_author:
    157158        # this is a pqm commit or something like it
    158         change['who'] = repository.get_revision(
     159        change['author'] = repository.get_revision(
    159160            new_rev.parent_ids[-1]).get_apparent_authors()[0]
    160161    else:
    161         change['who'] = new_rev.get_apparent_authors()[0]
     162        change['author'] = new_rev.get_apparent_authors()[0]
    162163    # maybe useful to know:
    163     # name, email = bzrtools.config.parse_username(change['who'])
     164    # name, email = bzrtools.config.parse_username(change['author'])
    164165    change['comments'] = new_rev.message
    165166    change['revision'] = new_revno
     167    latestrev = repository.gather_stats(new_revid)['latestrev']
     168    change['when_timestamp'] = datetime.datetime.fromtimestamp(latestrev[0] - latestrev[1])
    166169    files = change['files'] = []
    167170    changes = repository.revision_tree(new_revid).changes_from(
    168171        repository.revision_tree(old_revid))
    if DEFINE_POLLER: 
    229232                ourbranch = self.url
    230233            else:
    231234                ourbranch = self.branch_name
    232             for change in reversed(self.parent.changes):
    233                 if change.branch == ourbranch:
    234                     self.last_revision = change.revision
    235                     break
    236             else:
    237                 self.last_revision = None
     235            self.last_revision = None
    238236            self.polling = False
    239237            twisted.internet.reactor.callWhenRunning(
    240238                self.loop.start, self.poll_interval)
    if DEFINE_POLLER: 
    247245        def describe(self):
    248246            return "BzrPoller watching %s" % self.url
    249247
    250         @twisted.internet.defer.inlineCallbacks
    251248        def poll(self):
    252249            if self.polling: # this is called in a loop, and the loop might
    253250                # conceivably overlap.
    254                 return
    255             self.polling = True
    256             try:
    257                 # On a big tree, even individual elements of the bzr commands
    258                 # can take awhile. So we just push the bzr work off to a
    259                 # thread.
    260                 try:
    261                     changes = yield twisted.internet.threads.deferToThread(
    262                         self.getRawChanges)
    263                 except (SystemExit, KeyboardInterrupt):
    264                     raise
    265                 except:
    266                     # we'll try again next poll.  Meanwhile, let's report.
    267                     twisted.python.log.err()
    268                 else:
    269                     for change in changes:
    270                         yield self.addChange(
    271                             buildbot.changes.changes.Change(**change))
    272                         self.last_revision = change['revision']
    273             finally:
    274                 self.polling = False
    275 
    276         def getRawChanges(self):
     251                log.msg('Not polling, last poll is still working')
     252            else:
     253                log.msg('BzrPoller polling %s' % self.url)
     254                self.polling = True
     255                d = twisted.internet.threads.deferToThread(self._getRawChanges)
     256                d.addCallback(self._processChanges)
     257                d.addCallbacks(self._finishedOk, self._finishedFail)
     258                return d
     259
     260
     261        def _finishedOk(self, res):
     262            assert self.polling
     263            self.polling = False
     264            log.msg('Finished polling %s successfully' % self.url)
     265            return res
     266
     267        def _finishedFail(self, res):
     268            assert self.polling
     269            self.polling = False
     270            log.msg('Error while polling %s' % self.url)
     271            return None
     272
     273        def _getRawChanges(self):
    277274            branch = bzrlib.branch.Branch.open_containing(self.url)[0]
    278275            if self.branch_name is FULL:
    279276                branch_name = self.url
    if DEFINE_POLLER: 
    299296            changes.reverse()
    300297            return changes
    301298
    302         def addChange(self, change):
    303             d = twisted.internet.defer.Deferred()
    304             def _add_change():
    305                 d.callback(
    306                     self.parent.addChange(change, src='bzr'))
    307             twisted.internet.reactor.callLater(0, _add_change)
    308             return d
     299        @twisted.internet.defer.deferredGenerator
     300        def _processChanges(self, changes):
     301            if self.last_revision is not None or True:
     302                for change in changes:
     303                    d = self.master.addChange(src='bzr',
     304                            **change)
     305                    wfd = defer.waitForDeferred(d)
     306                    yield wfd
     307                    results = wfd.getResult()
     308
     309            if changes:
     310                self.last_revision = changes[-1]['revision']
    309311
    310312#############################################################################
    311313# hooks