| 1 |
#!/usr/bin/env python |
|---|
| 2 |
# -*- coding: iso8859-1 -*- |
|---|
| 3 |
# |
|---|
| 4 |
# Author: Jonas Borgström <jonas@edgewall.com> |
|---|
| 5 |
# |
|---|
| 6 |
# This script will enforce the following policy: |
|---|
| 7 |
# |
|---|
| 8 |
# "A checkin must reference an open ticket." |
|---|
| 9 |
# |
|---|
| 10 |
# This script should be invoked from the subversion pre-commit hook like this: |
|---|
| 11 |
# |
|---|
| 12 |
# REPOS="$1" |
|---|
| 13 |
# TXN="$2" |
|---|
| 14 |
# TRAC_ENV="/somewhere/trac/project/" |
|---|
| 15 |
# LOG=`/usr/bin/svnlook log -t "$TXN" "$REPOS"` |
|---|
| 16 |
# /usr/bin/python /some/path/trac-pre-commit-hook "$TRAC_ENV" "$LOG" || exit 1 |
|---|
| 17 |
# |
|---|
| 18 |
import os |
|---|
| 19 |
import re |
|---|
| 20 |
import sys |
|---|
| 21 |
|
|---|
| 22 |
from trac.env import open_environment |
|---|
| 23 |
|
|---|
| 24 |
def main(): |
|---|
| 25 |
if len(sys.argv) != 3: |
|---|
| 26 |
print >> sys.stderr, 'Usage: %s <trac_project> <log_message>' % sys.argv[0] |
|---|
| 27 |
sys.exit(1) |
|---|
| 28 |
|
|---|
| 29 |
env_path = sys.argv[1] |
|---|
| 30 |
log = sys.argv[2] |
|---|
| 31 |
|
|---|
| 32 |
tickets = [] |
|---|
| 33 |
for tmp in re.findall('(?:close|closed|closes|fix|fixed|fixes|addresses|references|refs|re|see)' |
|---|
| 34 |
'.?(#[0-9]+(?:(?:[, &]+| *and *)#[0-9]+)*)', log.lower()): |
|---|
| 35 |
tickets += re.findall('#([0-9]+)', tmp) |
|---|
| 36 |
|
|---|
| 37 |
# At least one ticket has to be mentioned in the log message |
|---|
| 38 |
if tickets == []: |
|---|
| 39 |
print >> sys.stderr, 'At least one open ticket must be mentioned ' \ |
|---|
| 40 |
'in the log message.' |
|---|
| 41 |
sys.exit(1) |
|---|
| 42 |
|
|---|
| 43 |
env = open_environment(env_path) |
|---|
| 44 |
db = env.get_db_cnx() |
|---|
| 45 |
|
|---|
| 46 |
cursor = db.cursor() |
|---|
| 47 |
cursor.execute("SELECT COUNT(id) FROM ticket WHERE " |
|---|
| 48 |
"status <> 'closed' AND id IN (%s)" % ','.join(tickets)) |
|---|
| 49 |
row = cursor.fetchone() |
|---|
| 50 |
# At least one of the tickets mentioned in the log messages has to |
|---|
| 51 |
# be open |
|---|
| 52 |
if not row or row[0] < 1: |
|---|
| 53 |
print >> sys.stderr, 'At least one open ticket must be mentioned ' \ |
|---|
| 54 |
'in the log message.' |
|---|
| 55 |
sys.exit(1) |
|---|
| 56 |
else: |
|---|
| 57 |
sys.exit(0) |
|---|
| 58 |
|
|---|
| 59 |
if __name__ == '__main__': |
|---|
| 60 |
main() |
|---|
| 61 |
|
|---|
| 62 |
|
|---|
| 63 |
|
|---|