[Pysvnmanager-svn] SF.net SVN: pysvnmanager:[47] trunk
Status: Alpha
Brought to you by:
jiangx
From: <ji...@us...> - 2008-08-28 11:15:35
|
Revision: 47 http://pysvnmanager.svn.sourceforge.net/pysvnmanager/?rev=47&view=rev Author: jiangx Date: 2008-08-28 11:15:39 +0000 (Thu, 28 Aug 2008) Log Message: ----------- add more hooks plugins; add hook scripts; refactor hook-plugin Modified Paths: -------------- trunk/pySvnManager.egg-info/SOURCES.txt trunk/pysvnmanager/controllers/repos.py trunk/pysvnmanager/hooks/plugins/BugtrackMantis.py trunk/pysvnmanager/hooks/plugins/CaseInsensitive.py trunk/pysvnmanager/hooks/plugins/CommitLogCheck.py trunk/pysvnmanager/hooks/plugins/EmailNotify.py trunk/pysvnmanager/hooks/plugins/EolStyleCheck.py trunk/pysvnmanager/hooks/plugins/__init__.py trunk/pysvnmanager/i18n/en/LC_MESSAGES/pysvnmanager.po trunk/pysvnmanager/i18n/pysvnmanager.pot trunk/pysvnmanager/i18n/zh/LC_MESSAGES/pysvnmanager.po trunk/pysvnmanager/model/hooks.py trunk/pysvnmanager/model/repos.py trunk/pysvnmanager/tests/test_repos.py trunk/setup.py Added Paths: ----------- trunk/pysvnmanager/hooks/init/hook1.4/ trunk/pysvnmanager/hooks/init/hook1.4/parse_ini.sh trunk/pysvnmanager/hooks/init/hook1.4/post-commit trunk/pysvnmanager/hooks/init/hook1.4/post-lock.tmpl trunk/pysvnmanager/hooks/init/hook1.4/post-revprop-change trunk/pysvnmanager/hooks/init/hook1.4/post-unlock.tmpl trunk/pysvnmanager/hooks/init/hook1.4/pre-commit trunk/pysvnmanager/hooks/init/hook1.4/pre-lock.tmpl trunk/pysvnmanager/hooks/init/hook1.4/pre-revprop-change trunk/pysvnmanager/hooks/init/hook1.4/pre-unlock.tmpl trunk/pysvnmanager/hooks/init/hook1.4/scripts/ trunk/pysvnmanager/hooks/init/hook1.4/scripts/README trunk/pysvnmanager/hooks/init/hook1.4/scripts/check-authz.py trunk/pysvnmanager/hooks/init/hook1.4/scripts/check-case-insensitive.pl trunk/pysvnmanager/hooks/init/hook1.4/scripts/check-case-insensitive.py trunk/pysvnmanager/hooks/init/hook1.4/scripts/check-mime-type.pl trunk/pysvnmanager/hooks/init/hook1.4/scripts/check-mime-type.py trunk/pysvnmanager/hooks/init/hook1.4/scripts/commit-access-control.cfg trunk/pysvnmanager/hooks/init/hook1.4/scripts/commit-access-control.cfg.example trunk/pysvnmanager/hooks/init/hook1.4/scripts/commit-access-control.pl trunk/pysvnmanager/hooks/init/hook1.4/scripts/commit-block-joke.py trunk/pysvnmanager/hooks/init/hook1.4/scripts/commit-email.pl trunk/pysvnmanager/hooks/init/hook1.4/scripts/commit-email.rb trunk/pysvnmanager/hooks/init/hook1.4/scripts/commit_log_check.py trunk/pysvnmanager/hooks/init/hook1.4/scripts/detect-merge-conflicts.sh trunk/pysvnmanager/hooks/init/hook1.4/scripts/log-police.py trunk/pysvnmanager/hooks/init/hook1.4/scripts/pre-commit-check.py trunk/pysvnmanager/hooks/init/hook1.4/scripts/pre-lock-require-needs-lock.py trunk/pysvnmanager/hooks/init/hook1.4/scripts/svn2rss.py trunk/pysvnmanager/hooks/init/hook1.4/scripts/svnperms.conf trunk/pysvnmanager/hooks/init/hook1.4/scripts/svnperms.conf.example trunk/pysvnmanager/hooks/init/hook1.4/scripts/svnperms.py trunk/pysvnmanager/hooks/init/hook1.4/scripts/verify-po.py trunk/pysvnmanager/hooks/init/hook1.4/start-commit trunk/pysvnmanager/hooks/init/hook1.5/ trunk/pysvnmanager/hooks/init/hook1.5/parse_ini.sh trunk/pysvnmanager/hooks/init/hook1.5/post-commit trunk/pysvnmanager/hooks/init/hook1.5/post-lock.tmpl trunk/pysvnmanager/hooks/init/hook1.5/post-revprop-change trunk/pysvnmanager/hooks/init/hook1.5/post-unlock.tmpl trunk/pysvnmanager/hooks/init/hook1.5/pre-commit trunk/pysvnmanager/hooks/init/hook1.5/pre-lock.tmpl trunk/pysvnmanager/hooks/init/hook1.5/pre-revprop-change trunk/pysvnmanager/hooks/init/hook1.5/pre-unlock.tmpl trunk/pysvnmanager/hooks/init/hook1.5/scripts/ trunk/pysvnmanager/hooks/init/hook1.5/scripts/README trunk/pysvnmanager/hooks/init/hook1.5/scripts/check-authz.py trunk/pysvnmanager/hooks/init/hook1.5/scripts/check-case-insensitive.pl trunk/pysvnmanager/hooks/init/hook1.5/scripts/check-case-insensitive.py trunk/pysvnmanager/hooks/init/hook1.5/scripts/check-mime-type.pl trunk/pysvnmanager/hooks/init/hook1.5/scripts/check-mime-type.py trunk/pysvnmanager/hooks/init/hook1.5/scripts/commit-access-control.cfg trunk/pysvnmanager/hooks/init/hook1.5/scripts/commit-access-control.cfg.example trunk/pysvnmanager/hooks/init/hook1.5/scripts/commit-access-control.pl trunk/pysvnmanager/hooks/init/hook1.5/scripts/commit-block-joke.py trunk/pysvnmanager/hooks/init/hook1.5/scripts/commit-email.pl trunk/pysvnmanager/hooks/init/hook1.5/scripts/commit-email.rb trunk/pysvnmanager/hooks/init/hook1.5/scripts/commit_log_check.py trunk/pysvnmanager/hooks/init/hook1.5/scripts/detect-merge-conflicts.sh trunk/pysvnmanager/hooks/init/hook1.5/scripts/log-police.py trunk/pysvnmanager/hooks/init/hook1.5/scripts/pre-commit-check.py trunk/pysvnmanager/hooks/init/hook1.5/scripts/pre-lock-require-needs-lock.py trunk/pysvnmanager/hooks/init/hook1.5/scripts/svn2rss.py trunk/pysvnmanager/hooks/init/hook1.5/scripts/svnperms.conf trunk/pysvnmanager/hooks/init/hook1.5/scripts/svnperms.conf.example trunk/pysvnmanager/hooks/init/hook1.5/scripts/svnperms.py trunk/pysvnmanager/hooks/init/hook1.5/scripts/verify-po.py trunk/pysvnmanager/hooks/init/hook1.5/start-commit trunk/pysvnmanager/hooks/plugins/AllowRevpropChange.py trunk/pysvnmanager/hooks/plugins/CapCheckMergeInfo.py trunk/pysvnmanager/hooks/plugins/ReadonlySvnMirror.py Removed Paths: ------------- trunk/pysvnmanager/hooks/plugins/MergeinfoClient.py Modified: trunk/pySvnManager.egg-info/SOURCES.txt =================================================================== --- trunk/pySvnManager.egg-info/SOURCES.txt 2008-08-27 14:04:28 UTC (rev 46) +++ trunk/pySvnManager.egg-info/SOURCES.txt 2008-08-28 11:15:39 UTC (rev 47) @@ -20,11 +20,16 @@ pysvnmanager/__init__.py pysvnmanager/websetup.py pysvnmanager/config/DefaultConfig.py +pysvnmanager/config/DefaultConfig.pyc pysvnmanager/config/__init__.py +pysvnmanager/config/__init__.pyc pysvnmanager/config/environment.py +pysvnmanager/config/environment.pyc pysvnmanager/config/localconfig.py.in pysvnmanager/config/middleware.py +pysvnmanager/config/middleware.pyc pysvnmanager/config/routing.py +pysvnmanager/config/routing.pyc pysvnmanager/config/svn.access.in pysvnmanager/config/svn.passwd.in pysvnmanager/controllers/__init__.py @@ -32,9 +37,41 @@ pysvnmanager/controllers/check.py pysvnmanager/controllers/error.py pysvnmanager/controllers/logs.py +pysvnmanager/controllers/repos.py pysvnmanager/controllers/role.py pysvnmanager/controllers/security.py pysvnmanager/controllers/template.py +pysvnmanager/hooks/__init__.py +pysvnmanager/hooks/init/__init__.py +pysvnmanager/hooks/init/hook1.4/parse_ini.sh +pysvnmanager/hooks/init/hook1.4/post-commit +pysvnmanager/hooks/init/hook1.4/post-lock.tmpl +pysvnmanager/hooks/init/hook1.4/post-revprop-change +pysvnmanager/hooks/init/hook1.4/post-unlock.tmpl +pysvnmanager/hooks/init/hook1.4/pre-commit +pysvnmanager/hooks/init/hook1.4/pre-lock.tmpl +pysvnmanager/hooks/init/hook1.4/pre-revprop-change +pysvnmanager/hooks/init/hook1.4/pre-unlock.tmpl +pysvnmanager/hooks/init/hook1.4/start-commit +pysvnmanager/hooks/init/hook1.5/parse_ini.sh +pysvnmanager/hooks/init/hook1.5/post-commit +pysvnmanager/hooks/init/hook1.5/post-lock.tmpl +pysvnmanager/hooks/init/hook1.5/post-revprop-change +pysvnmanager/hooks/init/hook1.5/post-unlock.tmpl +pysvnmanager/hooks/init/hook1.5/pre-commit +pysvnmanager/hooks/init/hook1.5/pre-lock.tmpl +pysvnmanager/hooks/init/hook1.5/pre-revprop-change +pysvnmanager/hooks/init/hook1.5/pre-unlock.tmpl +pysvnmanager/hooks/init/hook1.5/start-commit +pysvnmanager/hooks/plugins/AllowRevpropChange.py +pysvnmanager/hooks/plugins/BugtrackMantis.py +pysvnmanager/hooks/plugins/CapCheckMergeInfo.py +pysvnmanager/hooks/plugins/CaseInsensitive.py +pysvnmanager/hooks/plugins/CommitLogCheck.py +pysvnmanager/hooks/plugins/EmailNotify.py +pysvnmanager/hooks/plugins/EolStyleCheck.py +pysvnmanager/hooks/plugins/ReadonlySvnMirror.py +pysvnmanager/hooks/plugins/__init__.py pysvnmanager/i18n/pysvnmanager.pot pysvnmanager/i18n/en/LC_MESSAGES/pysvnmanager.mo pysvnmanager/i18n/en/LC_MESSAGES/pysvnmanager.po @@ -46,11 +83,19 @@ pysvnmanager/lib/helpers.py pysvnmanager/model/__init__.py pysvnmanager/model/configobj.py +pysvnmanager/model/hooks.py pysvnmanager/model/rcsbackup.py +pysvnmanager/model/repos.py +pysvnmanager/model/rest.py pysvnmanager/model/svnauthz.py pysvnmanager/model/auth/__init__.py pysvnmanager/model/auth/http.py pysvnmanager/model/auth/ldap_login.py +pysvnmanager/public/css/common.css +pysvnmanager/public/img/alert.png +pysvnmanager/public/img/attention.png +pysvnmanager/public/img/icon-error.png +pysvnmanager/public/img/icon-info.png pysvnmanager/templates/auth_failed.mako pysvnmanager/templates/base.mako pysvnmanager/templates/authz/index.mako @@ -61,13 +106,19 @@ pysvnmanager/templates/logs/index.mako pysvnmanager/templates/logs/rollback.mako pysvnmanager/templates/logs/view.mako +pysvnmanager/templates/repos/create.mako +pysvnmanager/templates/repos/hooks.mako +pysvnmanager/templates/repos/remove.mako pysvnmanager/templates/role/index.mako pysvnmanager/tests/__init__.py pysvnmanager/tests/test_models.py pysvnmanager/tests/test_rcs_backup.py +pysvnmanager/tests/test_repos.py +pysvnmanager/tests/data/svnroot.tar.bz2 pysvnmanager/tests/functional/__init__.py pysvnmanager/tests/functional/test_authz.py pysvnmanager/tests/functional/test_check.py pysvnmanager/tests/functional/test_login.py pysvnmanager/tests/functional/test_logs.py +pysvnmanager/tests/functional/test_repos.py pysvnmanager/tests/functional/test_role.py \ No newline at end of file Modified: trunk/pysvnmanager/controllers/repos.py =================================================================== --- trunk/pysvnmanager/controllers/repos.py 2008-08-27 14:04:28 UTC (rev 46) +++ trunk/pysvnmanager/controllers/repos.py 2008-08-28 11:15:39 UTC (rev 47) @@ -58,9 +58,9 @@ msg += 'id[0]="%s";' % '...' msg += 'name[0]="%s";\n' % _("Please choose...") total += 1; - for name in h.unapplied_plugins.keys(): + for name in h.unapplied_plugins: msg += 'id[%d]="%s";' % (total, name) - msg += 'name[%d]="%s";\n' % (total, h.plugins[name].name) + msg += 'name[%d]="%s";\n' % (total, name + ': ' + h.plugins[name].name) total += 1; msg += 'total=%d;\n' % total @@ -81,7 +81,7 @@ "<th align='left'>" + _("Plugin name") + "</th>" + \ "<th align='left'>" + _("Type") + "</th>" + \ "</tr>\n" - for name in h.applied_plugins.keys(): + for name in h.applied_plugins: msg += "<tr><td width='1' rolspan='2'>" msg += '<input type="checkbox" name="pluginid_%(num)d" value="%(plugin)s">' % { 'num': num, 'plugin': name, } @@ -117,7 +117,7 @@ plugin.install(d) except Exception, e: result = "<div class='error'>" + _("Apply plugin '%(plugin)s' on '%(repos)s' Failed. Error message:<br>\n%(msg)s") % { - "plugin": pluginname, "repos":reposname, "msg": e.message} + "</div>" + "plugin": pluginname, "repos":reposname, "msg": e} + "</div>" else: result = "<div class='info'>" + _("Apply plugin '%(plugin)s' on '%(repos)s' success.") % { "plugin": pluginname, "repos":reposname} + "</div>" Added: trunk/pysvnmanager/hooks/init/hook1.4/parse_ini.sh =================================================================== --- trunk/pysvnmanager/hooks/init/hook1.4/parse_ini.sh (rev 0) +++ trunk/pysvnmanager/hooks/init/hook1.4/parse_ini.sh 2008-08-28 11:15:39 UTC (rev 47) @@ -0,0 +1,54 @@ +#!/bin/bash + + +CONFIG=../conf/hooks.ini + +function readconf() { + + match=0 + + while read line; do + # skip comments + [[ $line =~ ^\ {0,}# ]] && continue + + + # skip empty lines + [[ -z "$line" ]] && continue + + # still no match? lets check again + if [ $match == 0 ]; then + + # do we have a section tag ? + if [[ $line =~ ^\[.*?\] ]]; then + + #strip [] + line=${line:1:$((${#line}-2))} + # strip whitespace + section=${line// /} + + # do we have a match ? + if [[ "$section" == "$1" ]]; then + match=1 + continue + fi + + continue + fi + + # found next section after config was read - exit loop + elif [[ $line =~ ^\[.*?\] && $match == 1 ]]; then + break + + # got a config line eval it + else + var=${line%%=*} + var=${var// /} + value=${line##*=} + value=${value## } + eval "$var='$value'" + fi + + done < "$CONFIG" +} + + Added: trunk/pysvnmanager/hooks/init/hook1.4/post-commit =================================================================== --- trunk/pysvnmanager/hooks/init/hook1.4/post-commit (rev 0) +++ trunk/pysvnmanager/hooks/init/hook1.4/post-commit 2008-08-28 11:15:39 UTC (rev 47) @@ -0,0 +1,88 @@ +#!/bin/sh + +# POST-COMMIT HOOK +# +# The post-commit hook is invoked after a commit. Subversion runs +# this hook by invoking a program (script, executable, binary, etc.) +# named 'post-commit' (for which this file is a template) with the +# following ordered arguments: +# +# [1] REPOS-PATH (the path to this repository) +# [2] REV (the number of the revision just committed) +# +# The default working directory for the invocation is undefined, so +# the program should set one explicitly if it cares. +# +# Because the commit has already completed and cannot be undone, +# the exit code of the hook program is ignored. The hook program +# can use the 'svnlook' utility to help it examine the +# newly-committed tree. +# +# On a Unix system, the normal procedure is to have 'post-commit' +# invoke other programs to do the real work, though it may do the +# work itself too. +# +# Note that 'post-commit' must be executable by the user(s) who will +# invoke it (typically the user httpd runs as), and that user must +# have filesystem-level permission to access the repository. +# +# On a Windows system, you should name the hook program +# 'post-commit.bat' or 'post-commit.exe', +# but the basic idea is the same. +# +# The hook program typically does not inherit the environment of +# its parent process. For example, a common problem is for the +# PATH environment variable to not be set to its usual value, so +# that subprograms fail to launch unless invoked via absolute path. +# If you're having unexpected problems with a hook program, the +# culprit may be unusual (or missing) environment variables. +# +# Here is an example hook script, for a Unix /bin/sh interpreter. +# For more examples and pre-written hooks, see those in +# the Subversion repository at +# http://svn.collab.net/repos/svn/trunk/tools/hook-scripts/ and +# http://svn.collab.net/repos/svn/trunk/contrib/hook-scripts/ + + +REPOS="$1" +REV="$2" +TOOLS_DIR=$REPOS/hooks/scripts + +source $REPOS/hooks/parse_ini.sh +CONFIG=$REPOS/conf/hooks.ini +readconf post_commit +readconf email + +## Sync with downstream mirror sites using svnsync +#SVNSYNCCMD=$REPOS/hooks/svnsync.commit +#if [ -x "$SVNSYNCCMD" ]; then +# $SVNSYNCCMD +#fi + +if [ "$email_notify_enable" = "yes" ]; then + #$TOOLS_DIR/log-commit.py --repository "$REPOS" --revision "$REV" + #$TOOLS_DIR/commit-email.pl "$REPOS" "$REV" -m "." --diff y --from no...@fo...r -r no...@fo...r -s "[Prefix]" li...@fo...r + mailcmd="$TOOLS_DIR/commit-email.pl \"$REPOS\" \"$REV\" $email_notify_config" + eval $mailcmd +fi + +############################################################ +# +# Mantisbt integration ( http://www.worldhello.net ) +# +############################################################ +if [ "$mantis_integration" = "yes" ]; then + SVNLOOK=/opt/svn/bin/svnlook + SED=/bin/sed + MANTISBT=/opt/mantis/web + PHP=/opt/php5/bin/php5 + + if [ -f "$MANTISBT/core/checkin.php" ]; then + export LC_ALL=zh_CN.utf8 + commitlog=`$SVNLOOK log -r "$REV" "$REPOS" | $SED -e 's/\$/\\\\n/g'` + commitauthor=`$SVNLOOK author -r "$REV" "$REPOS" | $SED -e 's/\$/\\\\n/g'` + commitdiff=`$SVNLOOK diff -r "$REV" "$REPOS" | head -25 | $SED -e 's/\$/\\\\n/g'` + echo -e "Author: $commitauthor\nCommit Log:\n$commitlog\n\n****** Source code change ******\nRepository: $REPOS, Revision: $REV.\n\n$commitdiff" | $PHP -q $MANTISBT/core/checkin.php + fi +fi + Added: trunk/pysvnmanager/hooks/init/hook1.4/post-lock.tmpl =================================================================== --- trunk/pysvnmanager/hooks/init/hook1.4/post-lock.tmpl (rev 0) +++ trunk/pysvnmanager/hooks/init/hook1.4/post-lock.tmpl 2008-08-28 11:15:39 UTC (rev 47) @@ -0,0 +1,45 @@ +#!/bin/sh + +# POST-LOCK HOOK +# +# The post-lock hook is run after a path is locked. Subversion runs +# this hook by invoking a program (script, executable, binary, etc.) +# named 'post-lock' (for which this file is a template) with the +# following ordered arguments: +# +# [1] REPOS-PATH (the path to this repository) +# [2] USER (the user who created the lock) +# +# The paths that were just locked are passed to the hook via STDIN (as +# of Subversion 1.2, only one path is passed per invocation, but the +# plan is to pass all locked paths at once, so the hook program +# should be written accordingly). +# +# The default working directory for the invocation is undefined, so +# the program should set one explicitly if it cares. +# +# Because the lock has already been created and cannot be undone, +# the exit code of the hook program is ignored. The hook program +# can use the 'svnlook' utility to help it examine the +# newly-created lock. +# +# On a Unix system, the normal procedure is to have 'post-lock' +# invoke other programs to do the real work, though it may do the +# work itself too. +# +# Note that 'post-lock' must be executable by the user(s) who will +# invoke it (typically the user httpd runs as), and that user must +# have filesystem-level permission to access the repository. +# +# On a Windows system, you should name the hook program +# 'post-lock.bat' or 'post-lock.exe', +# but the basic idea is the same. +# +# Here is an example hook script, for a Unix /bin/sh interpreter: + +REPOS="$1" +USER="$2" +TOOLS_DIR=$REPOS/hooks/scripts + +# Send email to interested parties, let them know a lock was created: +#$TOOLS_DIR/mailer/mailer.py lock "$REPOS" "$USER" $TOOLS_DIR/mailer/mailer.conf Added: trunk/pysvnmanager/hooks/init/hook1.4/post-revprop-change =================================================================== --- trunk/pysvnmanager/hooks/init/hook1.4/post-revprop-change (rev 0) +++ trunk/pysvnmanager/hooks/init/hook1.4/post-revprop-change 2008-08-28 11:15:39 UTC (rev 47) @@ -0,0 +1,71 @@ +#!/bin/sh + +# POST-REVPROP-CHANGE HOOK +# +# The post-revprop-change hook is invoked after a revision property +# has been added, modified or deleted. Subversion runs this hook by +# invoking a program (script, executable, binary, etc.) named +# 'post-revprop-change' (for which this file is a template), with the +# following ordered arguments: +# +# [1] REPOS-PATH (the path to this repository) +# [2] REV (the revision that was tweaked) +# [3] USER (the username of the person tweaking the property) +# [4] PROPNAME (the property that was changed) +# [5] ACTION (the property was 'A'dded, 'M'odified, or 'D'eleted) +# +# [STDIN] PROPVAL ** the old property value is passed via STDIN. +# +# Because the propchange has already completed and cannot be undone, +# the exit code of the hook program is ignored. The hook program +# can use the 'svnlook' utility to help it examine the +# new property value. +# +# On a Unix system, the normal procedure is to have 'post-revprop-change' +# invoke other programs to do the real work, though it may do the +# work itself too. +# +# Note that 'post-revprop-change' must be executable by the user(s) who will +# invoke it (typically the user httpd runs as), and that user must +# have filesystem-level permission to access the repository. +# +# On a Windows system, you should name the hook program +# 'post-revprop-change.bat' or 'post-revprop-change.exe', +# but the basic idea is the same. +# +# The hook program typically does not inherit the environment of +# its parent process. For example, a common problem is for the +# PATH environment variable to not be set to its usual value, so +# that subprograms fail to launch unless invoked via absolute path. +# If you're having unexpected problems with a hook program, the +# culprit may be unusual (or missing) environment variables. +# +# Here is an example hook script, for a Unix /bin/sh interpreter. +# For more examples and pre-written hooks, see those in +# the Subversion repository at +# http://svn.collab.net/repos/svn/trunk/tools/hook-scripts/ and +# http://svn.collab.net/repos/svn/trunk/contrib/hook-scripts/ + + +REPOS="$1" +REV="$2" +USER="$3" +PROPNAME="$4" +ACTION="$5" +TOOLS_DIR=$REPOS/hooks/scripts + +source $REPOS/hooks/parse_ini.sh +CONFIG=$REPOS/conf/hooks.ini +readconf email + +## Sync with downstream mirror sites using svnsync +#SVNSYNCCMD=$REPOS/hooks/svnsync.revprop +#if [ -x "$SVNSYNCCMD" ]; then +# $SVNSYNCCMD +#fi + +if [ "$email_notify_enable" = "yes" ]; then + #$TOOLS_DIR/commit-email.pl --revprop-change "$REPOS" "$REV" "$USER" "$PROPNAME" -m "." --from no...@fo...r -r no...@fo...r -s "[Prefix]" li...@fo...r + mailcmd="$TOOLS_DIR/commit-email.pl --revprop-change \"$REPOS\" \"$REV\" \"$USER\" \"$PROPNAME\" $email_notify_config" + eval $mailcmd +fi Added: trunk/pysvnmanager/hooks/init/hook1.4/post-unlock.tmpl =================================================================== --- trunk/pysvnmanager/hooks/init/hook1.4/post-unlock.tmpl (rev 0) +++ trunk/pysvnmanager/hooks/init/hook1.4/post-unlock.tmpl 2008-08-28 11:15:39 UTC (rev 47) @@ -0,0 +1,43 @@ +#!/bin/sh + +# POST-UNLOCK HOOK +# +# The post-unlock hook runs after a path is unlocked. Subversion runs +# this hook by invoking a program (script, executable, binary, etc.) +# named 'post-unlock' (for which this file is a template) with the +# following ordered arguments: +# +# [1] REPOS-PATH (the path to this repository) +# [2] USER (the user who destroyed the lock) +# +# The paths that were just unlocked are passed to the hook via STDIN +# (as of Subversion 1.2, only one path is passed per invocation, but +# the plan is to pass all unlocked paths at once, so the hook program +# should be written accordingly). +# +# The default working directory for the invocation is undefined, so +# the program should set one explicitly if it cares. +# +# Because the lock has already been destroyed and cannot be undone, +# the exit code of the hook program is ignored. +# +# On a Unix system, the normal procedure is to have 'post-unlock' +# invoke other programs to do the real work, though it may do the +# work itself too. +# +# Note that 'post-unlock' must be executable by the user(s) who will +# invoke it (typically the user httpd runs as), and that user must +# have filesystem-level permission to access the repository. +# +# On a Windows system, you should name the hook program +# 'post-unlock.bat' or 'post-unlock.exe', +# but the basic idea is the same. +# +# Here is an example hook script, for a Unix /bin/sh interpreter: + +REPOS="$1" +USER="$2" +TOOLS_DIR=$REPOS/hooks/scripts + +# Send email to interested parties, let them know a lock was removed: +$TOOLS_DIR/mailer/mailer.py unlock "$REPOS" "$USER" $TOOLS_DIR/mailer/mailer.conf Added: trunk/pysvnmanager/hooks/init/hook1.4/pre-commit =================================================================== --- trunk/pysvnmanager/hooks/init/hook1.4/pre-commit (rev 0) +++ trunk/pysvnmanager/hooks/init/hook1.4/pre-commit 2008-08-28 11:15:39 UTC (rev 47) @@ -0,0 +1,89 @@ +#!/bin/sh + +# PRE-COMMIT HOOK +# +# The pre-commit hook is invoked before a Subversion txn is +# committed. Subversion runs this hook by invoking a program +# (script, executable, binary, etc.) named 'pre-commit' (for which +# this file is a template), with the following ordered arguments: +# +# [1] REPOS-PATH (the path to this repository) +# [2] TXN-NAME (the name of the txn about to be committed) +# +# The default working directory for the invocation is undefined, so +# the program should set one explicitly if it cares. +# +# If the hook program exits with success, the txn is committed; but +# if it exits with failure (non-zero), the txn is aborted, no commit +# takes place, and STDERR is returned to the client. The hook +# program can use the 'svnlook' utility to help it examine the txn. +# +# On a Unix system, the normal procedure is to have 'pre-commit' +# invoke other programs to do the real work, though it may do the +# work itself too. +# +# *** NOTE: THE HOOK PROGRAM MUST NOT MODIFY THE TXN, EXCEPT *** +# *** FOR REVISION PROPERTIES (like svn:log or svn:author). *** +# +# This is why we recommend using the read-only 'svnlook' utility. +# In the future, Subversion may enforce the rule that pre-commit +# hooks should not modify the versioned data in txns, or else come +# up with a mechanism to make it safe to do so (by informing the +# committing client of the changes). However, right now neither +# mechanism is implemented, so hook writers just have to be careful. +# +# Note that 'pre-commit' must be executable by the user(s) who will +# invoke it (typically the user httpd runs as), and that user must +# have filesystem-level permission to access the repository. +# +# On a Windows system, you should name the hook program +# 'pre-commit.bat' or 'pre-commit.exe', +# but the basic idea is the same. +# +# The hook program typically does not inherit the environment of +# its parent process. For example, a common problem is for the +# PATH environment variable to not be set to its usual value, so +# that subprograms fail to launch unless invoked via absolute path. +# If you're having unexpected problems with a hook program, the +# culprit may be unusual (or missing) environment variables. +# +# Here is an example hook script, for a Unix /bin/sh interpreter. +# For more examples and pre-written hooks, see those in +# the Subversion repository at +# http://svn.collab.net/repos/svn/trunk/tools/hook-scripts/ and +# http://svn.collab.net/repos/svn/trunk/contrib/hook-scripts/ + + +REPOS="$1" +TXN="$2" +TOOLS_DIR=$REPOS/hooks/scripts + +source $REPOS/hooks/parse_ini.sh +CONFIG=$REPOS/conf/hooks.ini +readconf pre_commit + +if [ "$commit_log_check_enable" = "yes" ]; then + # Check commit log, by <WorldHello.net.AT.gmail.com> + $TOOLS_DIR/commit_log_check.py \ + -s "$commit_log_check_size" \ + -p "$commit_log_check_permit" \ + -P "$commit_log_check_prohibit" "$REPOS" "$TXN" || exit 1 +fi + +if [ "$eol_style_check" = "yes" ]; then + # New file must set svn:mime-type and svn:eol-style + $TOOLS_DIR/check-mime-type.py "$REPOS" "$TXN" || exit 1 +fi + +if [ "$detect_case_insensitive_clash" = "yes" ]; then + # Check for case conflicts + $TOOLS_DIR/check-case-insensitive.pl "$REPOS" "$TXN" || exit 1 + #$TOOLS_DIR/check-case-insensitive.py "$REPOS" "$TXN" || exit 1 +fi + +# Check that the author of this commit has the rights to perform +# the commit on the files and directories being modified. +#commit-access-control.pl "$REPOS" "$TXN" commit-access-control.cfg || exit 1 + +# All checks passed, so allow the commit. +exit 0 Added: trunk/pysvnmanager/hooks/init/hook1.4/pre-lock.tmpl =================================================================== --- trunk/pysvnmanager/hooks/init/hook1.4/pre-lock.tmpl (rev 0) +++ trunk/pysvnmanager/hooks/init/hook1.4/pre-lock.tmpl 2008-08-28 11:15:39 UTC (rev 47) @@ -0,0 +1,64 @@ +#!/bin/sh + +# PRE-LOCK HOOK +# +# The pre-lock hook is invoked before an exclusive lock is +# created. Subversion runs this hook by invoking a program +# (script, executable, binary, etc.) named 'pre-lock' (for which +# this file is a template), with the following ordered arguments: +# +# [1] REPOS-PATH (the path to this repository) +# [2] LOCKPATH (the path in the repository about to be locked) +# [3] USER (the user creating the lock) +# +# The default working directory for the invocation is undefined, so +# the program should set one explicitly if it cares. +# +# If the hook program exits with success, the lock is created; but +# if it exits with failure (non-zero), the lock action is aborted +# and STDERR is returned to the client. + +# On a Unix system, the normal procedure is to have 'pre-lock' +# invoke other programs to do the real work, though it may do the +# work itself too. +# +# Note that 'pre-lock' must be executable by the user(s) who will +# invoke it (typically the user httpd runs as), and that user must +# have filesystem-level permission to access the repository. +# +# On a Windows system, you should name the hook program +# 'pre-lock.bat' or 'pre-lock.exe', +# but the basic idea is the same. +# +# Here is an example hook script, for a Unix /bin/sh interpreter: + +REPOS="$1" +LOCKPATH="$2" +USER="$3" + +# If a lock exists and is owned by a different person, don't allow it +# to be stolen (e.g., with 'svn lock --force ...'). + +# (Maybe this script could send email to the lock owner?) +SVNLOOK=/opt/svn/bin/svnlook +GREP=/bin/grep +SED=/bin/sed + +LOCK_OWNER=`LANG=C $SVNLOOK lock "$REPOS" "$LOCKPATH" | \ + $GREP '^Owner: ' | $SED 's/Owner: //'` + +# If we get no result from svnlook, there's no lock, allow the lock to +# happen: +if [ "$LOCK_OWNER" = "" ]; then + exit 0 +fi + +# If the person locking matches the lock's owner, allow the lock to +# happen: +if [ "$LOCK_OWNER" = "$USER" ]; then + exit 0 +fi + +# Otherwise, we've got an owner mismatch, so return failure: +echo "Error: $LOCKPATH already locked by ${LOCK_OWNER}." 1>&2 +exit 1 Added: trunk/pysvnmanager/hooks/init/hook1.4/pre-revprop-change =================================================================== --- trunk/pysvnmanager/hooks/init/hook1.4/pre-revprop-change (rev 0) +++ trunk/pysvnmanager/hooks/init/hook1.4/pre-revprop-change 2008-08-28 11:15:39 UTC (rev 47) @@ -0,0 +1,86 @@ +#!/bin/sh + +# PRE-REVPROP-CHANGE HOOK +# +# The pre-revprop-change hook is invoked before a revision property +# is added, modified or deleted. Subversion runs this hook by invoking +# a program (script, executable, binary, etc.) named 'pre-revprop-change' +# (for which this file is a template), with the following ordered +# arguments: +# +# [1] REPOS-PATH (the path to this repository) +# [2] REVISION (the revision being tweaked) +# [3] USER (the username of the person tweaking the property) +# [4] PROPNAME (the property being set on the revision) +# [5] ACTION (the property is being 'A'dded, 'M'odified, or 'D'eleted) +# +# [STDIN] PROPVAL ** the new property value is passed via STDIN. +# +# If the hook program exits with success, the propchange happens; but +# if it exits with failure (non-zero), the propchange doesn't happen. +# The hook program can use the 'svnlook' utility to examine the +# existing value of the revision property. +# +# WARNING: unlike other hooks, this hook MUST exist for revision +# properties to be changed. If the hook does not exist, Subversion +# will behave as if the hook were present, but failed. The reason +# for this is that revision properties are UNVERSIONED, meaning that +# a successful propchange is destructive; the old value is gone +# forever. We recommend the hook back up the old value somewhere. +# +# On a Unix system, the normal procedure is to have 'pre-revprop-change' +# invoke other programs to do the real work, though it may do the +# work itself too. +# +# Note that 'pre-revprop-change' must be executable by the user(s) who will +# invoke it (typically the user httpd runs as), and that user must +# have filesystem-level permission to access the repository. +# +# On a Windows system, you should name the hook program +# 'pre-revprop-change.bat' or 'pre-revprop-change.exe', +# but the basic idea is the same. +# +# The hook program typically does not inherit the environment of +# its parent process. For example, a common problem is for the +# PATH environment variable to not be set to its usual value, so +# that subprograms fail to launch unless invoked via absolute path. +# If you're having unexpected problems with a hook program, the +# culprit may be unusual (or missing) environment variables. +# +# Here is an example hook script, for a Unix /bin/sh interpreter. +# For more examples and pre-written hooks, see those in +# the Subversion repository at +# http://svn.collab.net/repos/svn/trunk/tools/hook-scripts/ and +# http://svn.collab.net/repos/svn/trunk/contrib/hook-scripts/ + + +REPOS="$1" +REV="$2" +USER="$3" +PROPNAME="$4" +ACTION="$5" + +source $REPOS/hooks/parse_ini.sh +CONFIG=$REPOS/conf/hooks.ini +readconf pre_revprop_change +readconf start_commit + +if [ "$mirror_readonly" = "yes" ]; then + # Readonly repos if this repos is a mirror using svnsync + if [ "$USER" = "$mirror_admin" ]; then + exit 0 + else + echo "Only the mirror admin may change revprop." >&2 + exit 1 + fi +fi + +if [ "$revprop_change_enable" = "yes" ]; then + if [ "$ACTION" = "M" -a "$PROPNAME" = "svn:log" ]; then exit 0; fi + + echo "Changing revision properties other than svn:log is prohibited" >&2 + exit 1 +else + echo "Changing revision properties is prohibited" >&2 + exit 1 +fi Added: trunk/pysvnmanager/hooks/init/hook1.4/pre-unlock.tmpl =================================================================== --- trunk/pysvnmanager/hooks/init/hook1.4/pre-unlock.tmpl (rev 0) +++ trunk/pysvnmanager/hooks/init/hook1.4/pre-unlock.tmpl 2008-08-28 11:15:39 UTC (rev 47) @@ -0,0 +1,61 @@ +#!/bin/sh + +# PRE-UNLOCK HOOK +# +# The pre-unlock hook is invoked before an exclusive lock is +# destroyed. Subversion runs this hook by invoking a program +# (script, executable, binary, etc.) named 'pre-unlock' (for which +# this file is a template), with the following ordered arguments: +# +# [1] REPOS-PATH (the path to this repository) +# [2] UNLOCKPATH (the path in the repository about to be unlocked) +# [3] USER (the user destroying the lock) +# +# The default working directory for the invocation is undefined, so +# the program should set one explicitly if it cares. +# +# If the hook program exits with success, the lock is destroyed; but +# if it exits with failure (non-zero), the unlock action is aborted +# and STDERR is returned to the client. + +# On a Unix system, the normal procedure is to have 'pre-unlock' +# invoke other programs to do the real work, though it may do the +# work itself too. +# +# Note that 'pre-unlock' must be executable by the user(s) who will +# invoke it (typically the user httpd runs as), and that user must +# have filesystem-level permission to access the repository. +# +# On a Windows system, you should name the hook program +# 'pre-unlock.bat' or 'pre-unlock.exe', +# but the basic idea is the same. +# +# Here is an example hook script, for a Unix /bin/sh interpreter: + +REPOS="$1" +UNLOCKPATH="$2" +USER="$3" + +# If a lock is owned by a different person, don't allow it be broken. +# (Maybe this script could send email to the lock owner?) + +SVNLOOK=/opt/svn/bin/svnlook +GREP=/bin/grep +SED=/bin/sed + +LOCK_OWNER=`LANG=C $SVNLOOK lock "$REPOS" "$UNLOCKPATH" | \ + $GREP '^Owner: ' | $SED 's/Owner: //'` + +# If we get no result from svnlook, there's no lock, return success: +if [ "$LOCK_OWNER" = "" ]; then + exit 0 +fi + +# If the person unlocking matches the lock's owner, return success: +if [ "$LOCK_OWNER" = "$USER" ]; then + exit 0 +fi + +# Otherwise, we've got an owner mismatch, so return failure: +echo "Error: $UNLOCKPATH locked by ${LOCK_OWNER}." 1>&2 +exit 1 Added: trunk/pysvnmanager/hooks/init/hook1.4/scripts/README =================================================================== --- trunk/pysvnmanager/hooks/init/hook1.4/scripts/README (rev 0) +++ trunk/pysvnmanager/hooks/init/hook1.4/scripts/README 2008-08-28 11:15:39 UTC (rev 47) @@ -0,0 +1,4 @@ + +An overview of the scripts can be found at: +http://subversion.tigris.org/tools_contrib.html. + Added: trunk/pysvnmanager/hooks/init/hook1.4/scripts/check-authz.py =================================================================== --- trunk/pysvnmanager/hooks/init/hook1.4/scripts/check-authz.py (rev 0) +++ trunk/pysvnmanager/hooks/init/hook1.4/scripts/check-authz.py 2008-08-28 11:15:39 UTC (rev 47) @@ -0,0 +1,28 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +import sys, locale +from svn import repos, fs, core +locale.setlocale(locale.LC_ALL, 'zh_CN.UTF8') + +def test_authz(path): + try: + repos.svn_repos_authz_read(path, 1) + except core.SubversionException, ( strerror, errorno ): + if errorno == 0: + errorno = 1 + return (errorno, strerror) + except: + return (1, sys.exc_info()[1]) + + return (0, 0) + +filename = sys.argv[1] +(errorno, strerror) = test_authz(filename) +if errorno: + sys.stderr.write('Parse authz config file "%s" failed\n' % (filename)) + sys.stderr.write('Possible errors:\n') + sys.stderr.write(' %s\n' % strerror) + sys.exit(1) +else: + sys.exit(0) Added: trunk/pysvnmanager/hooks/init/hook1.4/scripts/check-case-insensitive.pl =================================================================== --- trunk/pysvnmanager/hooks/init/hook1.4/scripts/check-case-insensitive.pl (rev 0) +++ trunk/pysvnmanager/hooks/init/hook1.4/scripts/check-case-insensitive.pl 2008-08-28 11:15:39 UTC (rev 47) @@ -0,0 +1,263 @@ +#!/usr/bin/perl -w +# ==================================================================== +# Copyright (c) 2000-2004 CollabNet. All rights reserved. +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at http://subversion.tigris.org/license-1.html. +# If newer versions of this license are posted there, you may use a +# newer version instead, at your option. +# +# This software consists of voluntary contributions made by many +# individuals. For exact contribution history, see the revision +# history and logs, available at http://subversion.tigris.org/. +# ==================================================================== + +# This script is deprecated, please use check-case-insensitve.py instead. + +use strict; +require 5.004; # This is when locale support was added. +# This 'use encoding' and setting the LANG environment variable has the +# desired effect of handling the comparison of extended characters and +# preventing a commit. However, if any of the files in conflict have +# extended characters in them this is the error displayed by the client: +# +# Commit failed (details follow): +# svn: MERGE request failed on '/svn/play/martinto/trunk' +# svn: General svn error from server +# +# It should list the file names which are in conflict. But it does stop the +# commit. +use encoding "utf8"; +$ENV{'LANG'} = 'zh_CN.UTF8'; +$ENV{'LC_ALL'} = 'zh_CN.UTF8'; + +# Please check the path to svnlook is correct... +my $svnlook; +if ($^O eq 'MSWin32') { + $svnlook = '"c:\\Program Files\\subversion\\bin\\svnlook.exe"'; +} else { + $svnlook = '/opt/svn/bin/svnlook'; +} + +# This script can be called from a pre-commit hook on either Windows or a Unix +# like operating system. It implements the checks required to ensure that the +# repository acts in a way which is compatible with a case preserving but +# case insensitive file system. +# +# When a file is added this script checks the file tree in the repository for +# files which would be the same name on a case insensitive file system and +# rejects the commit. +# +# On a Unix system put this script in the hooks directory and add this to the +# pre-commit script: +# +# $REPOS/hooks/check-case-insensitive.pl "$REPOS" "$TXN" || exit 1 +# +# On a windows machine add this to pre-commit.bat: +# +# perl <path-to-script>\\check-case-insensitive.pl %1 %2 +# if errorlevel 1 goto :ERROR +# exit 0 +# :ERROR +# echo Error found in commit 1>&2 +# exit 1 +# +# You may need to change the setting of $svnlook to the path to the +# executable on your system. +# +# Turn on debug by adding up to three -debug options as the first options in +# the list. The more -debug options the more output. If you specify more +# than one the output goes into a file. +# +# If you have any problems with this script feel free to contact +# Martin Tomes <ma...@to...> + +# Bugfixes and some debug code added by Jeremy Bettis <je...@de...> + +my $openstr = '-|'; +# Shift off any debug options. +my $debug = 0; +while (@ARGV and $ARGV[0] =~ /^-d(ebug)?$/) { + $debug++; + shift; +} + +# If there is too much debug output to STDERR subversion doesn't like it, so, +# if a lot of output is expected send it to a file instead. +if ($debug > 0) { + if ($^O eq 'MSWin32') { + open(STDERR, ">c:/svnlog.txt") + or die "$0: cannot open 'c:/svnlog.txt' for writing: $!\n"; + } else { + open(STDERR, ">/tmp/svnlog.txt") + or die "$0: cannot open '/tmp/svnlog.txt' for writing: $!\n"; + } +} + +# Fetch the command line arguments. +unless (@ARGV > 1) { + die "usage: $0 [-d [-d [-d]]] repos txn [--revision]\n"; +} + +my $repos = shift; +my $txn = shift; + +# Jeremy Bettis <je...@de...> wrote the $flag code and has this to +# say about it: +# +# The reason I did that was so that I could test the hook without actually +# doing a commit. Whenever I had a commit that succeeded in making a bad file +# or directory, or when a commit took too long I just did a sequence of +# operations like this: +# +# svnlook youngest path +# (it tells me that HEAD is 987 or whatever) +# check-case-insensitive.pl -debug path 987 -r +# and then the check-case-insensitive.pl passes -r to svnlook instead of +# --transaction. +# +# Of course when it gets down to # Get the file tree at the previous revision, +# then it doesn't work, but most of my problems were found before that point. +my $flag = '--transaction'; +$flag = shift if @ARGV; + +# Each added path put here. +my @added; + +# The file tree as a hash, index lower cased name, value actual name. +my %tree; + +# Command being executed. +my $cmd; + +print STDERR "LANG=", $ENV{'LANG'}, "\n" if ($debug and defined($ENV{'LANG'})); +# Get a list of added files. +local *SVNLOOK; +$cmd = "$svnlook changed \"$repos\" $flag $txn"; +print STDERR "$cmd\n" if ($debug); +open(SVNLOOK, $openstr, $cmd) + or die("$0: cannot open '$cmd' pipe for reading: $!\n"); +while (<SVNLOOK>) { + chomp; + if (/^A\s+(\S.*)/) { + push @added, $1; + } +} +close SVNLOOK; + +if ($debug) { + print STDERR "Added " . ($#added + 1) . " items:\n"; + foreach my $itm (@added) { + print STDERR " $itm\n"; + } +} + +unless (@added) { + print STDERR "No files added\n" if ($debug); + # No added files so no problem. + exit(0); +} + +# Get the shortest directory name which has changed, this will be the path +# into the repository to use to get the history. +$cmd = "$svnlook dirs-changed \"$repos\" $flag $txn"; +print STDERR "$cmd\n" if ($debug); +open(SVNLOOK, $openstr, $cmd) + or die("$0: cannot open '$cmd' pipe for reading: $!\n"); +my $shortest=999999; +my $changed; +while (<SVNLOOK>) { + chomp; + print STDERR " ", $_, "\n" if ($debug > 2); + if (length($_) < $shortest) { + $changed = $_; + $shortest = length($_); + } +} +close SVNLOOK; +# There isn't a leading slash on $changed but there is a trailing one. When +# it is the root of the repository the / is a pain, so always remove the +# trailing slash and put it back in where needed. +$changed =~ s/\/$//; + +# Use the history of $changed path to find the revision of the previous commit. +$cmd = "$svnlook history \"$repos\" \"$changed/\""; +print STDERR "$cmd\n" if ($debug); +open(SVNLOOK, $openstr, $cmd) + or die("$0: cannot open '$cmd' pipe for reading: $!\n"); +my $lastrev; +while (<SVNLOOK>) { + chomp; + if (/(\d+)/) { + $lastrev = $1; + last; + } +} +close SVNLOOK; + +# Get the file tree at the previous revision and turn the output into +# complete paths for each file. +my @path; +$cmd = "$svnlook tree \"$repos\" \"$changed/\" --revision $lastrev"; +print STDERR "$cmd\n" if ($debug); +open(SVNLOOK, $openstr, $cmd) + or die("$0: cannot open '$cmd' pipe for reading: $!\n"); +while (<SVNLOOK>) { + chomp; + print STDERR "tree: '", $_, "'\n" if ($debug > 2); + next if (/^\/{1,2}$/); # Ignore the root node. Two /'s at root of the repos. + if (/^(\s+)(.*)\/$/) { # Is a directory. + $#path = length($1)-2; # Number of spaces at start of line is nest level. + push @path, $2; + my $name = join('/', @path) . '/'; + my $index; + if ($changed eq '') { + $index = $name; + } else { + $index = $changed . '/' . $name; + } + $tree{lc($index)} = $name; # Index the hash with case folded name. + print STDERR "\$tree{lc($index)}=$name (dir)\n" if ($debug > 1); + } elsif (/^(\s+)(.*)$/) { # This is a real file name, not a directory. + $#path = length($1)-2; # Number of spaces at start of line is nest level. + my $name; + if ($#path eq -1) { + $name = $2; + } else { + $name = join('/', @path) . '/' . $2; + } + my $index; + if ($changed eq '') { + $index = $name; + } else { + $index = $changed . '/' . $name; + } + $tree{lc($index)} = $name; # Index the hash with case folded name. + print STDERR "\$tree{lc($index)}=$name\n" if ($debug > 1); + } +} +close SVNLOOK; + +my $failmsg; + +my %newtree; +foreach my $newfile (@added) { + print STDERR "Checking \$tree{lc($newfile)}\n" if ($debug > 1); + # Without the following line it gets the lc() wrong. + my $junk = "x$newfile"; + my $lcnewfile = lc($newfile); + if (exists($tree{$lcnewfile})) { + $failmsg .= "\n $newfile 已经存在于 " . $tree{lc($newfile)}; + } + elsif (exists($newtree{$lcnewfile})) { + $failmsg .= "\n $newfile 已经添加为 " . $newtree{lc($newfile)}; + } + $newtree{$lcnewfile} = $newfile; +} +if (defined($failmsg)) { + print STDERR "\n发现文件名大小写冲突:\n" . $failmsg . "\n"; + exit 1; +} + +exit 0; Added: trunk/pysvnmanager/hooks/init/hook1.4/scripts/check-case-insensitive.py =================================================================== --- trunk/pysvnmanager/hooks/init/hook1.4/scripts/check-case-insensitive.py (rev 0) +++ trunk/pysvnmanager/hooks/init/hook1.4/scripts/check-case-insensitive.py 2008-08-28 11:15:39 UTC (rev 47) @@ -0,0 +1,99 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# A pre-commit hook to detect case-insensitive filename clashes. +# +# What this script does: +# - Detects new paths that 'clash' with existing, or other new, paths. +# - Ignores existings paths that already 'clash' +# - Exits with an error code, and a diagnostic on stderr, if 'clashes' +# are detected. +# +# How it does it: +# - Get a list of changed paths. +# - From that list extract the new paths that represent adds or replaces. +# - For each new path: +# - Split the path into a directory and a name. +# - Get the names of all the entries in the version of the directory +# within the txn. +# - Compare the canonical new name with each canonical entry name. +# - If the canonical names match and the pristine names do not match +# then we have a 'clash'. +# +# Notes: +# - All the paths from the Subversion filesystem bindings are encoded +# in UTF-8 and the separator is '/' on all OS's. +# - The canonical form determines what constitutes a 'clash', at present +# a simple 'lower case' is used. That's probably not identical to the +# behaviour of Windows or OSX, but it might be good enough. +# - Hooks get invoked with an empty environment so this script explicitly +# sets a locale; make sure it is a sensible value. +# - If used with Apache the 'clash' diagnostic must be ASCII irrespective +# of the locale, see the 'Force' comment near the end of the script for +# one way to achieve this. + +import sys, locale +sys.path.append('/usr/local/subversion/lib/svn-python') +from svn import repos, fs +locale.setlocale(locale.LC_ALL, 'zh_CN.UTF8') + +def canonicalize(path): + return path.decode('utf-8').lower().encode('utf-8') + +def get_new_paths(txn_root): + new_paths = [] + for path, change in fs.paths_changed(txn_root).iteritems(): + if (change.change_kind == fs.path_change_add + or change.change_kind == fs.path_change_replace): + new_paths.append(path) + return new_paths + +def split_path(path): + slash = path.rindex('/') + if (slash == 0): + return '/', path[1:] + return path[:slash], path[slash+1:] + +def join_path(dir, name): + if (dir == '/'): + return '/' + name + return dir + '/' + name + +def ensure_names(path, names, txn_root): + if (not names.has_key(path)): + names[path] = [] + for name, dirent in fs.dir_entries(txn_root, path).iteritems(): + names[path].append([canonicalize(name), name]) + +names = {} # map of: key - path, value - list of two element lists of names +clashes = {} # map of: key - path, value - map of: key - path, value - dummy + +native = locale.getlocale()[1] +if not native: native = 'utf-8' +repos_handle = repos.open(sys.argv[1].decode(native).encode('utf-8')) +fs_handle = repos.fs(repos_handle) +txn_handle = fs.open_txn(fs_handle, sys.argv[2].decode(native).encode('utf-8')) +txn_root = fs.txn_root(txn_handle) + +new_paths = get_new_paths(txn_root) +for path in new_paths: + dir, name = split_path(path) + canonical = canonicalize(name) + ensure_names(dir, names, txn_root) + for name_pair in names[dir]: + if (name_pair[0] == canonical and name_pair[1] != name): + canonical_path = join_path(dir, canonical) + if (not clashes.has_key(canonical_path)): + clashes[canonical_path] = {} + clashes[canonical_path][join_path(dir, name)] = True + clashes[canonical_path][join_path(dir, name_pair[1])] = True + +if (clashes): + # native = 'ascii' # Force ASCII output for Apache + for canonical_path in clashes.iterkeys(): + sys.stderr.write(u'Clash:'.encode(native)) + for path in clashes[canonical_path].iterkeys(): + sys.stderr.write(u' \''.encode(native) + + str(path).decode('utf-8').encode(native, 'replace') + + u'\''.encode(native)) + sys.stderr.write(u'\n'.encode(native)) + sys.exit(1) Added: trunk/pysvnmanager/hooks/init/hook1.4/scripts/check-mime-type.pl =================================================================== --- trunk/pysvnmanager/hooks/init/hook1.4/scripts/check-mime-type.pl (rev 0) +++ trunk/pysvnmanager/hooks/init/hook1.4/scripts/check-mime-type.pl 2008-08-28 11:15:39 UTC (rev 47) @@ -0,0 +1,262 @@ +#!/usr/bin/perl -w + +# ==================================================================== +# commit-mime-type-check.pl: check that every added file has the +# svn:mime-type property set and every added file with a mime-type +# matching text/* also has svn:eol-style set. If any file fails this +# test the user is sent a verbose error message suggesting solutions and +# the commit is aborted. +# +# Usage: commit-mime-type-check.pl REPOS TXN-NAME +# ==================================================================== +# Most of commit-mime-type-check.pl was taken from +# commit-access-control.pl, Revision 9986, 2004-06-14 16:29:22 -0400. +# ==================================================================== +# Copyright (c) 2000-2004 CollabNet. All rights reserved. +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at http://subversion.tigris.org/license.html. +# If newer versions of this license are posted there, you may use a +# newer version instead, at your option. +# +# This software consists of voluntary contributions made by many +# individuals. For exact contribution history, see the revision +# history and logs, available at http://subversion.tigris.org/. +# ==================================================================== + +# Turn on warnings the best way depending on the Perl version. +BEGIN { + if ( $] >= 5.006_000) + { require warnings; import warnings; } + else + { $^W = 1; } +} + +use strict; +use Carp; + + +###################################################################### +# Configuration section. + +# Svnlook path. +my $svnlook = "/opt/svn/bin/svnlook"; +$ENV{'LANG'} = 'zh_CN.UTF8'; +$ENV{'LC_ALL'} = 'zh_CN.UTF8'; + +# Since the path to svnlook depends upon the local installation +# preferences, check that the required program exists to insure that +# the administrator has set up the script properly. +{ + my $ok = 1; + foreach my $program ($svnlook) + { + if (-e $program) + { + unless (-x $program) + { + warn "$0: required program `$program' is not executable, ", + "edit $0.\n"; + $ok = 0; + } + } + else + { + warn "$0: required program `$program' does not exist, edit $0.\n"; + $ok = 0; + } + } + exit 1 unless $ok; +} + +###################################################################### +# Initial setup/command-line handling. + +&usage unless @ARGV == 2; + +my $repos = shift; +my $txn = shift; + +unless (-e $repos) + { + &usage("$0: repository directory `$repos' does not exist."); + } +unless (-d $repos) + { + &usage("$0: repository directory `$repos' is not a directory."); + } + +# Define two constant subroutines to stand for read-only or read-write +# access to the repository. +sub ACCESS_READ_ONLY () { 'read-only' } +sub ACCESS_READ_WRITE () { 'read-write' } + + +###################################################################### +# Harvest data using svnlook. + +# Change into /tmp so that svnlook diff can create its .svnlook +# directory. +my $tmp_dir = '/tmp'; +chdir($tmp_dir) + or die "$0: cannot chdir `$tmp_dir': $!\n"; + +# Figure out what files have added using svnlook. +my @files_added; +foreach my $line (&read_from_process($svnlook, 'changed', $repos, '-t', $txn)) + { + # Add only files that were added to @files_added + if ($line =~ /^A. (.*[^\/])$/) + { + push(@files_added, $1); + } + } + +my @errors; +foreach my $path ( @files_added ) + { + my $mime_type; + my $eol_style; + my $check_mime = 1; + + # Parse the complete list of property values of the file $path to extract + # the mime-type and eol-style + foreach my $prop (&read_from_process($svnlook, 'proplist', $repos, '-t', + $txn, '--verbose', $path)) + { + if ($prop =~ /^\s*svn:mime-type : (\S+)/) + { + $mime_type = $1; + } + elsif ($prop =~ /^\s*svn:eol-style : (\S+)/) + { + $eol_style = $1; + } + elsif ($prop =~ /^\s*svn:special : (\S+)/) + { + $check_mime = 0; + } + } + + # Detect error conditions and add them to @errors + if ($check_mime) + { + if (not $mime_type and not $eol_style) + { + push @errors, "$path : 属性 svn:mime-type 或者 svn:eol-style 没有设置"; + } + elsif ($mime_type =~ /^text\// and not $eol_style) + { + push @errors, "$path : svn:mime-type=$mime_type 但是 svn:eol-style 没有设置"; + } + } + } + +# If there are any errors list the problem files and give information +# on how to avoid the problem. Hopefully people will set up auto-props +# and will not see this verbose message more than once. +if (@errors) + { + warn "$0:\n\n", + join("\n", @errors), "\n\n", + <<EOS; + + 管理员已经启用换行符属性检查。每一个新添加的文件必须 + 指定换行符。如果 svn:mime-type 属性为文本文件,则 + 必须设置 svn:eol-style 属性。 + + 对于二进制文件,执行如下命令: + svn propset svn:mime-type application/octet-stream path/of/file + + 对于文本文件,可以执行如下命令: + svn propset svn:mime-type text/plain path/of/file + svn propset svn:eol-style native path/of/file + + 为了避免每次添加文件手动设置,可以启用自动属性设置。 + 需要修改文件 ~/.subversion/config (Unix平台)。 + 打开 auto-props 设置,并设置扩展名和属性的对应关系。 + 详细设置,参见 Subversion 参考: + (http://svnbook.red-bean.com/), Chapter 7, Properties section, + Automatic Property Setting subsection. +EOS + exit 1; + } +else + { + exit 0; + } + +sub usage +{ + warn "@_\n" if @_; + die "usage: $0 REPOS TXN-NAME\n"; +} + +sub safe_read_from_pipe +{ + unless (@_) + { + croak "$0: safe_read_from_pipe passed no arguments.\n"; + } + print "Running @_\n"; + my $pid = open(SAFE_READ, '-|'); + unless (defined $pid) + { + die "$0: cannot fork: $!\n"; + } + unless ($pid) + { + open(STDERR, ">&STDOUT") + or die "$0: cannot dup STDOUT: $!\n"; + exec(@_) + or die "$0: cannot exec `@_': $!\n"; + } + my @output; + while (<SAFE_READ>) + { + chomp; + push(@output, $_); + } + close(SAFE_READ); + my $result = $?; + my $exit = $result >> 8; + my $signal = $result & 127; + my $cd = $result & 128 ? "with core dump" : ""; + if ($signal or $cd) + { + warn "$0: pipe from `@_' failed $cd: exit=$exit signal=$signal\n"; + } + if (wantarray) + { + return ($result, @output); + } + else + { + return $result; + } +} + +sub read_from_process + { + unless (@_) + { + croak "$0: read_from_process passed no arguments.\n"; + } + my ($status, @output) = &safe_read_from_pipe(@_); + if ($status) + { + if (@output) + { + die "$0: `@_' failed with this output:\n", join("\n", @output), "\n"; + } + else + { + die "$0: `@_' failed with no output.\n"; + } + } + else + { + return @output; + } +} Added: trunk/pysvnmanager/hooks/init/hook1.4/scripts/check-mime-type.py =================================================================== --- trunk/pysvnmanager/hooks/init/hook1.4/scripts/check-mime-type.py (rev 0) +++ trunk/pysvnmanager/hooks/init/hook1.4/scripts/check-mime-type.py 2008-08-28 11:15:39 UTC (rev 47) @@ -0,0 +1,108 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +""" +check-mime-type.py: check that every added file has the +svn:mime-type property set and every added file with a mime-type +matching text/* also has svn:eol-style set. If any file fails this +test the user is sent a verbose error message suggesting solutions and +the commit is aborted. + +Usage: commit-mime-type-check.pl REPOS TXN-NAME + +Rewrite from check-mime-type.pl, by Jiang Xin<WorldHello.net.AT.gmail.com> +""" + +__revision__ = '$Id: commit_log_check.py 513 2006-05-06 17:12:03Z jiangxin $' + +import sys, os, re, string, locale + +if os.name == 'nt': + SVNLOOK = 'C:/Apps/Subversion/bin/svnlook.exe' +else: + SVNLOOK = '/opt/svn/bin/svnlook' + +os.environ['LANG'] = os.environ['LC_ALL'] = 'zh_CN.UTF8' + +MIN_LENGTH = 5 + +def main(repos, txn): + """main entry point""" + + files_added = [] + cmd = '%s changed -t "%s" "%s"' % (SVNLOOK, txn, repos) + padd = re.compile(r'^A. (.*[^/])$') + + for line in os.popen(cmd, 'r').readlines(): + match = padd.match( line.rstrip("\n") ); + if match: + groups = match.groups() + if len(groups) == 1: + files_added.append( groups[0] ); + + pmime = re.compile(r'\s*svn:mime-type : (\S+)') + peol = re.compile(r'\s*svn:eol-style : (\S+)') + ptext = re.compile(r'^text/') + pspecial = re.compile(r'\s*svn:special : (\S+)') + + errmsg = [] + fo... [truncated message content] |