1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56 import os
57
58 from mercurial.node import bin, hex, nullid
59 from mercurial.context import workingctx
60
61
62
63
64 try:
65 from mercurial import demandimport
66 demandimport.disable()
67 except ImportError:
68 pass
69
70
71
72
73 try:
74 from mercurial.encoding import fromlocal
75 _hush_pyflakes = [fromlocal]
76 del _hush_pyflakes
77 except ImportError:
80
81 -def hook(ui, repo, hooktype, node=None, source=None, **kwargs):
82
83 master = ui.config('hgbuildbot', 'master')
84 if master:
85 branchtype = ui.config('hgbuildbot', 'branchtype')
86 branch = ui.config('hgbuildbot', 'branch')
87 fork = ui.configbool('hgbuildbot', 'fork', False)
88
89 stripcount = int(ui.config('notify','strip') or ui.config('hgbuildbot','strip',3))
90 category = ui.config('hgbuildbot', 'category', None)
91 project = ui.config('hgbuildbot', 'project', '')
92 auth = ui.config('hgbuildbot', 'auth', None)
93 else:
94 ui.write("* You must add a [hgbuildbot] section to .hg/hgrc in "
95 "order to use buildbot hook\n")
96 return
97
98 if hooktype != "changegroup":
99 ui.status("hgbuildbot: hooktype %s not supported.\n" % hooktype)
100 return
101
102 if fork:
103 child_pid = os.fork()
104 if child_pid == 0:
105
106 pass
107 else:
108
109 ui.status("Notifying buildbot...\n")
110 return
111
112
113 from buildbot.clients import sendchange
114 from twisted.internet import defer, reactor
115
116 if branch is None:
117 if branchtype is not None:
118 if branchtype == 'dirname':
119 branch = os.path.basename(repo.root)
120 if branchtype == 'inrepo':
121 branch = workingctx(repo).branch()
122
123 if not auth:
124 auth = 'change:changepw'
125 auth = auth.split(':', 1)
126
127 s = sendchange.Sender(master, auth=auth)
128 d = defer.Deferred()
129 reactor.callLater(0, d.callback, None)
130
131 def _send(res, c):
132 if not fork:
133 ui.status("rev %s sent\n" % c['revision'])
134 return s.send(c['branch'], c['revision'], c['comments'],
135 c['files'], c['username'], category=category,
136 repository=repository, project=project)
137
138 try:
139 start = repo[node].rev()
140 end = len(repo)
141 except TypeError:
142 start = repo.changelog.rev(bin(node))
143 end = repo.changelog.count()
144
145 repository = strip(repo.root, stripcount)
146
147 for rev in xrange(start, end):
148
149 node = repo.changelog.node(rev)
150 manifest, user, (time, timezone), files, desc, extra = repo.changelog.read(node)
151 parents = filter(lambda p: not p == nullid, repo.changelog.parents(node))
152 if branchtype == 'inrepo':
153 branch = extra['branch']
154
155 if len(parents) > 1 and not files:
156 files = ["merge"]
157 if branch:
158 branch = fromlocal(branch)
159 change = {
160 'master': master,
161 'username': fromlocal(user),
162 'revision': hex(node),
163 'comments': fromlocal(desc),
164 'files': files,
165 'branch': branch
166 }
167 d.addCallback(_send, change)
168
169 def _printSuccess(res):
170 ui.status(s.getSuccessString(res) + '\n')
171
172 def _printFailure(why):
173 ui.warn(s.getFailureString(why) + '\n')
174
175 d.addCallbacks(_printSuccess, _printFailure)
176 d.addBoth(lambda _ : reactor.stop())
177 reactor.run()
178
179 if fork:
180 os._exit(os.EX_OK)
181 else:
182 return
183
184
186 '''Strip the count first slash of the path'''
187
188
189 path = '/'.join(path.split(os.sep))
190
191 while count > 0:
192 c = path.find('/')
193 if c == -1:
194 break
195 path = path[c + 1:]
196 count -= 1
197 return path
198