Changeset 3581
- Timestamp:
- 04/30/08 17:41:53 (5 months ago)
- Files:
-
- revtreeplugin/0.11/hooks/README (modified) (1 prop)
- revtreeplugin/0.11/hooks/repproxy.py (modified) (7 diffs, 1 prop)
- revtreeplugin/0.11/hooks/svnstubs/config (deleted)
- revtreeplugin/0.11/hooks/svnstubs/hook.conf (added)
- revtreeplugin/0.11/hooks/svnstubs/post-commit (modified) (1 diff, 1 prop)
- revtreeplugin/0.11/hooks/svnstubs/post-revprop-change (modified) (1 diff, 1 prop)
- revtreeplugin/0.11/hooks/svnstubs/pre-commit (modified) (1 diff, 1 prop)
- revtreeplugin/0.11/hooks/svnstubs/pre-revprop-change (modified) (1 diff, 1 prop)
- revtreeplugin/0.11/hooks/svnstubs/README (modified) (1 diff, 1 prop)
- revtreeplugin/0.11/hooks/svnstubs/winstubs (added)
- revtreeplugin/0.11/hooks/svnstubs/winstubs/post-commit.bat (added)
- revtreeplugin/0.11/hooks/svnstubs/winstubs/post-revprop-change.bat (added)
- revtreeplugin/0.11/hooks/svnstubs/winstubs/pre-commit.bat (added)
- revtreeplugin/0.11/hooks/svnstubs/winstubs/pre-revprop-change.bat (added)
- revtreeplugin/0.11/hooks/trac-commit-hook (modified) (22 diffs, 1 prop)
- revtreeplugin/0.11/hooks/trac-revprop-hook (modified) (6 diffs, 1 prop)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
revtreeplugin/0.11/hooks/README
- Property svn:eol-style set to native
revtreeplugin/0.11/hooks/repproxy.py
- Property svn:eol-style set to native
r2638 r3581 1 1 #!/usr/bin/env python 2 # -*- coding: utf8 -*- 2 3 # 3 # repproxy.py 4 # ---------------------------------------------------------------------------- 5 # Copyright (c) 2005-2007 Emmanuel Blot 6 # ---------------------------------------------------------------------------- 4 # Copyright (c) 2005-2008 Emmanuel Blot 5 # 7 6 8 7 import sys … … 78 77 for chgpath in chgpaths: 79 78 (srcrev, srcpath) = fs.svn_fs_copied_from(root, chgpath, self.pool) 79 #print >>sys.stderr, "chgpath: %s -> %s @ %d" % (chgpath, srcpath, srcrev) 80 80 if srcrev > 0 and srcpath is not None: 81 81 return (srcrev, srcpath) … … 93 93 for chgpath in chgpaths: 94 94 (srcrev, srcpath) = fs.svn_fs_copied_from(root, chgpath, self.pool) 95 #print >>sys.stderr, "chgpath: %s -> %s @ %d" % (chgpath, srcpath, srcrev) 95 96 if srcrev > 0 and srcpath is not None: 96 97 return (srcrev, srcpath) … … 135 136 def get_revision_changed_paths(self, revision): 136 137 root = self.get_revision_root(revision) 137 for (path, change) in self._get_changed_paths(root): 138 yield path 138 return self._get_changed_paths(root) 139 139 140 140 def _get_changed_paths(self, root): … … 152 152 return rev 153 153 154 def get_history(self, revision, path, traverse= 1):154 def get_history(self, revision, path, traverse=True): 155 155 """Provides a generator to iterate through the history of a path 156 156 … … 164 164 165 165 # svn_repos_history does not support the None argument 166 if not traverse:167 traverse = 0168 166 repos.svn_repos_history(self.fs, path, history_cb, 0, revision, \ 169 traverse , self.pool)167 traverse and 1 or 0, self.pool) 170 168 for h in history: 171 169 yield h … … 177 175 for rev in range(youngest,0,-1): 178 176 root = self.get_revision_root(rev) 179 for revpathin self.get_revision_changed_paths(rev):177 for (revpath, change) in self.get_revision_changed_paths(rev): 180 178 if revpath[:length] == path: 181 179 return rev revtreeplugin/0.11/hooks/svnstubs/post-commit
- Property svn:eol-style set to native
r2638 r3581 1 1 #!/bin/sh 2 3 # POST-COMMIT HOOK4 #5 # [1] REPOS-PATH (the path to this repository)6 # [2] TRANSACTION (the transaction being processed)7 2 8 3 REPOS="$1" 9 4 REV="$2" 10 CONFIG_PATH=`dirname $0`11 5 12 # Load global config 13 if [ -f "${CONFIG_PATH}/config" ]; then 14 . ${CONFIG_PATH}/config 6 SELF=`readlink -f $0` 7 CONF=`dirname ${SELF}`/hook.conf 8 if [ -f ${CONF} ]; then 9 . ${CONF} 15 10 else 16 echo "Missing config file" >&2 11 echo "Missing hook configuration file" >&2 12 exit -1 17 13 fi 18 14 19 REPOSNAME=`echo "$REPOS" | sed -r 's/^.*\/([^\/]+)$/\1/'` 20 TRAC_ENV="${TRAC_ENV_PARENT_DIR}/${REPOSNAME}" 21 LOGFILE="${TRAC_ENV}/log/svn-postcommit.log" 22 23 export PYTHONPATH=$TRACPATH 15 export PYTHONPATH=$TRACPATH:$GENSHIPATH 16 export PYTHON_EGG_CACHE 17 export PYTHON=`which python2.5` 24 18 date >> "$LOGFILE" 25 19 echo "Revision: $REV" >> "$LOGFILE" 26 ${PYTHON} ${ TRAC_PATH}/hooks/trac-commit-hook\27 -d "$REPOS" -r "$REV" -p "$TRAC_ENV"2>> "$LOGFILE"20 ${PYTHON} ${HOOKPATH}/trac-commit-hook -d "$REPOS" -r "$REV" -p "$TRAC_ENV" \ 21 2>> "$LOGFILE" 28 22 if [ $? -ne 0 ]; then 29 if [ -n ${MAIL_ADMIN} ];30 tail -5 "$LOGFILE" | mail ${MAIL_ADMIN} \31 -s "[${REPOSNAME}] Unable to post-commit revision ${REV}"23 tail -5 "$LOGFILE" | \ 24 cat 25 #mail admin -s "[${REPOSNAME}] Unable to post-commit revision ${REV}" 32 26 fi 27 revtreeplugin/0.11/hooks/svnstubs/post-revprop-change
- Property svn:eol-style set to native
r2638 r3581 17 17 PROPNAME="$4" 18 18 ACTION="$5" 19 CONFIG_PATH=`dirname $0`20 19 21 if [ -f "${CONFIG_PATH}/config" ]; then 22 . ${CONFIG_PATH}/config 20 SELF=`readlink -f $0` 21 CONF=`dirname ${SELF}`/hook.conf 22 if [ -f ${CONF} ]; then 23 . ${CONF} 23 24 else 24 echo "Missing config file" >&2 25 echo "Missing hook configuration file" >&2 26 exit -1 25 27 fi 26 28 27 REPOSNAME=`echo "$REPOS" | sed -r 's/^.*\/([^\/]+)$/\1/'` 28 TRAC_ENV="${TRAC_ENV_PARENT_DIR}/${REPOSNAME}" 29 LOGFILE="${TRAC_ENV}/log/svn-postrevpropchange.log" 30 31 export PYTHONPATH=$TRACPATH 29 export PYTHONPATH=$TRACPATH:$GENSHIPATH 30 export PYTHON_EGG_CACHE 31 export PYTHON=`which python2.5` 32 32 date >> "$LOGFILE" 33 33 echo "Revprop: $REV $PROPNAME" >> $LOGFILE 34 ${PYTHON} ${ TRACPATH}/hooks/trac-revprop-hook -p "$TRAC_ENV" -u "$USER" \34 ${PYTHON} ${HOOKPATH}/trac-revprop-hook -p "$TRAC_ENV" -u "$USER" \ 35 35 -n "$PROPNAME" -d "$REPOS" -r "$REV" -a "$ACTION" post 2>> "$LOGFILE" 36 36 if [ $? -ne 0 ]; then revtreeplugin/0.11/hooks/svnstubs/pre-commit
- Property svn:eol-style set to native
r2638 r3581 1 1 #!/bin/sh 2 3 # PRE-COMMIT HOOK4 #5 # [1] REPOS-PATH (the path to this repository)6 # [2] TRANSACTION (the transaction being processed)7 2 8 3 REPOS="$1" 9 4 TXN="$2" 10 CONFIG_PATH=`dirname $0`11 5 12 if [ -f "${CONFIG_PATH}/config" ]; then 13 . ${CONFIG_PATH}/config 6 SELF=`readlink -f $0` 7 CONF=`dirname ${SELF}`/hook.conf 8 if [ -f ${CONF} ]; then 9 . ${CONF} 14 10 else 15 echo "Missing config file" >&2 11 echo "Missing hook configuration file (${CONF})" >&2 12 exit -1 16 13 fi 17 14 18 REPOSNAME=`echo "$REPOS" | sed -r 's/^.*\/([^\/]+)$/\1/'` 19 TRAC_ENV="${TRAC_ENV_PARENT_DIR}/${REPOSNAME}" 20 LOGFILE="${TRAC_ENV}/log/svn-precommit.log" 21 22 export PYTHONPATH=$TRACPATH 15 export PYTHONPATH=$TRACPATH:$GENSHIPATH 16 export PYTHON_EGG_CACHE 17 export PYTHON=`which python2.5` 23 18 echo "Transaction: $TXN" >> $LOGFILE 24 ${PYTHON} ${TRACPATH}/hooks/trac-commit-hook \ 25 -d "$REPOS" -t "$TXN" -p "$TRAC_ENV" 19 ${PYTHON} ${HOOKPATH}/trac-commit-hook -d "$REPOS" -t "$TXN" -p "$TRAC_ENV" 26 20 RC=$? 27 21 echo "RESULT $RC" >> $LOGFILE revtreeplugin/0.11/hooks/svnstubs/pre-revprop-change
- Property svn:eol-style set to native
r2638 r3581 15 15 PROPNAME="$4" 16 16 ACTION="$5" 17 CONFIG_PATH=`dirname $0`18 17 19 if [ -f "${CONFIG_PATH}/config" ]; then 20 . ${CONFIG_PATH}/config 18 SELF=`readlink -f $0` 19 CONF=`dirname ${SELF}`/hook.conf 20 if [ -f ${CONF} ]; then 21 . ${CONF} 21 22 else 22 echo "Missing config file" >&2 23 echo "Missing hook configuration file" >&2 24 exit -1 23 25 fi 24 26 25 REPOSNAME=`echo "$REPOS" | sed -r 's/^.*\/([^\/]+)$/\1/'` 26 TRAC_ENV="${TRAC_ENV_PARENT_DIR}/${REPOSNAME}" 27 LOGFILE="${TRAC_ENV}/log/svn-prerevpropchange.log" 28 29 export PYTHONPATH=$TRACPATH 27 export PYTHONPATH=$TRACPATH:$GENSHIPATH 28 export PYTHON_EGG_CACHE 29 export PYTHON=`which python2.5` 30 30 echo "Revprop: $REV $PROPNAME action:$ACTION" >> $LOGFILE 31 ${PYTHON} ${ TRACPATH}/hooks/trac-revprop-hook -p "$TRAC_ENV" -u "$USER" \32 -n "$PROPNAME" -d "$REPOS" -r "$REV" -a "$ACTION" pre 31 ${PYTHON} ${HOOKPATH}/trac-revprop-hook -p "$TRAC_ENV" -u "$USER" \ 32 -n "$PROPNAME" -d "$REPOS" -r "$REV" -a "$ACTION" pre 2>> "$LOGFILE" 33 33 RC=$? 34 34 echo "RESULT $RC" >> $LOGFILE revtreeplugin/0.11/hooks/svnstubs/README
- Property svn:eol-style set to native
r2638 r3581 3 3 environment. 4 4 5 Do not forget to edit the ' config' file to match your environment.5 Do not forget to edit the 'hook.conf' file to match your environment. revtreeplugin/0.11/hooks/trac-commit-hook
- Property svn:eol-style set to native
r2638 r3581 4 4 # ---------------------------------------------------------------------------- 5 5 # Copyright (c) 2004 Stephen Hansen 6 # Copyright (c) 2005-200 7Emmanuel Blot, Jerome Souquieres6 # Copyright (c) 2005-2008 Emmanuel Blot, Jerome Souquieres 7 7 # 8 8 # Permission is hereby granted, free of charge, to any person obtaining a copy … … 16 16 # all copies or substantial portions of the Software. 17 17 # ---------------------------------------------------------------------------- 18 19 # This Subversion unified pre/post-commit hook script is meant to interface20 # to the Trac (http://www.edgewall.com/products/trac/) issue tracking/wiki/etc21 # system.22 #23 # It should be called from the 'pre-commit' script in Subversion, such as24 # via:25 #26 # REPOS="$1"27 # TXN="$2"28 # TRAC_ENV="/somewhere/trac/project/"29 #30 # /usr/bin/python /usr/local/src/trac/contrib/trac-uni-commit-hook \31 # -d "$REPOS" \32 # -p "$TRAC_ENV" \33 # -t "$TXN"34 #35 #36 # It should be called from the 'post-commit' script in Subversion, such as37 # via:38 #39 # REPOS="$1"40 # REV="$2"41 # TRAC_ENV='/somewhere/trac/project/'42 #43 # /usr/bin/python /usr/local/src/trac/contrib/trac-uni-commit-hook \44 # -d "$REPOS" \45 # -p "$TRAC_ENV" \46 # -r "$REV"47 #48 18 49 19 import re … … 84 54 # 85 55 ticket_cmd_pattern = re.compile(r'^(?P<action>refs|closes|fixes).?#(?P<ticket>[0-9]+)', re.IGNORECASE) 86 changeset_cmd_pattern = re.compile(r'^(?P<action>delivers|brings)(?P<force> .?)\s+((\[(?P<first>\d+)\])(:\[(?P<second>\d+)\])?)?', re.IGNORECASE)56 changeset_cmd_pattern = re.compile(r'^(?P<action>delivers|brings)(?P<force>\!)?\s+((\[(?P<first>\d+)\])(\s*:\s*\[(?P<second>\d+)\])?)?', re.IGNORECASE) 87 57 create_pattern = re.compile(r'^(?P<action>creates)', re.IGNORECASE) 88 terminate_pattern = re.compile(r'^(?P<action>terminates)(?P<force> .?)\s', re.IGNORECASE)58 terminate_pattern = re.compile(r'^(?P<action>terminates)(?P<force>\!)?\s', re.IGNORECASE) 89 59 admin_pattern = re.compile(r'^(?P<action>admins)', re.IGNORECASE) 90 60 … … 99 69 # SVN directories 100 70 # 101 branch_directory = '/branches' 71 dev_branch_dirs = ['/sandboxes', '/branches'] 102 72 trunk_directory = '/trunk' 103 configpath = ' C:/Var/svn/config/access.conf'73 configpath = '/local/var/svn/config/access.conf' 104 74 105 75 # … … 137 107 self.author = self._get_author() 138 108 self.log = self._get_log() 139 os.environ['PYTHON_EGG_CACHE'] = \140 os.path.join(project, '..', '..', 'eggcache')141 109 if not os.path.isdir(os.environ['PYTHON_EGG_CACHE']): 142 110 raise AssertionError("Invalid egg cache directory: %s" % \ … … 148 116 r'(?:/(?P<path>.*))?$') 149 117 self.bcre = re.compile(bre) 118 119 # Nearly empty log message 120 if not self.log: 121 print>>sys.stderr, 'Log message is invalid' 122 self.finalize(ERROR) 150 123 151 124 # Administration commit … … 158 131 terminate = terminate_pattern.search(self.log) 159 132 if terminate: 160 rc = self._cmd_terminates(terminate.group('force') )133 rc = self._cmd_terminates(terminate.group('force') and True) 161 134 self.finalize(OK) 162 135 … … 174 147 func = getattr(self, CommitHook._changeset_cmds[cmd]) 175 148 rc = func(chgset_cmd.group('first'), chgset_cmd.group('second'), 176 chgset_cmd.group('force') )149 chgset_cmd.group('force') and True) 177 150 self.finalize(rc) 178 151 else: … … 189 162 self.finalize(rc) 190 163 else: 191 print>>sys.stderr, 'No supported action specifiedin log message !'164 print>>sys.stderr, 'No supported action in log message !' 192 165 self.finalize(ERROR) 193 166 194 167 # Unrecognized log message 195 print>>sys.stderr, 'No action specifiedin log message !'168 print>>sys.stderr, 'No known action in log message !' 196 169 self.finalize(ERROR) 197 170 … … 270 243 ticket_dict = {} 271 244 for rev in revisions: 272 bring_prop = self.proxy.get_revision_property(int(rev), bring_prop_name) 245 bring_prop = self.proxy.get_revision_property(int(rev), \ 246 bring_prop_name) 273 247 if bring_prop and len(bring_prop) > 0: 274 248 bring_revs = bring_prop.split(',') … … 295 269 return is_open 296 270 271 def _is_admin(self, author): 272 ''' 273 Verify whether the author has administrator priviledges 274 ''' 275 config = ConfigParser() 276 if not os.path.isfile(configpath): 277 raise AssertionError('Unable to find Subversion ACL for admins') 278 config.read(configpath) 279 admins = config.get('groups','admins') 280 if not admins: 281 raise AssertionError('Unable to retrieve Subversion ACL for admins') 282 if not author.lower() in [s.strip() for s in admins.lower().split(',')]: 283 return False 284 return True 285 286 def _is_dev_branch(self, dir_path): 287 ''' 288 Tell whether a directory is located inside a development branch or not 289 ''' 290 for dev_br in dev_branch_dirs: 291 if dir_path[:len(dev_br)] == dev_br: 292 return True 293 return False 294 297 295 298 296 class PreCommitHook(CommitHook): … … 323 321 ''' 324 322 log = self.proxy.get_txn_log_message() 323 if len(log) < 2: 324 return None 325 # Be sure the first letter is uppercased 326 log = log[0].upper() + log[1:] 325 327 return log 326 328 329 def _update_log(self, log): 330 ''' 331 Update the transaction log message 332 ''' 333 self.proxy.set_txn_log_message(log) 334 327 335 def _is_txn_branch_directory(self): 328 336 ''' 329 337 Check if the directory of the transaction is a branch directory 330 (located under /branches)338 (located under the branches directory) 331 339 ''' 332 340 dst_branch = self.proxy.find_txn_branch(self.bcre) 333 is_branch = dst_branch[:len(branch_directory)] == branch_directory 334 return is_branch 341 return self._is_dev_branch(dst_branch) 335 342 336 343 def finalize(self, result): 344 if OK == result: 345 self._update_log(self.log) 337 346 sys.exit(result) 338 347 … … 340 349 ''' 341 350 Administrative commit 342 Check that the author has administrator rights 343 ''' 344 config = ConfigParser() 345 if not os.path.isfile(configpath): 346 print >>sys.stderr, 'Unable to find Subversion ACL for admins' 347 self.finalize(ERROR) 348 config.read(configpath) 349 admins = config.get('groups','admins') 350 if not admins: 351 print >>sys.stderr, 'Unable to retrieve Subversion ACL for admins' 352 self.finalize(ERROR) 353 if not self.author.lower() in map(string.strip, admins.lower().split(',')): 351 ''' 352 if not self._is_admin(self.author): 354 353 print >>sys.stderr, 'Only administrator can execute admin commits' 355 354 self.finalize(ERROR) … … 368 367 self.finalize(ERROR) 369 368 dstbranch = self.proxy.find_txn_branch(self.bcre) 370 if dstbranch[:len(branch_directory)] != branch_directory:369 if not self._is_dev_branch(dstbranch): 371 370 print >> sys.stderr, 'Cannot create a new branch outside %s' \ 372 % branch_directory371 % dev_branch_dirs 373 372 self.finalize(ERROR) 374 373 return OK … … 383 382 item = change_gen.next() 384 383 except StopIteration: 385 print >> sys.stderr, "No deleted path in the submitted revision"384 print >> sys.stderr, 'No deleted path in the submitted revision' 386 385 self.finalize(ERROR) 387 386 try: … … 390 389 pass 391 390 else: 392 print >> sys.stderr, "Termination of more than one branch is not allowed" 391 print >> sys.stderr, 'Termination of more than one branch is not ' \ 392 'allowed' 393 393 self.finalize(ERROR) 394 394 (path, change) = item … … 397 397 self.finalize(ERROR) 398 398 dstbranch = self.proxy.find_txn_branch(self.bcre) 399 if dstbranch[:len(branch_directory)] != branch_directory:399 if not self._is_dev_branch(dstbranch): 400 400 print >> sys.stderr, 'Cannot terminates a non-branch dir (%s)' \ 401 % branch_directory402 self.finalize(ERROR) 403 if force != '!':401 % dev_branch_dirs 402 self.finalize(ERROR) 403 if not force: 404 404 youngest = self.proxy.get_youngest_path_revision(path) 405 405 # now checks that the deleter is the creator of the branch … … 428 428 self.finalize(ERROR) 429 429 if not self._is_txn_branch_directory(): 430 print >> sys.stderr, 'Cannot apply changes to a non-branch dir (%s)' \431 % branch_directory430 print >> sys.stderr, 'Cannot apply changes to a non-branch dir' \ 431 ' (%s)' % dev_branch_dirs 432 432 self.finalize(ERROR) 433 433 return OK … … 489 489 print >> sys.stderr, "Revisions %s %s %s" % (rev1, rev2, revisions) 490 490 self.finalize(ERROR) 491 491 492 # On error, the transaction is destroyed, so it is safe to apply the 492 493 # property even if the hook fails. … … 498 499 print >> sys.stderr, 'Unable to locate delivery destination' 499 500 self.finalize(ERROR) 501 502 # Ensure the branch is not delivered to self 500 503 branch1 = self.proxy.find_revision_branch(int(rev1), self.bcre) 501 504 if dstbranch == branch1: 502 505 print >> sys.stderr, 'Cannot deliver to self (%s -> %s)' % \ 503 506 (branch1, dstbranch) 507 self.finalize(ERROR) 508 509 # Ensure that the 'branch creation' revision is not selected as a source 510 print >> sys.stderr, "BRANCH1: (%s) [%s]" % (rev1, branch1) 511 brevs = [h[0] for h in self.proxy.get_history(int(rev1), branch1, None)] 512 if rev1 == brevs[0]: 513 print >> sys.stderr, \ 514 'Cannot deliver the initial branch revision (%d)' % rev1 504 515 self.finalize(ERROR) 505 516 … … 523 534 # 'as the latest CC export (rev %d on %s) has not been ' \ 524 535 # 'tagged and imported back into SVN' % (rev, exportval) 525 # if force != '!':536 # if not force: 526 537 # # Aborts if no force mode is specified 527 538 # self.finalize(ERROR) … … 530 541 # @todo there's probably a better way to format this 531 542 tickets = self._collect_tickets(revisions) 532 full_log = self.log 533 full_log += '\n'543 full_log = self.log.decode('utf8') 544 full_log += u'\n' 534 545 for tkt_id in tickets: 535 546 ticket = Ticket(self.env, tkt_id) 536 full_log += '\n* #%s: %s\n' % (tkt_id, ticket['summary']) 537 full_log += '\n'.join( [ "%s - %s" % (revi[0], revi[1]) for revi in tickets[tkt_id] ]) 538 full_log += '\n' 539 # print >> sys.stderr, full_log 540 self.proxy.set_txn_log_message(str(full_log)) 541 547 full_log += u'\n* #%s: %s\n' % (tkt_id, ticket['summary']) 548 full_log += u'\n'.join([u' %s' % (revi[1].decode('utf8')) \ 549 for revi in tickets[tkt_id]]) 550 full_log += u'\n' 551 full_log = full_log[0].upper() + full_log[1:] 552 self.log = full_log.encode('utf8') 553 542 554 # Check if there is a next milestone defined in Trac 543 555 # This is a bit too conservative, as a next milestone is only needed if revtreeplugin/0.11/hooks/trac-revprop-hook
- Property svn:eol-style set to native
r2638 r3581 3 3 # trac-revprop-hook 4 4 # ---------------------------------------------------------------------------- 5 # Copyright (c) 2007 Emmanuel Blot5 # Copyright (c) 2007-2008 Emmanuel Blot 6 6 # ---------------------------------------------------------------------------- 7 7 … … 35 35 ERROR = 1 36 36 37 configpath = 'C:/Var/svn/config/access.conf' 37 configpath = '/local/var/svn/config/access.conf' 38 39 changeset_cmd_pattern = r'^(?P<action>delivers|brings)(?P<force>\!)?\s+((\[(?P<first>\d+)\])(:\[(?P<second>\d+)\])?)?' 38 40 39 41 class RevpropHook(object): … … 42 44 def __init__(self, post, project, rev, name, value, 43 45 action=None, author=None, repos=None): 44 os.environ['PYTHON_EGG_CACHE'] = os.path.join(project, '..', '..', 'eggcache')45 46 if not os.path.isdir(os.environ['PYTHON_EGG_CACHE']): 46 47 raise AssertionError("Invalid egg cache directory: %s" % os.environ['PYTHON_EGG_CACHE']); … … 89 90 90 91 def _verify_log_msg(self): 91 regex = re.compile(r'^(?P<action>delivers|brings).?\s+((\[(?P<first>\d+)\])(:\[(?P<second>\d+)\])?)?', 92 re.IGNORECASE) 92 regex = re.compile(changeset_cmd_pattern, re.IGNORECASE) 93 93 self.proxy = RepositoryProxy(self.repospath) 94 94 oldlog = self.proxy.get_revision_log_message(self.rev) … … 96 96 if oldmo: 97 97 newmo = regex.search(self.value) 98 if (not newmo) or \ 99 (oldmo.group('first') != newmo.group('first')) or \ 98 if (not newmo): 99 print >> sys.stderr, \ 100 'Missing message:\n was: "%s"' % oldlog.split('\n')[0] 101 sys.exit(-ERROR) 102 if (oldmo.group('first') != newmo.group('first')) or \ 100 103 (oldmo.group('second') != newmo.group('second')): 101 print >> sys.stderr, \ 102 'Original parameters should be kept unaltered:\n "%s"' % \ 103 oldlog.split('\n')[0] 104 sys.exit(-ERROR) 104 if not self._is_admin(self.author) or not newmo.group('force'): 105 print >> sys.stderr, \ 106 'Original parameters should be kept unaltered:\n' \ 107 ' "%s"' % oldlog.split('\n')[0] 108 sys.exit(-ERROR) 105 109 106 110 def _verify_rth_deliver(self): … … 134 138 repos = self.env.get_repository() 135 139 repos.sync_changeset(self.rev) 140 141 def _is_admin(self, author): 142 ''' 143 Verify whether the author has administrator priviledges 144 ''' 145 config = ConfigParser() 146 if not os.path.isfile(configpath): 147 raise AssertionError('Unable to find Subversion ACL for admins') 148 config.read(configpath) 149 admins = config.get('groups','admins') 150 if not admins: 151 raise AssertionError('Unable to retrieve Subversion ACL for admins') 152 if not author.lower() in [s.strip() for s in admins.lower().split(',')]: 153 return False 154 return True 136 155 137 156
