Skip to content

Commit

Permalink
BitKeeper hook script, based off of svn_buildbot.py.
Browse files Browse the repository at this point in the history
  • Loading branch information
Amar Takhar committed Jan 3, 2010
1 parent 22f923d commit bd0ba65
Showing 1 changed file with 165 additions and 0 deletions.
165 changes: 165 additions & 0 deletions contrib/bk_buildbot.py
@@ -0,0 +1,165 @@
#!/usr/local/bin/python
#
# BitKeeper hook script.
#
# svn_buildbot.py was used as a base for this file, if you find any bugs or
# errors please email me.
#
# Amar Takhar <amar@ntp.org>


'''
/path/to/bk_buildbot.py --repository "$REPOS" --revision "$REV" --branch \
"<branch>" --bbserver localhost --bbport 9989
'''

import commands
import sys
import os
import re
if sys.version_info < (2, 6):
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)"],
['branch', 'b', None,
"Name of the branch to insert into the branch field. (REQUIRED)"],
['category', 'c', None,
"Schedular category."],
['bbserver', 's', 'localhost',
"The hostname of the server that buildbot is running on"],
['bbport', 'p', 8007,
"The port that buildbot is listening on"]
]
optFlags = [
['dryrun', 'n', "Do not actually send changes"],
]

def __init__(self):
usage.Options.__init__(self)

def postOptions(self):
if self['repository'] is None:
raise usage.error("You must pass --repository")

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("bk changes -v %s -d':GFILE:\\n' '%s'" % (
rev_arg, repo)).split('\n')

# Remove the first line, it's an info message you can't remove (annoying)
del changed[0]

change_info = commands.getoutput("bk changes %s -d':USER:\\n$each(:C:){(:C:)\\n}' '%s'" % (
rev_arg, repo)).split('\n')

# Remove the first line, it's an info message you can't remove (annoying)
del change_info[0]

who = change_info.pop(0)
branch = opts['branch']
message = '\n'.join(change_info)
revision = opts.get('revision')

changes = {'who': who,
'branch': branch,
'files': changed,
'comments': message,
'revision': revision}

if opts.get('category'):
changes['category'] = opts.get('category')

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', changes)
return dl

def run(self):
opts = Options()
try:
opts.parseOptions()
if not opts['branch']:
print "You must supply a branch with -b or --branch."
sys.exit(1);

except usage.error, ue:
print opts
print "%s: %s" % (sys.argv[0], ue)
sys.exit()

changes = self.getChanges(opts)
if opts['dryrun']:
for k in changes.keys():
print "[%10s]: %s" % (k, changes[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: %s" % f
reactor.stop()

d.addErrback(failed)
d.addCallback(quit, "SUCCESS")
reactor.callLater(60, quit, "TIMEOUT")

reactor.run()


if __name__ == '__main__':
s = ChangeSender()
s.run()

0 comments on commit bd0ba65

Please sign in to comment.