Forum: CFEngine Help
Subject: SVN pre-commit script to verify syntax before commits are allowed
Author: msvob...@linkedin.com
Link to topic: https://cfengine.com/forum/read.php?3,26459,26459#msg-26459

One of our interns at LinkedIn, William Orr, wrote a SVN pre-commit script to 
check for Cfengine syntax errors before allowing a commit into cfengine/trunk 
to happen.  You may need to tweak this a bit for your environment, but it works 
and it could save some headaches before pushes into production are allowed.


$ cat /opt/svnrepo/hooks/pre-commit 
#!/bin/bash

# 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.
#
REPOS="$1"
TXN="$2"

/opt/svnrepo/hooks/check-cfe-syntax.sh "${REPOS}" "${TXN}"|| exit 1

# All checks passed, so allow the commit.
exit 0


And the hook itself.


$ cat /opt/svnrepo/hooks/check-cfe-syntax.sh 
#!/bin/bash

REPOS=$1
TXN=$2
LOG="/opt/svnrepo/csvn/commit.log"
CHANGES=0

if [[ "$1" = "" && "$2" = "" ]]; then
  echo "Most be called as $0 REPOS TXN" >> "$LOG"
  exit 1
fi
 
AWK=/bin/awk
GREP=/bin/grep
RM=/bin/rm
ECHO=/bin/echo
SED=/bin/sed
SVN="/opt/CollabNet_Subversion/bin/svn";
SVNLOOK="/opt/CollabNet_Subversion/bin/svnlook";
SVN_URL="file:///opt/svnrepo/cfengine/trunk"
CF_PROMISES="/var/cfengine/sbin/cf-promises"

PROMISEDIR="/opt/svnrepo/csvn/.cfagent/inputs/"
MODULESIDR="/opt/svnrepo/csvn/.cfagent/modules/"

"${ECHO}" "Temp working Dir: ${WORKDIR}" >> "$LOG"
"${ECHO}" "REPOS ${REPOS}" >> "$LOG"
"${ECHO}" "TXN ${TXN}" >> "$LOG"

"${ECHO}" "Checking out working copy from $REPOS ...." >> "$LOG"
"${SVN}" co --depth immediates "${SVN_URL}/generic_cf-agent_policies" 
"${PROMISEDIR}" > /dev/null
if [[ $? -ne 0 ]]; then
  "${ECHO}" "Failed to get fresh working copy" >> "$LOG"
  exit 1
fi

"${SVN}" co --depth immediates "${SVN_URL}/cf-agent_modules" "${MODULESIDR}" > 
/dev/null
if [[ $? -ne 0 ]]; then
  "${ECHO}" "Failed to get fresh working copy" >> "$LOG"
  exit 1
fi
 
# Figure out what directories have changed using svnlook.
FILES=`${SVNLOOK} changed ${REPOS} -t ${TXN} | ${AWK} '{ print $2 }'` > 
/dev/null

for FILE in $FILES; do
  "${ECHO}" "file changed ${FILE}" >> "${LOG}"
  if [[ $("${ECHO}" "${FILE}" | ${GREP} cfengine/trunk) != "" ]]; then
    if [[ $("${ECHO}" "${FILE}" | ${GREP} generic_cf-agent_policies) != "" ]]; 
then
      if [[ $("${ECHO}" "${FILE}" | "${SED}" -e 
's/opt/svnrepo/cfengine\/trunk\/generic_cf-agent_policies\///g') != "" ]]; then
        CHANGES=1
        "${SVNLOOK}" cat "${REPOS}" "${FILE}" -t "${TXN}" > 
${PROMISEDIR}/$("${ECHO}" "${FILE}" | "${SED}" -e 
's/opt/svnrepo/cfengine\/trunk\/generic_cf-agent_policies\///g')
      fi
    fi
  fi
done

if [[ ${CHANGES} -eq 0 ]]; then
  exit 0
fi

"${CF_PROMISES}" > /dev/null
if [[ $? -ne 0 ]]; then
  "${ECHO}" "Syntax error! Aborting commit!" >> "${LOG}"

  "${RM}" -rf "${PROMISEDIR}"
  "${RM}" -rf "${MODULESIDR}"
  "${ECHO}" "CFEngine syntax check failed!"

  exit 1
fi
"${CF_PROMISES}" -f failsafe.cf > /dev/null
if [[ $? -ne 0 ]]; then
  "${ECHO}" "Syntax error! Aborting commit!" >> "${LOG}"

  "${RM}" -rf "${PROMISEDIR}"
  "${RM}" -rf "${MODULESIDR}"
  "${ECHO}" "CFEngine syntax check failed!"

  exit 1
fi

"${RM}" -rf "${PROMISEDIR}"
"${RM}" -rf "${MODULESIDR}"
"${ECHO}" "Passed CFEngine syntax check"


Cheers
Mike

_______________________________________________
Help-cfengine mailing list
Help-cfengine@cfengine.org
https://cfengine.org/mailman/listinfo/help-cfengine

Reply via email to