Page MenuHome

subversion.py
No OneTemporary

File Metadata

Created
Wed, Oct 16, 11:30 AM

subversion.py

"""Subversion interface."""
from __future__ import absolute_import
import re
import attr
import blinker
import svn.remote
import svn.common
from . import attrs_extra
task_logged = blinker.NamedSignal('task_logged')
task_marker_re = re.compile(r'\[(?P<task_id>T\d+)\]')
def obtain(server_location):
"""Returns a Connection object for the given server location."""
return svn.remote.RemoteClient(server_location)
@attr.s
class CommitLogObserver(object):
svn_client = attr.ib(validator=attr.validators.instance_of(svn.remote.RemoteClient))
last_seen_revision = attr.ib(default=0, validator=attr.validators.instance_of(int))
_log = attrs_extra.log('%s.CommitLogObserver' % __name__)
def fetch_and_observe(self):
"""Obtains task IDs from SVN logs."""
self._log.debug('%s: fetch_and_observe()', self)
try:
svn_log = self.svn_client.log_default(revision_from=self.last_seen_revision + 1)
for log_entry in svn_log:
self._log.debug('- %r', log_entry)
# assumption: revisions are always logged in strictly increasing order.
self.last_seen_revision = log_entry.revision
self._parse_log_entry(log_entry)
except svn.common.SvnCommandError:
# The SVN library just raises a SvnCommandError when something goes wrong,
# without any structured indication of the error. There isn't much else
# we can do, except to log the error and return.
self._log.exception('Error calling self.svn_client.log_default()')
return
def _parse_log_entry(self, log_entry):
"""Parses the commit log to see if there are any task markers."""
# Log entries can be None.
if not log_entry.msg:
return
# Parse the commit log to see if there are any task markers.
lines = log_entry.msg.split('\n', 1)
first_line = lines[0]
for match in task_marker_re.finditer(first_line):
task_id = match.group('task_id')
# Send a Blinker signal for each observed task identifier.
task_logged.send(self, task_id=task_id, log_entry=log_entry)

Event Timeline