#!/bin/sh
# sunrise-commit -- a helper script for Sunrise commiters.
# (c) 2010 Michał Górny <gentoo@mgorny.alt.pl>
# Released under the terms of the 3-clause BSD license.

# Few output helpers.
die() {
	echo "${@}" >&2
	exit 1
}

sayv() {
	[ -n "${SC_VERBOSE}" ] && echo "${@}" >&2
}

req() {
	"$@" || die "$@ failed."
}

# POSIX compat.
local_supported() {
	local test 2>/dev/null
}

local_supported || eval 'local() {
	unset ${@}
}'

# See if we're in a repo, and what VCS are we using.
find_repo() {
	svn info >/dev/null 2>&1

	if [ ${?} -eq 0 ]; then
		SC_VCS=svn
	else
		local remotes
		remotes=$(git branch -r 2>/dev/null)

		if [ ${?} -ne 127 -a ${?} -ne 128 ]; then
			echo "${remotes}" | grep git-svn >/dev/null 2>&1
			if [ ${?} -eq 0 ]; then
				SC_VCS=git-svn
			else
				SC_VCS=git
			fi
		else
			die 'Unable to find any familiar repository type (are you inside the repo?).'
		fi
	fi

	if [ ${SC_VCS} = svn ]; then
		die 'Native subversion repositories are not supported at the moment.'
	fi

	sayv "Ok, we're in ${SC_VCS} working tree. Let's see what I can do around here..."
}

# Look around for ebuilds.
find_ebuilds() {
	# POSIX is fun -- look for ebuilds in the current directory.
	if [ -n "$(find \( -name '*.ebuild' -print -o ! -name '.' -prune \))" ]; then
		local stripped

		# Get CATEGORY and PN.
		stripped=${PWD%/*}
		stripped=${stripped%/*}
		SC_CP=${PWD#${stripped}/}

		SC_SCENARIO=ebuild-commit
		sayv "We have some ebuilds for ${SC_CP} here."
	else
		die 'No familar situation found -- no ebuilds here.'
	fi
}

# VCS helpers.
check_for_changes() {
	local output

	if [ ${SC_VCS%-svn} = git ]; then
		output="$(git diff-index --name-only --relative HEAD)"
	fi

	# We do not care about user mangling ChangeLog, we will reset it anyway.
	echo "${output}" | grep -v ChangeLog >/dev/null
}

vcs_reset() {
	if [ ${SC_VCS%-svn} = git ]; then
		req git reset -q HEAD "${1}"
		req git checkout -f "${1}"
	fi
}

vcs_status() {
	if [ ${SC_VCS%-svn} = git ]; then
		git status -s .
	fi
}

# Guess what!
main() {
	local commitmsg
	unset SC_VERBOSE

	while [ ${#} -gt 0 ]; do
		case "${1}" in
			-v|--verbose)
				SC_VERBOSE=1
				;;
			--)
				shift
				commitmsg="${commitmsg+${commitmsg} }${@}"
				break
				;;
			*)
				commitmsg="${commitmsg+${commitmsg} }${1}"
				;;
		esac
		shift
	done

	[ -n "${commitmsg}" ] || die 'No commit message provided.'

	find_repo
	find_ebuilds

	case ${SC_SCENARIO} in
		ebuild-commit)
			check_for_changes || die 'No changes found to commit.'

			# With native git repos, we do not do ChangeLogs by default...
			# ...at least unless they're already there.
			if [ ${SC_VCS} != git -o -f ChangeLog ]; then
				sayv 'Cleaning up the ChangeLog...'
				vcs_reset ChangeLog

				local bns
				# Let's take a lucky guess bugnumbers consist of 4+ digits.
				bns="$(echo "${commitmsg}" | grep -o -E '[0-9]{4,}')"

				# Creating a new ChangeLog? Let's take a look at the commit message.
				[ ! -f ChangeLog -a -z "${bns}" ] && die 'Please supply the bug number in the initial commit message!'

				sayv '...and appending to it.'
				req echangelog "${commitmsg}"

				if [ -n "${bns}" ]; then
					echo
					local bn
					for bn in ${bns}; do
						wget -q http://bugs.gentoo.org/show_bug.cgi?id=12345 -O - \
							| sed -e 's; *<title>Gentoo Bug \([0-9]*\) - \(.*\)</title>;Bug \1: \2;gp' -e d 
					done
					echo
				fi
			fi

			vcs_status
			echo

			sayv "Now, let's let repoman do its job..."
			exec repoman commit -a -m "${SC_CP}: ${commitmsg}"
			;;
	esac
}

main "${@}"