Release script for SVN

I am currently working on a project that comprises several components individually managed in SVN. These components are built and then linked in to the final binary. To makes things easier I wrote a release script that creates an editable commit message with the SVN revisions of the components and commits the final binary. I thought it might be useful to others so generalised it.

The script is available here and is shown below.

#!/bin/bash

# Returns the SVN revision of a directory and whether it is modified.
getsvnrev() {
	if [ -n "$1" ] ; then
		dir=$1
	else
		dir=.
	fi

	if [ -d $dir ] ; then
		# Get the last changed revision
		ver=$(svn info $dir | sed -n "/^Last Changed Rev/p")
		if [ -n "$ver" ] ; then
			ver=$(echo $ver | awk '{ print $NF; }')
		fi

		# Test to see if there are modified files in the sandbox
		if [ -n "$ver" ] ; then
			mod=$(svn status $dir | sed -n "/^[AMD]/p")
			if [ -n "$mod" ] ; then
				echo "R$ver(modified)"
			else
				echo "R$ver"
			fi
		fi
	fi
}

# tempfile is nicer but not always supported
mktempfile() {
	if [ -n "$(which tempfile)" ]; then
		tempfile
	else
		mktemp /tmp/makerelease.XXXXX
	fi
}

# Output usage to stderr
usage() {
	echo "usage: makerelease [option] dir [dir]" >&2
}

# Output help to stdout
fullhelp() {
	echo "Usage: makerelease [option] dir [dir]"
	echo "  -r directory    commit specified release directory"
	echo "  -h              display this help"
}

# If no release directory supplied commits pwd
reldir=.

# Process command line options
while getopts :r:h opt
do
	case "$opt" in
		r)
			reldir="$OPTARG"
			;;
		h)
			fullhelp
			exit 0
			;;
		🙂
			echo "Missing argument for $OPTARG" >&2
			usage
			exit 1
			;;
		*)
			echo "Invalid option: $OPTARG" >&2
			usage 
			exit 1
			;;
	esac
done   

# Skip all the options processed above
shift `expr $OPTIND - 1`

# Check we have at least one argument
if [ $# -ne 1 ] ; then
	echo "You need to supply at least one component directory." >&2
	usage
	exit 1
fi

# Check to see if release directory is modified
reldirmod=$(svn status $reldir | sed -n "/^[AMD]/p")
if [ -z "$reldirmod" ] ; then
	echo "No changes to commit." >&2
	exit 1
fi

# Create a log file and allow user to edit it
msgfile=$(mktempfile)
if [ $? -ne 0 ] ; then
	echo "Could not create temp file." >&2
	exit 1
fi

echo "Components..." > $msgfile
while (( "$#" ))
do
	echo "   $1: $(getsvnrev $1)" >> $msgfile
	shift
done

nano $msgfile
if [ $? -ne 0 ] ; then
	echo "Editor returned an error." >&2
	rm -f $msgfile
	exit 1
fi

# Commit changes
svn commit -F $msgfile $reldir
if [ $? -ne 0 ] ; then
	echo "Commit failed." >&2
	rm -f $msgfile
	exit 1
fi

# Clean up
rm $msgfile
exit 0

It is commented so I will not explain it further. To use it either run it in the directory you wish to commit, or use the -r option (followed by the path to the directory to commit), together with a list of directories comprising the SVN components.

Tags: ,

Leave a Reply