forked from buildbot/buildbot
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
BitKeeper hook script, based off of svn_buildbot.py.
- Loading branch information
Amar Takhar
committed
Jan 3, 2010
1 parent
22f923d
commit bd0ba65
Showing
1 changed file
with
165 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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() |