diff --git a/Makefile.src.in b/Makefile.src.in --- a/Makefile.src.in +++ b/Makefile.src.in @@ -9,6 +9,7 @@ CFLAGS = !!CFLAGS!! CFLAGS_BUILD = !!CFLAGS_BUILD!! LIBS = !!LIBS!! LDFLAGS = !!LDFLAGS!! +ROOT_DIR = !!ROOT_DIR!! BIN_DIR = !!BIN_DIR!! LANG_DIR = !!LANG_DIR!! SRC_OBJS_DIR = !!SRC_OBJS_DIR!! @@ -87,58 +88,19 @@ all: $(BIN_DIR)/$(TTD) $(LANG_OBJS_DIR)/table/strings.h: $(LANG_DIR)/english.txt $(LANG_OBJS_DIR)/$(STRGEN) $(MAKE) -C $(LANG_OBJS_DIR) table/strings.h +# Always run version detection, so we always have an accurate modified +# flag +VERSIONS := $(shell AWK="$(AWK)" "$(ROOT_DIR)/findversion.sh") +MODIFIED := $(shell echo "$(VERSIONS)" | cut -f 3) -# Determine if we are using a modified version -ifeq ($(shell if test -d $(SRC_DIR)/.svn; then echo 1; fi), 1) -REV_MODIFIED := $(shell svnversion $(SRC_DIR) | sed -n 's/.*\(M\).*/\1/p' ) -else -# Are we a git dir? -ifeq ($(shell if test -d $(SRC_DIR)/../.git; then echo 1; fi), 1) -REV_MODIFIED := $(shell if cd "$(SRC_DIR)/.." && git diff-index HEAD src | read dummy; then echo M; fi) -else -# Are we a hg (Mercurial) dir? -ifeq ($(shell if test -d $(SRC_DIR)/../.hg; then echo 1; fi), 1) -REV_MODIFIED := $(shell if hg status $(SRC_DIR) | grep -v '^?' | read dummy; then echo M; fi) -else -MODIFIED="1" -endif -endif -endif - -ifneq ($(MODIFIED),"1") -ifeq ($(REV_MODIFIED),) -MODIFIED="0" -else -MODIFIED="2" -endif -endif - -# Make the revision number ifdef REVISION +# Use specified revision (which should be of the form "r000"). REV := $(REVISION) REV_NR := $(shell echo $(REVISION) | sed "s/[^0-9]//g") else -# Are we a SVN dir? -ifeq ($(shell if test -d $(SRC_DIR)/.svn; then echo 1; fi), 1) -# Find if the local source if modified -# Find the revision like: rXXXXM-branch -REV := $(shell LC_ALL=C svn info $(SRC_DIR) | $(AWK) '/^URL:.*branches/ { split($$2, a, "/"); for(i in a) if (a[i]=="branches") { BRANCH="-"a[i+1]; break } } /^Last Changed Rev:/ { REV="r"$$4"$(REV_MODIFIED)" } END { print REV BRANCH }') -REV_NR := $(shell LC_ALL=C svn info $(SRC_DIR) | $(AWK) '/^Last Changed Rev:/ { print $$4 }') -else -# Are we a git dir? -ifeq ($(shell if test -d $(SRC_DIR)/../.git; then echo 1; fi), 1) -# Find the revision like: gXXXXM-branch -REV := g$(shell if head=`LC_ALL=C git rev-parse --verify HEAD 2>/dev/null`; then echo "$$head" | cut -c1-8; fi)$(REV_MODIFIED)$(shell git branch|grep '[*]' | sed 's/\* /-/;s/^-master$$//') -REV_NR := $(shell LC_ALL=C cd "$(SRC_DIR)/.." && git log --pretty=format:%s src | grep "^(svn r[0-9]*)" | head -n 1 | sed "s/.*(svn r\([0-9]*\)).*/\1/" ) -else -# Are we a hg (Mercurial) dir? -ifeq ($(shell if test -d $(SRC_DIR)/../.hg; then echo 1; fi), 1) -# Find the revision like: hXXXXM-branch -REV := h$(shell if head=`LC_ALL=C hg tip 2>/dev/null`; then echo "$$head" | head -n 1 | cut -d: -f3 | cut -c1-8; fi)$(REV_MODIFIED)$(shell hg branch | sed 's/^/-/;s/^-default$$//') -REV_NR := $(shell LC_ALL=C hg log -k "svn" -l 1 --template "{desc}\n" $(SRC_DIR) | grep "^(svn r[0-9]*)" | head -n 1 | sed "s/.*(svn r\([0-9]*\)).*/\1/" ) -endif -endif -endif +# Use autodetected revisions +REV := $(shell echo "$(VERSIONS)" | cut -f 1) +REV_NR := $(shell echo "$(VERSIONS)" | cut -f 2) endif # Make sure we have something in REV and REV_NR diff --git a/findversion.sh b/findversion.sh new file mode 100755 --- /dev/null +++ b/findversion.sh @@ -0,0 +1,106 @@ +#!/bin/sh + +# Arguments given? Show help text. +if [ "$#" != "0" ]; then + cat <\t\t +REV + a string describing what version of the code the current checkout is + based on. The exact format of this string depends on the version + control system in use, but it tries to identify the revision used as + close as possible (using the svn revision number or hg/git hash). + This also includes an indication of whether the checkout was + modified and which branch was checked out. This value is not + guaranteed to be sortable, but is mainly meant for identifying the + revision and user display. + + If no revision identifier could be found, this is left empty. +REV_NR + the revision number of the svn revision this checkout is based on. + This can be used to determine which functionality is present in this + checkout. For trunk svn checkouts and hg/git branches based upon it, + this number should be accurate. For svn branch checkouts, this + number is mostly meaningless, at least when comparing with the + REV_NR from other branches or trunk. + + This number should be sortable. Within a given branch or trunk, a + higher number means a newer version. However, when using git or hg, + this number will not increase on new commits. + + If no revision number could be found, this is left empty. +MODIFIED + Whether (the src directory of) this checkout is modified or not. A + value of 0 means not modified, a value of 2 means it was modified. + Modification is determined in relation to the commit identified by + REV, so not in relation to the svn revision identified by REV_NR. + + A value of 1 means that the modified status is unknown, because this + is not an svn/git/hg checkout for example. + +By setting the AWK environment variable, a caller can determine which +version of "awk" is used. If nothing is set, this script defaults to +"awk". +EOF +exit 1; +fi + +# Allow awk to be provided by the caller. +if [ -z "$AWK" ]; then + AWK=awk +fi + +# Find out some dirs +cd `dirname "$0"` +ROOT_DIR=`pwd` +SRC_DIR=src + +# Determine if we are using a modified version +# Assume the dir is not modified +MODIFIED="0" +if [ -d "$ROOT_DIR/.svn" ]; then + # We are an svn checkout + if svnversion "$SRC_DIR" | grep 'M' > /dev/null; then + MODIFIED="2" + fi + # Find the revision like: rXXXXM-branch + BRANCH=`LC_ALL=C svn info "$SRC_DIR" | "$AWK" '/^URL:.*branches/ { split($2, a, "/"); for(i in a) if (a[i]=="branches") { print a[i+1]; break } }'` + REV_NR=`LC_ALL=C svn info "$SRC_DIR" | "$AWK" '/^Last Changed Rev:/ { print $4 }'` + REV="r$REV_NR" +elif [ -d "$ROOT_DIR/.git" ]; then + # We are a git checkout + if git diff-index HEAD "$SRC_DIR" | read dummy; then + MODIFIED="2" + fi + HASH=`LC_ALL=C git rev-parse --verify HEAD 2>/dev/null | cut -c1-8` + REV="g$HASH" + BRANCH=`git branch|grep '[*]' | sed 's/\* //;s/^master$//'` + REV_NR=`LC_ALL=C git log --pretty=format:%s "$SRC_DIR" | grep "^(svn r[0-9]*)" | head -n 1 | sed "s/.*(svn r\([0-9]*\)).*/\1/"` +elif [ -d "$ROOT_DIR/.hg" ]; then + # We are a hg checkout + if hg status "$SRC_DIR" | grep -v '^?' | read dummy; then + MODIFIED="2" + fi + HASH=`LC_ALL=C hg tip 2>/dev/null | head -n 1 | cut -d: -f3 | cut -c1-8` + REV="h$HASH" + BRANCH=`hg branch | sed 's/^default$//'` + REV_NR=`LC_ALL=C hg log -k "svn" -l 1 --template "{desc}\n" "$SRC_DIR" | grep "^(svn r[0-9]*)" | head -n 1 | sed "s/.*(svn r\([0-9]*\)).*/\1/"` +else + # We don't know + MODIFIED="1" + BRANCH="" + REV="" + REV_NR="" +fi + +if [ "$MODIFIED" -eq "2" ]; then + REV="${REV}M" +fi + +if [ -n "$BRANCH" ]; then + REV="${REV}-$BRANCH" +fi + +echo -e "$REV\t$REV_NR\t$MODIFIED"