##// END OF EJS Templates
hooks: add extra debug/logging to help track hook errors.
marcink -
r591:80e010eb default
parent child Browse files
Show More
@@ -1,702 +1,711 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 return json.loads(response.read())
55
56 response_data = response.read()
57
58 try:
59 return json.loads(response_data)
60 except Exception:
61 log.exception('Failed to decode hook response json data. '
62 'response_code:%s, raw_data:%s',
63 response.status, response_data)
64 raise
56 65
57 66 def _serialize(self, hook_name, extras):
58 67 data = {
59 68 'method': hook_name,
60 69 'extras': extras
61 70 }
62 71 return json.dumps(data)
63 72
64 73
65 74 class HooksDummyClient(object):
66 75 def __init__(self, hooks_module):
67 76 self._hooks_module = importlib.import_module(hooks_module)
68 77
69 78 def __call__(self, hook_name, extras):
70 79 with self._hooks_module.Hooks() as hooks:
71 80 return getattr(hooks, hook_name)(extras)
72 81
73 82
74 83 class RemoteMessageWriter(object):
75 84 """Writer base class."""
76 85 def write(self, message):
77 86 raise NotImplementedError()
78 87
79 88
80 89 class HgMessageWriter(RemoteMessageWriter):
81 90 """Writer that knows how to send messages to mercurial clients."""
82 91
83 92 def __init__(self, ui):
84 93 self.ui = ui
85 94
86 95 def write(self, message):
87 96 # TODO: Check why the quiet flag is set by default.
88 97 old = self.ui.quiet
89 98 self.ui.quiet = False
90 99 self.ui.status(message.encode('utf-8'))
91 100 self.ui.quiet = old
92 101
93 102
94 103 class GitMessageWriter(RemoteMessageWriter):
95 104 """Writer that knows how to send messages to git clients."""
96 105
97 106 def __init__(self, stdout=None):
98 107 self.stdout = stdout or sys.stdout
99 108
100 109 def write(self, message):
101 110 self.stdout.write(message.encode('utf-8'))
102 111
103 112
104 113 class SvnMessageWriter(RemoteMessageWriter):
105 114 """Writer that knows how to send messages to svn clients."""
106 115
107 116 def __init__(self, stderr=None):
108 117 # SVN needs data sent to stderr for back-to-client messaging
109 118 self.stderr = stderr or sys.stderr
110 119
111 120 def write(self, message):
112 121 self.stderr.write(message.encode('utf-8'))
113 122
114 123
115 124 def _handle_exception(result):
116 125 exception_class = result.get('exception')
117 126 exception_traceback = result.get('exception_traceback')
118 127
119 128 if exception_traceback:
120 129 log.error('Got traceback from remote call:%s', exception_traceback)
121 130
122 131 if exception_class == 'HTTPLockedRC':
123 132 raise exceptions.RepositoryLockedException()(*result['exception_args'])
124 133 elif exception_class == 'HTTPBranchProtected':
125 134 raise exceptions.RepositoryBranchProtectedException()(*result['exception_args'])
126 135 elif exception_class == 'RepositoryError':
127 136 raise exceptions.VcsException()(*result['exception_args'])
128 137 elif exception_class:
129 138 raise Exception('Got remote exception "%s" with args "%s"' %
130 139 (exception_class, result['exception_args']))
131 140
132 141
133 142 def _get_hooks_client(extras):
134 143 if 'hooks_uri' in extras:
135 144 protocol = extras.get('hooks_protocol')
136 145 return HooksHttpClient(extras['hooks_uri'])
137 146 else:
138 147 return HooksDummyClient(extras['hooks_module'])
139 148
140 149
141 150 def _call_hook(hook_name, extras, writer):
142 151 hooks_client = _get_hooks_client(extras)
143 152 log.debug('Hooks, using client:%s', hooks_client)
144 153 result = hooks_client(hook_name, extras)
145 154 log.debug('Hooks got result: %s', result)
146 155
147 156 _handle_exception(result)
148 157 writer.write(result['output'])
149 158
150 159 return result['status']
151 160
152 161
153 162 def _extras_from_ui(ui):
154 163 hook_data = ui.config('rhodecode', 'RC_SCM_DATA')
155 164 if not hook_data:
156 165 # maybe it's inside environ ?
157 166 env_hook_data = os.environ.get('RC_SCM_DATA')
158 167 if env_hook_data:
159 168 hook_data = env_hook_data
160 169
161 170 extras = {}
162 171 if hook_data:
163 172 extras = json.loads(hook_data)
164 173 return extras
165 174
166 175
167 176 def _rev_range_hash(repo, node, check_heads=False):
168 177
169 178 commits = []
170 179 revs = []
171 180 start = repo[node].rev()
172 181 end = len(repo)
173 182 for rev in range(start, end):
174 183 revs.append(rev)
175 184 ctx = repo[rev]
176 185 commit_id = mercurial.node.hex(ctx.node())
177 186 branch = ctx.branch()
178 187 commits.append((commit_id, branch))
179 188
180 189 parent_heads = []
181 190 if check_heads:
182 191 parent_heads = _check_heads(repo, start, end, revs)
183 192 return commits, parent_heads
184 193
185 194
186 195 def _check_heads(repo, start, end, commits):
187 196 changelog = repo.changelog
188 197 parents = set()
189 198
190 199 for new_rev in commits:
191 200 for p in changelog.parentrevs(new_rev):
192 201 if p == mercurial.node.nullrev:
193 202 continue
194 203 if p < start:
195 204 parents.add(p)
196 205
197 206 for p in parents:
198 207 branch = repo[p].branch()
199 208 # The heads descending from that parent, on the same branch
200 209 parent_heads = set([p])
201 210 reachable = set([p])
202 211 for x in xrange(p + 1, end):
203 212 if repo[x].branch() != branch:
204 213 continue
205 214 for pp in changelog.parentrevs(x):
206 215 if pp in reachable:
207 216 reachable.add(x)
208 217 parent_heads.discard(pp)
209 218 parent_heads.add(x)
210 219 # More than one head? Suggest merging
211 220 if len(parent_heads) > 1:
212 221 return list(parent_heads)
213 222
214 223 return []
215 224
216 225
217 226 def _get_git_env():
218 227 env = {}
219 228 for k, v in os.environ.items():
220 229 if k.startswith('GIT'):
221 230 env[k] = v
222 231
223 232 # serialized version
224 233 return [(k, v) for k, v in env.items()]
225 234
226 235
227 236 def _get_hg_env(old_rev, new_rev, txnid, repo_path):
228 237 env = {}
229 238 for k, v in os.environ.items():
230 239 if k.startswith('HG'):
231 240 env[k] = v
232 241
233 242 env['HG_NODE'] = old_rev
234 243 env['HG_NODE_LAST'] = new_rev
235 244 env['HG_TXNID'] = txnid
236 245 env['HG_PENDING'] = repo_path
237 246
238 247 return [(k, v) for k, v in env.items()]
239 248
240 249
241 250 def repo_size(ui, repo, **kwargs):
242 251 extras = _extras_from_ui(ui)
243 252 return _call_hook('repo_size', extras, HgMessageWriter(ui))
244 253
245 254
246 255 def pre_pull(ui, repo, **kwargs):
247 256 extras = _extras_from_ui(ui)
248 257 return _call_hook('pre_pull', extras, HgMessageWriter(ui))
249 258
250 259
251 260 def pre_pull_ssh(ui, repo, **kwargs):
252 261 extras = _extras_from_ui(ui)
253 262 if extras and extras.get('SSH'):
254 263 return pre_pull(ui, repo, **kwargs)
255 264 return 0
256 265
257 266
258 267 def post_pull(ui, repo, **kwargs):
259 268 extras = _extras_from_ui(ui)
260 269 return _call_hook('post_pull', extras, HgMessageWriter(ui))
261 270
262 271
263 272 def post_pull_ssh(ui, repo, **kwargs):
264 273 extras = _extras_from_ui(ui)
265 274 if extras and extras.get('SSH'):
266 275 return post_pull(ui, repo, **kwargs)
267 276 return 0
268 277
269 278
270 279 def pre_push(ui, repo, node=None, **kwargs):
271 280 """
272 281 Mercurial pre_push hook
273 282 """
274 283 extras = _extras_from_ui(ui)
275 284 detect_force_push = extras.get('detect_force_push')
276 285
277 286 rev_data = []
278 287 if node and kwargs.get('hooktype') == 'pretxnchangegroup':
279 288 branches = collections.defaultdict(list)
280 289 commits, _heads = _rev_range_hash(repo, node, check_heads=detect_force_push)
281 290 for commit_id, branch in commits:
282 291 branches[branch].append(commit_id)
283 292
284 293 for branch, commits in branches.items():
285 294 old_rev = kwargs.get('node_last') or commits[0]
286 295 rev_data.append({
287 296 'total_commits': len(commits),
288 297 'old_rev': old_rev,
289 298 'new_rev': commits[-1],
290 299 'ref': '',
291 300 'type': 'branch',
292 301 'name': branch,
293 302 })
294 303
295 304 for push_ref in rev_data:
296 305 push_ref['multiple_heads'] = _heads
297 306
298 307 repo_path = os.path.join(
299 308 extras.get('repo_store', ''), extras.get('repository', ''))
300 309 push_ref['hg_env'] = _get_hg_env(
301 310 old_rev=push_ref['old_rev'],
302 311 new_rev=push_ref['new_rev'], txnid=kwargs.get('txnid'),
303 312 repo_path=repo_path)
304 313
305 314 extras['hook_type'] = kwargs.get('hooktype', 'pre_push')
306 315 extras['commit_ids'] = rev_data
307 316
308 317 return _call_hook('pre_push', extras, HgMessageWriter(ui))
309 318
310 319
311 320 def pre_push_ssh(ui, repo, node=None, **kwargs):
312 321 extras = _extras_from_ui(ui)
313 322 if extras.get('SSH'):
314 323 return pre_push(ui, repo, node, **kwargs)
315 324
316 325 return 0
317 326
318 327
319 328 def pre_push_ssh_auth(ui, repo, node=None, **kwargs):
320 329 """
321 330 Mercurial pre_push hook for SSH
322 331 """
323 332 extras = _extras_from_ui(ui)
324 333 if extras.get('SSH'):
325 334 permission = extras['SSH_PERMISSIONS']
326 335
327 336 if 'repository.write' == permission or 'repository.admin' == permission:
328 337 return 0
329 338
330 339 # non-zero ret code
331 340 return 1
332 341
333 342 return 0
334 343
335 344
336 345 def post_push(ui, repo, node, **kwargs):
337 346 """
338 347 Mercurial post_push hook
339 348 """
340 349 extras = _extras_from_ui(ui)
341 350
342 351 commit_ids = []
343 352 branches = []
344 353 bookmarks = []
345 354 tags = []
346 355
347 356 commits, _heads = _rev_range_hash(repo, node)
348 357 for commit_id, branch in commits:
349 358 commit_ids.append(commit_id)
350 359 if branch not in branches:
351 360 branches.append(branch)
352 361
353 362 if hasattr(ui, '_rc_pushkey_branches'):
354 363 bookmarks = ui._rc_pushkey_branches
355 364
356 365 extras['hook_type'] = kwargs.get('hooktype', 'post_push')
357 366 extras['commit_ids'] = commit_ids
358 367 extras['new_refs'] = {
359 368 'branches': branches,
360 369 'bookmarks': bookmarks,
361 370 'tags': tags
362 371 }
363 372
364 373 return _call_hook('post_push', extras, HgMessageWriter(ui))
365 374
366 375
367 376 def post_push_ssh(ui, repo, node, **kwargs):
368 377 """
369 378 Mercurial post_push hook for SSH
370 379 """
371 380 if _extras_from_ui(ui).get('SSH'):
372 381 return post_push(ui, repo, node, **kwargs)
373 382 return 0
374 383
375 384
376 385 def key_push(ui, repo, **kwargs):
377 386 if kwargs['new'] != '0' and kwargs['namespace'] == 'bookmarks':
378 387 # store new bookmarks in our UI object propagated later to post_push
379 388 ui._rc_pushkey_branches = repo[kwargs['key']].bookmarks()
380 389 return
381 390
382 391
383 392 # backward compat
384 393 log_pull_action = post_pull
385 394
386 395 # backward compat
387 396 log_push_action = post_push
388 397
389 398
390 399 def handle_git_pre_receive(unused_repo_path, unused_revs, unused_env):
391 400 """
392 401 Old hook name: keep here for backward compatibility.
393 402
394 403 This is only required when the installed git hooks are not upgraded.
395 404 """
396 405 pass
397 406
398 407
399 408 def handle_git_post_receive(unused_repo_path, unused_revs, unused_env):
400 409 """
401 410 Old hook name: keep here for backward compatibility.
402 411
403 412 This is only required when the installed git hooks are not upgraded.
404 413 """
405 414 pass
406 415
407 416
408 417 HookResponse = collections.namedtuple('HookResponse', ('status', 'output'))
409 418
410 419
411 420 def git_pre_pull(extras):
412 421 """
413 422 Pre pull hook.
414 423
415 424 :param extras: dictionary containing the keys defined in simplevcs
416 425 :type extras: dict
417 426
418 427 :return: status code of the hook. 0 for success.
419 428 :rtype: int
420 429 """
421 430 if 'pull' not in extras['hooks']:
422 431 return HookResponse(0, '')
423 432
424 433 stdout = io.BytesIO()
425 434 try:
426 435 status = _call_hook('pre_pull', extras, GitMessageWriter(stdout))
427 436 except Exception as error:
428 437 status = 128
429 438 stdout.write('ERROR: %s\n' % str(error))
430 439
431 440 return HookResponse(status, stdout.getvalue())
432 441
433 442
434 443 def git_post_pull(extras):
435 444 """
436 445 Post pull hook.
437 446
438 447 :param extras: dictionary containing the keys defined in simplevcs
439 448 :type extras: dict
440 449
441 450 :return: status code of the hook. 0 for success.
442 451 :rtype: int
443 452 """
444 453 if 'pull' not in extras['hooks']:
445 454 return HookResponse(0, '')
446 455
447 456 stdout = io.BytesIO()
448 457 try:
449 458 status = _call_hook('post_pull', extras, GitMessageWriter(stdout))
450 459 except Exception as error:
451 460 status = 128
452 461 stdout.write('ERROR: %s\n' % error)
453 462
454 463 return HookResponse(status, stdout.getvalue())
455 464
456 465
457 466 def _parse_git_ref_lines(revision_lines):
458 467 rev_data = []
459 468 for revision_line in revision_lines or []:
460 469 old_rev, new_rev, ref = revision_line.strip().split(' ')
461 470 ref_data = ref.split('/', 2)
462 471 if ref_data[1] in ('tags', 'heads'):
463 472 rev_data.append({
464 473 # NOTE(marcink):
465 474 # we're unable to tell total_commits for git at this point
466 475 # but we set the variable for consistency with GIT
467 476 'total_commits': -1,
468 477 'old_rev': old_rev,
469 478 'new_rev': new_rev,
470 479 'ref': ref,
471 480 'type': ref_data[1],
472 481 'name': ref_data[2],
473 482 })
474 483 return rev_data
475 484
476 485
477 486 def git_pre_receive(unused_repo_path, revision_lines, env):
478 487 """
479 488 Pre push hook.
480 489
481 490 :param extras: dictionary containing the keys defined in simplevcs
482 491 :type extras: dict
483 492
484 493 :return: status code of the hook. 0 for success.
485 494 :rtype: int
486 495 """
487 496 extras = json.loads(env['RC_SCM_DATA'])
488 497 rev_data = _parse_git_ref_lines(revision_lines)
489 498 if 'push' not in extras['hooks']:
490 499 return 0
491 500 empty_commit_id = '0' * 40
492 501
493 502 detect_force_push = extras.get('detect_force_push')
494 503
495 504 for push_ref in rev_data:
496 505 # store our git-env which holds the temp store
497 506 push_ref['git_env'] = _get_git_env()
498 507 push_ref['pruned_sha'] = ''
499 508 if not detect_force_push:
500 509 # don't check for forced-push when we don't need to
501 510 continue
502 511
503 512 type_ = push_ref['type']
504 513 new_branch = push_ref['old_rev'] == empty_commit_id
505 514 if type_ == 'heads' and not new_branch:
506 515 old_rev = push_ref['old_rev']
507 516 new_rev = push_ref['new_rev']
508 517 cmd = [settings.GIT_EXECUTABLE, 'rev-list',
509 518 old_rev, '^{}'.format(new_rev)]
510 519 stdout, stderr = subprocessio.run_command(
511 520 cmd, env=os.environ.copy())
512 521 # means we're having some non-reachable objects, this forced push
513 522 # was used
514 523 if stdout:
515 524 push_ref['pruned_sha'] = stdout.splitlines()
516 525
517 526 extras['hook_type'] = 'pre_receive'
518 527 extras['commit_ids'] = rev_data
519 528 return _call_hook('pre_push', extras, GitMessageWriter())
520 529
521 530
522 531 def git_post_receive(unused_repo_path, revision_lines, env):
523 532 """
524 533 Post push hook.
525 534
526 535 :param extras: dictionary containing the keys defined in simplevcs
527 536 :type extras: dict
528 537
529 538 :return: status code of the hook. 0 for success.
530 539 :rtype: int
531 540 """
532 541 extras = json.loads(env['RC_SCM_DATA'])
533 542 if 'push' not in extras['hooks']:
534 543 return 0
535 544
536 545 rev_data = _parse_git_ref_lines(revision_lines)
537 546
538 547 git_revs = []
539 548
540 549 # N.B.(skreft): it is ok to just call git, as git before calling a
541 550 # subcommand sets the PATH environment variable so that it point to the
542 551 # correct version of the git executable.
543 552 empty_commit_id = '0' * 40
544 553 branches = []
545 554 tags = []
546 555 for push_ref in rev_data:
547 556 type_ = push_ref['type']
548 557
549 558 if type_ == 'heads':
550 559 if push_ref['old_rev'] == empty_commit_id:
551 560 # starting new branch case
552 561 if push_ref['name'] not in branches:
553 562 branches.append(push_ref['name'])
554 563
555 564 # Fix up head revision if needed
556 565 cmd = [settings.GIT_EXECUTABLE, 'show', 'HEAD']
557 566 try:
558 567 subprocessio.run_command(cmd, env=os.environ.copy())
559 568 except Exception:
560 569 cmd = [settings.GIT_EXECUTABLE, 'symbolic-ref', 'HEAD',
561 570 'refs/heads/%s' % push_ref['name']]
562 571 print("Setting default branch to %s" % push_ref['name'])
563 572 subprocessio.run_command(cmd, env=os.environ.copy())
564 573
565 574 cmd = [settings.GIT_EXECUTABLE, 'for-each-ref',
566 575 '--format=%(refname)', 'refs/heads/*']
567 576 stdout, stderr = subprocessio.run_command(
568 577 cmd, env=os.environ.copy())
569 578 heads = stdout
570 579 heads = heads.replace(push_ref['ref'], '')
571 580 heads = ' '.join(head for head
572 581 in heads.splitlines() if head) or '.'
573 582 cmd = [settings.GIT_EXECUTABLE, 'log', '--reverse',
574 583 '--pretty=format:%H', '--', push_ref['new_rev'],
575 584 '--not', heads]
576 585 stdout, stderr = subprocessio.run_command(
577 586 cmd, env=os.environ.copy())
578 587 git_revs.extend(stdout.splitlines())
579 588 elif push_ref['new_rev'] == empty_commit_id:
580 589 # delete branch case
581 590 git_revs.append('delete_branch=>%s' % push_ref['name'])
582 591 else:
583 592 if push_ref['name'] not in branches:
584 593 branches.append(push_ref['name'])
585 594
586 595 cmd = [settings.GIT_EXECUTABLE, 'log',
587 596 '{old_rev}..{new_rev}'.format(**push_ref),
588 597 '--reverse', '--pretty=format:%H']
589 598 stdout, stderr = subprocessio.run_command(
590 599 cmd, env=os.environ.copy())
591 600 git_revs.extend(stdout.splitlines())
592 601 elif type_ == 'tags':
593 602 if push_ref['name'] not in tags:
594 603 tags.append(push_ref['name'])
595 604 git_revs.append('tag=>%s' % push_ref['name'])
596 605
597 606 extras['hook_type'] = 'post_receive'
598 607 extras['commit_ids'] = git_revs
599 608 extras['new_refs'] = {
600 609 'branches': branches,
601 610 'bookmarks': [],
602 611 'tags': tags,
603 612 }
604 613
605 614 if 'repo_size' in extras['hooks']:
606 615 try:
607 616 _call_hook('repo_size', extras, GitMessageWriter())
608 617 except:
609 618 pass
610 619
611 620 return _call_hook('post_push', extras, GitMessageWriter())
612 621
613 622
614 623 def _get_extras_from_txn_id(path, txn_id):
615 624 extras = {}
616 625 try:
617 626 cmd = ['svnlook', 'pget',
618 627 '-t', txn_id,
619 628 '--revprop', path, 'rc-scm-extras']
620 629 stdout, stderr = subprocessio.run_command(
621 630 cmd, env=os.environ.copy())
622 631 extras = json.loads(base64.urlsafe_b64decode(stdout))
623 632 except Exception:
624 633 log.exception('Failed to extract extras info from txn_id')
625 634
626 635 return extras
627 636
628 637
629 638 def _get_extras_from_commit_id(commit_id, path):
630 639 extras = {}
631 640 try:
632 641 cmd = ['svnlook', 'pget',
633 642 '-r', commit_id,
634 643 '--revprop', path, 'rc-scm-extras']
635 644 stdout, stderr = subprocessio.run_command(
636 645 cmd, env=os.environ.copy())
637 646 extras = json.loads(base64.urlsafe_b64decode(stdout))
638 647 except Exception:
639 648 log.exception('Failed to extract extras info from commit_id')
640 649
641 650 return extras
642 651
643 652
644 653 def svn_pre_commit(repo_path, commit_data, env):
645 654 path, txn_id = commit_data
646 655 branches = []
647 656 tags = []
648 657
649 658 if env.get('RC_SCM_DATA'):
650 659 extras = json.loads(env['RC_SCM_DATA'])
651 660 else:
652 661 # fallback method to read from TXN-ID stored data
653 662 extras = _get_extras_from_txn_id(path, txn_id)
654 663 if not extras:
655 664 return 0
656 665
657 666 extras['hook_type'] = 'pre_commit'
658 667 extras['commit_ids'] = []
659 668 extras['txn_id'] = txn_id
660 669 extras['new_refs'] = {
661 670 'total_commits': 1,
662 671 'branches': branches,
663 672 'bookmarks': [],
664 673 'tags': tags,
665 674 }
666 675
667 676 return _call_hook('pre_push', extras, SvnMessageWriter())
668 677
669 678
670 679 def svn_post_commit(repo_path, commit_data, env):
671 680 """
672 681 commit_data is path, rev, txn_id
673 682 """
674 683 path, commit_id, txn_id = commit_data
675 684 branches = []
676 685 tags = []
677 686
678 687 if env.get('RC_SCM_DATA'):
679 688 extras = json.loads(env['RC_SCM_DATA'])
680 689 else:
681 690 # fallback method to read from TXN-ID stored data
682 691 extras = _get_extras_from_commit_id(commit_id, path)
683 692 if not extras:
684 693 return 0
685 694
686 695 extras['hook_type'] = 'post_commit'
687 696 extras['commit_ids'] = [commit_id]
688 697 extras['txn_id'] = txn_id
689 698 extras['new_refs'] = {
690 699 'branches': branches,
691 700 'bookmarks': [],
692 701 'tags': tags,
693 702 'total_commits': 1,
694 703 }
695 704
696 705 if 'repo_size' in extras['hooks']:
697 706 try:
698 707 _call_hook('repo_size', extras, SvnMessageWriter())
699 708 except Exception:
700 709 pass
701 710
702 711 return _call_hook('post_push', extras, SvnMessageWriter())
General Comments 0
You need to be logged in to leave comments. Login now