#!/bin/bash
# 2006-2008 Etersoft www.etersoft.ru
# Author: Vitaly Lipatov <lav@etersoft.ru>
# Public domain

get_var()
{
	grep -i "^$1:" | head -n 1 | sed -e "s/^[^:]*[ \t]*:[ \t]*//"

}

# FIXME: only ALT handled rpm -bE
# Раскрывает макросы в спеке и выводит на стандартный вывод
eval_spec()
{
	# TODO: use rpm -showrc instead -bE for get main variables?

	# Hack: just print spec if -bE failed
	if is_alt ; then
		# on ALT we have to done without errors
		$RPMBUILD -bE --target $SYSARCH $RPMBUILDARG $@ || fatal "Check spec's fields"
	else
		$RPMBUILD -bE --target $SYSARCH $RPMBUILDARG $@ 2>/dev/null || cat $1
	fi
}

get_release()
{
	eval_spec $1 | get_var "Release"
}

# get 11 from alt11, 12.1 from alt12.1t
get_numrelease()
{
	get_release "$1" | sed -e "s|\([a-zA-Z]*\)\([0-9\.]\)[^0-9\.]*|\2|" || echo "0"
}

# get alt from alt11
get_txtrelease()
{
	get_release "$1" | sed -e "s|\([a-zA-Z]*\)\([0-9\.]\).*|\1|" || echo "$RELEASEPREFIX"
}

set_var()
{
	subst "s|\($2:\).*\$|\1 $3|" $1
}

set_release()
{
	local RELEASE=$2
	[ -n "$RELEASE" ] || RELEASE="${RELEASEPREFIX}1"
	set_var $1 Release $RELEASE
}

# inc 2 release to 3
inc_release()
{
	local BASERELEASE=$(get_numrelease "$1")
	local MAJOR=`echo "$BASERELEASE" | sed -e "s|\..*||"`
	set_release "$1" $(get_txtrelease "$1")$(($MAJOR + 1 ))
}

# inc 2.x to 2.(x+1) or 2 to 2.1
inc_subrelease()
{
	local BASERELEASE=$(get_numrelease $1)
	local MAJOR=`echo "$BASERELEASE" | sed -e "s|\..*||"`
	local MINOR=`echo "$BASERELEASE" | sed -e "s|.*\.||"`
	[ "$MINOR" = "$BASERELEASE" ] && MINOR="0"
	set_release "$1" "$(get_txtrelease $1)${MAJOR}.$(($MINOR + 1 ))"
}

get_name()
{
	eval_spec $1 | get_var "Name"
}

get_version()
{
	eval_spec $1 | get_var "Version"
}

get_tarballname()
{
	local SOURCE=$(eval_spec $1 | get_var "Source$2")
	basename $(basename $SOURCE | sed -e "s|-$(get_version $1).*||g") .tar
}


# Set version for spec (args: spec version), f.i. test.spec 1.2.3)
# Supports %major and %ver_major macros in spec
# версия может быть указана как 2.6.1 (полная), 2.6 (major) или .1 (minor)
set_version()
{
	local SPEC=$1
	local VER=$2

	if [ -z "$SPEC" ] ; then
		return 1
	fi

	if [ -z "$VER" ] ; then
		return 2
	fi

	VERMAJOR=`echo $VER | sed -e "s|\([0-9]*\.[0-9]*\)\..*|\1|"`
	VERMINOR=`echo $VER | sed -e "s|^[0-9]*\.[0-9]*||;s|^\.||"`
	if [ -z ${VER/.*/} ] ; then
		VERMAJOR=
	fi

	MAJORMACROS=`grep "\%define[[:space:]]\(\|ver_\)major" $SPEC | sed -e "s|.*[[:space:]]\(.*major\).*|\1|"`
	if [ -n "${MAJORMACROS}" ] ; then
		# Change major define
		test -n "$VERMAJOR" && subst "s|\(\%define[[:space:]]$MAJORMACROS[[:space:]]\).*|\1$VERMAJOR|" $SPEC
		# Change version if VERMINOR is defined
		if [ -n "$VERMINOR" ] ; then
			set_var $SPEC Version %$MAJORMACROS.$VERMINOR || fatal "Error 1 with set version to spec"
		else
			set_var $SPEC Version %$MAJORMACROS || fatal "Error 2 with set version to spec"
		fi
	else
		set_var $SPEC Version $VER || fatal "Error 3 with set version to spec"
	fi
}

inc_version()
{
	local VER=$(get_version "$1")
	# fixme: more general and use in other functions (see increment_release test)
	local MAJOR=`echo "$VER" | sed -e "s|\.[0-9]*$||"`
	local MINOR=`echo "$VER" | sed -e "s|.*\.||"`
	[ "$MINOR" = "$VER" ] && MINOR="0"
	VER="${MAJOR}.$(($MINOR + 1 ))"
	set_version "$1" $VER
}

# decrement release with workaround about non textual release
decrement_release()
{
	local NUMPART=$(echo $1 | sed -e "s|[^0-9].*||g")
	[ -n "$NUMPART" ] || NUMPART=1
	[ "$NUMPART" = "0" ] && NUMPART=1
	echo $(($NUMPART - 1))
}

subst_namever()
{
	sed -e "s|%{name}|$BASENAME|g
			s|%{version}|$VERSION|g
			s|%name|$BASENAME|g
			s|%version|$VERSION|g"
}


add_changelog_helper()
{
	# it is permitted to run with "" DESC
	local DESC="$1"
	shift
	local SPECS="$*"
	if ! tty -s && [ -z "$DESC" ] ; then
		echo "skip changelog fixing without tty"
		return 1
	fi
	[ -z "$SPECS" ] && fatal "run add_changelog with incorrect args"
	add_changelog -e "$DESC" $SPECS
	R=$?
	[ -z "$EDITOR" ] && { echo "skip changelog editing without EDITOR var"; return 1 ; }
	# If changelog sucessfully added
	if [ "$R" = "0" ]; then
		local SPEC
		for SPEC in $SPECS ; do
			N=`grep -n '^%changelog' $SPEC | head -n 1 | sed s!:.*!!g`
			# +1 -- comment with date and packager name
			# +2 -- place for edit comments
			# +N works for mcedit and vi
			${EDITOR} +$(($N + 2)) $SPEC
		done
	fi
	return $R
}


# set specdir by spec (run with full path to spec only or in spec dir)
set_specdir()
{
	SPECDIR=.
	# get dir from the first spec
	if [ -r "$1" ] ; then
		SPECDIR=`dirname $1`
	fi
	# if spec has no full path, guess from pwd
	if [ "$SPECDIR" = "." ] ; then
		SPECDIR=`pwd`
	fi
}

get_gear_rule_spec()
{
	local SPEC="$(grep "^spec:" $(get_root_git_dir)/.gear/rules 2>/dev/null | cut -d" " -f2)"
	test -r "$(get_root_git_dir)/$SPEC" && echo $(get_root_git_dir)/$SPEC
}

# search for gear spec
get_gear_spec()
{
        local trySpec=""
        # check locally only if in gear repo
        is_gear && trySpec=$(echo *.spec)
        # if not in local dir, check spec in git root dir
        [ -f "$trySpec" ] || trySpec=`echo $(get_root_git_dir)/*.spec`
        [ -f "$trySpec" ] || trySpec=$(get_gear_rule_spec)
        # printout nothing if can't get spec
        [ -f "$trySpec" ] || trySpec=""
        echo $trySpec
        test -f "$trySpec"
}
