Last Updated: February 25, 2016
·
1.912K
· dongli

Sync application version with Git tag automatically!

When developing an application, we need to track the version of it. In my work, I set a string in the code, and user can inquire it through some command option as following:

<command> -v

In the same time, the codes should be version controlled by a version control software. I prefer Git. In Git, there is a subcommand that let you tag the commit, so it is perfect to set version using it to show the development progress:

Picture

But sometimes I made a tag but forgot to update the version, so it would be great that the tag and the version can be synchronized. I searched around and wrote a pre-push (do not forget to make it executable!) hook to do the dirty job for me:

#!/bin/bash

REPO_DIR=$(pwd)
CODE=$REPO_DIR/src/codemate/operator/Master.java

# check the latest tag
LATEST_TAG=$(git tag -l | tail -n 1)

# check the version number in code
LATEST_VERSION=$(awk -F '"' '/String version/ { print $2; }' $CODE)

# compare
if [[ $LATEST_TAG != $LATEST_VERSION ]]; then
    echo "[Warning]: The latest tag ($LATEST_TAG) does not equal" \
        "the latest version number ($LATEST_VERSION) in code!"
    echo "[Notice]: Be CLEAR-HEADED! Use tag (0) or version number (1)?"
    read -p '[0/1] > ' ans
    if [[ $ans == 0 ]]; then
        echo "[Notice]: Change the version number in code."
        awk -F '"' -v tag=$LATEST_TAG '/String version/ {
                sub($2, tag);
                print;
            } !/String version/ {
                print;
            }' $CODE > tmp
        mv tmp $CODE
        git add $CODE
        DIR=$REPO_DIR/products/installer
        echo "[Notice]: Building installer"
        cd $DIR
        ./build.sh
        cd $REPO_DIR
        for file in $(ls $DIR/payload); do
            git add $DIR/payload/$file
        done
        git add $DIR/codemate.installer
        git commit -m "Update version number to $LATEST_TAG"
        git tag -f $LATEST_TAG
    elif [[ $ans == 1 ]]; then
        echo "[Notice]: Retag to the new commit."
        git tag $LATEST_VERSION
    else
        echo "[Error]: Unknown input \"$ans\", so quit pushing!"
        exit 1
    fi
else
    echo "[Notice]: Tag-version consistency is checked."
fi

In short, I just compare the latest tag with the version number in the code, if they are different, then update the version number and add the changes in the code and commit, and finally retag.

Edit:
To avoid silly mistake, I add a conditional block to let human choose which one should be used (tag or version number).