Useful PHP Subversion Commit Hook

words by Brian Racer

Here is a subversion pre-commit hook script we use on PHP projects to make sure the developer making the commit is providing a meaningful description, and then PHP lint is run on each PHP script to make sure it will compile correctly.

#!/bin/bash
 
REPOS="$1"
TXN="$2"
 
PHP="/usr/bin/php"
SVNLOOK="/usr/bin/svnlook"
AWK="/usr/bin/awk"
GREP="/bin/egrep"
SED="/bin/sed"
 
CHANGED=`$SVNLOOK changed -t "$TXN" "$REPOS" | $AWK '{print $2}' | $GREP \\.php$`
 
for FILE in $CHANGED
do
    MESSAGE=`$SVNLOOK cat -t "$TXN" "$REPOS" "$FILE" | $PHP -l`
    if [ $? -ne 0 ]
    then
        echo 1>&2
        echo "***********************************" 1>&2
        echo "PHP error in: $FILE:" 1>&2
        echo `echo "$MESSAGE" | $SED "s| -| $FILE|g"` 1>&2
        echo "***********************************" 1>&2
        exit 1
    fi
done
 
# Make sure that the log message contains some text.
SVNLOOKOK=1
SVNLOOK=/usr/bin/svnlook
$SVNLOOK log -t "$TXN" "$REPOS" | \
   grep "[a-zA-Z0-9]" > /dev/null || SVNLOOKOK=0
if [ $SVNLOOKOK = 0 ]; then
  echo Empty log messages are not allowed. Please provide a proper log message. 1>&2
  exit 1
fi
 
# Make sure text might be meaningful
LOGMSGLEN=$($SVNLOOK log -t "$TXN" "$REPOS" | grep [a-zA-Z0-9] | wc -c)
if [ "$LOGMSGLEN" -lt 6 ]; then
  echo -e "Please provide a meaningful comment when committing changes." 1>&2
  exit 1
fi
 
# All checks passed, so allow the commit.
exit 0

Override PHP’s mail() function during development

words by Brian Racer

When doing local development we generally don’t want our test servers sending out mail to the world. And it would be ideal to be able to review the emails our application does send out before deploying the changes to the world. An easy way to achieve this functionality is to override PHP’s sendmail_path config variable. First lets install a few packegs that will allow us to send mail, and some useful scripts to rewrite the mail:

sudo apt-get install procmail sendmail

Next create the following script that will rewrite any mail that all mail generated by PHP’s mail() function to the local user of your choice:

vi /usr/local/bin/trapmail
formail -R cc X-original-cc \
-R to X-original-to \
-R bcc X-original-bcc \
-f -A"To: [email protected]" \
| /usr/sbin/sendmail -t -i

Replace [email protected] with your local username or an external email address.

Now update your php.ini file’s sendmail_path:

grep sendmail_path /etc/php5/apache2/conf/php.ini
 
sendmail_path=/usr/local/bin/trapmail

You can then use mail client like mutt or Thunderbird to review the emails, or just tail your mbox file.


SVN autobackup restore

words by Brian Racer

I have been using Doug Hellman’s useful svnautobackup script for our subversion backups. I think it is a pretty useful script, but it only focuses on backups and not restoration.

During a recent server upgrade I needed to restore a large amount of repositories from our dumpfiles. I made the following shell script in php that will loop through all of the backup dumps and restore them. There is a similar tool that uses ruby, but it can only restore one repository and I do not know enough ruby to modify it 🙂

#!/usr/bin/php -q
<?php 
// edit this
$repo_dir = '/svn/';
$backup_dir = '/home/backup/svn/';
 
// don't edit this
foreach(new DirectoryIterator($backup_dir) as $file)
{ 
  if(isDir() && !$file->isDot())
  {
    // get files
    $dumpfiles = glob($backup_dir.$file.'/dumpfile*.bzip2');
    // sort them
    natsort($dumpfiles);
 
    // create the repo if not exists
    if(!is_dir($repo_dir.$file))
    {
      $cmd =  "svnadmin create {$repo_dir}{$file}";
      system(escapeshellcmd($cmd));
    }
 
    // restore dump files
    foreach($dumpfiles as $dumpfile)
    {
      $cmd = "bzcat {$dumpfile} | svnadmin load {$repo_dir}{$file}";
      system(escapeshellcmd($cmd));
    }
  }
}

For reference, here is the script that runs nightly though cron

#!/bin/bash
 
files=`ls /svn`
for file in $files
do
  if [ -d /svn/$file ]
  then
    mkdir -p $file
    /home/backup/scripts/svnautobackup/svnbackup.sh -v -i 100 --history-file /home/backup/svn/$file-hist --out-dir /home/backup/svn/$file /svn/$file
  fi
done