#!/bin/sh # # This script creates a package version for packages. The package # version is the "release" or other version attached by the packaging # software (eg, RPM or Dpkg) after the upstream software version. # # This software must be invoked like so: # # svnrev.guess # # and it expects that release tags are of the form: # # /tags/- # # Note that release tag versioning expects a working connection to # the repository (for SVN log), but all other branches don't require it. # # If there is no .svn directory or it cannot discover the repository # version, the script sets a version of 0.local. # if [ $# -lt 1 ] then echo "Usage: svnrev.guess " >&2 exit 1 fi PACKAGE="$1" getstat() { if [ ! -d .svn ] then return fi svn stat -v | awk 'BEGIN{modified = "false";lastrev = 0} /Status against/{next} /^\?/{next} { col1=substr($0, 0, 1); if (col1 != " ") {modified = "true"} sub(/^......../, ""); if ($1 > lastrev) { lastrev=$1 } } END{print modified,lastrev}' } # # Branches that are not releases get a work-in-progress package version. # This is 0.[m]. The 0. ensures that an upcoming real # release, with an package version of 1, will supercede this package. # The "m" is added if the working tree has modifications to distinguish # it from a committed revision. # # If there is no repository or there is a problem getting the revision, # the package version is 0.local. # workingrev() { STATINFO="$(getstat)" MODIFIED=$(echo "$STATINFO" | cut -f1 -d" ") LASTREV=$(echo "$STATINFO" | cut -f2 -d" ") if [ -z "$LASTREV" ] then PKG_VERSION=0.local else PKG_VERSION=0.${LASTREV} if [ "$MODIFIED" = "true" ] then PKG_VERSION="${PKG_VERSION}m" fi fi echo "$PKG_VERSION" } # # If the branch is a tag (tags/project-x.y), it needs a release-based # package version (-1, -2, etc). Generally, it will be the tip of the # branch (package version 1). However, if there is a slight release # fixup, that warrants bumping the package version. # # The logic is pretty simple. Walk the history looking for the # creation of the tag (A /tags/project-x.y). For each revsion later # than the creation of the tag, bump the package version. # releaserev() { BRANCH="$1" BRANCH_SEARCH="`echo "$BRANCH" | sed -e 's/\//\\\\\//g'`" svn log -v 2>&1 | awk 'BEGIN{rev=0} /^r[0-9]+ \|/{rev += 1} /^ +A \/'"$BRANCH_SEARCH"'$/{exit} /^ +A \/'"$BRANCH_SEARCH"' (.*)$/{exit} END{print rev}' } # # Tag branches are releases, and need a release-style package version. # All other branches are non-release, and get an obviously # work-in-progress package version. # # guessbranch() expects the standard Subversion layout of # /trunk # /branches/ # /tags/ # guessbranch() { if [ ! -d .svn ] then return fi svn info | awk '/URL: .*\/trunk\/?$/{print "trunk"; exit 0} /URL: .*\/branches\/[^/]+\/?/{ gsub(/\/$/, "", $2); sub(/^.*\/branches\//, "", $2); print "branches/"$2; exit 0; } /URL: .*\/tags\/[^/]+\/?/{ gsub(/\/$/, "", $2); sub(/^.*\/tags\//, "", $2); print "tags/"$2; exit 0; }' } if ! which svn 1>/dev/null 2>&1 then echo "0.local" else BRANCH=$(guessbranch) case "$BRANCH" in tags/${PACKAGE}*) releaserev "$BRANCH" ;; *) workingrev ;; esac fi