Skip to content

Instantly share code, notes, and snippets.

@xx7y7xx
Created April 6, 2016 16:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save xx7y7xx/6f2c8a6f628667b902c804861c727604 to your computer and use it in GitHub Desktop.
Save xx7y7xx/6f2c8a6f628667b902c804861c727604 to your computer and use it in GitHub Desktop.
Checking file encoding (UTF-8) in svn pre-commit
#!/bin/bash
# SVN pre-commit hook for "svn-read-only"
##############################################################
#
# FEATURES:
#
# 1) Introduces the "svn-read-only" property for SVN.
#
# If the "svn-read-only" property is set on a FILE, then no
# change to this file (except for a property change) can be
# committed into the repository until after the property is
# deleted.
#
# If the "svn-read-only" property is set on a DIRECTORY,
# then no change to an item inside the directory or inside
# the subdirectories can be committed.
#
# 2) Checks the SPELLING of the property being set
# against the complete list of known properties.
#
# This is to prevent user from unintentional spelling
# errors while setting properties. Trying to set the
# properties "svn-rea-nly" for example, will trigger an
# error message. This feature is optional and is controlled
# by variable SPELLCHK in the script below.
#
# PLATFORMS CURRENTLY SUPPORTED: Tested on Linux and Cygwin
# under Windows. Should work on a Macs as well, but not
# tested. No support for native Windows so far.
#
# SETTING UP: Copy this file into the hooks directory
# (located right inside your svn repository) and modify the
# value of SVNLOOK below. If using a Linux platform, make
# this file executable with chmod.
#
##############################################################
#
# EXAMPLE OF USE: Assuming your "Project-1.0.0" directory
# is located at /home/user/projects/tags/Project-1.0.0 on
# your machine. Open the bash terminal and type:
#
# cd /home/user/projects/tags
#
# Ensure that your working copy does not have any local
# modifications by typing "svn st". If it does have
# modifications, they should either be committed or
# reverted before proceeding. Now, set the property and
# commit the property change by
#
# svn ps svn-read-only on Project-1.0.0
# svn ci -m "Making the project read only" Project-1.0.0
#
# You can still make any local changes within the
# "Project-1.0.0" directory at this point. They however can
# not be committed. Your "Project-1.0.0" directory is now
# safe from any unintentional commits. In order to undo
# this behavior, type
#
# svn pd svn-read-only Project-1.0.0
# svn ci -m "Making the project modifiable again" Project-1.0.0
#
##############################################################
#
# AUTHOR: This program is designed and written by Alexander
# Shirokov in Toronto Canada on a personal initiative. Its
# first copy was made available on December 5, 2011 at
# http://www.cita.utoronto.ca/~shirokov/soft/svn-hooks/svn-read-only
#
# LICENSE & DISCLAIMER: The program is available for anyone
# who wishes to use it, without any restrictions. There is
# no explicit or implied warranty for its use.
#
##############################################################
REPOS="$1"
TXN="$2"
# Please make sure to set SVNLOOK to an existing path
SVNLOOK=/usr/bin/svnlook
ICONV=/usr/bin/iconv
#chenyang20141112
SVN_USER="`$SVNLOOK author -t "$TXN" "$REPOS"`"
#
# check glue stable code
#
# Set SPELLCHK to "yes" or "no".
SPELLCHK=yes
# Do not modify this, unless you want to change the name of the property.
#SVNREADONLY=svn-read-only
SVNREADONLY="glue:stable"
# If you use any additional svn properties, please add them
# to the list below.
KNOWNPROPERTIES=(
$SVNREADONLY
svn:externals \
glue:stable
)
USER1="chenyang"
USER2="chenzhongming"
USER3="fengmingming"
USER4="wanglingzhao"
typeset -i blockcnt=0
typeset -i contentchangecnt=0
if [ ! -f "$SVNLOOK" ]; then
echo "Error: file missing: $SVNLOOK" 1>&2
echo "To correct this error, please fix the SVNLOOK in your pre-commit hook." 1>&2
exit 3
fi
while IFS= read -r line
do
status="${line:0:2}"
filepath="${line:4}"
# valid property change is always allowed
if [ "$status" != "_U" ]; then
contentchangecnt+=1
fi
while IFS= read -r property
do
# Strip property of whitespaces to get property
property=`echo "$property" | awk '{$1=$1;print}'`
# Check for nocommit property
if [ "$property" == "$SVNREADONLY" ] && [ "$status" != "_U" ]; then
#chenyang20141112
msg="[`date`] Property \"$property\" is set on path being changed: \"$filepath\""
echo "$msg" >> /tmp/svn-pre-commit
if [ "X$SVN_USER" != "X$USER1" -a "X$SVN_USER" != "X$USER2" -a "X$SVN_USER" != "X$USER3" -a "X$SVN_USER" != "X$USER4" ]; then
echo "$msg" 1>&2
blockcnt+=1
fi
fi
# Alternatively, check spelling.
if [ "$SPELLCHK" != "yes" ]; then
typeset -i block=1
for svnproperty in ${KNOWNPROPERTIES[*]}; do
if [ "$property" == "$svnproperty" ]; then
block=0
break
fi
done
if [ "$block" != "0" ]; then
echo "Invalid property svn:* : \"$property\" on path $filepath" 1>&2
blockcnt+=$block
fi
unset block
fi
done < <("$SVNLOOK" proplist -t "$TXN" "$REPOS" "$filepath")
done < <("$SVNLOOK" changed -t "$TXN" "$REPOS")
if [ $blockcnt != 0 ]; then
echo "[ERROR] Commit blocked by changed item check" 1>&2
exit 1
fi
# If the content is changed on an item that does not bear the
# SVNREADONLY, investigate upper directories for this property.
if [ "$contentchangecnt" != "0" ]; then
while IFS= read -r line
do
dirpath="$line"
upperdir="$dirpath"
while [ 1 ]; do
while IFS= read -r property
do
# Strip the line of leading and trailing blankspaces
property=`echo "$property" | awk '{$1=$1;print}'`
if [ "$property" == "$SVNREADONLY" ]; then
#chenyang20150205
msg="[`date`] Property \"$property\" is set on the superdirectory \"$upperdir\" of an item changed \"$dirpath\""
echo $msg >> /tmp/svn-pre-commit
if [ "X$SVN_USER" != "X$USER1" -a "X$SVN_USER" != "X$USER2" -a "X$SVN_USER" != "X$USER3" -a "X$SVN_USER" != "X$USER4" ]; then
echo "$msg" 1>&2
blockcnt+=1
fi
fi
done < <("$SVNLOOK" proplist -t "$TXN" "$REPOS" "${upperdir}")
if [ "$upperdir" == "." ] || [ "$upperdir" == "/" ] || [ "$upperdir" == "" ] ; then
break
fi
upperdir=`dirname $upperdir`
done
done < <($SVNLOOK dirs-changed -t "$TXN" "$REPOS" )
if [ $blockcnt != 0 ]; then
echo "[ERROR] Commit blocked by superdirectory check" 1>&2
exit 2
fi
fi
#
# Make sure that the log message contains some text.
#
SVNLOOKOK=1
$SVNLOOK log -t "$TXN" "$REPOS" | grep "[a-zA-Z0-9]" > /dev/null || SVNLOOKOK=0
if [ $SVNLOOKOK = 0 ]; then
echo "[ERROR] Empty log messages are not allowed. Please provide a proper log message." >&2
exit 1
fi
#
# Comments should have more than 5 characters
#
LOGMSG=$($SVNLOOK log -t "$TXN" "$REPOS" | grep [a-zA-Z0-9] | wc -c)
if [ "$LOGMSG" -lt 6 ]; then
echo -e "[ERROR] Please provide a meaningful comment when committing changes." 1>&2
exit 1
fi
#
# Make sure that all files to be committed are encoded in UTF-8.
#
while read changeline;
do
# Get just the file (not the add / update / etc. status).
file=${changeline:4}
# Only check source files.
if [[ $file == *.java || $file == *.html || $file == *.esp ]] ; then
$SVNLOOK cat -t "$TXN" "$REPOS" "$file" | $ICONV -f UTF-8 -t UTF-8 -o /dev/null
if [ "${PIPESTATUS[1]}" != 0 ] ; then
echo "[ERROR] Only UTF-8 files can be committed ("$file")" 1>&2
exit 1
fi
# ticket:14508 has Zero-width space?
# hex dump
#---------------------------------------------
#e2808b 68747470 3a 2f2f 777777
# http : // www .xuaran001.com
#---------------------------------------------
#$SVNLOOK cat -t "$TXN" "$REPOS" "$file" | grep "$(printf %b '\u200b')"
$SVNLOOK cat -t "$TXN" "$REPOS" "$file" | xxd -p - | tr -d '\n' | grep "e2808b68747470"
if [ "${PIPESTATUS[3]}" = 0 ] ; then
echo "[ERROR100] Find zero-width space ("$file")" 1>&2
#exit 1
fi
fi
done < <($SVNLOOK changed -t "$TXN" "$REPOS")
# All checks passed, so allow the commit.
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment