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