A little bash deployment assistant

I wanted to copy some files from one directory to another while I am working on my wordpress blog-in-blog plugin.  Basically I needed to copy the files checked out from svn, from the working directory, to the root of the web directory on my local machine.

Feature requirements:

  • Should only move a file if it has been edited. (we assume that the filesize will have changed by at least 1 byte!)
  • Should not just sit there copying all the time.
  • Should find out about all files in the specified directory.
  • Should report when it updated the file and which file was updated
  • First run should copy all files to the destination directory. (assumes I have updated my working copy from svn)

So after several attempts, here is a more polished version which stores the filename and the last size of the file in a ‘bash hash’. OK bash doesn’t have hashes (mores the pity) but reading around on the web I found this post with a comment from Scott Mcdermott which does the job nicely (once I had stripped offending characters from the file names).

So here is the full code of the deployment assistant:

#!/bin/bash
# script to deploy code from SOURCEDIR to DELIVERDIR 

PROJECTNAME="blog-in-blog"
SOURCEDIR=blog-in-blog/trunk
DELIVERDIR=/var/www/wordpress/wp-content/plugins/blog-in-blog/
FILENAMES=blog-in-blog/trunk/*
LASTFILESIZE=0
COUNTER=1

echo "======================================================"
echo -e "delivering changes \n\tin \033[1m$SOURCEDIR\033[0m \n\tto \033[1m$DELIVERDIR\033[0m"
echo "======================================================"		

if [ -z $1 ]
then
	echo "usage$  $0 "
	exit 1
fi

hash_insert ()
{
	local name=$1 key=$2 val=$3
	eval __hash_${name}_${key}=$val
}

hash_find ()
{
	local name=$1 key=$2
	local var=__hash_${name}_${key}
	echo -n ${!var}
}

while true
do
	for FILE in $FILENAMES
	do
		FILESIZE=$(stat -c%s "$FILE")

		#tidy up file to avoid problems in variable name
		FILE=`basename $FILE`
		FILEORIG=$FILE
		FILE=`echo "$FILE" | sed 's/[\.\_-]//g'`

		LASTFILESIZE=`hash_find fileHash $FILE`
		#echo "filesize:"$FILESIZE
		#echo "lastfilesize:"$LASTFILESIZE
		if [ "$FILESIZE" != "$LASTFILESIZE" ]
		then
			echo "--- $COUNTER ---------------------------------------"
			date
			echo -e "deploying \033[1m$FILEORIG\033[0m from project $PROJECTNAME"
			echo "Size was $LASTFILESIZE bytes, now $FILESIZE bytes."
			cp $SOURCEDIR/$FILEORIG $DELIVERDIR
			hash_insert fileHash $FILE $FILESIZE
			UPDATE=1
		elif [ "$UPDATE" -ne "1" ]
		then
			UPDATE=0
		fi
	done

	if [ "$UPDATE" = 1 ]
	then
		echo "======================================================"
		let COUNTER+=1
		UPDATE=0
	fi

	sleep $1
done
#ends

Leave a comment