OLD | NEW |
| (Empty) |
1 # hgbuildbot.py - mercurial hooks for buildbot | |
2 # | |
3 # Copyright 2007 Frederic Leroy <fredo@starox.org> | |
4 # | |
5 # This software may be used and distributed according to the terms | |
6 # of the GNU General Public License, incorporated herein by reference. | |
7 | |
8 # hook extension to send change notifications to buildbot when a changeset is | |
9 # brought into the repository from elsewhere. | |
10 # | |
11 # default mode is to use mercurial branch | |
12 # | |
13 # to use, configure hgbuildbot in .hg/hgrc like this: | |
14 # | |
15 # [hooks] | |
16 # changegroup = python:buildbot.changes.hgbuildbot.hook | |
17 # | |
18 # [hgbuildbot] | |
19 # # config items go in here | |
20 # | |
21 # config items: | |
22 # | |
23 # REQUIRED: | |
24 # master = host:port # host to send buildbot changes | |
25 # | |
26 # OPTIONAL: | |
27 # branchtype = inrepo|dirname # dirname: branch = name of directory | |
28 # # containing the repository | |
29 # # | |
30 # # inrepo: branch = mercurial branch | |
31 # | |
32 # branch = branchname # if set, branch is always branchname | |
33 | |
34 import os | |
35 | |
36 from mercurial.i18n import gettext as _ | |
37 from mercurial.node import bin, hex, nullid | |
38 from mercurial.context import workingctx | |
39 | |
40 # mercurial's on-demand-importing hacks interfere with the: | |
41 #from zope.interface import Interface | |
42 # that Twisted needs to do, so disable it. | |
43 try: | |
44 from mercurial import demandimport | |
45 demandimport.disable() | |
46 except ImportError: | |
47 pass | |
48 | |
49 from buildbot.clients import sendchange | |
50 from twisted.internet import defer, reactor | |
51 | |
52 | |
53 def hook(ui, repo, hooktype, node=None, source=None, **kwargs): | |
54 # read config parameters | |
55 master = ui.config('hgbuildbot', 'master') | |
56 if master: | |
57 branchtype = ui.config('hgbuildbot', 'branchtype') | |
58 branch = ui.config('hgbuildbot', 'branch') | |
59 else: | |
60 ui.write("* You must add a [hgbuildbot] section to .hg/hgrc in " | |
61 "order to use buildbot hook\n") | |
62 return | |
63 | |
64 if branch is None: | |
65 if branchtype is not None: | |
66 if branchtype == 'dirname': | |
67 branch = os.path.basename(os.getcwd()) | |
68 if branchtype == 'inrepo': | |
69 branch = workingctx(repo).branch() | |
70 | |
71 if hooktype == 'changegroup': | |
72 s = sendchange.Sender(master, None) | |
73 d = defer.Deferred() | |
74 reactor.callLater(0, d.callback, None) | |
75 # process changesets | |
76 def _send(res, c): | |
77 ui.status("rev %s sent\n" % c['revision']) | |
78 return s.send(c['branch'], c['revision'], c['comments'], | |
79 c['files'], c['username']) | |
80 | |
81 try: # first try Mercurial 1.1+ api | |
82 start = repo[node].rev() | |
83 end = len(repo) | |
84 except TypeError: # else fall back to old api | |
85 start = repo.changelog.rev(bin(node)) | |
86 end = repo.changelog.count() | |
87 | |
88 for rev in xrange(start, end): | |
89 # send changeset | |
90 node = repo.changelog.node(rev) | |
91 manifest, user, (time, timezone), files, desc, extra = repo.changelo
g.read(node) | |
92 parents = filter(lambda p: not p == nullid, repo.changelog.parents(n
ode)) | |
93 if branchtype == 'inrepo': | |
94 branch = extra['branch'] | |
95 # merges don't always contain files, but at least one file is requir
ed by buildbot | |
96 if len(parents) > 1 and not files: | |
97 files = ["merge"] | |
98 change = { | |
99 'master': master, | |
100 'username': user, | |
101 'revision': hex(node), | |
102 'comments': desc, | |
103 'files': files, | |
104 'branch': branch | |
105 } | |
106 d.addCallback(_send, change) | |
107 | |
108 d.addCallbacks(s.printSuccess, s.printFailure) | |
109 d.addBoth(s.stop) | |
110 s.run() | |
111 else: | |
112 ui.status(_('hgbuildbot: hook %s not supported\n') % hooktype) | |
113 return | |
114 | |
OLD | NEW |