##// END OF EJS Templates
release: merge back stable branch into default
marcink -
r441:86f525c3 merge default
parent child Browse files
Show More
@@ -1,38 +1,39 b''
1 1 c6fad7d1e61f22b1f4a4863eff207a04c27e9462 v4.0.0
2 2 77b6e243b4cc5b702c15abd6d737798edbac60dc v4.0.1
3 3 a359c072337fdd8e1e71df72cc520b8a9b042f80 v4.1.0
4 4 49aa7ed030a36b7ceba149a21e587cb5d20b4946 v4.1.1
5 5 f38ed1e1a31dce3c170b4d31585ba43471cf0705 v4.1.2
6 6 21269ba7bafd8f0c77e79dd86a31eb9bce7643d2 v4.2.0
7 7 b53930c918c25b2c8f69ceddc6641e511be27fd3 v4.2.1
8 8 6627ff4119723d8b2b60918e8b1aa49e9f055aab v4.3.0
9 9 d38f2c2b861dde6c4178923f7cf15ea58b85aa92 v4.3.1
10 10 1232313f9e6adac5ce5399c2a891dc1e72b79022 v4.4.0
11 11 cbb9f1d329ae5768379cdec55a62ebdd546c4e27 v4.4.1
12 12 24ffe44a27fcd1c5b6936144e176b9f6dd2f3a17 v4.4.2
13 13 beaeeaa440cd17471110d4621b8816506c0dff4a v4.5.0
14 14 668e5c656f61dd94595611844e1106d1361aa6a7 v4.5.1
15 15 ae0640240cb7a77e6dc8c77e64dd80d79732cb5b v4.5.2
16 16 7af06899f426813583fe60449d7517cc49c15b28 v4.6.0
17 17 8f7f4299bf341b43f94dadafa1ea73d6cea2c9ba v4.6.1
18 18 de00a831a0709ffaac57f948738ea927b97223a9 v4.7.0
19 19 57f527e0646d731768fb5e0fe742b12a35bdc63b v4.7.1
20 20 f9b09787da9845e4a105f4bffdc252099902cefb v4.7.2
21 21 0b7c790b726f08385e6ebdf4f257c905787b9244 v4.8.0
22 22 f4123e725b74d0e82fe89982ab8791a66062e2b3 v4.9.0
23 23 940bac044a0fe1ec839759df81399b50141be720 v4.9.1
24 24 582d9ebbe46bdddac4b26eacae36ee5ecabca267 v4.10.0
25 25 12fbd08d0ab57acce9c0bdccee75633cfa08d7f4 v4.10.1
26 26 78352f95021a9d128f5803fdbca7036daef5dabe v4.10.2
27 27 a47ccfb020cda78c8680e3844aaf0b82b1390f3b v4.10.3
28 28 347ae9ae544bba8deb417995285287a3b6be1611 v4.10.4
29 29 9b257ac49841f850434be0d518baca0827e6c8cc v4.10.5
30 30 e8bf26eea118694edc4ffe50c6c5aa91022bc434 v4.10.6
31 31 71fa9274ba59fb982104f0b9b3d0d024c78675f7 v4.11.0
32 32 92471577ef25636e5babe8001d47fc8e51521522 v4.11.1
33 33 0277edbcda5a8d075e1e41a95bcee6dcf21f3f77 v4.11.2
34 34 6c5ecbf0778ef870e5b23d9fad5340135b563356 v4.11.3
35 35 be788a89a939ebd63606220064bd624fa9d5c9c9 v4.11.4
36 36 15c90a04098a373ac761fab07695fd80dde3bcdb v4.11.5
37 37 77aff155b3251cc00394a49f5e8f2c99e33149a7 v4.11.6
38 38 c218a1ce5d370c2e671d42a91684b3fc2c91b81d v4.12.0
39 80085fb846cc948195a5c76b579ca34cbc49b59b v4.12.1
@@ -1,51 +1,51 b''
1 1 #!_ENV_
2 2 import os
3 3 import sys
4 4 path_adjust = [_PATH_]
5 5
6 6 if path_adjust:
7 7 sys.path = path_adjust
8 8
9 9 try:
10 10 from vcsserver import hooks
11 11 except ImportError:
12 12 if os.environ.get('RC_DEBUG_GIT_HOOK'):
13 13 import traceback
14 14 print traceback.format_exc()
15 15 hooks = None
16 16
17 17
18 18 # TIMESTAMP: _DATE_
19 19 RC_HOOK_VER = '_TMPL_'
20 20
21 21
22 22 def main():
23 23 if hooks is None:
24 24 # exit with success if we cannot import vcsserver.hooks !!
25 25 # this allows simply push to this repo even without rhodecode
26 26 sys.exit(0)
27 27
28 if os.environ.get('RC_SKIP_HOOKS'):
28 if os.environ.get('RC_SKIP_HOOKS') or os.environ.get('RC_SKIP_GIT_HOOKS'):
29 29 sys.exit(0)
30 30
31 31 repo_path = os.getcwd()
32 32 push_data = sys.stdin.readlines()
33 33 os.environ['RC_HOOK_VER'] = RC_HOOK_VER
34 34 # os.environ is modified here by a subprocess call that
35 35 # runs git and later git executes this hook.
36 36 # Environ gets some additional info from rhodecode system
37 37 # like IP or username from basic-auth
38 38 try:
39 39 result = hooks.git_post_receive(repo_path, push_data, os.environ)
40 40 sys.exit(result)
41 41 except Exception as error:
42 42 # TODO: johbo: Improve handling of this special case
43 43 if not getattr(error, '_vcs_kind', None) == 'repo_locked':
44 44 raise
45 45 print 'ERROR:', error
46 46 sys.exit(1)
47 47 sys.exit(0)
48 48
49 49
50 50 if __name__ == '__main__':
51 51 main()
@@ -1,51 +1,51 b''
1 1 #!_ENV_
2 2 import os
3 3 import sys
4 4 path_adjust = [_PATH_]
5 5
6 6 if path_adjust:
7 7 sys.path = path_adjust
8 8
9 9 try:
10 10 from vcsserver import hooks
11 11 except ImportError:
12 12 if os.environ.get('RC_DEBUG_GIT_HOOK'):
13 13 import traceback
14 14 print traceback.format_exc()
15 15 hooks = None
16 16
17 17
18 18 # TIMESTAMP: _DATE_
19 19 RC_HOOK_VER = '_TMPL_'
20 20
21 21
22 22 def main():
23 23 if hooks is None:
24 24 # exit with success if we cannot import vcsserver.hooks !!
25 25 # this allows simply push to this repo even without rhodecode
26 26 sys.exit(0)
27 27
28 if os.environ.get('RC_SKIP_HOOKS'):
28 if os.environ.get('RC_SKIP_HOOKS') or os.environ.get('RC_SKIP_GIT_HOOKS'):
29 29 sys.exit(0)
30 30
31 31 repo_path = os.getcwd()
32 32 push_data = sys.stdin.readlines()
33 33 os.environ['RC_HOOK_VER'] = RC_HOOK_VER
34 34 # os.environ is modified here by a subprocess call that
35 35 # runs git and later git executes this hook.
36 36 # Environ gets some additional info from rhodecode system
37 37 # like IP or username from basic-auth
38 38 try:
39 39 result = hooks.git_pre_receive(repo_path, push_data, os.environ)
40 40 sys.exit(result)
41 41 except Exception as error:
42 42 # TODO: johbo: Improve handling of this special case
43 43 if not getattr(error, '_vcs_kind', None) == 'repo_locked':
44 44 raise
45 45 print 'ERROR:', error
46 46 sys.exit(1)
47 47 sys.exit(0)
48 48
49 49
50 50 if __name__ == '__main__':
51 51 main()
@@ -1,50 +1,50 b''
1 1 #!_ENV_
2 2
3 3 import os
4 4 import sys
5 5 path_adjust = [_PATH_]
6 6
7 7 if path_adjust:
8 8 sys.path = path_adjust
9 9
10 10 try:
11 11 from vcsserver import hooks
12 12 except ImportError:
13 13 if os.environ.get('RC_DEBUG_SVN_HOOK'):
14 14 import traceback
15 15 print traceback.format_exc()
16 16 hooks = None
17 17
18 18
19 19 # TIMESTAMP: _DATE_
20 20 RC_HOOK_VER = '_TMPL_'
21 21
22 22
23 23 def main():
24 24 if hooks is None:
25 25 # exit with success if we cannot import vcsserver.hooks !!
26 26 # this allows simply push to this repo even without rhodecode
27 27 sys.exit(0)
28 28
29 if os.environ.get('RC_SKIP_HOOKS'):
29 if os.environ.get('RC_SKIP_HOOKS') or os.environ.get('RC_SKIP_SVN_HOOKS'):
30 30 sys.exit(0)
31 31 repo_path = os.getcwd()
32 32 push_data = sys.argv[1:]
33 33
34 34 os.environ['RC_HOOK_VER'] = RC_HOOK_VER
35 35
36 36 try:
37 37 result = hooks.svn_post_commit(repo_path, push_data, os.environ)
38 38 sys.exit(result)
39 39 except Exception as error:
40 40 # TODO: johbo: Improve handling of this special case
41 41 if not getattr(error, '_vcs_kind', None) == 'repo_locked':
42 42 raise
43 43 print 'ERROR:', error
44 44 sys.exit(1)
45 45 sys.exit(0)
46 46
47 47
48 48
49 49 if __name__ == '__main__':
50 50 main()
@@ -1,52 +1,52 b''
1 1 #!_ENV_
2 2
3 3 import os
4 4 import sys
5 5 path_adjust = [_PATH_]
6 6
7 7 if path_adjust:
8 8 sys.path = path_adjust
9 9
10 10 try:
11 11 from vcsserver import hooks
12 12 except ImportError:
13 13 if os.environ.get('RC_DEBUG_SVN_HOOK'):
14 14 import traceback
15 15 print traceback.format_exc()
16 16 hooks = None
17 17
18 18
19 19 # TIMESTAMP: _DATE_
20 20 RC_HOOK_VER = '_TMPL_'
21 21
22 22
23 23 def main():
24 24 if os.environ.get('SSH_READ_ONLY') == '1':
25 25 sys.stderr.write('Only read-only access is allowed')
26 26 sys.exit(1)
27 27
28 28 if hooks is None:
29 29 # exit with success if we cannot import vcsserver.hooks !!
30 30 # this allows simply push to this repo even without rhodecode
31 31 sys.exit(0)
32 if os.environ.get('RC_SKIP_HOOKS'):
32 if os.environ.get('RC_SKIP_HOOKS') or os.environ.get('RC_SKIP_SVN_HOOKS'):
33 33 sys.exit(0)
34 34 repo_path = os.getcwd()
35 35 push_data = sys.argv[1:]
36 36
37 37 os.environ['RC_HOOK_VER'] = RC_HOOK_VER
38 38
39 39 try:
40 40 result = hooks.svn_pre_commit(repo_path, push_data, os.environ)
41 41 sys.exit(result)
42 42 except Exception as error:
43 43 # TODO: johbo: Improve handling of this special case
44 44 if not getattr(error, '_vcs_kind', None) == 'repo_locked':
45 45 raise
46 46 print 'ERROR:', error
47 47 sys.exit(1)
48 48 sys.exit(0)
49 49
50 50
51 51 if __name__ == '__main__':
52 52 main()
@@ -1,543 +1,572 b''
1 1 # -*- coding: utf-8 -*-
2 2
3 3 # RhodeCode VCSServer provides access to different vcs backends via network.
4 4 # Copyright (C) 2014-2018 RhodeCode GmbH
5 5 #
6 6 # This program is free software; you can redistribute it and/or modify
7 7 # it under the terms of the GNU General Public License as published by
8 8 # the Free Software Foundation; either version 3 of the License, or
9 9 # (at your option) any later version.
10 10 #
11 11 # This program is distributed in the hope that it will be useful,
12 12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 14 # GNU General Public License for more details.
15 15 #
16 16 # You should have received a copy of the GNU General Public License
17 17 # along with this program; if not, write to the Free Software Foundation,
18 18 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 19
20 20 import io
21 21 import os
22 22 import sys
23 23 import logging
24 24 import collections
25 25 import importlib
26 26 import base64
27 27
28 28 from httplib import HTTPConnection
29 29
30 30
31 31 import mercurial.scmutil
32 32 import mercurial.node
33 33 import simplejson as json
34 34
35 35 from vcsserver import exceptions, subprocessio, settings
36 36
37 37 log = logging.getLogger(__name__)
38 38
39 39
40 40 class HooksHttpClient(object):
41 41 connection = None
42 42
43 43 def __init__(self, hooks_uri):
44 44 self.hooks_uri = hooks_uri
45 45
46 46 def __call__(self, method, extras):
47 47 connection = HTTPConnection(self.hooks_uri)
48 48 body = self._serialize(method, extras)
49 49 try:
50 50 connection.request('POST', '/', body)
51 51 except Exception:
52 52 log.error('Connection failed on %s', connection)
53 53 raise
54 54 response = connection.getresponse()
55 55 return json.loads(response.read())
56 56
57 57 def _serialize(self, hook_name, extras):
58 58 data = {
59 59 'method': hook_name,
60 60 'extras': extras
61 61 }
62 62 return json.dumps(data)
63 63
64 64
65 65 class HooksDummyClient(object):
66 66 def __init__(self, hooks_module):
67 67 self._hooks_module = importlib.import_module(hooks_module)
68 68
69 69 def __call__(self, hook_name, extras):
70 70 with self._hooks_module.Hooks() as hooks:
71 71 return getattr(hooks, hook_name)(extras)
72 72
73 73
74 74 class RemoteMessageWriter(object):
75 75 """Writer base class."""
76 76 def write(self, message):
77 77 raise NotImplementedError()
78 78
79 79
80 80 class HgMessageWriter(RemoteMessageWriter):
81 81 """Writer that knows how to send messages to mercurial clients."""
82 82
83 83 def __init__(self, ui):
84 84 self.ui = ui
85 85
86 86 def write(self, message):
87 87 # TODO: Check why the quiet flag is set by default.
88 88 old = self.ui.quiet
89 89 self.ui.quiet = False
90 90 self.ui.status(message.encode('utf-8'))
91 91 self.ui.quiet = old
92 92
93 93
94 94 class GitMessageWriter(RemoteMessageWriter):
95 95 """Writer that knows how to send messages to git clients."""
96 96
97 97 def __init__(self, stdout=None):
98 98 self.stdout = stdout or sys.stdout
99 99
100 100 def write(self, message):
101 101 self.stdout.write(message.encode('utf-8'))
102 102
103 103
104 104 class SvnMessageWriter(RemoteMessageWriter):
105 105 """Writer that knows how to send messages to svn clients."""
106 106
107 107 def __init__(self, stderr=None):
108 108 # SVN needs data sent to stderr for back-to-client messaging
109 109 self.stderr = stderr or sys.stderr
110 110
111 111 def write(self, message):
112 112 self.stderr.write(message.encode('utf-8'))
113 113
114 114
115 115 def _handle_exception(result):
116 116 exception_class = result.get('exception')
117 117 exception_traceback = result.get('exception_traceback')
118 118
119 119 if exception_traceback:
120 120 log.error('Got traceback from remote call:%s', exception_traceback)
121 121
122 122 if exception_class == 'HTTPLockedRC':
123 123 raise exceptions.RepositoryLockedException(*result['exception_args'])
124 124 elif exception_class == 'RepositoryError':
125 125 raise exceptions.VcsException(*result['exception_args'])
126 126 elif exception_class:
127 127 raise Exception('Got remote exception "%s" with args "%s"' %
128 128 (exception_class, result['exception_args']))
129 129
130 130
131 131 def _get_hooks_client(extras):
132 132 if 'hooks_uri' in extras:
133 133 protocol = extras.get('hooks_protocol')
134 134 return HooksHttpClient(extras['hooks_uri'])
135 135 else:
136 136 return HooksDummyClient(extras['hooks_module'])
137 137
138 138
139 139 def _call_hook(hook_name, extras, writer):
140 140 hooks_client = _get_hooks_client(extras)
141 141 log.debug('Hooks, using client:%s', hooks_client)
142 142 result = hooks_client(hook_name, extras)
143 143 log.debug('Hooks got result: %s', result)
144 144 writer.write(result['output'])
145 145 _handle_exception(result)
146 146
147 147 return result['status']
148 148
149 149
150 150 def _extras_from_ui(ui):
151 151 hook_data = ui.config('rhodecode', 'RC_SCM_DATA')
152 152 if not hook_data:
153 153 # maybe it's inside environ ?
154 154 env_hook_data = os.environ.get('RC_SCM_DATA')
155 155 if env_hook_data:
156 156 hook_data = env_hook_data
157 157
158 158 extras = {}
159 159 if hook_data:
160 160 extras = json.loads(hook_data)
161 161 return extras
162 162
163 163
164 164 def _rev_range_hash(repo, node):
165 165
166 166 commits = []
167 167 start = repo[node].rev()
168 168 for rev in xrange(start, len(repo)):
169 169 ctx = repo[rev]
170 170 commit_id = mercurial.node.hex(ctx.node())
171 171 branch = ctx.branch()
172 172 commits.append((commit_id, branch))
173 173
174 174 return commits
175 175
176 176
177 177 def repo_size(ui, repo, **kwargs):
178 178 extras = _extras_from_ui(ui)
179 179 return _call_hook('repo_size', extras, HgMessageWriter(ui))
180 180
181 181
182 182 def pre_pull(ui, repo, **kwargs):
183 183 extras = _extras_from_ui(ui)
184 184 return _call_hook('pre_pull', extras, HgMessageWriter(ui))
185 185
186 186
187 187 def pre_pull_ssh(ui, repo, **kwargs):
188 188 extras = _extras_from_ui(ui)
189 189 if extras and extras.get('SSH'):
190 190 return pre_pull(ui, repo, **kwargs)
191 191 return 0
192 192
193 193
194 194 def post_pull(ui, repo, **kwargs):
195 195 extras = _extras_from_ui(ui)
196 196 return _call_hook('post_pull', extras, HgMessageWriter(ui))
197 197
198 198
199 199 def post_pull_ssh(ui, repo, **kwargs):
200 200 extras = _extras_from_ui(ui)
201 201 if extras and extras.get('SSH'):
202 202 return post_pull(ui, repo, **kwargs)
203 203 return 0
204 204
205 205
206 206 def pre_push(ui, repo, node=None, **kwargs):
207 207 extras = _extras_from_ui(ui)
208 208
209 209 rev_data = []
210 210 if node and kwargs.get('hooktype') == 'pretxnchangegroup':
211 211 branches = collections.defaultdict(list)
212 212 for commit_id, branch in _rev_range_hash(repo, node):
213 213 branches[branch].append(commit_id)
214 214
215 215 for branch, commits in branches.iteritems():
216 216 old_rev = kwargs.get('node_last') or commits[0]
217 217 rev_data.append({
218 218 'old_rev': old_rev,
219 219 'new_rev': commits[-1],
220 220 'ref': '',
221 221 'type': 'branch',
222 222 'name': branch,
223 223 })
224 224
225 225 extras['commit_ids'] = rev_data
226 226 return _call_hook('pre_push', extras, HgMessageWriter(ui))
227 227
228 228
229 229 def pre_push_ssh(ui, repo, node=None, **kwargs):
230 230 if _extras_from_ui(ui).get('SSH'):
231 231 return pre_push(ui, repo, node, **kwargs)
232 232
233 233 return 0
234 234
235 235
236 236 def pre_push_ssh_auth(ui, repo, node=None, **kwargs):
237 237 extras = _extras_from_ui(ui)
238 238 if extras.get('SSH'):
239 239 permission = extras['SSH_PERMISSIONS']
240 240
241 241 if 'repository.write' == permission or 'repository.admin' == permission:
242 242 return 0
243 243
244 244 # non-zero ret code
245 245 return 1
246 246
247 247 return 0
248 248
249 249
250 250 def post_push(ui, repo, node, **kwargs):
251 251 extras = _extras_from_ui(ui)
252 252
253 253 commit_ids = []
254 254 branches = []
255 255 bookmarks = []
256 256 tags = []
257 257
258 258 for commit_id, branch in _rev_range_hash(repo, node):
259 259 commit_ids.append(commit_id)
260 260 if branch not in branches:
261 261 branches.append(branch)
262 262
263 263 if hasattr(ui, '_rc_pushkey_branches'):
264 264 bookmarks = ui._rc_pushkey_branches
265 265
266 266 extras['commit_ids'] = commit_ids
267 267 extras['new_refs'] = {
268 268 'branches': branches,
269 269 'bookmarks': bookmarks,
270 270 'tags': tags
271 271 }
272 272
273 273 return _call_hook('post_push', extras, HgMessageWriter(ui))
274 274
275 275
276 276 def post_push_ssh(ui, repo, node, **kwargs):
277 277 if _extras_from_ui(ui).get('SSH'):
278 278 return post_push(ui, repo, node, **kwargs)
279 279 return 0
280 280
281 281
282 282 def key_push(ui, repo, **kwargs):
283 283 if kwargs['new'] != '0' and kwargs['namespace'] == 'bookmarks':
284 284 # store new bookmarks in our UI object propagated later to post_push
285 285 ui._rc_pushkey_branches = repo[kwargs['key']].bookmarks()
286 286 return
287 287
288 288
289 289 # backward compat
290 290 log_pull_action = post_pull
291 291
292 292 # backward compat
293 293 log_push_action = post_push
294 294
295 295
296 296 def handle_git_pre_receive(unused_repo_path, unused_revs, unused_env):
297 297 """
298 298 Old hook name: keep here for backward compatibility.
299 299
300 300 This is only required when the installed git hooks are not upgraded.
301 301 """
302 302 pass
303 303
304 304
305 305 def handle_git_post_receive(unused_repo_path, unused_revs, unused_env):
306 306 """
307 307 Old hook name: keep here for backward compatibility.
308 308
309 309 This is only required when the installed git hooks are not upgraded.
310 310 """
311 311 pass
312 312
313 313
314 314 HookResponse = collections.namedtuple('HookResponse', ('status', 'output'))
315 315
316 316
317 317 def git_pre_pull(extras):
318 318 """
319 319 Pre pull hook.
320 320
321 321 :param extras: dictionary containing the keys defined in simplevcs
322 322 :type extras: dict
323 323
324 324 :return: status code of the hook. 0 for success.
325 325 :rtype: int
326 326 """
327 327 if 'pull' not in extras['hooks']:
328 328 return HookResponse(0, '')
329 329
330 330 stdout = io.BytesIO()
331 331 try:
332 332 status = _call_hook('pre_pull', extras, GitMessageWriter(stdout))
333 333 except Exception as error:
334 334 status = 128
335 335 stdout.write('ERROR: %s\n' % str(error))
336 336
337 337 return HookResponse(status, stdout.getvalue())
338 338
339 339
340 340 def git_post_pull(extras):
341 341 """
342 342 Post pull hook.
343 343
344 344 :param extras: dictionary containing the keys defined in simplevcs
345 345 :type extras: dict
346 346
347 347 :return: status code of the hook. 0 for success.
348 348 :rtype: int
349 349 """
350 350 if 'pull' not in extras['hooks']:
351 351 return HookResponse(0, '')
352 352
353 353 stdout = io.BytesIO()
354 354 try:
355 355 status = _call_hook('post_pull', extras, GitMessageWriter(stdout))
356 356 except Exception as error:
357 357 status = 128
358 358 stdout.write('ERROR: %s\n' % error)
359 359
360 360 return HookResponse(status, stdout.getvalue())
361 361
362 362
363 363 def _parse_git_ref_lines(revision_lines):
364 364 rev_data = []
365 365 for revision_line in revision_lines or []:
366 366 old_rev, new_rev, ref = revision_line.strip().split(' ')
367 367 ref_data = ref.split('/', 2)
368 368 if ref_data[1] in ('tags', 'heads'):
369 369 rev_data.append({
370 370 'old_rev': old_rev,
371 371 'new_rev': new_rev,
372 372 'ref': ref,
373 373 'type': ref_data[1],
374 374 'name': ref_data[2],
375 375 })
376 376 return rev_data
377 377
378 378
379 379 def git_pre_receive(unused_repo_path, revision_lines, env):
380 380 """
381 381 Pre push hook.
382 382
383 383 :param extras: dictionary containing the keys defined in simplevcs
384 384 :type extras: dict
385 385
386 386 :return: status code of the hook. 0 for success.
387 387 :rtype: int
388 388 """
389 389 extras = json.loads(env['RC_SCM_DATA'])
390 390 rev_data = _parse_git_ref_lines(revision_lines)
391 391 if 'push' not in extras['hooks']:
392 392 return 0
393 393 extras['commit_ids'] = rev_data
394 394 return _call_hook('pre_push', extras, GitMessageWriter())
395 395
396 396
397 397 def git_post_receive(unused_repo_path, revision_lines, env):
398 398 """
399 399 Post push hook.
400 400
401 401 :param extras: dictionary containing the keys defined in simplevcs
402 402 :type extras: dict
403 403
404 404 :return: status code of the hook. 0 for success.
405 405 :rtype: int
406 406 """
407 407 extras = json.loads(env['RC_SCM_DATA'])
408 408 if 'push' not in extras['hooks']:
409 409 return 0
410 410
411 411 rev_data = _parse_git_ref_lines(revision_lines)
412 412
413 413 git_revs = []
414 414
415 415 # N.B.(skreft): it is ok to just call git, as git before calling a
416 416 # subcommand sets the PATH environment variable so that it point to the
417 417 # correct version of the git executable.
418 418 empty_commit_id = '0' * 40
419 419 branches = []
420 420 tags = []
421 421 for push_ref in rev_data:
422 422 type_ = push_ref['type']
423 423
424 424 if type_ == 'heads':
425 425 if push_ref['old_rev'] == empty_commit_id:
426 426 # starting new branch case
427 427 if push_ref['name'] not in branches:
428 428 branches.append(push_ref['name'])
429 429
430 430 # Fix up head revision if needed
431 431 cmd = [settings.GIT_EXECUTABLE, 'show', 'HEAD']
432 432 try:
433 433 subprocessio.run_command(cmd, env=os.environ.copy())
434 434 except Exception:
435 435 cmd = [settings.GIT_EXECUTABLE, 'symbolic-ref', 'HEAD',
436 436 'refs/heads/%s' % push_ref['name']]
437 437 print("Setting default branch to %s" % push_ref['name'])
438 438 subprocessio.run_command(cmd, env=os.environ.copy())
439 439
440 440 cmd = [settings.GIT_EXECUTABLE, 'for-each-ref',
441 441 '--format=%(refname)', 'refs/heads/*']
442 442 stdout, stderr = subprocessio.run_command(
443 443 cmd, env=os.environ.copy())
444 444 heads = stdout
445 445 heads = heads.replace(push_ref['ref'], '')
446 446 heads = ' '.join(head for head
447 447 in heads.splitlines() if head) or '.'
448 448 cmd = [settings.GIT_EXECUTABLE, 'log', '--reverse',
449 449 '--pretty=format:%H', '--', push_ref['new_rev'],
450 450 '--not', heads]
451 451 stdout, stderr = subprocessio.run_command(
452 452 cmd, env=os.environ.copy())
453 453 git_revs.extend(stdout.splitlines())
454 454 elif push_ref['new_rev'] == empty_commit_id:
455 455 # delete branch case
456 456 git_revs.append('delete_branch=>%s' % push_ref['name'])
457 457 else:
458 458 if push_ref['name'] not in branches:
459 459 branches.append(push_ref['name'])
460 460
461 461 cmd = [settings.GIT_EXECUTABLE, 'log',
462 462 '{old_rev}..{new_rev}'.format(**push_ref),
463 463 '--reverse', '--pretty=format:%H']
464 464 stdout, stderr = subprocessio.run_command(
465 465 cmd, env=os.environ.copy())
466 466 git_revs.extend(stdout.splitlines())
467 467 elif type_ == 'tags':
468 468 if push_ref['name'] not in tags:
469 469 tags.append(push_ref['name'])
470 470 git_revs.append('tag=>%s' % push_ref['name'])
471 471
472 472 extras['commit_ids'] = git_revs
473 473 extras['new_refs'] = {
474 474 'branches': branches,
475 475 'bookmarks': [],
476 476 'tags': tags,
477 477 }
478 478
479 479 if 'repo_size' in extras['hooks']:
480 480 try:
481 481 _call_hook('repo_size', extras, GitMessageWriter())
482 482 except:
483 483 pass
484 484
485 485 return _call_hook('post_push', extras, GitMessageWriter())
486 486
487 487
488 def _get_extras_from_txn_id(path, txn_id):
489 extras = {}
490 try:
491 cmd = ['svnlook', 'pget',
492 '-t', txn_id,
493 '--revprop', path, 'rc-scm-extras']
494 stdout, stderr = subprocessio.run_command(
495 cmd, env=os.environ.copy())
496 extras = json.loads(base64.urlsafe_b64decode(stdout))
497 except Exception:
498 log.exception('Failed to extract extras info from txn_id')
499
500 return extras
501
502
488 503 def svn_pre_commit(repo_path, commit_data, env):
489 504 path, txn_id = commit_data
490 505 branches = []
491 506 tags = []
492 507
493 cmd = ['svnlook', 'pget',
494 '-t', txn_id,
495 '--revprop', path, 'rc-scm-extras']
496 stdout, stderr = subprocessio.run_command(
497 cmd, env=os.environ.copy())
498 extras = json.loads(base64.urlsafe_b64decode(stdout))
508 if env.get('RC_SCM_DATA'):
509 extras = json.loads(env['RC_SCM_DATA'])
510 else:
511 # fallback method to read from TXN-ID stored data
512 extras = _get_extras_from_txn_id(path, txn_id)
513 if not extras:
514 return 0
499 515
500 516 extras['commit_ids'] = []
501 517 extras['txn_id'] = txn_id
502 518 extras['new_refs'] = {
503 519 'branches': branches,
504 520 'bookmarks': [],
505 521 'tags': tags,
506 522 }
507 sys.stderr.write(str(extras))
523
508 524 return _call_hook('pre_push', extras, SvnMessageWriter())
509 525
510 526
527 def _get_extras_from_commit_id(commit_id, path):
528 extras = {}
529 try:
530 cmd = ['svnlook', 'pget',
531 '-r', commit_id,
532 '--revprop', path, 'rc-scm-extras']
533 stdout, stderr = subprocessio.run_command(
534 cmd, env=os.environ.copy())
535 extras = json.loads(base64.urlsafe_b64decode(stdout))
536 except Exception:
537 log.exception('Failed to extract extras info from commit_id')
538
539 return extras
540
541
511 542 def svn_post_commit(repo_path, commit_data, env):
512 543 """
513 544 commit_data is path, rev, txn_id
514 545 """
515 546 path, commit_id, txn_id = commit_data
516 547 branches = []
517 548 tags = []
518 549
519 cmd = ['svnlook', 'pget',
520 '-r', commit_id,
521 '--revprop', path, 'rc-scm-extras']
522 stdout, stderr = subprocessio.run_command(
523 cmd, env=os.environ.copy())
524
525 extras = json.loads(base64.urlsafe_b64decode(stdout))
550 if env.get('RC_SCM_DATA'):
551 extras = json.loads(env['RC_SCM_DATA'])
552 else:
553 # fallback method to read from TXN-ID stored data
554 extras = _get_extras_from_commit_id(commit_id, path)
555 if not extras:
556 return 0
526 557
527 558 extras['commit_ids'] = [commit_id]
528 559 extras['txn_id'] = txn_id
529 560 extras['new_refs'] = {
530 561 'branches': branches,
531 562 'bookmarks': [],
532 563 'tags': tags,
533 564 }
534 565
535 566 if 'repo_size' in extras['hooks']:
536 567 try:
537 568 _call_hook('repo_size', extras, SvnMessageWriter())
538 except:
569 except Exception:
539 570 pass
540 571
541 572 return _call_hook('post_push', extras, SvnMessageWriter())
542
543
General Comments 0
You need to be logged in to leave comments. Login now