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 master = ui.config('hgbuildbot', 'master')
51 if master:
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 s = sendchange.Sender(master, auth=auth)
92 d = defer.Deferred()
93 reactor.callLater(0, d.callback, None)
94
95 def _send(res, c):
96 if not fork:
97 ui.status("rev %s sent\n" % c['revision'])
98 return s.send(c['branch'], c['revision'], c['comments'],
99 c['files'], c['username'], category=category,
100 repository=repository, project=project, vc='hg',
101 properties=c['properties'])
102
103 try:
104 start = repo[node].rev()
105 end = len(repo)
106 except TypeError:
107 start = repo.changelog.rev(bin(node))
108 end = repo.changelog.count()
109
110 repository = strip(repo.root, stripcount)
111 repository = baseurl + repository
112
113 for rev in xrange(start, end):
114
115 node = repo.changelog.node(rev)
116 manifest, user, (time, timezone), files, desc, extra = repo.changelog.read(node)
117 parents = filter(lambda p: not p == nullid, repo.changelog.parents(node))
118 if branchtype == 'inrepo':
119 branch = extra['branch']
120 is_merge = len(parents) > 1
121
122 if is_merge and not files:
123 files = ["merge"]
124 properties = {'is_merge': is_merge}
125 if branch:
126 branch = fromlocal(branch)
127 change = {
128 'master': master,
129 'username': fromlocal(user),
130 'revision': hex(node),
131 'comments': fromlocal(desc),
132 'files': files,
133 'branch': branch,
134 'properties':properties
135 }
136 d.addCallback(_send, change)
137
138 def _printSuccess(res):
139 ui.status(s.getSuccessString(res) + '\n')
140
141 def _printFailure(why):
142 ui.warn(s.getFailureString(why) + '\n')
143
144 d.addCallbacks(_printSuccess, _printFailure)
145 d.addBoth(lambda _ : reactor.stop())
146 reactor.run()
147
148 if fork:
149 os._exit(os.EX_OK)
150 else:
151 return
152
153
155 '''Strip the count first slash of the path'''
156
157
158 path = '/'.join(path.split(os.sep))
159
160 while count > 0:
161 c = path.find('/')
162 if c == -1:
163 break
164 path = path[c + 1:]
165 count -= 1
166 return path
167