Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/buildbot/contrib/svn_buildbot.py
diff options
context:
space:
mode:
Diffstat (limited to 'buildbot/contrib/svn_buildbot.py')
-rwxr-xr-xbuildbot/contrib/svn_buildbot.py260
1 files changed, 0 insertions, 260 deletions
diff --git a/buildbot/contrib/svn_buildbot.py b/buildbot/contrib/svn_buildbot.py
deleted file mode 100755
index 5a671dc..0000000
--- a/buildbot/contrib/svn_buildbot.py
+++ /dev/null
@@ -1,260 +0,0 @@
-#!/usr/bin/python
-
-# this requires python >=2.3 for the 'sets' module.
-
-# The sets.py from python-2.3 appears to work fine under python2.2 . To
-# install this script on a host with only python2.2, copy
-# /usr/lib/python2.3/sets.py from a newer python into somewhere on your
-# PYTHONPATH, then edit the #! line above to invoke python2.2
-
-# python2.1 is right out
-
-# If you run this program as part of your SVN post-commit hooks, it will
-# deliver Change notices to a buildmaster that is running a PBChangeSource
-# instance.
-
-# edit your svn-repository/hooks/post-commit file, and add lines that look
-# like this:
-
-'''
-# set up PYTHONPATH to contain Twisted/buildbot perhaps, if not already
-# installed site-wide
-. ~/.environment
-
-/path/to/svn_buildbot.py --repository "$REPOS" --revision "$REV" \
---bbserver localhost --bbport 9989
-'''
-
-import commands
-import sys
-import os
-import re
-import sets
-
-# We have hackish "-d" handling here rather than in the Options
-# subclass below because a common error will be to not have twisted in
-# PYTHONPATH; we want to be able to print that error to the log if
-# debug mode is on, so we set it up before the imports.
-
-DEBUG = None
-
-if '-d' in sys.argv:
- i = sys.argv.index('-d')
- DEBUG = sys.argv[i+1]
- del sys.argv[i]
- del sys.argv[i]
-
-if DEBUG:
- f = open(DEBUG, 'a')
- sys.stderr = f
- sys.stdout = f
-
-
-from twisted.internet import defer, reactor
-from twisted.python import usage
-from twisted.spread import pb
-from twisted.cred import credentials
-
-
-class Options(usage.Options):
- optParameters = [
- ['repository', 'r', None,
- "The repository that was changed."],
- ['revision', 'v', None,
- "The revision that we want to examine (default: latest)"],
- ['bbserver', 's', 'localhost',
- "The hostname of the server that buildbot is running on"],
- ['bbport', 'p', 8007,
- "The port that buildbot is listening on"],
- ['include', 'f', None,
- '''\
-Search the list of changed files for this regular expression, and if there is
-at least one match notify buildbot; otherwise buildbot will not do a build.
-You may provide more than one -f argument to try multiple
-patterns. If no filter is given, buildbot will always be notified.'''],
- ['filter', 'f', None, "Same as --include. (Deprecated)"],
- ['exclude', 'F', None,
- '''\
-The inverse of --filter. Changed files matching this expression will never
-be considered for a build.
-You may provide more than one -F argument to try multiple
-patterns. Excludes override includes, that is, patterns that match both an
-include and an exclude will be excluded.'''],
- ]
- optFlags = [
- ['dryrun', 'n', "Do not actually send changes"],
- ]
-
- def __init__(self):
- usage.Options.__init__(self)
- self._includes = []
- self._excludes = []
- self['includes'] = None
- self['excludes'] = None
-
- def opt_include(self, arg):
- self._includes.append('.*%s.*' % (arg, ))
-
- opt_filter = opt_include
-
- def opt_exclude(self, arg):
- self._excludes.append('.*%s.*' % (arg, ))
-
- def postOptions(self):
- if self['repository'] is None:
- raise usage.error("You must pass --repository")
- if self._includes:
- self['includes'] = '(%s)' % ('|'.join(self._includes), )
- if self._excludes:
- self['excludes'] = '(%s)' % ('|'.join(self._excludes), )
-
-
-def split_file_dummy(changed_file):
- """Split the repository-relative filename into a tuple of (branchname,
- branch_relative_filename). If you have no branches, this should just
- return (None, changed_file).
- """
- return (None, changed_file)
-
-
-# this version handles repository layouts that look like:
-# trunk/files.. -> trunk
-# branches/branch1/files.. -> branches/branch1
-# branches/branch2/files.. -> branches/branch2
-#
-
-
-def split_file_branches(changed_file):
- pieces = changed_file.split(os.sep)
- if pieces[0] == 'branches':
- return (os.path.join(*pieces[:2]),
- os.path.join(*pieces[2:]))
- if pieces[0] == 'trunk':
- return (pieces[0], os.path.join(*pieces[1:]))
- ## there are other sibilings of 'trunk' and 'branches'. Pretend they are
- ## all just funny-named branches, and let the Schedulers ignore them.
- #return (pieces[0], os.path.join(*pieces[1:]))
-
- raise RuntimeError("cannot determine branch for '%s'" % changed_file)
-
-
-split_file = split_file_dummy
-
-
-class ChangeSender:
-
- def getChanges(self, opts):
- """Generate and stash a list of Change dictionaries, ready to be sent
- to the buildmaster's PBChangeSource."""
-
- # first we extract information about the files that were changed
- repo = opts['repository']
- print "Repo:", repo
- rev_arg = ''
- if opts['revision']:
- rev_arg = '-r %s' % (opts['revision'], )
- changed = commands.getoutput('svnlook changed %s "%s"' % (
- rev_arg, repo)).split('\n')
- # the first 4 columns can contain status information
- changed = [x[4:] for x in changed]
-
- message = commands.getoutput('svnlook log %s "%s"' % (rev_arg, repo))
- who = commands.getoutput('svnlook author %s "%s"' % (rev_arg, repo))
- revision = opts.get('revision')
- if revision is not None:
- revision = int(revision)
-
- # see if we even need to notify buildbot by looking at filters first
- changestring = '\n'.join(changed)
- fltpat = opts['includes']
- if fltpat:
- included = sets.Set(re.findall(fltpat, changestring))
- else:
- included = sets.Set(changed)
-
- expat = opts['excludes']
- if expat:
- excluded = sets.Set(re.findall(expat, changestring))
- else:
- excluded = sets.Set([])
- if len(included.difference(excluded)) == 0:
- print changestring
- print """\
- Buildbot was not interested, no changes matched any of these filters:\n %s
- or all the changes matched these exclusions:\n %s\
- """ % (fltpat, expat)
- sys.exit(0)
-
- # now see which branches are involved
- files_per_branch = {}
- for f in changed:
- branch, filename = split_file(f)
- if branch in files_per_branch.keys():
- files_per_branch[branch].append(filename)
- else:
- files_per_branch[branch] = [filename]
-
- # now create the Change dictionaries
- changes = []
- for branch in files_per_branch.keys():
- d = {'who': who,
- 'branch': branch,
- 'files': files_per_branch[branch],
- 'comments': message,
- 'revision': revision}
- changes.append(d)
-
- return changes
-
- def sendChanges(self, opts, changes):
- pbcf = pb.PBClientFactory()
- reactor.connectTCP(opts['bbserver'], int(opts['bbport']), pbcf)
- d = pbcf.login(credentials.UsernamePassword('change', 'changepw'))
- d.addCallback(self.sendAllChanges, changes)
- return d
-
- def sendAllChanges(self, remote, changes):
- dl = [remote.callRemote('addChange', change)
- for change in changes]
- return defer.DeferredList(dl)
-
- def run(self):
- opts = Options()
- try:
- opts.parseOptions()
- except usage.error, ue:
- print opts
- print "%s: %s" % (sys.argv[0], ue)
- sys.exit()
-
- changes = self.getChanges(opts)
- if opts['dryrun']:
- for i, c in enumerate(changes):
- print "CHANGE #%d" % (i+1)
- keys = c.keys()
- keys.sort()
- for k in keys:
- print "[%10s]: %s" % (k, c[k])
- print "*NOT* sending any changes"
- return
-
- d = self.sendChanges(opts, changes)
-
- def quit(*why):
- print "quitting! because", why
- reactor.stop()
-
- def failed(f):
- print "FAILURE"
- print f
- reactor.stop()
-
- d.addCallback(quit, "SUCCESS")
- d.addErrback(failed)
- reactor.callLater(60, quit, "TIMEOUT")
- reactor.run()
-
-
-if __name__ == '__main__':
- s = ChangeSender()
- s.run()