Thursday, December 25, 2008

Packaging with svn-buildpackage

When you start making packages for your software - we're talking about Debian (and Ubuntu spin-off) packages a few problems start popping up.

What you need to start off is having your upstream source in a VCS like SVN and have it tagged in some sort of way (either as tags or using revisions corresponding) to your releases.
What you want to avoid now is messing up your upstream source with the packaging files.

Enter svn-buildpackage: with the mergeWithUpstream mode you can have the upstream sources separate from the packaging files and have it merged on build time.
The catch is that for this to work, you need to have the upstream tarballs stored somewhere - which tends to get pretty annoying.

Luckily svn-buildpackage has a few hooks, so you can have a script check out the corresponding release (e.g. a tag containing the version numbers, say release-0.2.1) at build time.
The only thing you need to add is a file in your packaging tree containing the necessary data to get the upstream sources (in our case the SVN URL).

Here goes an example:

Upstream sources:

myproject/
trunk/
Makefile # to build and install your app
... all other project files

branches/
tags/
0.2.1/ # a tagged release


SVN-buildpackage tree:

myproject/
trunk/
debian/
control
changelog
...
upstream #indicates where the upstream source is located. Contains a variable containing SVN URL

tags/
0.2.1-1/


So the checkout script ends up being something like this:

#!/bin/sh

. debian/upstream # source the config file

#use svn-buildpackage vars to determine package name and upstream version

UPSNAME=${PACKAGE}_$upstream_version
TARBALLDIR=$origDir
DEST=$TARBALLDIR/$UPSNAME
TARNAME=$UPSNAME.orig.tar.gz
TARBALL=$TARBALLDIR/$TARNAME
BUILDAREA=$buildArea
UPSTREAM_VERSION=$upstream_version

if ! [ -f $TARBALL ]; then
# upstream version tag mode
echo "Exporting tag $upstream_version from $URL to $DEST..."
#find the tag to check out
UPSTREAMURL=$URL/tags/$UPSTREAM_VERSION

echo "Exporting revision $REVISION from $URL to $DEST"
svn export $UPSTREAMURL $DEST

echo "Making tarball $TARBALL from $origDir"
tar zvcf $TARBALL -C $TARBALLDIR $UPSNAME

echo "Deleting exported upstream directory"
rm -rf $DEST

echo "Deleting outdated build area tar"
rm $BUILDAREA/$TARNAME
else
echo "Upstream tarball found at $TARBALL - nothing to do"
fi

Then you simply have to run svn-buildpackage with this hook:

svn-buildpackage --svn-prebuild checkout.sh -uc -us -rfakeroot


And each time you build the package the original tarball is created in case it's not present.