4 # - Bumps version according to specified level (major, minor, or patch)
5 # - Updates all necessary headers with new version
6 # - Commits the changes
8 # - Creates a release tarball
11 PROJECT_UC=$(echo $PROJECT | tr '[:lower:]' '[:upper:]')
17 echo "usage: $SCRIPT {major | minor | patch}"
23 echo "$SCRIPT: error: $1" 1>&2
30 # verify header exists
31 if [ ! -f "$HEADER" ]; then
32 report_err "$HEADER does not exist"
35 # verify valid release type
37 if [ "$RTYPE" != "major" -a "$RTYPE" != "minor" -a "$RTYPE" != "patch" ]; then
38 report_err "release type must be major, minor, or patch"
41 # verify git is available
42 if ! type git >/dev/null 2>&1; then
43 report_err "unable to find 'git' in the system path"
46 # verify the git repository is on the master branch
47 BRANCH=$(git branch | grep '\*' | cut -c3-)
48 if [ "$BRANCH" != "master" ]; then
49 report_err "git repository must be on the master branch"
52 # verify there are no uncommitted modifications prior to release modifications
53 NUM_MODIFIED=$(git diff 2>/dev/null | wc -l | sed 's/^[ \t]*//')
54 NUM_STAGED=$(git diff --cached 2>/dev/null | wc -l | sed 's/^[ \t]*//')
55 if [ "$NUM_MODIFIED" != "0" -o "$NUM_STAGED" != "0" ]; then
56 report_err "the working directory contains uncommitted modifications"
60 PAT_PREFIX="(^#define[[:space:]]+${PROJECT_UC}"
61 PAT_SUFFIX='[[:space:]]+)[0-9]+$'
62 MAJOR=$(egrep "${PAT_PREFIX}_MAJOR${PAT_SUFFIX}" $HEADER | awk '{print $3}')
63 MINOR=$(egrep "${PAT_PREFIX}_MINOR${PAT_SUFFIX}" $HEADER | awk '{print $3}')
64 PATCH=$(egrep "${PAT_PREFIX}_PATCH${PAT_SUFFIX}" $HEADER | awk '{print $3}')
65 if [ -z "$MAJOR" -o -z "$MINOR" -o -z "$PATCH" ]; then
66 report_err "unable to get version from $HEADER"
69 # bump version according to level
70 if [ "$RTYPE" = "major" ]; then
71 MAJOR=$(expr $MAJOR + 1)
74 elif [ "$RTYPE" = "minor" ]; then
75 MINOR=$(expr $MINOR + 1)
77 elif [ "$RTYPE" = "patch" ]; then
78 PATCH=$(expr $PATCH + 1)
80 PROJ_VER="$MAJOR.$MINOR.$PATCH"
82 # update header with new version
84 s/${PAT_PREFIX}_MAJOR${PAT_SUFFIX}/\1${MAJOR}/;
85 s/${PAT_PREFIX}_MINOR${PAT_SUFFIX}/\1${MINOR}/;
86 s/${PAT_PREFIX}_PATCH${PAT_SUFFIX}/\1${PATCH}/;
87 " <"$HEADER" >"${HEADER}.tmp"
90 mv "${HEADER}.tmp" "$HEADER"
93 TAG="${PROJECT_UC}_${MAJOR}_${MINOR}_${PATCH}"
94 git commit -am "Prepare for release ${PROJ_VER}." ||
95 report_err "unable to commit changes"
96 git tag -a "$TAG" -m "Release ${PROJ_VER}" || report_err "unable to create tag"
98 # create temp working space and copy repo over
99 TD=$(mktemp -d /tmp/release.XXXXXXXXXX)
100 if [ ! -d "$TD" ]; then
101 report_err "unable to create temp directory"
103 RELEASE_DIR="$PROJECT-$PROJ_VER"
104 RELEASE_TAR="$PROJECT-$PROJ_VER.tgz"
105 git clone . "$TD/$RELEASE_DIR" ||
106 report_err "unable to copy to $TD/$RELEASE_DIR"
108 # cleanup repository files
110 if [ -d "$RELEASE_DIR" -a -d "$RELEASE_DIR/.git" ]; then
111 rm -rf "$RELEASE_DIR/.git"
113 if [ -d "$RELEASE_DIR" -a -f "$RELEASE_DIR/.gitignore" ]; then
114 rm -f "$RELEASE_DIR/.gitignore"
118 tar -zcf "$RELEASE_TAR" "$RELEASE_DIR" ||
119 report_err "unable to create $RELEASE_TAR"
122 echo "Release tarball:"
123 echo " $TD/$RELEASE_TAR"
125 echo "If everything is accurate, use the following command to push the changes:"
126 echo " git push --tags origin master"