autorevision-1.7/000755 000765 000024 00000000000 12247004042 014236 5ustar00dak180staff000000 000000 autorevision-1.7/AUTHORS000644 000765 000024 00000000402 12247004042 015302 0ustar00dak180staff000000 000000 dak180 Eric S. Raymond Dmitry Marakasov Mike Swanson Paul Wise Joel C. Salomon yuanchuan autorevision-1.7/autorevision.asciidoc000644 000765 000024 00000014163 12170067670 020505 0ustar00dak180staff000000 000000 = AUTOREVISION(1) = :doctype: manpage == NAME == autorevision - extract current-revision metadata from version-control repositories == SYNOPSIS == *`autorevision`* {*`-t`* `` | *`-s`* ``} [*`-o`* `` [*`-f`*] ] [*`-U`*] [*`-V`*] == DESCRIPTION == Extracts metadata about the head revision from your repository. This program is meant to be used by project build systems to extract properties that can be used in software version strings. It can emit source files containing variable and macro definitions suitable for use with C, C++, Java, sh, Python, Perl, Mac info.plist and other types of files (see below for the full list). The generated source is written to standard output. This program can normally be called from anywhere within a repository copy. Under bzr the copy must be of a branch, not a full multibranch repository. Under Subversion it must be called under a repository checkout, not the repository itself. If you specify a cache file, then when *autorevision* is run where no repository can be recognized, the values from the cache file will be used instead. If a repository can be recognized, the cache is rewritten. This feature makes it possible for your build to run from an unpacked tarball that includes the cache file. === Valid Repository Types === *Git*: A version greater than 1.7.2.3 is recommended. *Mercurial*: A version greater than 1.6 is recommended. *Subversion*: Any production version. *Bazaar*: Any production version. === Valid Output Types === *h*:: A header file suitable for C/C++. *xcode*:: A header like output for use with xcode to populate info.plist strings. *sh*:: A text file suitable for including from a bash script. Will work with Ruby. *py*:: A Python source file setting Python variables (*`python`* is an acceptable synonym). *pl*:: A Perl source file setting Perl variables (*`perl`* is an acceptable synonym). *lua*:: A lua source file setting lua variables. *php*:: A PHP source file setting PHP variables. *ini*:: A ini source file setting ini variables. *js*:: A javascript source file setting javascript variables. *json*:: A JSON format file. *java*:: A Java source file setting class properties. *javaprop*:: A Java properties file (like ini); useful when META-INF is readable in Java. *tex*:: A TeX source file defining TeX macros. Note that the symbols are given different names since the underscore has a special meaning in TeX. For example, VCS_SHORT_HASH is renamed to \vcsShortHash. *m4*:: An m4 source file defining m4 macros. === Valid Symbol Names === *VCS_TYPE*:: The repository type - "git", "hg", "bzr", or "svn". *VCS_BASENAME*:: The basename of the directory root. For most VCSes this will simply be the basename of the repository root directory. For Subversion, *autorevision* will navigate up though trunk, branches, and tags directories to find the actual root. *VCS_NUM*:: A count of revisions between the current one and the initial one; useful for reporting build numbers. *VCS_DATE*:: The date of the most recent commit in true ISO-8601/RFC3339 format, including seconds. *VCS_BRANCH*:: The name of the branch of the commit graph that was selected when autoversion was run. Under Subversion this will normally be either 'trunk' or the basename of some branch or tag subdirectory, depending on where *autoversion* was run. Under git, this will normally be the shortname of the current branch (the asterisked line in the output of of "git branch") except that when the branch doesn't have a shortname it will be a full refspec. Under hg the feature that is called 'branches' is actually a sort of graph coloring (multiple heads can have the same branch name) so this variable is filled with the current bookmark if it exists, with the current branch name as a fallback. Under bzr, this is the nick of the branch you are on. *VCS_TAG*:: The name of the most recent tag ancestral to the current commit. Empty under Subversion. *VCS_TICK*:: A count of commits since most recent tag ancestral to the current commit or an alias of *VCS_NUM* if there are no prior tags. + Empty under Subversion. *VCS_FULL_HASH*:: A full unique identifier for the current revision. *VCS_SHORT_HASH*:: A shortened version of VCS_FULL_HASH, but VCS_FULL_HASH if it cannot be shortened. *VCS_WC_MODIFIED*:: Set to `1` if the current working directory has been modified and `0` if not. 'Untracked files are not ignored; see *`-U`* for details.' If the output language is interpreted and has native Boolean literals, true will mean modified and false unmodified. The C/C++ output is left as numeric so the preprocessor can test it. == OPTIONS == *-t* '':: Sets the output type. It is required unless *`-s`* is specified; both *`-t`* and *`-s`* cannot be used in the same invocation. *-s* '':: Changes the reporting behavior; instead of emitting a symbol file to stdout, only the value of that individual symbol will be reported. It is required unless *`-t`* is specified; both *`-t`* and *`-s`* cannot be used in the same invocation. *-o* '':: Sets the name of the cache file. *-f*:: Forces the use cache data even when in a repo; useful if you want to preprocess the data before final output. *-U*:: Causes untracked files to be checked when determining if the working copy is modified 'for Subversion only'. While this is the default behavior for all other repository types it is off by default for Subversion because of speed concerns. *-V*:: Emits the autorevision version and exits. == BUGS == The bzr extractor is not very well tested as yet. When a git repo is actually a git-svn remote, this tool tries to do the right thing and return a Subversion revision. The bug is that the detector code for this case is somewhat unreliable; you will get the hash instead if your configuration doesn't use svn-remote.svn.url. Nested repositories, particularly repositories of different types, may result in incorrect and unintended behavior. == AUTHORS == dak180 : concept, bash/C/C++/XCode/PHP/ini support, git and hg extraction. Eric S. Raymond : Python/Perl/lua/m4 support, svn and bzr extraction, git-svn support, CLI design, man page. autorevision-1.7/autorevision.cache000644 000765 000024 00000000450 12247004021 017746 0ustar00dak180staff000000 000000 # Generated by autorevision - do not hand-hack! VCS_TYPE="git" VCS_BASENAME="autorevision" VCS_NUM=202 VCS_DATE="2013-12-01T23:07:07-0500" VCS_BRANCH="master" VCS_TAG="v/1.7" VCS_TICK=0 VCS_FULL_HASH="59ef15da409144148400a239e7874cb1f2e486ba" VCS_SHORT_HASH="59ef15d" VCS_WC_MODIFIED=0 # end autorevision-1.7/autorevision.sh000755 000765 000024 00000044433 12242666313 017346 0ustar00dak180staff000000 000000 #!/bin/sh # Copyright (c) 2012 - 2013 dak180 and contributors. See # http://opensource.org/licenses/mit-license.php or the included # COPYING.md for licence terms. # # autorevision - extracts metadata about the head version from your # repository. # Usage message. arUsage() { cat > "/dev/stderr" << EOF usage: ./autorevision {-t output-type | -s symbol} [-o cache-file [-f] ] [-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 -U = check for untracked files in svn -V = emit version and exit -? = help message The folowing are valid output types: h = Header for use with c/c++ xcode = Header useful for populating info.plist files sh = Bash sytax py = Python file pl = Perl file lua = Lua file php = PHP file ini = INI file js = javascript file json = JSON file java = Java file javaprop = Java properties file tex = (La)TeX file m4 = m4 file The following are valid symbols: VCS_TYPE VCS_BASENAME VCS_NUM VCS_DATE VCS_BRANCH VCS_TAG VCS_TICK VCS_FULL_HASH VCS_SHORT_HASH VCS_WC_MODIFIED EOF exit 1 } # Config ARVERSION="&&ARVERSION&&" TARGETFILE="/dev/stdout" while getopts ":t:o:s:VfU" OPTION; do case "${OPTION}" in t) AFILETYPE="${OPTARG}" ;; o) CACHEFILE="${OPTARG}" ;; f) CACHEFORCE="1" ;; s) VAROUT="${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 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 # Functions to extract data from different repo types. # For git repos gitRepo() { cd "$(git rev-parse --show-toplevel)" VCS_TYPE="git" VCS_BASENAME="$(basename "${PWD}")" # 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 HEAD 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 HEAD)" # The short hash VCS_SHORT_HASH="$(echo "${VCS_FULL_HASH}" | cut -b 1-7)" else # The git-svn revision number VCS_FULL_HASH="$(git svn find-rev HEAD)" 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 HEAD 2>/dev/null)" 2>/dev/null | sed -e 's:refs/heads/::' | sed -e 's:refs/::')" # Cache the description local DESCRIPTION="$(git describe --long --tags 2>/dev/null)" # Current or last tag ancestor (empty if no tags) VCS_TAG="$(echo "${DESCRIPTION}" | sed -e "s:-g${VCS_SHORT_HASH}\$::" | sed -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="$(git log -1 --pretty=format:%ci | sed -e 's: :T:' | sed -e 's: ::')" } # For hg repos hgRepo() { cd "$(hg root)" VCS_TYPE="hg" VCS_BASENAME="$(basename "${PWD}")" # 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=' --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:' | sed -e 's: ::')" } # For bzr repos bzrRepo() { cd "$(bzr root)" VCS_TYPE="bzr" VCS_BASENAME="$(basename "${PWD}")" # 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:' | sed -e 's: ::')" } # For svn repos svnRepo() { 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 fn="$(dirname "${fn}")" if [ "${fn}" = '/' ]; then VCS_BASENAME="$(basename "${PWD}")" else VCS_BASENAME="$(basename "${fn}")" fi ;; *) VCS_BASENAME="$(basename "${PWD}")" ;; esac # 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 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="" loacl 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 | sed -n -e 's:Last Changed Date\: ::p' | sed 's: (.*)::' | sed -e 's: :T:' | sed -e 's: ::')" } # Functions to output data in different formats. # For header output hOutput() { cat > "${TARGETFILE}" << EOF /* Generated by autorevision - do not hand-hack! */ #ifndef AUTOREVISION_H #define AUTOREVISION_H #define VCS_TYPE "${VCS_TYPE}" #define VCS_BASENAME "${VCS_BASENAME}" #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 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() { cat > "${TARGETFILE}" << EOF /* Generated by autorevision - do not hand-hack! */ #ifndef AUTOREVISION_H #define AUTOREVISION_H #define VCS_TYPE ${VCS_TYPE} #define VCS_BASENAME ${VCS_BASENAME} #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 VCS_FULL_HASH ${VCS_FULL_HASH} #define VCS_SHORT_HASH ${VCS_SHORT_HASH} #define VCS_WC_MODIFIED ${VCS_WC_MODIFIED} #endif /* end */ EOF } # For bash output shOutput() { cat > "${TARGETFILE}" << EOF # Generated by autorevision - do not hand-hack! VCS_TYPE="${VCS_TYPE}" VCS_BASENAME="${VCS_BASENAME}" VCS_NUM=${VCS_NUM} VCS_DATE="${VCS_DATE}" VCS_BRANCH="${VCS_BRANCH}" VCS_TAG="${VCS_TAG}" VCS_TICK=${VCS_TICK} VCS_FULL_HASH="${VCS_FULL_HASH}" VCS_SHORT_HASH="${VCS_SHORT_HASH}" VCS_WC_MODIFIED=${VCS_WC_MODIFIED} # end EOF } # For Python output pyOutput() { case "${VCS_WC_MODIFIED}" in 0) VCS_WC_MODIFIED="False" ;; 1) VCS_WC_MODIFIED="True" ;; esac cat > "${TARGETFILE}" << EOF # Generated by autorevision - do not hand-hack! VCS_TYPE = "${VCS_TYPE}" VCS_BASENAME = "${VCS_BASENAME}" VCS_NUM = ${VCS_NUM} VCS_DATE = "${VCS_DATE}" VCS_BRANCH = "${VCS_BRANCH}" VCS_TAG = "${VCS_TAG}" VCS_TICK = ${VCS_TICK} VCS_FULL_HASH = "${VCS_FULL_HASH}" VCS_SHORT_HASH = "${VCS_SHORT_HASH}" VCS_WC_MODIFIED = ${VCS_WC_MODIFIED} # end EOF } # For Perl output plOutput() { cat << EOF # Generated by autorevision - do not hand-hack! \$VCS_TYPE = "${VCS_TYPE}"; \$VCS_BASENAME = "${VCS_BASENAME}" \$VCS_NUM = ${VCS_NUM}; \$VCS_DATE = "${VCS_DATE}"; \$VCS_BRANCH = "${VCS_BRANCH}"; \$VCS_TAG = "${VCS_TAG}"; \$VCS_TICK = ${VCS_TICK}; \$VCS_FULL_HASH = "${VCS_FULL_HASH}"; \$VCS_SHORT_HASH = "${VCS_SHORT_HASH}"; \$VCS_WC_MODIFIED = ${VCS_WC_MODIFIED}; # end EOF } # For lua output luaOutput() { case "${VCS_WC_MODIFIED}" in 0) VCS_WC_MODIFIED="false" ;; 1) VCS_WC_MODIFIED="true" ;; esac cat > "${TARGETFILE}" << EOF -- Generated by autorevision - do not hand-hack! VCS_TYPE = "${VCS_TYPE}" VCS_BASENAME = "${VCS_BASENAME}" VCS_NUM = ${VCS_NUM} VCS_DATE = "${VCS_DATE}" VCS_BRANCH = "${VCS_BRANCH}" VCS_TAG = "${VCS_TAG}" VCS_TICK = ${VCS_TICK} 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 cat > "${TARGETFILE}" << EOF EOF } # For ini output iniOutput() { case "${VCS_WC_MODIFIED}" in 0) VCS_WC_MODIFIED="false" ;; 1) VCS_WC_MODIFIED="true" ;; esac cat > "${TARGETFILE}" << EOF ; Generated by autorevision - do not hand-hack! [VCS] VCS_TYPE = "${VCS_TYPE}" VCS_BASENAME = "${VCS_BASENAME}" VCS_NUM = ${VCS_NUM} VCS_DATE = "${VCS_DATE}" VCS_BRANCH = "${VCS_BRANCH}" VCS_TAG = "${VCS_TAG}" VCS_TICK = ${VCS_TICK} 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 cat > "${TARGETFILE}" << EOF /** Generated by autorevision - do not hand-hack! */ var autorevision = { VCS_TYPE: "${VCS_TYPE}", VCS_BASENAME: "${VCS_BASENAME}", VCS_NUM: ${VCS_NUM}, VCS_DATE: "${VCS_DATE}", VCS_BRANCH: "${VCS_BRANCH}", VCS_TAG: "${VCS_TAG}", VCS_TICK: ${VCS_TICK}, 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 cat > "${TARGETFILE}" << EOF { "VCS_TYPE": "${VCS_TYPE}", "VCS_BASENAME": "${VCS_BASENAME}", "VCS_NUM": ${VCS_NUM}, "VCS_DATE": "${VCS_DATE}", "VCS_BRANCH":"${VCS_BRANCH}", "VCS_TAG": "${VCS_TAG}", "VCS_TICK": ${VCS_TICK}, "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 cat > "${TARGETFILE}" << EOF /* Generated by autorevision - do not hand-hack! */ import java.util.Date; public class autorevision { public static final String VCS_TYPE = "${VCS_TYPE}"; public static final String VCS_BASENAME = "${VCS_BASENAME}"; 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 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 } # For Java properties output javapropOutput() { case "${VCS_WC_MODIFIED}" in 1) VCS_WC_MODIFIED="true" ;; 0) VCS_WC_MODIFIED="false" ;; esac cat > "${TARGETFILE}" << EOF # Generated by autorevision - do not hand-hack! VCS_TYPE=${VCS_TYPE} VCS_BASENAME=${VCS_BASENAME} VCS_NUM=${VCS_NUM} VCS_DATE=${VCS_DATE} VCS_BRANCH=${VCS_BRANCH} VCS_TAG=${VCS_TAG} VCS_TICK=${VCS_TICK} VCS_FULL_HASH=${VCS_FULL_HASH} VCS_SHORT_HASH=${VCS_SHORT_HASH} VCS_WC_MODIFIED=${VCS_WC_MODIFIED} EOF } # For m4 output m4Output() { cat > "${TARGETFILE}" << EOF define(\`VCS_TYPE', \`${VCS_TYPE}')dnl define(\`VCS_BASENAME', \`${VCS_BASENAME}')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(\`VCS_FULLHASH', \`${VCS_FULL_HASH}')dnl define(\`VCS_SHIRTHASH', \`${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 cat > "${TARGETFILE}" << EOF % Generated by autorevision - do not hand-hack! \def \vcsType {${VCS_TYPE}} \def \vcsBasename {${VCS_BASENAME}} \def \vcsNum {${VCS_NUM}} \def \vcsDate {${VCS_DATE}} \def \vcsBranch {${VCS_BRANCH}} \def \vcsTag {${VCS_TAG}} \def \vcsTick {${VCS_TICK}} \def \vcsFullHash {${VCS_FULL_HASH}} \def \vcsShortHash {${VCS_SHORT_HASH}} \def \vcsWCModified {${VCS_WC_MODIFIED}} \endinput EOF } # Detect and collect repo data. if [ -f "${CACHEFILE}" ] && [ "${CACHEFORCE}" = "1" ]; then # When requested only read from the cache to populate our symbols. . "${CACHEFILE}" elif [ ! -z "$(git rev-parse HEAD 2>/dev/null)" ]; then gitRepo elif [ ! -z "$(hg root 2>/dev/null)" ]; then hgRepo elif [ ! -z "$(bzr root 2>/dev/null)" ]; then bzrRepo elif [ ! -z "$(svn info 2>/dev/null)" ]; then svnRepo elif [ -f "${CACHEFILE}" ]; 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" else echo "error: No repo or cache detected." 1>&2 exit 1 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}" 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}" = "h" ]; then hOutput elif [ "${AFILETYPE}" = "xcode" ]; then xcodeOutput 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}" = "tex" ]; then texOutput elif [ "${AFILETYPE}" = "m4" ]; then m4Output 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 TARGETFILE="${CACHEFILE}" shOutput fi autorevision-1.7/CONTRIBUTING.md000644 000765 000024 00000003577 12101254050 016476 0ustar00dak180staff000000 000000 Things to Keep in Mind ====================== Support For New Repo Types -------------------------- When supporting new types of repos you should set all of the currently used symbols and document how they are populated. Support for new repos should include a function named in the form `Repo` and a two part test: the first part should try to detect the presence of a repo without using any of the native repository commands, the second test should test for the presence the native repository commands, ideally by determining the full path to the top level of the repo. Generally you *should* assume that you are executing from the top of the repo. The first thing that any repo function should do is `cd` to the root level of the repository, if possible. As a rule of thumb, try to use commands to gather the data to populate the symbols in such a way as to require the least amount of post processing by things like `sed` or `grep`. Support For New Output Types ---------------------------- When supporting new types of outputs you *should* use all of the currently set symbols; if you do not, that needs to be explicitly documented. Support for new outputs should include a function named in the form `Output`; find one that's similar to your target language, clone it, and modify it. Make sure that you commit an example of the output into the `example` directory. Other Conventions ----------------- * Do not forget to update the documentation. * You generally should *not* assume that any extras, extensions or otherwise non-default commands are available. * Any use of `sed` *should* use `:` as a delimiter whenever feasible. * All variables should be written in the form `"${}"`. * All error messages should be prefixed with `error: `. * All warning messages should be prefixed with `warning: `. * Try to avoid stderr output from any subcommand leaking through. autorevision-1.7/control000644 000765 000024 00000001636 12247002603 015650 0ustar00dak180staff000000 000000 # This is not a real Debian control file, though the syntax is compatible. # It's project metadata for the shipper tool Package: autorevision Description: Extracts metadata about the current revision from your repository. This program is meant to be used by project build systems to extract properties that can be used in software version strings. Repository types supported include git, hg, bzr, and svn. It can create files containing variable and macro definitions suitable for C, C++, Java, sh, Python, Perl, PHP, lua, Javascript, and header files suitable for use with preprocessing Info.plist files. XBS-Github-URL: https://github.com/Autorevision/autorevision XBS-Ohloh-URL: http://www.ohloh.net/p/autorevision XBS-Destinations: freecode Homepage: http://www.catb.org/esr/autorevision XBS-HTML-Target: index.html XBS-Freecode-Tags: svn git hg perl python c c++ bash build_tools XBS-VC-Tag-Template: v/%s autorevision-1.7/COPYING.md000644 000765 000024 00000002040 12170072752 015674 0ustar00dak180staff000000 000000 Copyright (c) 2012 -2013 dak180 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. autorevision-1.7/Makefile000644 000765 000024 00000004733 12247002725 015713 0ustar00dak180staff000000 000000 # Makefile for the autorevision project # `a2x / asciidoc` is required to generate the Man page. # `markdown` is required for the `docs` target, though it is not # strictly necessary for packaging. # `shipper` is required for the `release` target, which should only be # used if you are shipping tarballs (you probably are not). # Get the version number VERS := $(shell ./autorevision.sh -s VCS_TAG -o ./autorevision.cache | sed -e 's:v/::') .SUFFIXES: .md .html .md.html: markdown $< > $@ # `prefix`, `mandir` & `DESTDIR` can and should be set on the command line to control installation locations prefix ?= /usr/local mandir ?= /share/man target = $(DESTDIR)$(prefix) DOCS = \ NEWS \ autorevision.asciidoc \ README.md \ CONTRIBUTING.md \ COPYING.md SOURCES = \ $(DOCS) \ autorevision.sh \ Makefile \ control EXTRA_DIST = \ AUTHORS \ autorevision.cache all : cmd man # The script cmd: autorevision autorevision: autorevision.sh sed -e 's:&&ARVERSION&&:$(VERS):g' autorevision.sh > autorevision chmod +x autorevision # The Man Page man: autorevision.1 autorevision.1: autorevision.asciidoc a2x -f manpage autorevision.asciidoc # HTML representation of the man page autorevision.html: autorevision.asciidoc asciidoc --doctype=manpage --backend=xhtml11 autorevision.asciidoc # The tarball dist: autorevision-$(VERS).tgz autorevision-$(VERS).tgz: $(SOURCES) cmd man git log --format='%aN <%aE>' | awk '{arr[$$0]++} END{for (i in arr){print arr[i], i;}}' | sort -rn | cut -d\ -f2- > AUTHORS mkdir autorevision-$(VERS) cp -pR $(SOURCES) $(EXTRA_DIST) autorevision-$(VERS)/ @COPYFILE_DISABLE=1 tar -czf autorevision-$(VERS).tgz autorevision-$(VERS) rm -fr autorevision-$(VERS) install: cmd man install -d "$(target)/bin" install -m 755 autorevision "$(target)/bin/autorevision" install -d "$(target)$(mandir)/man1" gzip --no-name < autorevision.1 > "$(target)$(mandir)/man1/autorevision.1.gz" uninstall: rm -f "$(target)/bin/autorevision" "$(target)$(mandir)/man1/autorevision.1.gz" clean: rm -f autorevision autorevision.html autorevision.1 *.tgz rm -f docbook-xsl.css rm -f AUTHORS rm -f CONTRIBUTING.html COPYING.html README.html rm -f *~ index.html # Not safe to run in a tarball devclean: clean rm -f autorevision.cache # HTML versions of doc files suitable for use on a website docs: \ autorevision.html \ README.html \ CONTRIBUTING.html \ COPYING.html # Tag with `git tag -s v/` before running this. release: docs dist shipper version=$(VERS) | sh -e -x autorevision-1.7/NEWS000644 000765 000024 00000001636 12247003425 014747 0ustar00dak180staff000000 000000 autorevision history 1.7 @ 2013-12-01 Autogenerate the AUTHORS file. Do not set change empty CACHEFILE to `./`. Make sure the -U option works properly. 1.6 @ 2013-08-28 Use autorevision in autorevision. Ensure that the cache path is one that can be sourced. Add an AUTHORS file. 1.5 @ 2013-08-12 Add support for git-svn - gives back the Subversion revision, not the hash. Add a -U to check for unversioned files in svn. 1.4 @ 2013-01-18 Remove bashisms. Add "python" and "perl" language synonyms. Add m4. Work around unreliable return value of git diff in 1.7.9.5. 1.3 @ 2012-12-09 (La)TeX output support added. 1.2 @ 2012-10-30 Bazaar extractor added. autorevision can now usually be called safely from subdirectories. Drop back to numeric VCS_WC_MODIFIED so the C processor can use it. 1.1 @ 2012-10-28 Java and Java properties support added. 1.0 @ 2012-10-25 Initial release. autorevision-1.7/README.md000644 000765 000024 00000001375 12043467414 015535 0ustar00dak180staff000000 000000 Autorevision ============ A program for extracting version information useful in release/build scripting from repositories. Supported repository types include `git`, `hg`, `bzr`, and `svn`. The record can be emitted in a ready-to-use form for `C`, `C++`, `Java`, `bash`, `Python`, `Perl`, `lua`, `php`, `ini` and others. Emitted information includes the ID of the most recent commit, its branch, its date, and several other useful pieces of meta-information. There is support for reading and writing a cache file so autorevision will remain useful during a build from an unpacked distribution tarball. See the [manual page](https://github.com/Autorevision/autorevision/blob/master/autorevision.asciidoc), included in the distribution, for invocation details.