Few Pre commit SVN scripts and tricks


SVN hook scripts

Today I would like to talk about some SVN pre-commit hooks scripts and customizations.
SVN comes with feature of precommit hook script which can be used to control commit and put tab on the basis of multiple requirements.
Here are few very common needed features in form of scripts.

Binary file check




It’s always a pain using SVN to prevent developer checking in compiled objects or binary files even by mistake. If they check-in the binary files like jar, war, tar, zip etc.. will dramatically increase the repo size which will create unnecessary complication for backup and cleaning the repo.
Here is a script to detect Binay file and abort the commit operation which SVN check-in.
#binary_file_check.sh
#!/bin/bash
SVNLOOK=/etc/subversion/bin/svnlook
REPO=$1
TXN=$2
# Check arguments
if [ -z "$REPOS" -o -z "$TXN" ]; then
  echo "Syntax: $0 path_to_repos txn_id" >&2
  exit 1
fi
for file in `$SVNLOOK changed $REPO -t $TXN`
do
        $SVNLOOK cat $REPO $file -t $TXN > /tmp/binary_test_file
        Check=`file –i /tmp/binary_test_file | grep binary`
        if [ “x$Check” != “x” ]; then
                echo "You are trying to commit a binary file like" >&2
                echo "$file" >&2
                echo "You can not check in binary or compiled object to the svn" >&2
                echo "Fix the above issue and try to check in again" >&2
                $SVNLOOK changed -t $TXN $REPO > /tmp/binary.txt
                mail -s "Binary file commit failed for $REPO file" abc@domain.com < /tmp/binary.txt
                exit 1
        fi
        rm –f /tmp/binary_test_file
done

Above script will check for any binary type file and abort the commit.
But what if you want to selectively allow binary files to commit, here is the script.

#binary_file_check.sh
#!/bin/bash
SVNLOOK=/etc/subversion/bin/svnlook
REPO=$1
TXN=$2
# Check arguments
if [ -z "$REPOS" -o -z "$TXN" ]; then
  echo "Syntax: $0 path_to_repos txn_id" >&2
  exit 1
fi
binaryExtensions="jar zip dll exe apk xap war tar gz tgz"
for i in $binaryExtensions
do
        File_count=`$SVNLOOK changed -t $TXN $REPO | grep [.]${i}$ | grep -v ^D | wc -l`
        if [ $File_count -gt 0 ]; then
                echo "You are trying to commit a binary file like" >&2
                echo "${binaryExtensions} etc..." >&2
                echo "You can not check in binary or compiled object to the svn" >&2
                echo "Fix the above issue and try to check in again" >&2
                $SVNLOOK changed -t $TXN $REPO > /tmp/binary.txt
                mail -s "Binary file commit failed for $REPO file" abc@domain.com < /tmp/binary.txt
                exit 1
        fi
done

You can add the list of extensions you don’t want to allow.

Usage-> Call the binary script from your pre-commit script like this
/<SOmelocation>/binary_file_check.sh $REPOS $TXN || exit 1
Changes->
·         Change the SVNLOOK in the script as per your svn installation.
·         Change the abc@domain.com
·         Change the SOmelocation to the exact location of the script where you are going to keep it.

Detect merge conflict

It’s very much possible that developer may commit the file with svn merge conflicts without resolving or removing those extra “<<<<<<<<” or “>>>>>>>>>” or ”========”.
Here is the script which can take care of this.
# detect-merge-conflicts.sh
#!/bin/sh
#
# A pre-commit hook to detect changes that look like forgotten
# conflict markers. If any additions starting with '>>>>>>>',
# '=======' or '<<<<<<<' are found, the commit is aborted with a nice
# error message.

REPOS=$1
TXN=$2

SVNLOOK=/usr/local/bin/svnlook

# Check arguments
if [ -z "$REPOS" -o -z "$TXN" ]; then
  echo "Syntax: $0 path_to_repos txn_id" >&2
  exit 1
fi

# We scan through the transaction diff, looking for things that look
# like conflict markers.  If we find one, we abort the commit.
SUSPICIOUS=$($SVNLOOK diff -t "$TXN" "$REPOS" | grep -E '^\+(<{7} \.|={7}$|>{7} \.)' | wc -l)

if [ $SUSPICIOUS -ne 0 ]; then
  echo "Some parts of your commit look suspiciously like merge" >&2
  echo "conflict markers.  Please double-check your diff and try" >&2
  echo "committing again." >&2
  exit 1
fi

# No conflict markers detected, let it fly!
exit 0

Thanks for the original writer of the detect-merge-conflicts script.

Puppet  file parsing 

This is real life scenario where user has checked in wrong puppet file in svn and when puppet server sync the file it breaks, it’s really important to verify the puppet (.pp or .yaml) file for any syntax error by parsing it.
Following is the script for .pp file

#puppet-parser.sh
#!/bin/bash
SVNLOOK=/etc/subversion/bin/svnlook
REPO=$1
TXN=$2
for files in `$SVNLOOK changed $REPO -t $TXN | grep puppet | awk '{ print $2 }' | grep .pp$`
  do
        $SVNLOOK cat $REPO $files -t $TXN > /tmp/precommit.pp
        if [ `/usr/bin/puppet parser validate /tmp/precommit.pp | wc -l` -ne 0 ]
      then
         echo "Parser Issue: Run </usr/bin/puppet parser validate $files> to find the issue\n" >&2
         echo "Please fix it and recommit" >&2
         exit 1
    fi
 done
exit 0

Following is the script for .yaml file
#puppet-parser_yaml.sh
#!/bin/bash
set -a
SVNLOOK=/etc/subversion/bin/svnlook
REPO=$1
TXN=$2
for files in `$SVNLOOK changed $REPO -t $TXN | grep puppet | awk '{ print $2 }' | grep .yaml$`
  do
    $SVNLOOK cat $REPO $files -t $TXN > /tmp/precommit.yaml
    file="/tmp/precommit.yaml"
    OUT=`/usr/bin/perl -MData::Dumper -MYAML -e '$h = YAML::LoadFile($ENV{file});' && echo OK || echo Failed`
      if [ $OUT != OK ]
        then
           echo "Parser Issue: $files has some syntax issue\n" >&2
           echo "Please fix it and recommit" >&2
           exit 1
        fi
  done
exit 0

If you want you can merge both scripts and combine in to one.

Write or commit access to repo for a user

The need for the script is to put commit restriction on repo and give access to only set of users.

user_access.sh
#!/bin/bash
user=$1
auth=`grep -i $user /opt/svnroot/scripts/access_list.txt`
if test -z $auth
then
        echo "svn commit: ERROR you dont have access to commit to ifd repository"
        echo "svn [server aborted]: please contact the SCM or owner of the repository"
        exit 1;
else
        exit 0;
fi

Usage ->Call the script in following way in your pre-commit.sh script
/<SOmelocation>/repo_operation_commit.sh "$author" 1>&2
Create access_list.txt file and keep the user name in file who need commit access.
You can get the author via following command in your pre-commit script
author=$($SVNLOOK author -t "$TXN" "$REPOS")

Popular posts from this blog

Manage Docker images on local disk

Gradle or Maven - A Dilemma

Code Review - Write your code right