-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpre-receive
More file actions
executable file
·99 lines (72 loc) · 2.74 KB
/
pre-receive
File metadata and controls
executable file
·99 lines (72 loc) · 2.74 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Copyright (c) 2011 Grzegorz Sobański (initial code)
# Modified 2013 Dmitrii Tsyganov (SD Attractor)
#
# Version: 0.2
#
# Git pre receive hook to validate commit messages before allowing to push.
# Is part of the TracChangesetValidationPlugin
#
# Original script:
# http://trac-hacks.org/attachment/wiki/GitPlugin/trac-post-receive-hook-0.12-new-commits-from-all-branches.py
import json
import re
import os
import sys
from subprocess import Popen, PIPE, call
TRAC_VENV = os.path.join(os.getenv('TRAC_VENV', '/home/itattractor/trac-venv'), 'bin/activate_this.py')
execfile(TRAC_VENV, dict(__file__=TRAC_VENV))
# config
TRAC_ENV = os.getenv('TRAC_ENV', '../trac_env')
GIT_PATH = 'git'
TRAC_ADMIN = 'trac-admin'
REPO_NAME = os.getenv('REPO_NAME', '(default)')
# communication with git
def call_git(command, args, input=None):
return Popen([GIT_PATH, command] + args, stdin=PIPE, stdout=PIPE).communicate(input)[0]
def get_new_commits(ref_updates):
""" Gets a list uf updates from git running post-receive,
we want the list of new commits to the repo, that are part
of the push. Even if the are in more then one ref in the push.
Basically, we are running:
git rev-list new1 ^old1 new2 ^old2 ^everything_else
It returns a list of commits"""
all_refs = set(call_git('for-each-ref', ['--format=%(refname)']).splitlines())
commands = []
for old, new, ref in ref_updates:
# branch delete, skip it
if re.match('0*$', new):
continue
commands += [new]
all_refs.discard(ref)
if not re.match('0*$', old):
# update
commands += ["^%s" % old]
# else: new - do nothing more
for ref in all_refs:
commands += ["^%s" % ref]
new_commits = call_git('rev-list', ['--stdin', '--reverse'], '\n'.join(commands)).splitlines()
return new_commits
def handle_trac_admin(command, sub_command, parameters):
if not (os.path.exists(TRAC_ENV) and os.path.isdir(TRAC_ENV)):
print "Trac path (%s) is not a directory." % TRAC_ENV
args = [TRAC_ADMIN, TRAC_ENV, command, sub_command] + parameters
return call(args)
def get_messages(commits):
messages = {}
for commit in commits:
messages[commit] = call_git('show', ['-s', '--pretty=%s', commit])
return messages
# main
if __name__ == '__main__':
# gather all commits
lines = sys.stdin.readlines()
print lines
input_refs = [line.split() for line in lines]
commit_refs = get_new_commits(input_refs)
messages = get_messages(commit_refs)
# call trac-admin
result = handle_trac_admin('changeset', 'validate_messages', [REPO_NAME, json.dumps(messages).replace("\'", "'")])
sys.exit(result)