1#!/usr/bin/env bash
2# See LICENSE.Batten for license details.
3#
4#=========================================================================
5# vcs-version.sh [options] [src-dir]
6#=========================================================================
7#
8#  -h  Display this message
9#  -v  Verbose mode
10#
11# This script will create a version string by querying a version control
12# system. The string is appropriate for use in installations and
13# distributions. Currently this script assumes we are using git as our
14# version control system but it would be possible to check and see if we
15# are using an alternative version control system and create a version
16# string appropriately.
17# 
18# The script uses git describe plus a few other git commands to create a
19# version strings in the following format:
20#
21#  X.Y[-Z-gN][-dirty]
22#
23# where X is the major release, Y is the minor release, Z is the number
24# of commits since the X.Y release, N is an eight digit abbreviated SHA
25# hash of the most recent commit and the dirty suffix is appended when
26# the working directory used to create the installation or distribution
27# is not a pristine checkout. Here are some example version strings:
28#
29#  0.0                    : initial import
30#  0.0-3-g99ef6933        : 3rd commit since initial import (N=99ef6933)
31#  1.0                    : release 1.0
32#  1.1-12-g3487ab12       : 12th commit since release 1.1 (N=3487ab12)
33#  1.1-12-g3487ab12-dirty : 12th commit since release 1.1 (N=3487ab12)
34#
35# The last example is from a dirty working directory. To find the last
36# release, the script looks for the last tag (does not need to be an
37# annotated tag, but probably should be) which matches the format rel-*.
38# If there is no such tag in the history, then the script uses 0.0 as
39# the release number and counts the total number of commits since the
40# original import for the commit count.
41#
42# If the current directory is not within the working directory, then the
43# path to the source directory should be supplied on the command line.
44#
45# Author : Christopher Batten
46# Date   : August 5, 2009
47
48set -e
49
50#-------------------------------------------------------------------------
51# Command line parsing
52#-------------------------------------------------------------------------
53
54if ( test "$1" = "-h" ); then
55  echo ""
56  sed -n '3p' $0 | sed -e 's/#//'
57  sed -n '5,/^$/p' $0 | sed -e 's/#//'
58  exit 1
59fi
60
61# Source directory command line option
62
63src_dir="."
64if ( test -n "$1" ); then
65  src_dir="$1"
66fi
67
68#-------------------------------------------------------------------------
69# Verify source directory
70#-------------------------------------------------------------------------
71# If the source directory is not a git working directory output a
72# question mark. A distribution will not be in a working directory, but
73# the build system should be structured such that this script is not
74# executed (and instead the version information should probably come
75# from configure). If the user does not specify a source directory use
76# the current directory.
77
78if !( git rev-parse --is-inside-work-tree &> /dev/null ); then
79  echo "?"
80  exit 1;
81fi
82
83top_dir=`git rev-parse --show-cdup`
84cd ./${top_dir}
85
86#-------------------------------------------------------------------------
87# Create the version string
88#-------------------------------------------------------------------------
89# See if we can do a describe based on a tag and if not use a default
90# release number of 0.0 so that we always get canonical version number
91
92if ( git describe --tags --match "rel-*" &> /dev/null ); then
93  ver_str=`git describe --tags --match "rel-*" | sed 's/rel-//'`
94else
95  ver_num="0.0"
96  ver_commits=`git rev-list --all | wc -l | tr -d " "`
97  ver_sha=`git describe --tags --match "rel-*" --always`
98  ver_str="${ver_num}-${ver_commits}-g${ver_sha}"
99fi
100
101# Add a dirty suffix if working directory is dirty
102
103if !( git diff --quiet ); then
104  ver_str="${ver_str}-dirty"
105else
106  untracked=`git ls-files --directory --exclude-standard --others -t`
107  if ( test -n "${untracked}" ); then
108    ver_str="${ver_str}-dirty"
109  fi  
110fi
111
112# Output the final version string
113
114echo "${ver_str}"
115
116# Final exit status
117
118exit 0;
119
120