#!/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::
#	Description of the tag.
# -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.
# OBJECT_ID::
#	This is most usually the ID of the commit to tag. Tagging
#	other objects than commits is possible, but rather "unusual".

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

. ${COGITO_LIB}cg-Xlib || exit 1

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=$(cg-object-id -n "$id") || exit 1
type=$(git-cat-file -t "$id")
id=${id% *}

(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/$(git-symbolic-ref HEAD)")"


tagdir="$(mktemp -d -t gittag.XXXXXX)"

cat <<SIGEND >"$tagdir/tag"
object $id
type $type
tag $name
tagger $(git-var GIT_COMMITTER_IDENT)
SIGEND
if [ "$description" ]; then
	echo >>"$tagdir/tag"
	echo "$description" >>"$tagdir/tag"
fi
if [ "$sign" ]; then
	echo >>"$tagdir/tag"
	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"
fi
if ! git-mktag <"$tagdir/tag" >$_git/refs/tags/$name; then
	rm -rf "$tagdir"
	die "error creating tag"
fi

rm -rf "$tagdir"
