xenocara/driver/xf86-video-radeonhd/git_version.sh
2007-12-04 22:20:01 +00:00

311 lines
8.3 KiB
Bash

#!/bin/sh
#
# Generate some basic versioning information which can be piped to a header.
#
# Copyright (c) 2006-2007 Luc Verhaegen <libv@skynet.be>
# Copyright (C) 2007 Hans Ulrich Niedermann <hun@n-dimensional.de>
#
# The author thanks the nice people on #git for the assistance!
#
# Simple testing of this script:
# /sbin/busybox sh git_version.sh --example > moo.c \
# && gcc -Wall -Wextra -Wno-unused -o moo moo.c \
# && ./moo
# (bash should also do)
# Help messages
USAGE="[<option>...]"
LONG_USAGE="\
Options:
-h, --help Print this help message.
-k, --keep-if-no-repo Keep old output file if no git repo found.
-o, --output FILENAME Set output file name.
-q, --quiet Quiet output.
-s, --srcdir DIRNAME Set source tree dir name.
-x, --example Print complete example program."
# The caller may have set these for us
SED="${SED-"sed"}"
# Initialize
working_dir="$(pwd)"
# Who am I?
self="$(basename "$0")"
# Defaults
ifndef_symbol="GIT_VERSION_H"
outfile="-"
print_example=false
keep_if_no_repo=no
quiet=false
srcdir="$(pwd)"
# Parse command line parameter, affecting defaults
while [ "x$1" != "x" ]
do
case "$1" in
-x|--example)
print_example=:
;;
-o|--output)
if shift; then
outfile="$1"
if [ "x$outfile" = "x-" ]; then
: # keep default ifndef_symbol
else
ifndef_symbol=`basename "$outfile" | $SED 's|\.|_|g; s|[^A-Za-z0-9_]||g' | tr a-z A-Z`
fi
else
echo "$self: Fatal: \"$1\" option requires parameter." >&2
exit 1
fi
;;
-q|--quiet)
quiet=:
;;
-h|--help)
echo "Usage: ${self} $USAGE"
[ -n "$LONG_USAGE" ] && echo "$LONG_USAGE"
exit
;;
-k|--keep-if-no-repo)
keep_if_no_repo=yes
;;
-s|--srcdir)
if shift; then
if test -d "$1"; then
srcdir="$1"
else
echo "$self: Fatal: \"$1\" not a directory." >&2
exit 1
fi
else
echo "$self: Fatal: \"$1\" option requires directory parameter." >&2
exit 1
fi
;;
*)
echo "$self: Fatal: Invalid command line paramenter: \"$1\"" >&2
exit 1
;;
esac
shift
done
# If not printing to stdout, redirect stdout to output file
rename_new_output=false
if [ "x$outfile" = "x-" ]
then
: # keep using stdout
else
exec 1> "${outfile}.new"
fi
# Done with creating output files, so we can change to source dir
cd "$srcdir"
# Write program header
cat<<EOF
/*
* Basic versioning gathered from the git repository.
* Automatically generated by $0.
*/
#ifndef ${ifndef_symbol}
#define ${ifndef_symbol} 1
/* whether this is a dist tarball or not */
#undef GIT_IS_DIST
EOF
# Detect git tools (should work with old and new git versions)
git_found=yes
for git_tool in git-symbolic-ref git-rev-parse git-diff-files git-diff-index git
do
if [ x`which $git_tool 2>/dev/null` = "x" ]; then
git_found="'$git_tool' not found"
break
fi
done
# Determine git specific defines
unset git_errors ||:
if [ "x$git_found" = "xyes" ]; then
git_version=`git --version`
if [ "x$git_version" = "x" ]; then
git_errors="${git_errors+"${git_errors}; "}error running 'git --version'"
fi
fi
git_repo=no
# "git-rev-parse --git-dir" since git-0.99.7
if [ "x$(git-rev-parse --git-dir 2> /dev/null)" != "x" ]; then
git_repo=yes
if [ "x$git_found" = "xyes" ]; then
# git-1.4 and probably earlier understand "git-rev-parse HEAD"
git_shaid=`git-rev-parse HEAD | $SED -n 's/^\(.\{8\}\).*/\1/p'`
if [ "x$git_shaid" = "x" ]; then
git_errors="${git_errors+"${git_errors}; "}error running 'git-rev-parse HEAD'"
fi
# git-1.4 and probably earlier understand "git-symbolic-ref HEAD"
git_branch=`git-symbolic-ref HEAD | $SED -n 's|^refs/heads/||p'`
if [ "x$git_branch" = "x" ]; then
# This happens, is OK, and "(no branch)" is what "git branch" prints.
git_branch="(no branch)"
fi
git_dirty=yes
# git-1.4 does not understand "git-diff-files --quiet"
# git-1.4 does not understand "git-diff-index --cached --quiet HEAD"
if [ "x$(git-diff-files)" = "x" ] && [ "x$(git-diff-index --cached HEAD)" = "x" ]; then
git_dirty=no
fi
fi
fi
# Write git specific defines
if [ "x$git_errors" = "x" ]; then
echo "/* No errors occured while running git */"
echo "#undef GIT_ERRORS"
else
echo "/* Some errors occured while running git */"
echo "#define GIT_ERRORS \"${git_errors}\""
fi
echo ""
if [ "x$git_found" = "xyes" ]; then
echo "/* git utilities found */"
echo "#undef GIT_NOT_FOUND"
echo "#define GIT_VERSION \"${git_version}\""
else
echo "/* git utilities not found */"
echo "#define GIT_NOT_FOUND \"${git_found}\""
echo "#undef GIT_VERSION"
fi
echo ""
if [ "x$git_repo" = "xno" ]; then
echo "/* No git repo found, probably building from dist tarball */"
echo "#undef GIT_REPO"
else
echo "/* git repo found */"
echo "#define GIT_REPO 1"
echo ""
if [ "x$git_found" = "xyes" ]; then
echo "/* Git SHA ID of last commit */"
echo "#define GIT_SHAID \"${git_shaid}\""
echo ""
echo "/* Branch this tree is on */"
echo "#define GIT_BRANCH \"$git_branch\""
echo ""
# Any uncommitted changes we should know about?
# Or technically: Are the working tree or index dirty?
if [ "x$git_dirty" = "xno" ]; then
echo "/* SHA-ID uniquely defines the state of this code */"
echo "#undef GIT_DIRTY"
else
echo "/* Local changes might be breaking things */"
echo "#define GIT_DIRTY 1"
fi
fi
fi
# Define a few immediately useful message strings
cat<<EOF
/* Define GIT_MESSAGE such that
* printf("%s: built from %s", argv[0], GIT_MESSAGE);
* forms a proper sentence.
*/
#ifdef GIT_DIRTY
# define GIT_DIRTY_MSG " + changes"
#else /* !GIT_DIRTY */
# define GIT_DIRTY_MSG ""
#endif /* GIT_DIRTY */
#ifdef GIT_ERRORS
# define GIT_ERROR_MSG " with error: " GIT_ERRORS
#else /* !GIT_ERRORS */
# define GIT_ERROR_MSG ""
#endif /* GIT_ERRORS */
#ifdef GIT_IS_DIST
# define GIT_DIST_MSG "dist of "
#else /* !GIT_IS_DIST */
# define GIT_DIST_MSG ""
#endif /* GIT_IS_DIST */
#ifdef GIT_REPO
# ifdef GIT_NOT_FOUND
# define GIT_MESSAGE GIT_DIST_MSG "git sources without git: " GIT_NOT_FOUND
# else /* !GIT_NOT_FOUND */
# define GIT_MESSAGE \\
GIT_DIST_MSG \\
"git branch " GIT_BRANCH ", " \\
"commit " GIT_SHAID GIT_DIRTY_MSG \\
GIT_ERROR_MSG
# endif /* GIT_NOT_FOUND */
#else /* !GIT_REPO */
# define GIT_MESSAGE GIT_DIST_MSG "non-git sources" GIT_ERROR_MSG
#endif /* GIT_REPO */
#endif /* ${ifndef_symbol} */
EOF
# Example program
if "$print_example"
then
cat<<EOF
/* example program demonstrating the use of git_version.sh output */
#include <stdio.h>
#include <string.h>
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
int main(int argc, char *argv[])
{
const char *const idx = strrchr(argv[0], '/');
const char *const prog = (idx)?(idx+1):(argv[0]);
#ifdef PACKAGE_VERSION
printf("%s: version %s, built from %s\n", prog, PACKAGE_VERSION, GIT_MESSAGE);
#elif defined(GIT_USED)
printf("%s: built from %s\n", prog, GIT_MESSAGE);
#endif
return 0;
}
EOF
fi
# Change back to working dir for the remaining output file manipulations.
cd "$working_dir"
# If necessary, overwrite outdated output file with new one
if [ "x$outfile" != "x-" ]
then
if [ -f "$outfile" ]; then
if [ "x$keep_if_no_repo" = "xyes" ] && [ "x$git_repo" = "xno" ]; then
"$quiet" || echo "$self: Not a git repo, keeping existing $outfile" >&2
rm -f "$outfile.new"
elif cmp "$outfile" "$outfile.new" > /dev/null; then
"$quiet" || echo "$self: Output is unchanged, keeping $outfile" >&2
rm -f "$outfile.new"
else
echo "$self: Output has changed, updating $outfile" >&2
mv -f "$outfile.new" "$outfile"
fi
else
echo "$self: Output is new file, creating $outfile" >&2
mv -f "$outfile.new" "$outfile"
fi
fi
# THE END.