Index: third_party/buildbot_7_12/buildbot/changes/p4poller.py |
diff --git a/third_party/buildbot_7_12/buildbot/changes/p4poller.py b/third_party/buildbot_7_12/buildbot/changes/p4poller.py |
deleted file mode 100644 |
index 456b6bad6c4734640bf90cd5f34e344c3ea478d6..0000000000000000000000000000000000000000 |
--- a/third_party/buildbot_7_12/buildbot/changes/p4poller.py |
+++ /dev/null |
@@ -1,207 +0,0 @@ |
-# -*- test-case-name: buildbot.test.test_p4poller -*- |
- |
-# Many thanks to Dave Peticolas for contributing this module |
- |
-import re |
-import time |
- |
-from twisted.python import log, failure |
-from twisted.internet import defer, reactor |
-from twisted.internet.utils import getProcessOutput |
-from twisted.internet.task import LoopingCall |
- |
-from buildbot import util |
-from buildbot.changes import base, changes |
- |
-def get_simple_split(branchfile): |
- """Splits the branchfile argument and assuming branch is |
- the first path component in branchfile, will return |
- branch and file else None.""" |
- |
- index = branchfile.find('/') |
- if index == -1: return None, None |
- branch, file = branchfile.split('/', 1) |
- return branch, file |
- |
-class P4Source(base.ChangeSource, util.ComparableMixin): |
- """This source will poll a perforce repository for changes and submit |
- them to the change master.""" |
- |
- compare_attrs = ["p4port", "p4user", "p4passwd", "p4base", |
- "p4bin", "pollinterval"] |
- |
- changes_line_re = re.compile( |
- r"Change (?P<num>\d+) on \S+ by \S+@\S+ '.*'$") |
- describe_header_re = re.compile( |
- r"Change \d+ by (?P<who>\S+)@\S+ on (?P<when>.+)$") |
- file_re = re.compile(r"^\.\.\. (?P<path>[^#]+)#\d+ \w+$") |
- datefmt = '%Y/%m/%d %H:%M:%S' |
- |
- parent = None # filled in when we're added |
- last_change = None |
- loop = None |
- working = False |
- |
- def __init__(self, p4port=None, p4user=None, p4passwd=None, |
- p4base='//', p4bin='p4', |
- split_file=lambda branchfile: (None, branchfile), |
- pollinterval=60 * 10, histmax=None): |
- """ |
- @type p4port: string |
- @param p4port: p4 port definition (host:portno) |
- @type p4user: string |
- @param p4user: p4 user |
- @type p4passwd: string |
- @param p4passwd: p4 passwd |
- @type p4base: string |
- @param p4base: p4 file specification to limit a poll to |
- without the trailing '...' (i.e., //) |
- @type p4bin: string |
- @param p4bin: path to p4 binary, defaults to just 'p4' |
- @type split_file: func |
- $param split_file: splits a filename into branch and filename. |
- @type pollinterval: int |
- @param pollinterval: interval in seconds between polls |
- @type histmax: int |
- @param histmax: (obsolete) maximum number of changes to look back through. |
- ignored; accepted for backwards compatibility. |
- """ |
- |
- self.p4port = p4port |
- self.p4user = p4user |
- self.p4passwd = p4passwd |
- self.p4base = p4base |
- self.p4bin = p4bin |
- self.split_file = split_file |
- self.pollinterval = pollinterval |
- self.loop = LoopingCall(self.checkp4) |
- |
- def startService(self): |
- base.ChangeSource.startService(self) |
- |
- # Don't start the loop just yet because the reactor isn't running. |
- # Give it a chance to go and install our SIGCHLD handler before |
- # spawning processes. |
- reactor.callLater(0, self.loop.start, self.pollinterval) |
- |
- def stopService(self): |
- self.loop.stop() |
- return base.ChangeSource.stopService(self) |
- |
- def describe(self): |
- return "p4source %s %s" % (self.p4port, self.p4base) |
- |
- def checkp4(self): |
- # Our return value is only used for unit testing. |
- if self.working: |
- log.msg("Skipping checkp4 because last one has not finished") |
- return defer.succeed(None) |
- else: |
- self.working = True |
- d = self._get_changes() |
- d.addCallback(self._process_changes) |
- d.addBoth(self._finished) |
- return d |
- |
- def _finished(self, res): |
- assert self.working |
- self.working = False |
- |
- # Again, the return value is only for unit testing. |
- # If there's a failure, log it so it isn't lost. |
- if isinstance(res, failure.Failure): |
- log.msg('P4 poll failed: %s' % res) |
- return None |
- return res |
- |
- def _get_changes(self): |
- args = [] |
- if self.p4port: |
- args.extend(['-p', self.p4port]) |
- if self.p4user: |
- args.extend(['-u', self.p4user]) |
- if self.p4passwd: |
- args.extend(['-P', self.p4passwd]) |
- args.extend(['changes']) |
- if self.last_change is not None: |
- args.extend(['%s...@%d,now' % (self.p4base, self.last_change+1)]) |
- else: |
- args.extend(['-m', '1', '%s...' % (self.p4base,)]) |
- env = {} |
- return getProcessOutput(self.p4bin, args, env) |
- |
- def _process_changes(self, result): |
- last_change = self.last_change |
- changelists = [] |
- for line in result.split('\n'): |
- line = line.strip() |
- if not line: continue |
- m = self.changes_line_re.match(line) |
- assert m, "Unexpected 'p4 changes' output: %r" % result |
- num = int(m.group('num')) |
- if last_change is None: |
- log.msg('P4Poller: starting at change %d' % num) |
- self.last_change = num |
- return [] |
- changelists.append(num) |
- changelists.reverse() # oldest first |
- |
- # Retrieve each sequentially. |
- d = defer.succeed(None) |
- for c in changelists: |
- d.addCallback(self._get_describe, c) |
- d.addCallback(self._process_describe, c) |
- return d |
- |
- def _get_describe(self, dummy, num): |
- args = [] |
- if self.p4port: |
- args.extend(['-p', self.p4port]) |
- if self.p4user: |
- args.extend(['-u', self.p4user]) |
- if self.p4passwd: |
- args.extend(['-P', self.p4passwd]) |
- args.extend(['describe', '-s', str(num)]) |
- env = {} |
- d = getProcessOutput(self.p4bin, args, env) |
- return d |
- |
- def _process_describe(self, result, num): |
- lines = result.split('\n') |
- # SF#1555985: Wade Brainerd reports a stray ^M at the end of the date |
- # field. The rstrip() is intended to remove that. |
- lines[0] = lines[0].rstrip() |
- m = self.describe_header_re.match(lines[0]) |
- assert m, "Unexpected 'p4 describe -s' result: %r" % result |
- who = m.group('who') |
- when = time.mktime(time.strptime(m.group('when'), self.datefmt)) |
- comments = '' |
- while not lines[0].startswith('Affected files'): |
- comments += lines.pop(0) + '\n' |
- lines.pop(0) # affected files |
- |
- branch_files = {} # dict for branch mapped to file(s) |
- while lines: |
- line = lines.pop(0).strip() |
- if not line: continue |
- m = self.file_re.match(line) |
- assert m, "Invalid file line: %r" % line |
- path = m.group('path') |
- if path.startswith(self.p4base): |
- branch, file = self.split_file(path[len(self.p4base):]) |
- if (branch == None and file == None): continue |
- if branch_files.has_key(branch): |
- branch_files[branch].append(file) |
- else: |
- branch_files[branch] = [file] |
- |
- for branch in branch_files: |
- c = changes.Change(who=who, |
- files=branch_files[branch], |
- comments=comments, |
- revision=num, |
- when=when, |
- branch=branch) |
- self.parent.addChange(c) |
- |
- self.last_change = num |