[Git][NTPsec/ntpsec][master] Use python in wscript instead of autorevision.sh

Eric S. Raymond gitlab at mg.gitlab.com
Tue Mar 13 17:07:46 UTC 2018


Eric S. Raymond pushed to branch master at NTPsec / ntpsec


Commits:
7f83b7f0 by Matt Selsky at 2018-03-13T04:43:16Z
Use python in wscript instead of autorevision.sh

Fewer languages and hopefully more predictable builds

- - - - -


18 changed files:

- .gitignore
- INSTALL
- VERSION
- devel/TODO
- devel/hacking.txt
- devel/ifdex-ignores
- devel/make-tarball
- devel/release.nix
- ntpd/ntpd.c
- ntpd/wscript
- ntptime/ntptime.c
- pylib/util.py → pylib/util.py.in
- pylib/wscript
- tests/pylib/test_util.py → tests/pylib/test_util.py.in
- tests/wscript
- − wafhelpers/autorevision.sh
- wafhelpers/options.py
- wscript


Changes:

=====================================
.gitignore
=====================================
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,4 @@
-wafhelpers/.autorevision-cache
 .lock-waf*
 .waf*
 *.pyc
-ntpd/version.h
 build


=====================================
INSTALL
=====================================
--- a/INSTALL
+++ b/INSTALL
@@ -166,28 +166,6 @@ Linux File Hierarchy Standard.
 You should have neither issue if you install from an OS distribution's
 binary package.
 
-== Caveat for Crossbuilders ==
-
-If you see a build failure with the message "error: No repo or cache
-detected.", you have collided with an unusual feature of our build recipe.
-
-To generate the version.h file, the uses a script called
-'autorevision.sh' which needs one of two preconditions.  Either (1)
-you are building in a local repository clone, or (2) you are building
-from an unpacked release tarball containing a file
-wafhelpers/.autorevision-cache containing version information.
-
-The motivation for this behavior is to have a version string that
-makes sense on every build from either the repository or a release
-tarball.  It means, however, that if you try to build when waf can see
-neither of these things, you'll get the "No repo or cache detected"
-error.  This can happen when atrempting to use a remote buildroot for
-cross-compilation or other purposes
-
-There are a couple of possible workarounds.  One is to do your remote build
-from a release tarball.  Another is to do a ./waf configure and build in the
-source directory before attempting a buildroot build.
-
 == Installation Names ==
 
 By default, `waf install' will install the package's files in


=====================================
VERSION
=====================================
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.0.1
+1.0


=====================================
devel/TODO
=====================================
--- a/devel/TODO
+++ b/devel/TODO
@@ -104,10 +104,6 @@ Waf detect need configure:
   after a git pull.  (From email on 23 May 2017)
 
 Version string cleanup:
-  This is tangled up with EPOCH
-  configure has --build-version-tag=
-  configure sets up NTPSEC_VERSION_STRING
-  ntptime is the only useage.
   The version string should change if I make an edit and rebuild
     currently it only changes when something in git changes
   We need to be sure not to break the stable checksum feature.


=====================================
devel/hacking.txt
=====================================
--- a/devel/hacking.txt
+++ b/devel/hacking.txt
@@ -377,7 +377,7 @@ a large common include file. These includes live in docs/includes
 and are probably what you need to edit if you're updating anything
 that appears on a man page.
 
-=== Version string ===
+=== Version number ===
 
 We use a variant of three part Semantic Versioning, of the form X.Y.Z.
 X, Y, and Z are non-negative decimal integers.
@@ -411,6 +411,20 @@ Note that this is a different numbering system from NTP Classic. In
 their A.B.C numbers, A was the protocol version, B was the major, and
 C was the minor.  They also use release-candidate suffixes.
 
+== Version string ==
+
+We use the BUILD_EPOCH as described in packaging/packaging.txt for the
+timestamp (converted to RFC 3339 format) part of the version string reported in
+ntpd and other binaries.
+
+Release builds have version strings of the form:
+
+<base version number> <BUILD_EPOCH in RFC 3339 format>
+
+Development builds have version strings of the form:
+
+<base version number>+ <BUILD_EPOCH in RFC 3339 format> (git rev <git shorthash>)
+
 == Contribution workflow and conventions ==
 
 Please work on one piece of conceptual work at a time.


=====================================
devel/ifdex-ignores
=====================================
--- a/devel/ifdex-ignores
+++ b/devel/ifdex-ignores
@@ -87,7 +87,6 @@ TEST_LIBPARSE
 
 # Purely internal symbols
 CONFIG_H
-AUTOREVISION_H
 BITSPERCHAR		# Only used in the Arcron refclock
 BACKTRACE_MAXFRAME	# Internal to the ISC backtrace code
 BACKTRACE_LIBC


=====================================
devel/make-tarball
=====================================
--- a/devel/make-tarball
+++ b/devel/make-tarball
@@ -5,9 +5,6 @@
 # a file named ntpsec-$V.tar.gz.  The name of this tarball is echoed to
 # standard output as part of the success message.
 #
-# The tricky part is that it has to include the autorevision cache file,
-# which can't be checked into the repo or there'd be an infinite loop.
-#
 # Do not try running this outside of devel/
 #
 # *Do* configure and test-build before running it.
@@ -18,12 +15,6 @@ then
     exit 1
 fi
 
-if [ ! -r ../wafhelpers/.autorevision-cache ]
-then
-    echo "Autorevision cache file does not exist, waf build and try again"
-    exit 1
-fi
-
 set -e
 
 if [ "$1" != "" ]
@@ -35,7 +26,7 @@ fi
 
 # Build the tarball
 rm -fr .tmp
-(cd ..; git ls-files; find build -print | grep '\.[0-9]$'; echo "wafhelpers/.autorevision-cache") >MANIFEST
+(cd ..; git ls-files; find build -print | grep '\.[0-9]$') >MANIFEST
 (cd ..; tar --transform="s:^:ntpsec-${V}/:" -T devel/MANIFEST -czf ntpsec-${V}.tar.gz)
 rm MANIFEST
 mv ../ntpsec-${V}.tar.gz .


=====================================
devel/release.nix
=====================================
--- a/devel/release.nix
+++ b/devel/release.nix
@@ -28,10 +28,6 @@ in with derivationOptions; rec {
     distPhase = ''
       runHook preDist
 
-      if [ -n "''${versionSuffix}" ]; then
-        distFlags="--build-version-tag=$versionSuffix $distFlags"
-      fi
-
       echo "dist flags: $distFlags ''${distFlagsArray[@]}"
       python waf dist $distFlags "''${distFlagsArray[@]}"
       
@@ -60,10 +56,6 @@ in with derivationOptions; rec {
           configureFlags="''${prefixKey:---prefix=}$prefix $configureFlags"
         fi
 
-        if [ -n "$versionSuffix" ]; then
-          configureFlags="--build-version-tag=$versionSuffix $configureFlags"
-        fi
-
         echo "configure flags: $configureFlags ''${configureFlagsArray[@]}"
         python waf configure $configureFlags "''${configureFlagsArray[@]}"
 


=====================================
ntpd/ntpd.c
=====================================
--- a/ntpd/ntpd.c
+++ b/ntpd/ntpd.c
@@ -32,8 +32,6 @@
 
 #include "recvbuff.h"
 
-#include "version.h"
-
 void catchQuit (int sig);
 static volatile int signo = 0;
 /* In an ideal world, 'finish_safe()' would declared as noreturn... */
@@ -485,7 +483,7 @@ const char *ntpd_version(void)
 {
     static char versionbuf[64];
     snprintf(versionbuf, sizeof(versionbuf),
-	     "ntpd ntpsec-%s+%d %s", VERSION, VCS_TICK, VCS_DATE);
+	     "ntpd ntpsec-%s", NTPSEC_VERSION);
     return versionbuf;
 }
 


=====================================
ntpd/wscript
=====================================
--- a/ntpd/wscript
+++ b/ntpd/wscript
@@ -2,8 +2,6 @@
 def build(ctx):
     srcnode = ctx.srcnode.abspath()
     bldnode = ctx.bldnode.abspath()
-    target3 = ctx.srcnode.make_node('ntpd/version.h')
-    target4 = ctx.srcnode.make_node('wafhelpers/.autorevision-cache')
 
     if ctx.variant == "host":
         bison_source = ["ntp_parser.y"]
@@ -17,15 +15,7 @@ def build(ctx):
             target="bison_obj",
         )
 
-        ctx(
-            cwd=srcnode,
-            rule='VCS_EXTRA=`cat ${SRC[0]}` wafhelpers/autorevision.sh '
-                 '-o ${TGT[1].abspath()} -e VERSION -t h >${TGT[0].abspath()}',
-            source=["../VERSION", '../wafhelpers/autorevision.sh'],
-            target=[target3, target4],
-        )
-
-        # Generate Bison and version.h files first.
+        # Generate Bison file first.
         ctx.add_group()
 
         keyword_gen_source = ["keyword-gen.c", ]


=====================================
ntptime/ntptime.c
=====================================
--- a/ntptime/ntptime.c
+++ b/ntptime/ntptime.c
@@ -410,7 +410,7 @@ main(
 		}
 		if (json)
 		    /* hack to avoid trailing comma - not semantically needed */
-		    fputs("\"version\":\""  NTPSEC_VERSION_STRING "\"}\n", stdout);
+		    printf("\"version\":\"ntpsec-%s\"}\n", NTPSEC_VERSION);
 		exit(EXIT_SUCCESS);
 	}
 


=====================================
pylib/util.py → pylib/util.py.in
=====================================
--- a/pylib/util.py
+++ b/pylib/util.py.in
@@ -13,7 +13,6 @@ import socket
 import sys
 import time
 import ntp.ntpc
-import ntp.version
 import ntp.magic
 import ntp.control
 
@@ -107,9 +106,7 @@ def safeargcast(arg, castfunc, errtext, usage):
 
 def stdversion():
     "Returns the NTPsec version string in a standard format"
-    return "ntpsec-%s+%s %s" % (ntp.version.VERSION,
-                                ntp.version.VCS_TICK,
-                                ntp.version.VCS_DATE)
+    return "ntpsec-%s" % "@NTPSEC_VERSION@"
 
 
 def rfc3339(t):


=====================================
pylib/wscript
=====================================
--- a/pylib/wscript
+++ b/pylib/wscript
@@ -16,15 +16,21 @@ def build(ctx):
     bldnode = ctx.bldnode.make_node('pylib')
     target1 = bldnode.make_node('control.py')
     target2 = bldnode.make_node('magic.py')
-    target3 = bldnode.make_node('version.py')
-    target4 = ctx.srcnode.make_node('wafhelpers/.autorevision-cache')
+
+    ctx(
+        features="subst",
+        source='util.py.in',
+        target='util.py'
+    )
+    # Force early creation of util.py
+    ctx.add_group()
+
     sources = srcnode.ant_glob('*.py')
     builds = [x.get_bld() for x in sources]
 
     # Remove generated files to ensure they are properly updated
     ctx.exec_command("rm -f %s" % target1.abspath())
     ctx.exec_command("rm -f %s" % target2.abspath())
-    ctx.exec_command("rm -f %s" % target3.abspath())
 
     # Make sure Python sees .py as well as .pyc/.pyo
     ctx(
@@ -49,21 +55,12 @@ def build(ctx):
         target=target2,
     )
 
-    ctx(
-        before=['pyc', 'pyo'],
-        cwd=srcnode,
-        rule='VCS_EXTRA=`cat ${SRC[0]}` ../wafhelpers/autorevision.sh '
-             '-o ${TGT[1].abspath()} -e VERSION -t python >${TGT[0].abspath()}',
-        source=["../VERSION", '../wafhelpers/autorevision.sh'],
-        target=[target3, target4],
-    )
-
     # Force early creation of generated files
     ctx.add_group()
 
     ctx(
         features='py',
-        source=builds+[target1, target2, target3],
+        source=builds+[target1, target2],
         install_from=bldnode,
         install_path='${PYTHONDIR}/ntp'
     )


=====================================
tests/pylib/test_util.py → tests/pylib/test_util.py.in
=====================================
--- a/tests/pylib/test_util.py
+++ b/tests/pylib/test_util.py.in
@@ -96,10 +96,8 @@ class TestPylibUtilMethods(unittest.TestCase):
     def test_stdversion(self):
         f = ntp.util.stdversion
 
-        ver = str(ntp.version.VERSION)
-        tick = str(ntp.version.VCS_TICK)
-        date = str(ntp.version.VCS_DATE)
-        self.assertEqual(f(), "ntpsec-" + ver + "+" + tick + " " + date)
+        ver = "@NTPSEC_VERSION@"
+        self.assertEqual(f(), "ntpsec-" + ver)
 
     def test_rfc3339(self):
         f = ntp.util.rfc3339


=====================================
tests/wscript
=====================================
--- a/tests/wscript
+++ b/tests/wscript
@@ -126,6 +126,14 @@ def build(ctx):
             pass
         os.symlink(pypath.abspath(), linkpath.abspath())
 
+    ctx(
+        features="subst",
+        source="pylib/test_util.py.in",
+        target="pylib/test_util.py"
+    )
+    # Force early creation of pylib/test_util.py
+    ctx.add_group()
+
     pytests = ["pylib/test_util.py",
                "pylib/test_agentx_packet.py",
                "pylib/test_packet.py",


=====================================
wafhelpers/autorevision.sh deleted
=====================================
--- a/wafhelpers/autorevision.sh
+++ /dev/null
@@ -1,1341 +0,0 @@
-#!/bin/sh
-
-# Copyright (c) 2012 - 2016 dak180 and contributors. See
-# https://opensource.org/licenses/mit-license.php or the included
-# COPYING.md for licence terms.
-#
-# autorevision - extracts metadata about the head version from your
-# repository.
-
-# shellcheck disable=SC2154
-
-# Usage message.
-arUsage() {
-	tee >&2 << EOF
-usage: autorevision {-t output-type | -s symbol} [-o cache-file [-f] ] [-e name] [-U] [-V]
-	Options include:
-	-t output-type		= specify output type
-	-s symbol		= specify symbol output
-	-o cache-file		= specify cache file location
-	-f			= force the use of cache data
-	-e name			= set a different output name for VCS_EXTRA
-	-U			= check for untracked files in svn
-	-V			= emit version and exit
-	-?			= help message
-
-The following are valid output types:
-	c			= C/C++ file
-	clojure			= clojure file
-	cmake 			= CMake script file
-	csharp			= CSharp properties file
-	h			= Header for use with c/c++
-	hpp			= Alternate C++ header strings with namespace
-	ini			= INI file
-	java			= Java file
-	javaprop		= Java properties file
-	js			= javascript file
-	json			= JSON file
-	lua			= Lua file
-	m4			= m4 file
-	matlab			= matlab file
-	octave			= octave file
-	php			= PHP file
-	pl			= Perl file
-	py			= Python file
-	rpm			= rpm file
-	scheme			= scheme file
-	sh			= Bash sytax
-	swift			= Swift file
-	tex			= (La)TeX file
-	xcode			= Header useful for populating info.plist files
-
-
-The following are valid symbols:
-	VCS_TYPE
-	VCS_BASENAME
-	VCS_UUID
-	VCS_NUM
-	VCS_DATE
-	VCS_BRANCH
-	VCS_TAG
-	VCS_TICK
-	VCS_EXTRA
-	VCS_FULL_HASH
-	VCS_SHORT_HASH
-	VCS_WC_MODIFIED
-	VCS_ACTION_STAMP
-EOF
-	exit 1
-}
-
-# Config
-ARVERSION="1.19"
-while getopts ":t:o:s:e:VfU" OPTION; do
-	case "${OPTION}" in
-		t)
-			AFILETYPE="${OPTARG}"
-		;;
-		o)
-			CACHEFILE="${OPTARG}"
-		;;
-		f)
-			CACHEFORCE="1"
-		;;
-		s)
-			VAROUT="${OPTARG}"
-		;;
-		e)
-			EXTRA_NAME="${OPTARG}"
-		;;
-		U)
-			UNTRACKEDFILES="1"
-		;;
-		V)
-			echo "autorevision ${ARVERSION}"
-			exit 0
-		;;
-		?)
-			# If an unknown flag is used (or -?):
-			arUsage
-		;;
-	esac
-done
-
-if [ ! -z "${VAROUT}" ] && [ ! -z "${AFILETYPE}" ]; then
-	# If both -s and -t are specified:
-	echo "error: Improper argument combination." 1>&2
-	exit 1
-elif [ -z "${VAROUT}" ] && [ -z "${AFILETYPE}" ]; then
-	# If neither -s or -t are specified:
-	arUsage
-elif [ -z "${CACHEFILE}" ] && [ "${CACHEFORCE}" = "1" ]; then
-	# If -f is specified without -o:
-	arUsage
-elif [ ! -f "${CACHEFILE}" ] && [ "${CACHEFORCE}" = "1" ]; then
-	# If we are forced to use the cache but it does not exist.
-	echo "error: Cache forced but no cache found." 1>&2
-	exit 1
-fi
-
-# Only use the local keyword if it is there (ksh we are looking at
-# you).
-
-if [ "$(command -v local 2> /dev/null)" = "local" ]; then
-	LOCAL="local"
-elif command -v typeset > /dev/null 2>&1; then
-	LOCAL="typeset"
-else
-	LOCAL=""
-fi
-
-# Make sure that the path we are given is one we can source
-# (dash, we are looking at you).
-if [ ! -z "${CACHEFILE}" ] && ! echo "${CACHEFILE}" | grep -q '^\.*/'; then
-	CACHEFILE="./${CACHEFILE}"
-fi
-
-GENERATED_HEADER="Generated by autorevision - do not hand-hack!"
-: "${EXTRA_NAME:="VCS_EXTRA"}"
-
-# Functions to extract data from different repo types.
-# For git repos
-# shellcheck disable=SC2039,SC2164,SC2155
-gitRepo() {
-	${LOCAL} oldPath="${PWD}"
-
-	cd "$(git rev-parse --show-toplevel)"
-
-	VCS_TYPE="git"
-
-	VCS_BASENAME="$(basename "${PWD}")"
-
-	${LOCAL} currentRev="$(git rev-parse HEAD)"
-
-	VCS_UUID="$(git rev-list --max-parents=0 --date-order --reverse "${currentRev}" 2>/dev/null | sed -n 1p)"
-	if [ -z "${VCS_UUID}" ]; then
-		VCS_UUID="$(git rev-list --topo-order "${currentRev}" | tail -n 1)"
-	fi
-
-	# Is the working copy clean?
-	test -z "$(git status --untracked-files=normal --porcelain)"
-	VCS_WC_MODIFIED="${?}"
-
-	# Enumeration of changesets
-	VCS_NUM="$(git rev-list --count "${currentRev}" 2>/dev/null)"
-	if [ -z "${VCS_NUM}" ]; then
-		echo "warning: Counting the number of revisions may be slower due to an outdated git version less than 1.7.2.3. If something breaks, please update it." 1>&2
-		VCS_NUM="$(git rev-list HEAD | wc -l)"
-	fi
-
-	# This may be a git-svn remote.  If so, report the Subversion revision.
-	if [ -z "$(git config svn-remote.svn.url 2>/dev/null)" ]; then
-		# The full revision hash
-		VCS_FULL_HASH="$(git rev-parse "${currentRev}")"
-
-		# The short hash
-		VCS_SHORT_HASH="$(git rev-parse --short "${currentRev}")"
-	else
-		# The git-svn revision number
-		VCS_FULL_HASH="$(git svn find-rev "${currentRev}")"
-		VCS_SHORT_HASH="${VCS_FULL_HASH}"
-	fi
-
-	# Current branch
-	VCS_BRANCH="$(git rev-parse --symbolic-full-name --verify "$(git name-rev --name-only --no-undefined "${currentRev}" 2>/dev/null)" 2>/dev/null | sed -e 's:refs/heads/::' | sed -e 's:refs/::')"
-
-	# Cache the description
-	${LOCAL} DESCRIPTION="$(git describe --long --tags "${currentRev}" 2>/dev/null)"
-
-	# Current or last tag ancestor (empty if no tags)
-	VCS_TAG="$(echo "${DESCRIPTION}" | sed -e "s:-g${VCS_SHORT_HASH}\$::" -e 's:-[0-9]*$::')"
-
-	# Distance to last tag or an alias of VCS_NUM if there is no tag
-	if [ ! -z "${DESCRIPTION}" ]; then
-		VCS_TICK="$(echo "${DESCRIPTION}" | sed -e "s:${VCS_TAG}-::" -e "s:-g${VCS_SHORT_HASH}::")"
-	else
-		VCS_TICK="${VCS_NUM}"
-	fi
-
-	# Date of the current commit
-	VCS_DATE="$(TZ=UTC git show -s --date=iso-strict-local --pretty=format:%cd "${currentRev}" 2>/dev/null | sed -e 's|+00:00|Z|')"
-	if [ -z "${VCS_DATE}" ]; then
-		echo "warning: Action stamps require git version 2.7+." 1>&2
-		VCS_DATE="$(git log -1 --pretty=format:%ci "${currentRev}" | sed -e 's: :T:' -e 's: ::' -e 's|+00:00|Z|')"
-		${LOCAL} ASdis="1"
-	fi
-
-	# Action Stamp
-	if [ -z "${ASdis}" ]; then
-		VCS_ACTION_STAMP="${VCS_DATE}!$(git show -s --pretty=format:%cE "${currentRev}")"
-	else
-		VCS_ACTION_STAMP=""
-	fi
-
-	cd "${oldPath}"
-}
-
-# For hg repos
-# shellcheck disable=SC2039,SC2164
-hgRepo() {
-	${LOCAL} oldPath="${PWD}"
-
-	cd "$(hg root)"
-
-	VCS_TYPE="hg"
-
-	VCS_BASENAME="$(basename "${PWD}")"
-
-	VCS_UUID="$(hg log -r "0" -l 1 --template '{node}\n')"
-
-	# Is the working copy clean?
-	test -z "$(hg status -duram)"
-	VCS_WC_MODIFIED="${?}"
-
-	# Enumeration of changesets
-	VCS_NUM="$(hg id -n | tr -d '+')"
-
-	# The full revision hash
-	VCS_FULL_HASH="$(hg log -r "${VCS_NUM}" -l 1 --template '{node}\n')"
-
-	# The short hash
-	VCS_SHORT_HASH="$(hg id -i | tr -d '+')"
-
-	# Current bookmark (bookmarks are roughly equivalent to git's branches)
-	# or branch if no bookmark
-	VCS_BRANCH="$(hg id -B | cut -d ' ' -f 1)"
-	# Fall back to the branch if there are no bookmarks
-	if [ -z "${VCS_BRANCH}" ]; then
-		VCS_BRANCH="$(hg id -b)"
-	fi
-
-	# Current or last tag ancestor (excluding auto tags, empty if no tags)
-	VCS_TAG="$(hg log -r "${VCS_NUM}" -l 1 --template '{latesttag}\n' 2>/dev/null | sed -e 's:qtip::' -e 's:tip::' -e 's:qbase::' -e 's:qparent::' -e "s:$(hg --config 'extensions.color=' --config 'extensions.mq=' --color never qtop 2>/dev/null)::" | cut -d ' ' -f 1)"
-
-	# Distance to last tag or an alias of VCS_NUM if there is no tag
-	if [ ! -z "${VCS_TAG}" ]; then
-		VCS_TICK="$(hg log -r "${VCS_NUM}" -l 1 --template '{latesttagdistance}\n' 2>/dev/null)"
-	else
-		VCS_TICK="${VCS_NUM}"
-	fi
-
-	# Date of the current commit
-	VCS_DATE="$(hg log -r "${VCS_NUM}" -l 1 --template '{date|isodatesec}\n' 2>/dev/null | sed -e 's: :T:' -e 's: ::' -e 's|+00:00|Z|')"
-
-	# Action Stamp
-	VCS_ACTION_STAMP="$(TZ=UTC hg log -r "${VCS_NUM}" -l 1 --template '{date|localdate|rfc3339date}\n' 2>/dev/null | sed -e 's|+00:00|Z|')!$(hg log -r "${VCS_NUM}" -l 1 --template '{author|email}\n' 2>/dev/null)"
-
-	cd "${oldPath}"
-}
-
-# For bzr repos
-# shellcheck disable=SC2039,SC2164
-bzrRepo() {
-	${LOCAL} oldPath="${PWD}"
-
-	cd "$(bzr root)"
-
-	VCS_TYPE="bzr"
-
-	VCS_BASENAME="$(basename "${PWD}")"
-
-	# Currently unimplemented because more investigation is needed.
-	VCS_UUID=""
-
-	# Is the working copy clean?
-	bzr version-info --custom --template='{clean}\n' | grep -q '1'
-	VCS_WC_MODIFIED="${?}"
-
-	# Enumeration of changesets
-	VCS_NUM="$(bzr revno)"
-
-	# The full revision hash
-	VCS_FULL_HASH="$(bzr version-info --custom --template='{revision_id}\n')"
-
-	# The short hash
-	VCS_SHORT_HASH="${VCS_NUM}"
-
-	# Nick of the current branch
-	VCS_BRANCH="$(bzr nick)"
-
-	# Current or last tag ancestor (excluding auto tags, empty if no tags)
-	VCS_TAG="$(bzr tags --sort=time | sed '/?$/d' | tail -n1 | cut -d ' ' -f1)"
-
-	# Distance to last tag or an alias of VCS_NUM if there is no tag
-	if [ ! -z "${VCS_TAG}" ]; then
-		VCS_TICK="$(bzr log --line -r "tag:${VCS_TAG}.." | tail -n +2 | wc -l | sed -e 's:^ *::')"
-	else
-		VCS_TICK="${VCS_NUM}"
-	fi
-
-	# Date of the current commit
-	VCS_DATE="$(bzr version-info --custom --template='{date}\n' | sed -e 's: :T:' -e 's: ::')"
-
-	# Action Stamp
-	# Currently unimplemented because more investigation is needed.
-	VCS_ACTION_STAMP=""
-
-	cd "${oldPath}"
-}
-
-# For svn repos
-# shellcheck disable=SC2039,SC2164,SC2155
-svnRepo() {
-	${LOCAL} oldPath="${PWD}"
-
-	VCS_TYPE="svn"
-
-	case "${PWD}" in
-	/*trunk*|/*branches*|/*tags*)
-		${LOCAL} fn="${PWD}"
-		while [ "$(basename "${fn}")" != 'trunk' ] && [ "$(basename "${fn}")" != 'branches' ] && [ "$(basename "${fn}")" != 'tags' ] && [ "$(basename "${fn}")" != '/' ]; do
-			${LOCAL} fn="$(dirname "${fn}")"
-		done
-		${LOCAL} fn="$(dirname "${fn}")"
-		if [ "${fn}" = '/' ]; then
-			VCS_BASENAME="$(basename "${PWD}")"
-		else
-			VCS_BASENAME="$(basename "${fn}")"
-		fi
-		;;
-	*) VCS_BASENAME="$(basename "${PWD}")" ;;
-	esac
-
-	VCS_UUID="$(svn info --xml | sed -n -e 's:<uuid>::' -e 's:</uuid>::p')"
-
-	# Cache svnversion output
-	${LOCAL} SVNVERSION="$(svnversion)"
-
-	# Is the working copy clean?
-	echo "${SVNVERSION}" | grep -q "M"
-	case "${?}" in
-		0)
-			VCS_WC_MODIFIED="1"
-		;;
-		1)
-			if [ ! -z "${UNTRACKEDFILES}" ]; then
-			# `svnversion` does not detect untracked files and `svn status` is really slow, so only run it if we really have to.
-				if [ -z "$(svn status)" ]; then
-					VCS_WC_MODIFIED="0"
-				else
-					VCS_WC_MODIFIED="1"
-				fi
-			else
-				VCS_WC_MODIFIED="0"
-			fi
-		;;
-	esac
-
-	# Enumeration of changesets
-	VCS_NUM="$(echo "${SVNVERSION}" | cut -d : -f 1 | sed -e 's:M::' -e 's:S::' -e 's:P::')"
-
-	# The full revision hash
-	VCS_FULL_HASH="${SVNVERSION}"
-
-	# The short hash
-	VCS_SHORT_HASH="${VCS_NUM}"
-
-	# Current branch
-	case "${PWD}" in
-	/*trunk*|/*branches*|/*tags*)
-		${LOCAL} lastbase=""
-		${LOCAL} fn="${PWD}"
-		while :
-		do
-			base="$(basename "${fn}")"
-			if [ "${base}" = 'trunk' ]; then
-				VCS_BRANCH='trunk'
-				break
-			elif [ "${base}" = 'branches' ] || [ "${base}" = 'tags' ]; then
-				VCS_BRANCH="${lastbase}"
-				break
-			elif [ "${base}" = '/' ]; then
-				VCS_BRANCH=""
-				break
-			fi
-			${LOCAL} lastbase="${base}"
-			${LOCAL} fn="$(dirname "${fn}")"
-		done
-		;;
-	*) VCS_BRANCH="" ;;
-	esac
-
-	# Current or last tag ancestor (empty if no tags). But "current
-	# tag" can't be extracted reliably because Subversion doesn't
-	# have tags the way other VCSes do.
-	VCS_TAG=""
-	VCS_TICK=""
-
-	# Date of the current commit
-	VCS_DATE="$(svn info --xml | sed -n -e 's:<date>::' -e 's:</date>::p')"
-
-	# Action Stamp
-	VCS_ACTION_STAMP="${VCS_DATE}!$(svn log --xml -l 1 -r "${VCS_SHORT_HASH}" | sed -n -e 's:<author>::' -e 's:</author>::p')"
-
-	cd "${oldPath}"
-}
-
-
-# Functions to output data in different formats.
-# For bash output
-# First in list because it is used by autorevision
-shOutput() {
-	tee << EOF
-# ${GENERATED_HEADER}
-
-VCS_TYPE="${VCS_TYPE}"
-VCS_BASENAME="${VCS_BASENAME}"
-VCS_UUID="${VCS_UUID}"
-VCS_NUM="${VCS_NUM}"
-VCS_DATE="${VCS_DATE}"
-VCS_BRANCH="${VCS_BRANCH}"
-VCS_TAG="${VCS_TAG}"
-VCS_TICK="${VCS_TICK}"
-${EXTRA_NAME}="${VCS_EXTRA}"
-
-VCS_ACTION_STAMP="${VCS_ACTION_STAMP}"
-VCS_FULL_HASH="${VCS_FULL_HASH}"
-VCS_SHORT_HASH="${VCS_SHORT_HASH}"
-
-VCS_WC_MODIFIED="${VCS_WC_MODIFIED}"
-
-# end
-EOF
-}
-
-# For source C output
-cOutput() {
-	tee << EOF
-/* ${GENERATED_HEADER} */
-
-const char *VCS_TYPE         = "${VCS_TYPE}";
-const char *VCS_BASENAME     = "${VCS_BASENAME}";
-const char *VCS_UUID         = "${VCS_UUID}";
-const int VCS_NUM            = ${VCS_NUM};
-const char *VCS_DATE         = "${VCS_DATE}";
-const char *VCS_BRANCH       = "${VCS_BRANCH}";
-const char *VCS_TAG          = "${VCS_TAG}";
-const int VCS_TICK           = ${VCS_TICK};
-const char *${EXTRA_NAME}        = "${VCS_EXTRA}";
-
-const char *VCS_ACTION_STAMP = "${VCS_ACTION_STAMP}";
-const char *VCS_FULL_HASH    = "${VCS_FULL_HASH}";
-const char *VCS_SHORT_HASH   = "${VCS_SHORT_HASH}";
-
-const int VCS_WC_MODIFIED     = ${VCS_WC_MODIFIED};
-
-/* end */
-EOF
-}
-
-# For Cmake output
-cmakeOutput() {
-	tee << EOF
-# ${GENERATED_HEADER}
-
-set(VCS_TYPE ${VCS_TYPE})
-set(VCS_BASENAME ${VCS_BASENAME})
-set(VCS_UUID ${VCS_UUID})
-set(VCS_NUM ${VCS_NUM})
-set(VCS_DATE ${VCS_DATE})
-set(VCS_BRANCH ${VCS_BRANCH})
-set(VCS_TAG ${VCS_TAG})
-set(VCS_TICK ${VCS_TICK})
-set(${EXTRA_NAME} ${VCS_EXTRA})
-
-set(VCS_ACTION_STAMP ${VCS_ACTION_STAMP})
-set(VCS_FULL_HASH ${VCS_FULL_HASH})
-set(VCS_SHORT_HASH ${VCS_SHORT_HASH})
-
-set(VCS_WC_MODIFIED ${VCS_WC_MODIFIED})
-
-# end
-EOF
-}
-
-# For header output
-hOutput() {
-	tee << EOF
-/* ${GENERATED_HEADER} */
-#ifndef AUTOREVISION_H
-#define AUTOREVISION_H
-
-#define VCS_TYPE		"${VCS_TYPE}"
-#define VCS_BASENAME	"${VCS_BASENAME}"
-#define VCS_UUID		"${VCS_UUID}"
-#define VCS_NUM			${VCS_NUM}
-#define VCS_DATE		"${VCS_DATE}"
-#define VCS_BRANCH		"${VCS_BRANCH}"
-#define VCS_TAG			"${VCS_TAG}"
-#define VCS_TICK		${VCS_TICK}
-#define ${EXTRA_NAME}		"${VCS_EXTRA}"
-
-#define VCS_ACTION_STAMP	"${VCS_ACTION_STAMP}"
-#define VCS_FULL_HASH		"${VCS_FULL_HASH}"
-#define VCS_SHORT_HASH		"${VCS_SHORT_HASH}"
-
-#define VCS_WC_MODIFIED		${VCS_WC_MODIFIED}
-
-#endif
-
-/* end */
-EOF
-}
-
-# A header output for use with xcode to populate info.plist strings
-xcodeOutput() {
-	tee << EOF
-/* ${GENERATED_HEADER} */
-#ifndef AUTOREVISION_H
-#define AUTOREVISION_H
-
-#define VCS_TYPE		${VCS_TYPE}
-#define VCS_BASENAME	${VCS_BASENAME}
-#define VCS_UUID		${VCS_UUID}
-#define VCS_NUM			${VCS_NUM}
-#define VCS_DATE		${VCS_DATE}
-#define VCS_BRANCH		${VCS_BRANCH}
-#define VCS_TAG			${VCS_TAG}
-#define VCS_TICK		${VCS_TICK}
-#define ${EXTRA_NAME}		${VCS_EXTRA}
-
-#define VCS_ACTION_STAMP	${VCS_ACTION_STAMP}
-#define VCS_FULL_HASH		${VCS_FULL_HASH}
-#define VCS_SHORT_HASH		${VCS_SHORT_HASH}
-
-#define VCS_WC_MODIFIED		${VCS_WC_MODIFIED}
-
-#endif
-
-/* end */
-EOF
-}
-
-# For Swift output
-swiftOutput() {
-	case "${VCS_WC_MODIFIED}" in
-		0) VCS_WC_MODIFIED="false" ;;
-		1) VCS_WC_MODIFIED="true" ;;
-	esac
-	# For values that may not exist depending on the type of repo we
-	# have read from, set them to `nil` when they are empty.
-	if [ -z "${VCS_UUID}" ]; then
-		VCS_UUID="nil"
-	else
-		VCS_UUID="\"${VCS_UUID}\""
-	fi
-	if [ -z "${VCS_TAG}" ]; then
-		VCS_TAG="nil"
-	else
-		VCS_TAG="\"${VCS_TAG}\""
-	fi
-	: "${VCS_TICK:="nil"}"
-	if [ -z "${VCS_EXTRA}" ]; then
-		VCS_EXTRA="nil"
-	else
-		VCS_EXTRA="\"${VCS_EXTRA}\""
-	fi
-	if [ -z "${VCS_ACTION_STAMP}" ]; then
-		VCS_ACTION_STAMP="nil"
-	else
-		VCS_ACTION_STAMP="\"${VCS_ACTION_STAMP}\""
-	fi
-	tee << EOF
-/* ${GENERATED_HEADER} */
-
-let VCS_TYPE			= "${VCS_TYPE}"
-let VCS_BASENAME		= "${VCS_BASENAME}"
-let VCS_UUID:	String?	= ${VCS_UUID}
-let VCS_NUM:	Int		= ${VCS_NUM}
-let VCS_DATE			= "${VCS_DATE}"
-let VCS_BRANCH:	String	= "${VCS_BRANCH}"
-let VCS_TAG:	String?	= ${VCS_TAG}
-let VCS_TICK:	Int?	= ${VCS_TICK}
-let ${EXTRA_NAME}:	String?	= ${VCS_EXTRA}
-
-let VCS_ACTION_STAMP:	String?	= ${VCS_ACTION_STAMP}
-let VCS_FULL_HASH:		String	= "${VCS_FULL_HASH}"
-let VCS_SHORT_HASH:		String	= "${VCS_SHORT_HASH}"
-
-let VCS_WC_MODIFIED:	Bool	= ${VCS_WC_MODIFIED}
-
-/* end */
-EOF
-}
-
-# For Python output
-pyOutput() {
-	case "${VCS_WC_MODIFIED}" in
-		0) PY_VCS_WC_MODIFIED="False" ;;
-		1) PY_VCS_WC_MODIFIED="True" ;;
-	esac
-	tee << EOF
-# -*- coding: utf-8 -*-
-# ${GENERATED_HEADER}
-
-VCS_TYPE = "${VCS_TYPE}"
-VCS_BASENAME = "${VCS_BASENAME}"
-VCS_UUID = "${VCS_UUID}"
-VCS_NUM = ${VCS_NUM}
-VCS_DATE = "${VCS_DATE}"
-VCS_BRANCH = "${VCS_BRANCH}"
-VCS_TAG = "${VCS_TAG}"
-VCS_TICK = ${VCS_TICK}
-${EXTRA_NAME} = "${VCS_EXTRA}"
-
-VCS_ACTION_STAMP = "${VCS_ACTION_STAMP}"
-VCS_FULL_HASH = "${VCS_FULL_HASH}"
-VCS_SHORT_HASH = "${VCS_SHORT_HASH}"
-
-VCS_WC_MODIFIED = ${PY_VCS_WC_MODIFIED}
-
-# end
-EOF
-}
-
-# For Perl output
-plOutput() {
-	tee << EOF
-# ${GENERATED_HEADER}
-
-\$VCS_TYPE = '${VCS_TYPE}';
-\$VCS_BASENAME = '${VCS_BASENAME}';
-\$VCS_UUID = '${VCS_UUID}';
-\$VCS_NUM = ${VCS_NUM};
-\$VCS_DATE = '${VCS_DATE}';
-\$VCS_BRANCH = '${VCS_BRANCH}';
-\$VCS_TAG = '${VCS_TAG}';
-\$VCS_TICK = ${VCS_TICK};
-\$${EXTRA_NAME} = '${VCS_EXTRA}';
-
-\$VCS_ACTION_STAMP = '${VCS_ACTION_STAMP}';
-\$VCS_FULL_HASH = '${VCS_FULL_HASH}';
-\$VCS_SHORT_HASH = '${VCS_SHORT_HASH}';
-
-\$VCS_WC_MODIFIED = ${VCS_WC_MODIFIED};
-
-# end
-1;
-EOF
-}
-
-# For lua output
-luaOutput() {
-	case "${VCS_WC_MODIFIED}" in
-		0) VCS_WC_MODIFIED="false" ;;
-		1) VCS_WC_MODIFIED="true" ;;
-	esac
-	tee << EOF
--- ${GENERATED_HEADER}
-
-VCS_TYPE = "${VCS_TYPE}"
-VCS_BASENAME = "${VCS_BASENAME}"
-VCS_UUID = "${VCS_UUID}"
-VCS_NUM = ${VCS_NUM}
-VCS_DATE = "${VCS_DATE}"
-VCS_BRANCH = "${VCS_BRANCH}"
-VCS_TAG = "${VCS_TAG}"
-VCS_TICK = ${VCS_TICK}
-${EXTRA_NAME} = "${VCS_EXTRA}"
-
-VCS_ACTION_STAMP = "${VCS_ACTION_STAMP}"
-VCS_FULL_HASH = "${VCS_FULL_HASH}"
-VCS_SHORT_HASH = "${VCS_SHORT_HASH}"
-
-VCS_WC_MODIFIED = ${VCS_WC_MODIFIED}
-
--- end
-EOF
-}
-
-# For php output
-phpOutput() {
-	case "${VCS_WC_MODIFIED}" in
-		0) VCS_WC_MODIFIED="false" ;;
-		1) VCS_WC_MODIFIED="true" ;;
-	esac
-	tee << EOF
-<?php
-# ${GENERATED_HEADER}
-
-return array(
-	"VCS_TYPE" => "${VCS_TYPE}",
-	"VCS_BASENAME" => "${VCS_BASENAME}",
-	"VCS_UUID" => "${VCS_UUID}",
-	"VCS_NUM" => ${VCS_NUM},
-	"VCS_DATE" => "${VCS_DATE}",
-	"VCS_BRANCH" => "${VCS_BRANCH}",
-	"VCS_TAG" => "${VCS_TAG}",
-	"VCS_TICK" => ${VCS_TICK},
-	"${EXTRA_NAME}" => "${VCS_EXTRA}",
-	"VCS_ACTION_STAMP" => "${VCS_ACTION_STAMP}",
-	"VCS_FULL_HASH" => "${VCS_FULL_HASH}",
-	"VCS_SHORT_HASH" => "${VCS_SHORT_HASH}",
-	"VCS_WC_MODIFIED" => ${VCS_WC_MODIFIED}
-);
-
-# end
-?>
-EOF
-}
-
-# For ini output
-iniOutput() {
-	case "${VCS_WC_MODIFIED}" in
-		0) VCS_WC_MODIFIED="false" ;;
-		1) VCS_WC_MODIFIED="true" ;;
-	esac
-	tee << EOF
-; ${GENERATED_HEADER}
-[VCS]
-VCS_TYPE = "${VCS_TYPE}"
-VCS_BASENAME = "${VCS_BASENAME}"
-VCS_UUID = "${VCS_UUID}"
-VCS_NUM = ${VCS_NUM}
-VCS_DATE = "${VCS_DATE}"
-VCS_BRANCH = "${VCS_BRANCH}"
-VCS_TAG = "${VCS_TAG}"
-VCS_TICK = ${VCS_TICK}
-${EXTRA_NAME} = "${VCS_EXTRA}"
-VCS_ACTION_STAMP = "${VCS_ACTION_STAMP}"
-VCS_FULL_HASH = "${VCS_FULL_HASH}"
-VCS_SHORT_HASH = "${VCS_SHORT_HASH}"
-VCS_WC_MODIFIED = ${VCS_WC_MODIFIED}
-; end
-EOF
-}
-
-# For javascript output
-jsOutput() {
-	case "${VCS_WC_MODIFIED}" in
-		1) VCS_WC_MODIFIED="true" ;;
-		0) VCS_WC_MODIFIED="false" ;;
-	esac
-	tee << EOF
-/** ${GENERATED_HEADER} */
-
-var autorevision = {
-	VCS_TYPE: "${VCS_TYPE}",
-	VCS_BASENAME: "${VCS_BASENAME}",
-	VCS_UUID: "${VCS_UUID}",
-	VCS_NUM: ${VCS_NUM},
-	VCS_DATE: "${VCS_DATE}",
-	VCS_BRANCH: "${VCS_BRANCH}",
-	VCS_TAG: "${VCS_TAG}",
-	VCS_TICK: ${VCS_TICK},
-	${EXTRA_NAME}: "${VCS_EXTRA}",
-
-	VCS_ACTION_STAMP: "${VCS_ACTION_STAMP}",
-	VCS_FULL_HASH: "${VCS_FULL_HASH}",
-	VCS_SHORT_HASH: "${VCS_SHORT_HASH}",
-
-	VCS_WC_MODIFIED: ${VCS_WC_MODIFIED}
-};
-
-/** Node.js compatibility */
-if (typeof module !== 'undefined') {
-	module.exports = autorevision;
-}
-
-/** end */
-EOF
-}
-
-# For JSON output
-jsonOutput() {
-	case "${VCS_WC_MODIFIED}" in
-		1) VCS_WC_MODIFIED="true" ;;
-		0) VCS_WC_MODIFIED="false" ;;
-	esac
-	tee << EOF
-{
-	"_comment": "${GENERATED_HEADER}",
-	"VCS_TYPE": "${VCS_TYPE}",
-	"VCS_BASENAME": "${VCS_BASENAME}",
-	"VCS_UUID": "${VCS_UUID}",
-	"VCS_NUM": ${VCS_NUM},
-	"VCS_DATE": "${VCS_DATE}",
-	"VCS_BRANCH":"${VCS_BRANCH}",
-	"VCS_TAG": "${VCS_TAG}",
-	"VCS_TICK": ${VCS_TICK},
-	"${EXTRA_NAME}": "${VCS_EXTRA}",
-
-	"VCS_ACTION_STAMP": "${VCS_ACTION_STAMP}",
-	"VCS_FULL_HASH": "${VCS_FULL_HASH}",
-	"VCS_SHORT_HASH": "${VCS_SHORT_HASH}",
-
-	"VCS_WC_MODIFIED": ${VCS_WC_MODIFIED}
-}
-EOF
-}
-
-# For Java output
-javaOutput() {
-	case "${VCS_WC_MODIFIED}" in
-		1) VCS_WC_MODIFIED="true" ;;
-		0) VCS_WC_MODIFIED="false" ;;
-	esac
-	tee << EOF
-/* ${GENERATED_HEADER} */
-
-public class autorevision {
-    public static final String VCS_TYPE = "${VCS_TYPE}";
-    public static final String VCS_BASENAME = "${VCS_BASENAME}";
-    public static final String VCS_UUID = "${VCS_UUID}";
-    public static final long VCS_NUM = ${VCS_NUM};
-    public static final String VCS_DATE = "${VCS_DATE}";
-    public static final String VCS_BRANCH = "${VCS_BRANCH}";
-    public static final String VCS_TAG = "${VCS_TAG}";
-    public static final long VCS_TICK = ${VCS_TICK};
-    public static final String ${EXTRA_NAME} = "${VCS_EXTRA}";
-
-    public static final String VCS_ACTION_STAMP = "${VCS_ACTION_STAMP}";
-    public static final String VCS_FULL_HASH = "${VCS_FULL_HASH}";
-    public static final String VCS_SHORT_HASH = "${VCS_SHORT_HASH}";
-
-    public static final boolean VCS_WC_MODIFIED = ${VCS_WC_MODIFIED};
-}
-EOF
-}
-
-csharpOutput() {
-	case "${VCS_WC_MODIFIED}" in
-		1) VCS_WC_MODIFIED="true" ;;
-		0) VCS_WC_MODIFIED="false" ;;
-	esac
-	if [ "${EXTRA_NAME}" = "VCS_EXTRA" ]; then
-        EXTRA_NAME="VcsExtra"
-    fi
-    tee << EOF
-/* ${GENERATED_HEADER} */
-
-namespace AutoRevision
-{
-    public class VersionInfo
-    {
-        public static string VcsType = "${VCS_TYPE}";
-        public static string VcsBasename = "${VCS_BASENAME}";
-        public static string VcsUuid = "${VCS_UUID}";
-        public static string VcsNum = "${VCS_NUM}";
-        public static string VcsDate = "${VCS_DATE}";
-        public static string VcsBranch = "${VCS_DATE}";
-        public static string VcsTag = "${VCS_TAG}";
-        public static string VcsTick = "${VCS_TICK}";
-        public static string ${EXTRA_NAME} = "${VCS_EXTRA}";
-        public static string VcsActionStamp = "${VCS_ACTION_STAMP}";
-        public static string VcsFullHash = "${VCS_FULL_HASH}";
-        public static string VcsShortHash = "${VCS_SHORT_HASH}";
-        public static string VcsWcModified = "${VCS_WC_MODIFIED}";
-    }
-}
-EOF
-}
-
-# For Java properties output
-javapropOutput() {
-	case "${VCS_WC_MODIFIED}" in
-		1) VCS_WC_MODIFIED="true" ;;
-		0) VCS_WC_MODIFIED="false" ;;
-	esac
-	tee << EOF
-# ${GENERATED_HEADER}
-
-VCS_TYPE=${VCS_TYPE}
-VCS_BASENAME=${VCS_BASENAME}
-VCS_UUID=${VCS_UUID}
-VCS_NUM=${VCS_NUM}
-VCS_DATE=${VCS_DATE}
-VCS_BRANCH=${VCS_BRANCH}
-VCS_TAG=${VCS_TAG}
-VCS_TICK=${VCS_TICK}
-${EXTRA_NAME}=${VCS_EXTRA}
-
-VCS_ACTION_STAMP=${VCS_ACTION_STAMP}
-VCS_FULL_HASH=${VCS_FULL_HASH}
-VCS_SHORT_HASH=${VCS_SHORT_HASH}
-
-VCS_WC_MODIFIED=${VCS_WC_MODIFIED}
-EOF
-}
-
-# For m4 output
-m4Output() {
-	tee << EOF
-dnl ${GENERATED_HEADER}
-define(\`VCS_TYPE', \`${VCS_TYPE}')dnl
-define(\`VCS_BASENAME', \`${VCS_BASENAME}')dnl
-define(\`VCS_UUID', \`${VCS_UUID}')dnl
-define(\`VCS_NUM', \`${VCS_NUM}')dnl
-define(\`VCS_DATE', \`${VCS_DATE}')dnl
-define(\`VCS_BRANCH', \`${VCS_BRANCH}')dnl
-define(\`VCS_TAG', \`${VCS_TAG}')dnl
-define(\`VCS_TICK', \`${VCS_TICK}')dnl
-define(\`${EXTRA_NAME}', \`${VCS_EXTRA}')dnl
-define(\`VCS_ACTIONSTAMP', \`${VCS_ACTION_STAMP}')dnl
-define(\`VCS_FULLHASH', \`${VCS_FULL_HASH}')dnl
-define(\`VCS_SHORTHASH', \`${VCS_SHORT_HASH}')dnl
-define(\`VCS_WC_MODIFIED', \`${VCS_WC_MODIFIED}')dnl
-EOF
-}
-
-# For (La)TeX output
-texOutput() {
-	case "${VCS_WC_MODIFIED}" in
-		0) VCS_WC_MODIFIED="false" ;;
-		1) VCS_WC_MODIFIED="true" ;;
-	esac
-	if [ "${EXTRA_NAME}" = "VCS_EXTRA" ]; then
-		EXTRA_NAME="vcsExtra"
-	fi
-	tee << EOF
-% ${GENERATED_HEADER}
-\def \vcsType {${VCS_TYPE}}
-\def \vcsBasename {${VCS_BASENAME}}
-\def \vcsUUID {${VCS_UUID}}
-\def \vcsNum {${VCS_NUM}}
-\def \vcsDate {${VCS_DATE}}
-\def \vcsBranch {${VCS_BRANCH}}
-\def \vcsTag {${VCS_TAG}}
-\def \vcsTick {${VCS_TICK}}
-\def \\${EXTRA_NAME} {${VCS_EXTRA}}
-\def \vcsACTIONSTAMP {${VCS_ACTION_STAMP}}
-\def \vcsFullHash {${VCS_FULL_HASH}}
-\def \vcsShortHash {${VCS_SHORT_HASH}}
-\def \vcsWCModified {${VCS_WC_MODIFIED}}
-\endinput
-EOF
-}
-
-# For scheme output
-schemeOutput() {
-	case "${VCS_WC_MODIFIED}" in
-		0) VCS_WC_MODIFIED="#f" ;;
-		1) VCS_WC_MODIFIED="#t" ;;
-	esac
-	tee << EOF
-;; ${GENERATED_HEADER}
-(define VCS_TYPE        "${VCS_TYPE}")
-(define VCS_BASENAME    "${VCS_BASENAME}")
-(define VCS_UUID        "${VCS_UUID}")
-(define VCS_NUM         ${VCS_NUM})
-(define VCS_DATE        "${VCS_DATE}")
-(define VCS_BRANCH      "${VCS_BRANCH}")
-(define VCS_TAG         "${VCS_TAG}")
-(define VCS_TICK        ${VCS_TICK})
-(define ${EXTRA_NAME}       "${VCS_EXTRA}")
-
-(define VCS_ACTION_STAMP   "${VCS_ACTION_STAMP}")
-(define VCS_FULL_HASH   "${VCS_FULL_HASH}")
-(define VCS_SHORT_HASH  "${VCS_SHORT_HASH}")
-
-(define VCS_WC_MODIFIED ${VCS_WC_MODIFIED})
-;; end
-EOF
-}
-
-# For clojure output
-clojureOutput() {
-	case "${VCS_WC_MODIFIED}" in
-		0) VCS_WC_MODIFIED="false" ;;
-		1) VCS_WC_MODIFIED="true" ;;
-	esac
-	tee << EOF
-;; ${GENERATED_HEADER}
-(def VCS_TYPE        "${VCS_TYPE}")
-(def VCS_BASENAME    "${VCS_BASENAME}")
-(def VCS_UUID        "${VCS_UUID}")
-(def VCS_NUM         ${VCS_NUM})
-(def VCS_DATE        "${VCS_DATE}")
-(def VCS_BRANCH      "${VCS_BRANCH}")
-(def VCS_TAG         "${VCS_TAG}")
-(def VCS_TICK        ${VCS_TICK})
-(def ${EXTRA_NAME}       "${VCS_EXTRA}")
-
-(def VCS_ACTION_STAMP   "${VCS_ACTION_STAMP}")
-(def VCS_FULL_HASH      "${VCS_FULL_HASH}")
-(def VCS_SHORT_HASH     "${VCS_SHORT_HASH}")
-
-(def VCS_WC_MODIFIED ${VCS_WC_MODIFIED})
-;; end
-EOF
-}
-
-# For rpm spec file output
-rpmOutput() {
-	tee << EOF
-# ${GENERATED_HEADER}
-$([ "${VCS_TYPE}" ] && echo "%define vcs_type		${VCS_TYPE}")
-$([ "${VCS_BASENAME}" ] && echo "%define vcs_basename		${VCS_BASENAME}")
-$([ "${VCS_UUID}" ] && echo "%define vcs_uuid		${VCS_UUID}")
-$([ "${VCS_NUM}" ] && echo "%define vcs_num			${VCS_NUM}")
-$([ "${VCS_DATE}" ] && echo "%define vcs_date		${VCS_DATE}")
-$([ "${VCS_BRANCH}" ] && echo "%define vcs_branch		${VCS_BRANCH}")
-$([ "${VCS_TAG}" ] && echo "%define vcs_tag			${VCS_TAG}")
-$([ "${VCS_TICK}" ] && echo "%define vcs_tick		${VCS_TICK}")
-$([ "${VCS_EXTRA}" ] && echo "%define ${EXTRA_NAME}		${VCS_EXTRA}")
-
-$([ "${VCS_ACTION_STAMP}" ] && echo "%define vcs_action_stamp		${VCS_ACTION_STAMP}")
-$([ "${VCS_FULL_HASH}" ] && echo "%define vcs_full_hash		${VCS_FULL_HASH}")
-$([ "${VCS_SHORT_HASH}" ] && echo "%define vcs_short_hash		${VCS_SHORT_HASH}")
-
-$([ "${VCS_WC_MODIFIED}" ] && echo "%define vcs_wc_modified		${VCS_WC_MODIFIED}")
-# end
-EOF
-}
-
-# For C++ Header output
-# shellcheck disable=SC2155,SC2039
-hppOutput() {
-	${LOCAL} NAMESPACE="$(echo "${VCS_BASENAME}" | sed -e 's:_::g' | tr '[:lower:]' '[:upper:]')"
-	tee << EOF
-/* ${GENERATED_HEADER} */
-
-#ifndef ${NAMESPACE}_AUTOREVISION_H
-#define ${NAMESPACE}_AUTOREVISION_H
-
-#include <string>
-
-namespace $(echo "${NAMESPACE}" | tr '[:upper:]' '[:lower:]')
-{
-	const std::string VCS_TYPE		= "${VCS_TYPE}";
-	const std::string VCS_BASENAME	= "${VCS_BASENAME}";
-	const std::string VCS_UUID		= "${VCS_UUID}";
-	const int VCS_NUM				= ${VCS_NUM};
-	const std::string VCS_DATE		= "${VCS_DATE}";
-	const std::string VCS_BRANCH	= "${VCS_BRANCH}";
-	const std::string VCS_TAG		= "${VCS_TAG}";
-	const int VCS_TICK				= ${VCS_TICK};
-	const std::string ${EXTRA_NAME}		= "${VCS_EXTRA}";
-
-	const std::string VCS_ACTION_STAMP	= "${VCS_ACTION_STAMP}";
-	const std::string VCS_FULL_HASH		= "${VCS_FULL_HASH}";
-	const std::string VCS_SHORT_HASH	= "${VCS_SHORT_HASH}";
-
-	const int VCS_WC_MODIFIED			= ${VCS_WC_MODIFIED};
-}
-
-#endif
-
-/* end */
-EOF
-}
-
-# For Matlab output
-matlabOutput() {
-	case "${VCS_WC_MODIFIED}" in
-		0) VCS_WC_MODIFIED="FALSE" ;;
-		1) VCS_WC_MODIFIED="TRUE" ;;
-	esac
-	tee << EOF
-% ${GENERATED_HEADER}
-
-VCS_TYPE = '${VCS_TYPE}';
-VCS_BASENAME = '${VCS_BASENAME}';
-VCS_UUID = '${VCS_UUID}';
-VCS_NUM = ${VCS_NUM};
-VCS_DATE = '${VCS_DATE}';
-VCS_BRANCH = '${VCS_BRANCH}';
-VCS_TAG = '${VCS_TAG}';
-VCS_TICK = ${VCS_TICK};
-${EXTRA_NAME} = '${VCS_EXTRA}';
-
-VCS_ACTION_STAMP = '${VCS_ACTION_STAMP}';
-VCS_FULL_HASH = '${VCS_FULL_HASH}';
-VCS_SHORT_HASH = '${VCS_SHORT_HASH}';
-
-VCS_WC_MODIFIED = ${VCS_WC_MODIFIED};
-
-% end
-EOF
-}
-
-# For Octave output
-octaveOutput() {
-	tee << EOF
-% ${GENERATED_HEADER}
-
-VCS_TYPE = '${VCS_TYPE}';
-VCS_BASENAME = '${VCS_BASENAME}';
-VCS_UUID = '${VCS_UUID}';
-VCS_NUM = ${VCS_NUM};
-VCS_DATE = '${VCS_DATE}';
-VCS_BRANCH = '${VCS_BRANCH}';
-VCS_TAG = '${VCS_TAG}';
-VCS_TICK = ${VCS_TICK};
-${EXTRA_NAME} = '${VCS_EXTRA}';
-
-VCS_ACTION_STAMP = '${VCS_ACTION_STAMP}';
-VCS_FULL_HASH = '${VCS_FULL_HASH}';
-VCS_SHORT_HASH = '${VCS_SHORT_HASH}';
-
-VCS_WC_MODIFIED = ${VCS_WC_MODIFIED};
-
-% end
-EOF
-}
-
-
-# Helper functions
-# Count path segments
-# shellcheck disable=SC2039
-pathSegment() {
-	${LOCAL} pathz="${1}"
-	${LOCAL} depth="0"
-
-	if [ ! -z "${pathz}" ]; then
-		# Continue until we are at / or there are no path separators left.
-		while [ ! "${pathz}" = "/" ] && [ ! "${pathz}" = "$(echo "${pathz}" | sed -e 's:/::')" ]; do
-			pathz="$(dirname "${pathz}")"
-			depth="$((depth+1))"
-		done
-	fi
-	echo "${depth}"
-}
-
-# Largest of four numbers
-# shellcheck disable=SC2039
-multiCompare() {
-	${LOCAL} larger="${1}"
-	${LOCAL} numA="${2}"
-	${LOCAL} numB="${3}"
-	${LOCAL} numC="${4}"
-
-	[ "${numA}" -gt "${larger}" ] && larger="${numA}"
-	[ "${numB}" -gt "${larger}" ] && larger="${numB}"
-	[ "${numC}" -gt "${larger}" ] && larger="${numC}"
-	echo "${larger}"
-}
-
-# Test for repositories
-# shellcheck disable=SC2155,SC2039
-repoTest() {
-	REPONUM="0"
-	if command -v git > /dev/null 2>&1; then
-		${LOCAL} gitPath="$(git rev-parse --show-toplevel 2>/dev/null)"
-		${LOCAL} gitDepth="$(pathSegment "${gitPath}")"
-		if [ ! -z "${gitPath}" ]; then
-			REPONUM="$((REPONUM+1))"
-		fi
-	else
-		${LOCAL} gitDepth="0"
-	fi
-	if command -v hg > /dev/null 2>&1; then
-		${LOCAL} hgPath="$(hg root 2>/dev/null)"
-		${LOCAL} hgDepth="$(pathSegment "${hgPath}")"
-		if [ ! -z "${hgPath}" ]; then
-			REPONUM="$((REPONUM+1))"
-		fi
-	else
-		${LOCAL} hgDepth="0"
-	fi
-	if command -v bzr > /dev/null 2>&1; then
-		${LOCAL} bzrPath="$(bzr root 2>/dev/null)"
-		${LOCAL} bzrDepth="$(pathSegment "${bzrPath}")"
-		if [ ! -z "${bzrPath}" ]; then
-			REPONUM="$((REPONUM+1))"
-		fi
-	else
-		${LOCAL} bzrDepth="0"
-	fi
-	if command -v svn > /dev/null 2>&1; then
-		${LOCAL} stringz="<wcroot-abspath>"
-		${LOCAL} stringx="</wcroot-abspath>"
-		${LOCAL} svnPath="$(svn info --xml 2>/dev/null | sed -n -e "s:${stringz}::" -e "s:${stringx}::p")"
-		# An old enough svn will not be able give us a path; default
-		# to 1 for that case.
-		if [ ! -z "${svnPath}" ]; then
-			${LOCAL} svnDepth="$(pathSegment "${svnPath}")"
-			REPONUM="$((REPONUM+1))"
-		elif [ -z "${svnPath}" ] && [ -d ".svn" ]; then
-			${LOCAL} svnDepth="1"
-			REPONUM="$((REPONUM+1))"
-		else
-			${LOCAL} svnDepth="0"
-		fi
-	else
-		${LOCAL} svnDepth="0"
-	fi
-
-	# Do not do more work then we have to.
-	if [ "${REPONUM}" = "0" ]; then
-		return 0
-	fi
-
-	# Figure out which repo is the deepest and use it.
-	${LOCAL} wonRepo="$(multiCompare "${gitDepth}" "${hgDepth}" "${bzrDepth}" "${svnDepth}")"
-	if [ "${wonRepo}" = "${gitDepth}" ]; then
-		gitRepo
-	elif [ "${wonRepo}" = "${hgDepth}" ]; then
-		hgRepo
-	elif [ "${wonRepo}" = "${bzrDepth}" ]; then
-		bzrRepo
-	elif [ "${wonRepo}" = "${svnDepth}" ]; then
-		svnRepo
-	fi
-}
-
-
-
-# Detect which repos we are in and gather data.
-# shellcheck source=/dev/null
-if [ -f "${CACHEFILE}" ] && [ "${CACHEFORCE}" = "1" ]; then
-	# When requested only read from the cache to populate our symbols.
-	. "${CACHEFILE}"
-else
-	# If a value is not set through the environment set VCS_EXTRA to nothing.
-	: "${VCS_EXTRA:=""}"
-	repoTest
-
-	if [ -f "${CACHEFILE}" ] && [ "${REPONUM}" = "0" ]; then
-		# We are not in a repo; try to use a previously generated cache to populate our symbols.
-		. "${CACHEFILE}"
-		# Do not overwrite the cache if we know we are not going to write anything new.
-		CACHEFORCE="1"
-	elif [ "${REPONUM}" = "0" ]; then
-		echo "error: No repo or cache detected." 1>&2
-		exit 1
-	fi
-fi
-
-
-# -s output is handled here.
-if [ ! -z "${VAROUT}" ]; then
-	if [ "${VAROUT}" = "VCS_TYPE" ]; then
-		echo "${VCS_TYPE}"
-	elif [ "${VAROUT}" = "VCS_BASENAME" ]; then
-		echo "${VCS_BASENAME}"
-	elif [ "${VAROUT}" = "VCS_NUM" ]; then
-		echo "${VCS_NUM}"
-	elif [ "${VAROUT}" = "VCS_DATE" ]; then
-		echo "${VCS_DATE}"
-	elif [ "${VAROUT}" = "VCS_BRANCH" ]; then
-		echo "${VCS_BRANCH}"
-	elif [ "${VAROUT}" = "VCS_TAG" ]; then
-		echo "${VCS_TAG}"
-	elif [ "${VAROUT}" = "VCS_TICK" ]; then
-		echo "${VCS_TICK}"
-	elif [ "${VAROUT}" = "VCS_FULL_HASH" ]; then
-		echo "${VCS_FULL_HASH}"
-	elif [ "${VAROUT}" = "VCS_SHORT_HASH" ]; then
-		echo "${VCS_SHORT_HASH}"
-	elif [ "${VAROUT}" = "VCS_WC_MODIFIED" ]; then
-		echo "${VCS_WC_MODIFIED}"
-	elif [ "${VAROUT}" = "VCS_ACTION_STAMP" ]; then
-		echo "${VCS_ACTION_STAMP}"
-	else
-		echo "error: Not a valid output symbol." 1>&2
-		exit 1
-	fi
-fi
-
-
-# Detect requested output type and use it.
-if [ ! -z "${AFILETYPE}" ]; then
-	if [ "${AFILETYPE}" = "c" ]; then
-		cOutput
-	elif [ "${AFILETYPE}" = "h" ]; then
-		hOutput
-	elif [ "${AFILETYPE}" = "xcode" ]; then
-		xcodeOutput
-	elif [ "${AFILETYPE}" = "swift" ]; then
-		swiftOutput
-	elif [ "${AFILETYPE}" = "sh" ]; then
-		shOutput
-	elif [ "${AFILETYPE}" = "py" ] || [ "${AFILETYPE}" = "python" ]; then
-		pyOutput
-	elif [ "${AFILETYPE}" = "pl" ] || [ "${AFILETYPE}" = "perl" ]; then
-		plOutput
-	elif [ "${AFILETYPE}" = "lua" ]; then
-		luaOutput
-	elif [ "${AFILETYPE}" = "php" ]; then
-		phpOutput
-	elif [ "${AFILETYPE}" = "ini" ]; then
-		iniOutput
-	elif [ "${AFILETYPE}" = "js" ]; then
-		jsOutput
-	elif [ "${AFILETYPE}" = "json" ]; then
-		jsonOutput
-	elif [ "${AFILETYPE}" = "java" ]; then
-		javaOutput
-	elif [ "${AFILETYPE}" = "javaprop" ]; then
-		javapropOutput
-	elif [ "${AFILETYPE}" = "csharp" ]; then
-		csharpOutput
-	elif [ "${AFILETYPE}" = "tex" ]; then
-		texOutput
-	elif [ "${AFILETYPE}" = "m4" ]; then
-		m4Output
-	elif [ "${AFILETYPE}" = "scheme" ]; then
-		schemeOutput
-	elif [ "${AFILETYPE}" = "clojure" ]; then
-		clojureOutput
-	elif [ "${AFILETYPE}" = "rpm" ]; then
-		rpmOutput
-	elif [ "${AFILETYPE}" = "hpp" ]; then
-		hppOutput
-	elif [ "${AFILETYPE}" = "matlab" ]; then
-		matlabOutput
-	elif [ "${AFILETYPE}" = "octave" ]; then
-		octaveOutput
-	elif [ "${AFILETYPE}" = "cmake" ]; then
-		cmakeOutput
-	else
-		echo "error: Not a valid output type." 1>&2
-		exit 1
-	fi
-fi
-
-
-# If requested, make a cache file.
-if [ ! -z "${CACHEFILE}" ] && [ ! "${CACHEFORCE}" = "1" ]; then
-	EXTRA_NAME="VCS_EXTRA"
-	shOutput > "${CACHEFILE}.tmp"
-
-	# Check to see if there have been any actual changes.
-	if [ ! -f "${CACHEFILE}" ]; then
-		mv -f "${CACHEFILE}.tmp" "${CACHEFILE}"
-	elif cmp -s "${CACHEFILE}.tmp" "${CACHEFILE}"; then
-		rm -f "${CACHEFILE}.tmp"
-	else
-		mv -f "${CACHEFILE}.tmp" "${CACHEFILE}"
-	fi
-fi


=====================================
wafhelpers/options.py
=====================================
--- a/wafhelpers/options.py
+++ b/wafhelpers/options.py
@@ -61,7 +61,7 @@ def options_cmd(ctx, config):
 
     grp = ctx.add_option_group("NTP developer configure options")
     grp.add_option('--build-version-tag', type='string',
-                   help="Append a tag to the version string.")
+                   help="Append a tag to the version string (unused)")
     grp.add_option('--cflags', type='string', action="callback",
                    callback=callback_flags,
                    help="Users should use CFLAGS in their environment.")


=====================================
wscript
=====================================
--- a/wscript
+++ b/wscript
@@ -1,7 +1,9 @@
 from __future__ import print_function
 
+from datetime import datetime
 import itertools
 import os
+import re
 import shlex
 import sys
 import time
@@ -199,24 +201,29 @@ def configure(ctx):
     if ctx.options.disable_manpage:
         ctx.env.DISABLE_MANPAGE = True
 
+    source_date_epoch = os.getenv('SOURCE_DATE_EPOCH', None)
+    if ctx.options.build_epoch is not None:
+        build_epoch = ctx.options.build_epoch
+        ctx.define("BUILD_EPOCH", build_epoch, comment="Using --build-epoch")
+    elif source_date_epoch:
+        if not source_date_epoch.isdigit():
+            ctx.fatal("ERROR: malformed SOURCE_DATE_EPOCH")
+        build_epoch = int(source_date_epoch)
+        ctx.define("BUILD_EPOCH", build_epoch, comment="Using SOURCE_DATE_EPOCH")
+    else:
+        build_epoch = int(time.time())
+        ctx.define("BUILD_EPOCH", build_epoch, comment="Using default")
+
+    build_epoch_formatted = datetime.utcfromtimestamp(build_epoch).strftime("%Y-%m-%dT%H:%M:%SZ")
     if ((os.path.exists(".git") and
             ctx.find_program("git", var="BIN_GIT", mandatory=False))):
-        ctx.start_msg("DEVEL: Getting revision")
-        cmd = shlex.split("git log -1 --format=%H")
-        ctx.env.NTPSEC_REVISION = ctx.cmd_and_log(cmd).strip()
-        ctx.end_msg(ctx.env.NTPSEC_REVISION)
-
-    ctx.start_msg("Building version")
-    ctx.env.NTPSEC_VERSION_STRING = ctx.env.NTPSEC_VERSION
-
-    if ctx.env.NTPSEC_REVISION:
-        ctx.env.NTPSEC_VERSION_STRING += "-%s" % ctx.env.NTPSEC_REVISION[:7]
-
-    if ctx.options.build_version_tag:
-        ctx.env.NTPSEC_VERSION_STRING += "-%s" % ctx.options.build_version_tag
+        cmd = ctx.env.BIN_GIT + shlex.split("log -1 --format=%h")
+        git_short_hash = ctx.cmd_and_log(cmd).strip()
 
-    ctx.define("NTPSEC_VERSION_STRING", ctx.env.NTPSEC_VERSION_STRING)
-    ctx.end_msg(ctx.env.NTPSEC_VERSION_STRING)
+        ctx.env.NTPSEC_VERSION += "+ %s (git rev %s)" % (build_epoch_formatted, git_short_hash)
+    else:
+        ctx.env.NTPSEC_VERSION += " %s" % build_epoch_formatted
+    ctx.define("NTPSEC_VERSION", ctx.env.NTPSEC_VERSION)
 
     # We require some things that C99 doesn't enable, like pthreads.
     # These flags get propagated to both the host and main parts of the build.
@@ -851,19 +858,6 @@ int main(int argc, char **argv) {
                 msg("WARNING: This system has a 32-bit time_t.")
                 msg("WARNING: Your ntpd will fail on 2038-01-19T03:14:07Z.")
 
-    source_date_epoch = os.getenv('SOURCE_DATE_EPOCH', None)
-    if ctx.options.build_epoch is not None:
-        ctx.define("BUILD_EPOCH", ctx.options.build_epoch,
-                   comment="Using --build-epoch")
-    elif source_date_epoch:
-        if not source_date_epoch.isdigit():
-            msg("ERROR: malformed SOURCE_DATE_EPOCH")
-            sys.exit(1)
-        ctx.define("BUILD_EPOCH", int(source_date_epoch),
-                   comment="Using SOURCE_DATE_EPOCH")
-    else:
-        ctx.define("BUILD_EPOCH", int(time.time()), comment="Using default")
-
     # before write_config()
     droproot_type = ""
     if ctx.is_defined("HAVE_LINUX_CAPABILITY"):
@@ -987,8 +981,6 @@ def afterparty(ctx):
     # Note that this setup is applied to the build tree, not the
     # source tree.  Only the build-tree copies of the programs are
     # expected to work.
-    if ctx.cmd == 'clean':
-        ctx.exec_command("rm -f ntpd/version.h ")
     for x in ("ntpclients", "tests/pylib",):
         # List used to be longer...
         path_build = ctx.bldnode.make_node("pylib")



View it on GitLab: https://gitlab.com/NTPsec/ntpsec/commit/7f83b7f0cdd9480160a9655c3319b8272fda024d

---
View it on GitLab: https://gitlab.com/NTPsec/ntpsec/commit/7f83b7f0cdd9480160a9655c3319b8272fda024d
You're receiving this email because of your account on gitlab.com.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.ntpsec.org/pipermail/vc/attachments/20180313/3107162b/attachment.html>


More information about the vc mailing list