#!/usr/bin/env bash
#
# Mark certain commit by a tag.
# Copyright (c) Petr Baudis, 2005
#
# Creates a tag referencing the given commit (or 'HEAD'). You can then
# use the tag anywhere you specify a commit or tree ID.
#
# cg-tag will try to sign the tag if you give it the -s option.
# You can override the default key choice by passing it the -k argument.
#
# Takes the tag name and optionally the associated ID as arguments.
#
# OPTIONS
# -------
# -d DESCRIPTION::
#	Append this text to the tag object before signing it.
# -k KEYNAME::
#	Use the given key to sign the tag, instead of the default one.
# -s::
#	Sign the tag by your private key using GPG.

USAGE="cg-tag [-s [-d DESCRIPTION] [-k KEYNAME]] TAG_NAME [COMMIT_ID]"

. ${COGITO_LIB:-/usr/lib/cogito/}cg-Xlib

sign=
keyname=
description=
while optparse; do
	if optparse -s; then
		sign=1
	elif optparse -k=; then
		keyname="$OPTARG"
	elif optparse -d=; then
		description="$OPTARG"
	else
		optfail
	fi
done

name="${ARGS[0]}"
id="${ARGS[1]}"

[ "$name" ] || usage
[ "$id" ] || id=$(commit-id) || exit 1

(echo $name | egrep -qv '[^a-zA-Z0-9_.@!:-]') || \
	die "name contains invalid characters"

mkdir -p $_git/refs/tags

[ -s "$_git/refs/tags/$name" ] && die "tag already exists ($name)"
[ "$id" ] || id=$(cat $_git/HEAD)


if [ "$sign" ]; then
	tagdir="$(mktemp -d -t gittag.XXXXXX)"

	cat <<SIGEND >"$tagdir/tag"
object $id
type commit
tag $name
tagger $(git-var GIT_COMMITTER_IDENT)

SIGEND
	if [ "$description" ]; then
		echo "$description" >>"$tagdir/tag"
		echo >>"$tagdir/tag"
	fi
	if ! gpg ${keyname:+--default-key "$keyname"} -bsa "$tagdir/tag"; then
		rm -rf "$tagdir"
		die "error signing the tag"
	fi
	cat "$tagdir/tag.asc" >>"$tagdir/tag"
	if ! git-mktag <"$tagdir/tag" >$_git/refs/tags/$name; then
		rm -rf "$tagdir"
		die "error creating tag"
	fi

	rm -rf "$tagdir"
else
	echo "$id" >$_git/refs/tags/$name
fi
