#!/bin/sh
# 2010, 2012, 2013, 2014, 2018 (c) Etersoft http://etersoft.ru
# Author: Vitaly Lipatov <lav@etersoft.ru>

# Script for update changelog or increment release

# load common functions, compatible with local and installed script
. `dirname $0`/../share/eterbuild/functions/common

load_mod spec rpm git etersoft spec

if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
	echog "rpmlog - update version/release and changelog"
	echog "Usage: rpmlog [-q] [-a|-r|-s|-v] [-l|-t] [-e [changelog entry]] [SPEC] [fromTAG] [toTAG]"
	echo
	echog "Options:"
	echog "   -a  increment version if code is changed or increment release if spec changed only"
	echog "   -v  increment version"
	echog "   -r  increment release"
	echog "   -s  increment subrelease"
	echog "   -l  add changelog from git log (since last release tag or TAG)"
	echog "   -e  add (empty) changelog entry"
	echo
	echog "Ext. options:"
	echog "   -t  test run (without change files and repo)"
	echog "   -o  print git log since last release tag or TAG"
	echog "   -q  quiet mode (do not ask anything)"
	echog "   -n VERSION  set version and reset release"
	echo
	echog "   --last-version    show current version of build"
	echog "   --last-changelog  show changelog the latest build"
	echo
	echog "Example:"
	echog "   $ rpmlog -v -l             - typical build new version"
	echog "   $ rpmlog -r -l HEAD~2      - build new version with last two commit message as changelog"
	echog "   $ rpmlog -r -e             - prepare new version build with empty changelog entry"
	echog "   $ rpmlog -r -e 'new build' - prepare new version build with changelog entry 'new build'"
	exit 0
fi

is_gear || fatal "rpmlog usable only with gear repo"

# TODO: rewrite option parsing

QUIET=
if [ "$1" = "-q" ] ; then
	QUIET=$1
	shift
fi

INCREMENTMODE=""
if [ "$1" = "-r" ] || [ "$1" = "-s" ] || [ "$1" = "-v" ] || [ "$1" = "-a" ] ; then
	INCREMENTMODE=$1
	shift
fi

if [ "$1" = "-n" ] ; then
	INCREMENTMODE=$1
	shift
	FORCEVERSION=$1
	shift
fi

CHANGELOGUPDATE=
if [ "$1" = "-l" ] ; then
	CHANGELOGUPDATE=$1
	shift
fi

CHANGELOGADD=
if [ "$1" = "-e" ] ; then
	CHANGELOGADD=$1
	shift
	TEXTMESSAGE="$@"
fi

TESTRUN=
if [ "$1" = "-t" ] ; then
	TESTRUN=$1
	shift
fi

GITLOG=
if [ "$1" = "-o" ] ; then
	GITLOG=$1
	shift
fi

LASTVERCMD=
if [ "$1" = "--last-version" ] ; then
    LASTVERCMD=1
    shift
fi

LASTCHANGELOGCMD=
if [ "$1" = "--last-changelog" ] ; then
    LASTCHANGELOGCMD=1
    shift
fi

if [ -n "${1/*.spec/}" ] || [ -z "$1" ] ; then
	SPECNAME=$(get_gear_spec)
	[ -z "$QUIET" ] && echo "Using autodetected spec $SPECNAME..."
else
	SPECNAME=$1
	shift
fi

FROMTAG=
if [ -n "$1" ] ; then
	FROMTAG="$1"
	shift
fi

TOTAG=HEAD
if [ -n "$1" ] ; then
	TOTAG="$1"
	shift
fi

if [ ! -r "$SPECNAME" ] ; then
	fatal "Spec $SPECNAME does not found"
fi

if [ -n "$LASTVERCMD" ] ; then
    echo $(get_version $SPECNAME)-$(get_release $SPECNAME)
    exit $?
fi

if [ -n "$LASTCHANGELOGCMD" ] ; then
    get_last_changelog $SPECNAME
    exit $?
fi

[ -n "$CHANGELOGADD$CHANGELOGUPDATE$TESTRUN$GITLOG" ] || fatal "Run with -t param for test or with -h for help"

if [ -z "$FROMTAG" ] ; then
	build_rpms_name $SPECNAME
	[ -n "$VERSION" ] || fatal "Can't get package version"
	[ -n "$RELEASE" ] || fatal "Can't get package release"
	FROMTAG="$VERSION-$RELEASE"
	# FIXME: if don't exists, use last tag?
fi

if [ -z "$CHANGELOGADD" ] && is_last_commit_tag ; then
	echo "There is no new commits after $(get_last_tag)"
	exit 0
fi

if [ -n "$GITLOG" ] ; then
	git log $FROMTAG..$TOTAG --reverse --no-merges --pretty="%H %s"
	exit
fi

if [ -n "$CHANGELOGADD" ] ; then
	CHANGELOG="- $TEXTMESSAGE"
else
	# TODO: найти параметр для упрощения истории. пока - sort?
	# Делает первую букву маленькой, убирает точку в конце строки
	CHANGELOG="`git log $FROMTAG..$TOTAG --reverse --simplify-merges --dense --pretty="- %s" | sed -e "s|\.\$||g" | sed -e "s|- \([A-Z]\)\([a-z]\)|- \l\1\2|g" | sed -e "s|%||g"`"
	[ -n "$CHANGELOG" ] || fatal "git log was failed. Probably, you have no tag $FROMTAG in your repo. Check the source repository."
fi

[ -n "$(get_packager $SPECNAME)" ] || fatal "You need set packager in your spec (use $ rpmcs for it) or in ~/.rpmmacros file"

if [ -n "$TESTRUN" ] ; then
	INCREMENTMODE=""
fi

if [ "$INCREMENTMODE" = "-a" ] ; then
    # print all files from commit exclude spec/rules
    RELLINE=$(git log --name-status --pretty=oneline $FROMTAG..$TOTAG | grep "^[MAD]" | grep -v ".gear/rules" | grep -v "$(basename "$SPECNAME")")
    if [ -z "$RELLINE" ] ; then
        INCREMENTMODE="-r"
    else
        INCREMENTMODE="-v"
    fi
fi

# increment release
case "$INCREMENTMODE" in
        "-r")
                inc_release $SPECNAME
                ;;
        "-n")
                set_version $SPECNAME $FORCEVERSION
                reset_release $SPECNAME
                ;;
        "-s")
                inc_subrelease $SPECNAME
                ;;
        "-v")
                inc_version $SPECNAME
                reset_release $SPECNAME
                ;;
        *)
                ;;
esac

NEWREV=$(get_version $SPECNAME)-$(get_release $SPECNAME)
echo "Add changelog to $NEWREV:"
echo "$CHANGELOG"

if [ -n "$TESTRUN" ] ; then
	exit
fi

add_changelog_helper "$CHANGELOG" $SPECNAME || fatal "add_changelog failed, leave all uncommitted"

#git_commit_ignore_nothing $SPECNAME -m "new build $NEWREV (with rpmlog script)"
gammit $QUIET --spec=$SPECNAME $SPECNAME

RGD=$(get_root_git_dir)
hook=$RGD/.gear/new-build-postcommit-hook
if [ -s $hook ] ; then
	( cd $RGD && sh $hook $NEWREV ) || fatal "Failed with hook $hook"
fi