#!/bin/sh -efu
#
# Copyright (C) 2006  Alexey Gladkov <legion@altlinux.org>
# Copyright (C) 2006  Dmitry V. Levin <ldv@altlinux.org>
#
# gear-release creates a release tag for the project.
#
# This file is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
#
# Example gear release tags:
#
# $ cat "$GIT_DIR/gear/release-tags"
# sisyphus
# master24
# rhel4
# fedora_5
#

. gear-sh-functions

show_help()
{
	cat <<EOF
Usage: $PROG [Options] <release-tag> <commit-ish>

The utility creates a release tag for the project.  It marks
specified tag or commit as "release" tag.  Release tag should be
listed it the gear tags file.  Default location of gear tags file
is \`\$GIT_DIR/gear/release-tags'.

<release-tag> - release tag name, names may be abbreviated.

<commit-ish> -  commit or tag object name.

Options:
  --sign[=<KEYID>]    make a GPG-signed release tag;
  --create[=TEXT]     create tag named \`<commit-ish>' before
                      release tag creation.  If TEXT is not empty
                      string, it will be used as tag message;
  -n,--pkgname=NAME   add project name to release tag message;
  -t,--tags=FILE      release tags file;
  -q,--quiet          try to be more quiet;
  -v,--verbose        print a message for each action;
  -V,--version        print program version and exit;
  -h,--help           show this text and exit.

Report bugs to http://bugs.altlinux.ru/

EOF
	exit
}

print_version()
{
	cat <<EOF
$PROG version $PROG_VERSION
Written by Alexey Gladkov <legion@altlinux.org>

Copyright (C) 2006  Alexey Gladkov <legion@altlinux.org>
Copyright (C) 2006  Dmitry V. Levin <ldv@altlinux.org>
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
EOF
	exit
}

TEMP=`getopt -n $PROG -o n:,t:,q,v,V,h -l create::,pkgname:,tags:,sign::,quiet,verbose,version,help -- "$@"` ||
	show_usage
eval set -- "$TEMP"

sign=-a
signkey=
tagsfile=
pkgname=
create_tag=
tag_msg=
while :; do
	case "$1" in
	    --create) shift; create_tag=1
		[ -z "$1" ] || tag_msg="$1"
		;;
	    --sign) shift; sign=-s
		if [ -n "$1" ]; then
		    sign=
		    signkey="$1"
		fi
		;;
	    -n|--pkgname) shift
		[ -z "$1" ] || pkgname="$1"
		;;
	    -t|--tags) shift
		[ ! -r "$1" ] || tagsfile="$1"
		;;
	    -q|--quiet) quiet=-q
		;;
	    -v|--verbose) verbose=-v
		;;
	    -V|--version) print_version
	    	;;
	    -h|--help) show_help
		;;
	    --) shift; break
		;;
	    *) fatal "unrecognized option: $1"
		;;
	esac
	shift
done

[ "$#" -ge 2 ] ||
	show_usage 'Not enough arguments.'
[ "$#" -eq 2 ] ||
	show_usage 'Too many arguments.'

GIT_DIR="$(git-rev-parse --git-dir)"
GIT_DIR="$(readlink -ev "$GIT_DIR")"
export GIT_DIR="$GIT_DIR"
[ -n "$tagsfile" ] || tagsfile="$GIT_DIR/gear/release-tags"
[ -e "$tagsfile" ] || { mkdir -p "${tagsfile%/*}" && >"$tagsfile"; }
[ -f "$tagsfile" ] || fatal "$tagsfile: file not available"
[ -s "$tagsfile" ] || fatal "$tagsfile: file is empty"

TAG=
rel="${1#tags/}"
while read n; do
	[ "$n" = "${n#\#}" ] || continue
	n="${n#tags/}"
	if [ "$n" != "${n#$rel}" ]; then
		[ -z "$TAG" ] || fatal "tag \'$TAG' is ambiguous"
		TAG="$n"
	fi
done < "$tagsfile"
[ -n "$TAG" ] || fatal "$1: tag should be listed in the \`$tagsfile'"
shift

COMMITISH="${1#tags/}" && shift

if [ -n "$create_tag" ]; then
	git-cat-file -t "$COMMITISH" >/dev/null 2>&1 &&
		fatal "'$COMMITISH' already exists" ||
		git-tag $sign ${signkey:+-u "$signkey"} -m "${tag_msg:-$COMMITISH}" "$COMMITISH"
fi
type="$(git-cat-file -t "$COMMITISH")"
case "$type" in
	tag|commit) ;;
	*) fatal "$type: Invalid commit-ish type" ;;
esac

git-tag $sign ${signkey:+-u "$signkey"} -f -m "${pkgname:+Package name: $pkgname
}Release $type: $COMMITISH" "$TAG" "$COMMITISH"
