Forum: CFEngine Help
Subject: SVN pre-commit script to verify syntax before commits are allowed
Author: [email protected]
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
[email protected]
https://cfengine.org/mailman/listinfo/help-cfengine