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