Skip to content

Commit

Permalink
Add the possibility to run Mercurial Change Hook as a forked process
Browse files Browse the repository at this point in the history
  • Loading branch information
Benoit Allard committed Mar 2, 2010
1 parent bce5e33 commit 604a8fe
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 42 deletions.
104 changes: 62 additions & 42 deletions buildbot/changes/hgbuildbot.py
Expand Up @@ -30,6 +30,9 @@
# # inrepo: branch = mercurial branch
#
# branch = branchname # if set, branch is always branchname
#
# fork = True|False # if mercurial should fork before
# # notifying the master

import os

Expand All @@ -46,69 +49,86 @@
except ImportError:
pass

from buildbot.clients import sendchange
from twisted.internet import defer, reactor


def hook(ui, repo, hooktype, node=None, source=None, **kwargs):
# read config parameters
master = ui.config('hgbuildbot', 'master')
if master:
branchtype = ui.config('hgbuildbot', 'branchtype')
branch = ui.config('hgbuildbot', 'branch')
fork = ui.configbool('hgbuildbot', 'fork', False)
else:
ui.write("* You must add a [hgbuildbot] section to .hg/hgrc in "
"order to use buildbot hook\n")
return

if hooktype != "changegroup":
ui.status("hgbuildbot: hooktype %s not supported.\n" % hooktype)
return

if fork:
child_pid = os.fork()
if child_pid == 0:
#child
pass
else:
#parent
ui.status("Notifying buildbot...\n")
return

# only import inside the fork if forked
from buildbot.clients import sendchange
from twisted.internet import defer, reactor

if branch is None:
if branchtype is not None:
if branchtype == 'dirname':
branch = os.path.basename(os.getcwd())
if branchtype == 'inrepo':
branch = workingctx(repo).branch()

if hooktype == 'changegroup':
s = sendchange.Sender(master, None)
d = defer.Deferred()
reactor.callLater(0, d.callback, None)
# process changesets
def _send(res, c):
s = sendchange.Sender(master, None)
d = defer.Deferred()
reactor.callLater(0, d.callback, None)
# process changesets
def _send(res, c):
if not fork:
ui.status("rev %s sent\n" % c['revision'])
return s.send(c['branch'], c['revision'], c['comments'],
c['files'], c['username'])
return s.send(c['branch'], c['revision'], c['comments'],
c['files'], c['username'])

try: # first try Mercurial 1.1+ api
start = repo[node].rev()
end = len(repo)
except TypeError: # else fall back to old api
start = repo.changelog.rev(bin(node))
end = repo.changelog.count()
try: # first try Mercurial 1.1+ api
start = repo[node].rev()
end = len(repo)
except TypeError: # else fall back to old api
start = repo.changelog.rev(bin(node))
end = repo.changelog.count()

for rev in xrange(start, end):
# send changeset
node = repo.changelog.node(rev)
manifest, user, (time, timezone), files, desc, extra = repo.changelog.read(node)
parents = filter(lambda p: not p == nullid, repo.changelog.parents(node))
if branchtype == 'inrepo':
branch = extra['branch']
# merges don't always contain files, but at least one file is required by buildbot
if len(parents) > 1 and not files:
files = ["merge"]
change = {
'master': master,
'username': user,
'revision': hex(node),
'comments': desc,
'files': files,
'branch': branch
}
d.addCallback(_send, change)
for rev in xrange(start, end):
# send changeset
node = repo.changelog.node(rev)
manifest, user, (time, timezone), files, desc, extra = repo.changelog.read(node)
parents = filter(lambda p: not p == nullid, repo.changelog.parents(node))
if branchtype == 'inrepo':
branch = extra['branch']
# merges don't always contain files, but at least one file is required by buildbot
if len(parents) > 1 and not files:
files = ["merge"]
change = {
'master': master,
'username': user,
'revision': hex(node),
'comments': desc,
'files': files,
'branch': branch
}
d.addCallback(_send, change)

d.addCallbacks(s.printSuccess, s.printFailure)
d.addBoth(s.stop)
s.run()
d.addCallbacks(s.printSuccess, s.printFailure)
d.addBoth(s.stop)
s.run()

if fork:
os._exit(os.EX_OK)
else:
ui.status(_('hgbuildbot: hook %s not supported\n') % hooktype)
return
return

7 changes: 7 additions & 0 deletions docs/cfg-changesources.texinfo
Expand Up @@ -655,6 +655,13 @@ If you use @code{branch=} like this, you'll need to put a separate
able to use the same .hgrc for all your repositories, stored in
@file{~/.hgrc} or @file{/etc/mercurial/hgrc}.

As twisted needs to hook some Signals, and that some web server are
strictly forbiding that, the parameter @code{fork} in the
@code{[hgbuildbot]} section will instruct mercurial to fork before
sending the change request. Then as the created process will be of short
life, it is considered as safe to disable the signal restriction in
the Apache setting like that @code{WSGIRestrictSignal Off}. Refer to the
documentation of your web server for other way to do the same.

@node Bzr Hook
@subsubsection Bzr Hook
Expand Down

0 comments on commit 604a8fe

Please sign in to comment.