#!/bin/bash --norc
set -fe
set -o pipefail
# note: bash-dependent, see checkbashisms

export LC_ALL=C
verbose=
OPTIONS=
LONGOPTIONS=
REPOSITORY_BRANCH="sisyphus"
# alt system gits
git_default_url=git://git.altlinux.org
# alt system web shared tasks
web_default_tasks_url=http://git.altlinux.org
WEBERY_HOST=
WEB_TASKS_URL=
# alt personal gits
gitery_default_url=git://gitery.altlinux.org
gitery_default_host=
GITERY_HOST=
GIRAR_HOST=
DRY_RUN=
TASKID=
BEFORE_SUBTASK=
add_to_task=
build_task=
case $0 in *-task-add*) add_to_task=1;; *girar-build-*) build_task=1;; esac;
TASK_SHARE=
task_deps=
TASK_RUN_HURRY=
TASK_RUN_UNHURRY=
TASK_RUN_TEST_ONLY=
TASK_RUN_FAIL_LATE=
girar_message=
expect_git_branch=
gitery_path=
commit_message=
tag_message=
tag=
kill_remote_repo_before=
kill_remote_repo_after=
GIT_AUTOCOMMIT=yes
GIT_AUTOCOMMIT_NO_EDIT=
GIT_CREATE_TAG=yes
GIT_CREATE_TRYTAG=
GIT_PUSH_RELATED_TAGS=
tolerate_existing_tag=
REPOPREFIX=

verbose=1

for config_file in /etc/girar-nmu/default ${XDG_CONFIG_HOME:-$HOME/.config}/girar-nmu/default; do
    ! [ -e "$config_file" ] || . "$config_file"
done
# --- autodetection in absence of config file ---
if [ -z "$gitery_default_host" ]; then
    if grep -E '^Host[[:space:]]+gitery[[:space:]]*$' ~/.ssh/config >/dev/null; then
	gitery_default_host=gitery
    elif grep -E '^Host[[:space:]]+git.alt[[:space:]]*$' ~/.ssh/config >/dev/null; then
	gitery_default_host=git.alt
    else
	gitery_default_host=gitery
    fi
fi
if [ -z "$GIRAR_HOST" ]; then
    if grep -E '^Host[[:space:]]+girar[[:space:]]*$' ~/.ssh/config >/dev/null; then
	GIRAR_HOST=girar
    elif grep -E '^Host[[:space:]]+gyle[[:space:]]*$' ~/.ssh/config >/dev/null; then
	GIRAR_HOST=gyle
    elif grep -E '^Host[[:space:]]+gyle.alt[[:space:]]*$' ~/.ssh/config >/dev/null; then
	GIRAR_HOST=gyle.alt
    elif grep -E '^Host[[:space:]]+sborochnitsa[[:space:]]*$' ~/.ssh/config >/dev/null; then
	GIRAR_HOST=sborochnitsa
    else
	GIRAR_HOST=girar
    fi
fi
# --- end autodetection ---------------------------

OPTIONS=a:AB:''SD:m:O''cCE:kKm:M:p:rTt:
LONGOPTIONS=,add,add-to-task:,task:,before:,before-subtask:,deps:,share,no-share,fail-early,fail-late,hurry,no-hurry,unhurry,no-test-only,test-only,message:,gm:,gyle-message:,girar-message:,auto-tag,no-auto-tag,try-tag,no-try-tag,commit,no-commit,commit-no-edit,no-edit,expect-git-branch:,gitery-path:,gitery-name:,kill-after,kill-before,cm:,tm:,commit-message:,tag-message:,prefix:,repo-prefix:,push-related-tags,no-push-related-tags,tag:
# not compatible with set -e
#getopt --test > /dev/null; #if [ "$?" -ne 4 ]; then
if getopt --test > /dev/null; then
    echo "Oops! `getopt --test` not failed. Bad getopt!." >&2
    exit 1
fi
__OPTS=hqVvb:H:P:R:
__LONGOPTS=dry-run,help,quiet,verbose,version,branch:,girar:,gyle:,gitery:,git.alt:,profile:,webery:,web_tasks_url:
PARSED=$(getopt --options=$__OPTS$OPTIONS --longoptions=$__LONGOPTS$LONGOPTIONS --name "$0" -- "$@")
if [ "$?" -ne 0 ]; then
    exit 2
fi
eval set -- "$PARSED"

while true; do
    case "$1" in
	-a|--add-to-task|--task) TASKID="$2"
	    add_to_task=1
	    readonly TASKID
            shift 2 ;;
	-A|--add)
	    TASKID=
	    add_to_task=1
	    readonly TASKID
	    shift ;;
	-B|--before|--before-subtask) BEFORE_SUBTASK="$2"
	    readonly BEFORE_SUBTASK
            shift 2 ;;
	-D|--deps) task_deps="$2"
            shift 2 ;;
	--no-share) TASK_SHARE=
            shift ;;
	-S|--share) TASK_SHARE=1
            shift ;;

	--gm|--girar-message|gyle-message) girar_message="$2"
	    girar_message=${girar_message// /_}
            shift 2 ;;
	-m|--message) girar_message="$2"
	    echo "WARINING: option -m (--message) is ambiguous. Assuming --girar-message">&2;
	    echo "Please, use --gm (--girar-message), --cm (--commit-message), --tm (--tag-message).">&2
	    girar_message=${girar_message// /_}
	    shift 2 ;;
	--test-only) TASK_RUN_TEST_ONLY=--test-only
            shift ;;
	-O|--no-test-only) TASK_RUN_TEST_ONLY=
            shift ;;
	--fail-late) TASK_RUN_FAIL_LATE=1
            shift ;;
	--fail-early) TASK_RUN_FAIL_LATE=
            shift ;;
	--no-hurry) TASK_RUN_HURRY=
            shift ;;
	--unhurry) TASK_RUN_UNHURRY=1
		TASK_RUN_HURRY=
            shift ;;
	--hurry) TASK_RUN_HURRY=1
		TASK_RUN_UNHURRY=
            shift ;;
	-c|--commit)
	    GIT_AUTOCOMMIT=yes
            shift ;;
	-C|--commit-no-edit)
	    GIT_AUTOCOMMIT=yes
	    GIT_AUTOCOMMIT_NO_EDIT=yes
            shift ;;
	--no-edit)
	    GIT_AUTOCOMMIT_NO_EDIT=yes
            shift ;;
	--no-commit)
	    GIT_AUTOCOMMIT=
            shift ;;
	-E|--expect-git-branch)
	    expect_git_branch="$2"
	    readonly expect_git_branch
            shift 2 ;;
	-k|--kill-before) kill_remote_repo_before=1
	    readonly kill_remote_repo_before
            shift ;;
	-K|--kill-after) kill_remote_repo_after=1
	    readonly kill_remote_repo_after
            shift ;;
	--cm|--commit-message) commit_message="$2"
            shift 2 ;;
	--tm|-M|--tag-message) tag_message="$2"
            shift 2 ;;
	--gitery-path|--gitery-name) gitery_path="$2"
            shift 2 ;;
	-p|--prefix|--repo-prefix) REPOPREFIX="$2"
	    readonly REPOPREFIX
            shift 2 ;;
	-r|--push-related-tags) GIT_PUSH_RELATED_TAGS=yes
            shift ;;
	--no-push-related-tags) GIT_PUSH_RELATED_TAGS=
            shift ;;
	-t|--tag)
	    tag="$2"
	    if [ -n "$tag" ]; then
		tolerate_existing_tag=1
	    else
		echo "Warning: bad tag. Using default tag. Use -t <tag>" >&2
		GIT_CREATE_TAG=1
	    fi
	    shift 2 ;;
	-T|--auto-tag) GIT_CREATE_TAG=yes
            shift ;;
	--no-auto-tag) GIT_CREATE_TAG=
            shift ;;
	--try-tag) GIT_CREATE_TRYTAG=yes
            shift ;;
	--no-try-tag) GIT_CREATE_TRYTAG=
            shift ;;
	-P|--profile)
	    local profile_file="$2"
	    for config_file in /etc/girar-nmu/"$profile_file" ${XDG_CONFIG_HOME:-$HOME/.config}/girar-nmu/"$profile_file"; do
		! [ -e "$config_file" ] || . "$config_file"
	    done
            shift 2 ;;
        -q|--quiet)
            verbose=
            shift ;;
        -V|--version)
            echo "2.015.2"
	    exit 0
            shift ;;
        -v|--verbose)
            verbose=$(($verbose+1))
            shift ;;
	-h|--help)
	    pod2usage --exit=0 "$0";
	    exit 0 ;;
	-b|--branch)
	    REPOSITORY_BRANCH="$2"
	    readonly REPOSITORY_BRANCH
            shift 2 ;;
	-H|--gitery|--git.alt)
	    GITERY_HOST="$2"
	    readonly GITERY_HOST
            shift 2 ;;
	-R|--girar|--gyle)
	    GIRAR_HOST="$2"
	    readonly GIRAR_HOST
            shift 2 ;;
	-W|--webery)
	    WEBERY_HOST="$2"
	    readonly WEBERY_HOST
            shift 2 ;;
	--web-tasks-url)
	    WEB_TASKS_URL="$2"
	    readonly WEB_TASKS_URL
            shift 2 ;;
        --dry-run)
            DRY_RUN=echo
            shift ;;
        --)
            shift
            break
            ;;
        *)
	    echo "Internal error: Unexpected option: $1 $2" >&2
	    #pod2usage --exit=3 "$0"
            exit 3
            ;;
    esac
done

# gpg1's usage of gpg-agent is broken in p10+
[ -n "`git config --global gpg.program`" ] || GIT_GPG_SIGN_OPT="-c gpg.program=gpg2"
if [ -n "$BEFORE_SUBTASK" ] && [ -z "$TASKID" ]; then
    echo "-B|--before <before_subtask_id> require -a|--task <taskid> option" >&2
    exit 2
fi

[ 0"$verbose" -ge 3 ] && set -x ||:

RETVAL=0
task_options_applied=
apply_task_properties()
{
    if [ -n "$TASK_SHARE" ] && [ $RETVAL -eq 0 ]; then
	$DRY_RUN ssh $GIRAR_HOST task share $TASKID enable || RETVAL=$?
    fi
    if [ -n "$task_deps" ] && [ $RETVAL -eq 0 ]; then
	for dep in `perl -e 'map {print $_, " " } split(",",$ARGV[0])' $task_deps`; do
	    $DRY_RUN ssh $GIRAR_HOST task deps $TASKID add $dep || RETVAL=$?
	done
    fi
    task_options_applied=1
    return $RETVAL
}

task_do_girar_action()
{
    local first_arg second_arg task_add_prefix
    first_arg=$1
    second_arg="$2"
    task_add_prefix=${3:-}
    if [ -n "$add_to_task" ]; then
	$DRY_RUN ssh $GIRAR_HOST task add $TASKID $BEFORE_SUBTASK $task_add_prefix $first_arg "$second_arg"
	[ -n "$task_options_applied" ] || apply_task_properties
    elif [ -n "$TASK_SHARE" ]; then
	$DRY_RUN ssh $GIRAR_HOST task new ${REPOSITORY_BRANCH:+$REPOSITORY_BRANCH}
	$DRY_RUN ssh $GIRAR_HOST task add $TASKID $BEFORE_SUBTASK $task_add_prefix $first_arg "$second_arg"
	apply_task_properties
	$DRY_RUN ssh "$GIRAR_HOST" task run ${TASK_RUN_TEST_ONLY:---commit} ${TASK_RUN_HURRY:+--hurry} ${TASK_RUN_UNHURRY:+--unhurry} ${TASK_RUN_FAIL_LATE:+--fail-late} ${girar_message:+-m "$girar_message"} "$TASKID"
    else
	$DRY_RUN ssh $GIRAR_HOST build ${REPOSITORY_BRANCH:+-b $REPOSITORY_BRANCH} ${TASK_RUN_TEST_ONLY:---commit} ${TASK_RUN_HURRY:+--hurry} ${TASK_RUN_UNHURRY:+--unhurry} ${TASK_RUN_FAIL_LATE:+--fail-late} ${task_deps:+--deps $task_deps} ${girar_message:+-m "$girar_message"} $first_arg "$second_arg"
    fi
}


git_push_build()
{
    set +e
    git_topdir=`git rev-parse --show-cdup`
    if [ $? -gt 0 ]; then
	echo `pwd`": not a git repository" >&2; exit 2;
    fi
    set -e

    if ! [ -e ${git_topdir}.git ] || ! ([ -e ${git_topdir}.gear ] || [ -e ${git_topdir}.gear-rules ]) ; then
	echo `pwd`": not a git/gear repository" >&2; exit 2;
    fi

    modified_files=`git status --porcelain --untracked-files=no`
    [ -n "$GIT_AUTOCOMMIT_NO_EDIT" ] && ([ "$GIT_AUTOCOMMIT_NO_EDIT" == '0' ] || [ "$GIT_AUTOCOMMIT_NO_EDIT" == 'no' ]) && $GIT_AUTOCOMMIT_NO_EDIT=

    [ -n "$modified_files" ] && [ -n "$GIT_AUTOCOMMIT" ] && [ "$GIT_AUTOCOMMIT" != '0' ] && [ "$GIT_AUTOCOMMIT" != 'no' ] &&
	gear-commit \
	    ${GIT_AUTOCOMMIT_NO_EDIT:+--no-edit} \
	    ${commit_message:+-m "$commit_message"}

    modified_files=`git status --porcelain --untracked-files=no`
    if [ -n "$modified_files" ]; then
	echo "WARNING: found modified files:"
	git status --porcelain --untracked-files=no
	echo "please, commit or discard them first." >&2
	exit 3;
    fi

    if [ -n "$expect_git_branch" ]; then
	CURRENT_BRANCH="$(git branch | awk '/^\*/{print $2}')"
	#[ "$CURRENT_BRANCH" = "(no_branch)" ] && CURRENT_BRANCH=
	if [ "$CURRENT_BRANCH" != "$expect_git_branch" ]; then
	    echo "WARNING: local branch is $CURRENT_BRANCH but should be $expect_git_branch" >&2
	    exit 9;
	fi
    fi

    abs_path_of_git_top=
    if [ -z "${git_topdir}" ]; then
	# we are on top
	abs_path_of_git_top=`pwd`
    else
	# readlink -f -- useful hack to print abspath of a path
	abs_path_of_git_top=`readlink -f "${git_topdir}"`
    fi
    gitery_path_from_dir=`basename "$abs_path_of_git_top"`

    # bash-specific; use variable inside of EOF instead
    read -r gear_pkg_name gear_pkg_version gear_pkg_release <<< `gear --describe`

    # hack around apache with gear_pkg_release=[%branch_release alt7.1]
    gear_pkg_release=${gear_pkg_release// /_}
    gear_pkg_release=${gear_pkg_release//%/_}
    gear_pkg_version=${gear_pkg_version//%/_}

    gitery_path_from_dir="${gitery_path_from_dir%%.git}"
    gitery_from_gear_pkg_name="${gear_pkg_name%%.git}"

    if [ -z "$gitery_path" ]; then
	gitery_path="$gitery_path_from_dir"
	if [ "$gitery_from_gear_pkg_name" != "$gitery_path_from_dir" ] && [ "$verbose" -ge 1 ] ; then
	    echo "info: gitery name guessed from path ($gitery_path_from_dir) differs from gear pkg name ($gitery_from_gear_pkg_name). $gitery_path_from_dir is used. Use --gitery-name to change."
	fi
    fi

    if [ -z "$gitery_path" ]; then
	echo "Failed to determine gitery name for this gear repo." >&2
	pod2usage --exit=2 "$0"; exit 2;
    fi

    set +e
    tag_at_latest_commit=`git describe --exact-match --abbrev=0 2>/dev/null`;
    if [ $? -gt 0 ] && [ -n "$tag_at_latest_commit" ]; then
	echo "Internal error: git describe --exact-match --abbrev=0 failed,"
	echo "but the output is not empty: $tag_at_latest_commit"
	exit 3
    fi
    set -e

    if [ -z "$tag" ] && [ -n "$tag_at_latest_commit" ]; then
	tag="$tag_at_latest_commit"
	tolerate_existing_tag=1
    fi

    if [ -z "$tag" ] && [ -n "$GIT_CREATE_TAG" ] && [ "$GIT_CREATE_TAG" != '0' ] && [ "$GIT_CREATE_TAG" != 'no' ]; then
	tag="${gear_pkg_version}-$gear_pkg_release"
	# check if the tag already exists and create $tag.tryN if required
	found_tag=$(git tag -l "$tag" ||:)
	if [ -n "$found_tag" ]; then
	    if ! git describe "$tag"; then
		echo "Tag $tag is found but it is not signed - deleting ..."
		echo "Maybe non-signed tag $tag was created by gear-srpminport?"
		git tag -d $tag || exit 1
		found_tag=
	    fi
	fi
	if [ -n "$found_tag" ] \
	       && [ -n "$GIT_CREATE_TRYTAG" ] && [ "$GIT_CREATE_TRYTAG" != '0' ] && [ "$GIT_CREATE_TRYTAG" != 'no' ] \
	       && [ -z "$tag_at_latest_commit" ]
	then
	    auto_tag_try=2
	    auto_tag_test="$tag"
	    while [ -n "$found_auto_tags" ] && [ "$auto_tag_try" -le 5000 ]; do
		[ -z "$verbose" ] || echo "tag $auto_tag_test exists, trying try${auto_tag_try}..."
		auto_tag_test="$tag".try$auto_tag_try
		found_auto_tags=$(git tag -l "$auto_tag_test" ||:)
		auto_tag_try=$(($auto_tag_try+1))
	    done
	    tag="$auto_tag_test"
	fi
    fi
    if [ -z "$tag" ]; then
	echo "git tag not found! to create a tag, add one of the options" >&2
	echo "	-T (creates tag %version-%release), or" >&2
	echo "	-t <tag> option, or place tag manually." >&2
	exit 5;
    else
	tag_message="${tag_message:-$tag}"
	found_tags=$(git tag -l "$tag" ||:)
	if [ -z "$found_tags" ]; then
	    [ -z "$verbose" ] || echo running git $GIT_GPG_SIGN_OPT tag -s -m "$tag_message" $tag >&2
	    $DRY_RUN git $GIT_GPG_SIGN_OPT tag -s -m "$tag_message" $tag || exit 3
	else
	    if [ -z "$tolerate_existing_tag" ]; then
		echo "tag $tag already exists. Use -t $tag to force use of that tag." >&2
		exit 3
	    fi
	fi
    fi
    uploaddir=`dirname "$gitery_path"`
    uploadname=`basename "$gitery_path" | sed -e 's,[^-A-Za-z0-9_.],,g'`
    if [ -n "$uploaddir" ] && [ x"$uploaddir" != x. ]; then
	repopath="$gitery_path"
	[ -n "$REPOPREFIX" ] && echo "repository name $reponame already contains '/'. Add prefix $REPOPREFIX to the name manually." >&2
    else
	reponame="${REPOPREFIX}${uploadname}"
	repopath="packages/$reponame"
    fi

    if [ -n "$kill_remote_repo_before" ];then
	[ -z "$verbose" ] || echo running ssh ${GITERY_HOST:-$gitery_default_host} git-rm-db "${repopath}" >&2
	$DRY_RUN ssh ${GITERY_HOST:-$gitery_default_host} git-rm-db "${repopath}" ||:
    fi

    kill_repopath_after()
    {
	if [ -n "$kill_remote_repo_after" ]; then
	    [ -z "$verbose" ] || echo running ssh ${GITERY_HOST:-$gitery_default_host} git-rm-db "$repopath" >&2
	    $DRY_RUN ssh ${GITERY_HOST:-$gitery_default_host} git-rm-db "$repopath" ||:
	fi
    }
    trap kill_repopath_after EXIT

    if [ -n "$uploaddir" ] && [ x"$uploaddir" != x. ]; then
	echo "$gitery_path is a path, not a name. Skipped remote git init-db/clone/push" >&2
    else
	# relative path; let's conveniently create the git repo to push to and then push
	name=`basename "$gitery_path"`
	commit=$(git ls-remote -h ${GITERY_HOST:-$git_default_url}:/gears/${name:0:1}/${name}.git refs/heads/$REPOSITORY_BRANCH | awk '{print $1}'||:)
	if [ -n "$commit" ]; then
	    [ -z "$verbose" ] || echo running ssh ${GITERY_HOST:-$gitery_default_host} clone "/gears/${name:0:1}/${name}.git" "${repopath}" >&2
	    $DRY_RUN ssh ${GITERY_HOST:-$gitery_default_host} clone "/gears/${name:0:1}/${name}.git" "${repopath}" ||:
	else
	    # $name is not a git-built package"
	    [ -z "$verbose" ] || echo running ssh ${GITERY_HOST:-$gitery_default_host} git-init-db "${repopath}" >&2
	    $DRY_RUN ssh ${GITERY_HOST:-$gitery_default_host} git-init-db "${repopath}" ||:
	fi

	PUSHLIST=$tag
	if [ -n "$GIT_PUSH_RELATED_TAGS" ] && [ "$GIT_PUSH_RELATED_TAGS" != '0' ] && [ "$GIT_PUSH_RELATED_TAGS" != 'no' ]; then
	    # Restore gears tags and branches
	    gear-restore-tags -f
	    # append related tags to pushlist
	    PUSHLIST="$PUSHLIST "`gear-restore-tags -q -l --no-tags --no-type --no-sha1 | sed -r -n 's/^[[:space:]]*([^[:space:]]+)[[:space:]]*$/\1:\1/p'`
	    PUSHLIST="$PUSHLIST "`gear-restore-tags -q -l --no-branches --no-type --no-sha1`
	fi

	$DRY_RUN git push --force ${GITERY_HOST:-$gitery_default_host}:${repopath} ${expect_git_branch:+$expect_git_branch:$expect_git_branch} $PUSHLIST
    fi

    task_do_girar_action "$repopath" $tag repo
    kill_repopath_after
    trap - EXIT
}

if [ -z "$1" ]; then
    if [ -n "$build_task" ] && [ -z "$TASKID" ] && [ -z "$add_to_task" ]; then
    add_to_task=1
    $DRY_RUN ssh $GIRAR_HOST task new ${REPOSITORY_BRANCH:+$REPOSITORY_BRANCH}
fi

    git_push_build
    if [ -n "$build_task" ]; then
    $DRY_RUN ssh "$GIRAR_HOST" task run ${TASK_RUN_TEST_ONLY:---commit} ${TASK_RUN_HURRY:+--hurry} ${TASK_RUN_UNHURRY:+--unhurry} ${TASK_RUN_FAIL_LATE:+--fail-late} ${girar_message:+-m "$girar_message"} "$TASKID"
fi

else
    if [ -n "$build_task" ] && [ -z "$TASKID" ] && [ -z "$add_to_task" ]; then
    add_to_task=1
    $DRY_RUN ssh $GIRAR_HOST task new ${REPOSITORY_BRANCH:+$REPOSITORY_BRANCH}
fi

    for path in "$@"; do
	if [ -e "$path/.git" ] && ([ -e "$path/.gear" ] || [ -e "$path/.gear-rules" ]); then
	    echo "entering $path ..." >&2
	    pushd "$path" >/dev/null
	    git_push_build
	    popd >/dev/null
	else
	    echo "bad path - does not look like gear repository: $path" >&2
	    exit 1
	fi
    done
    if [ -n "$build_task" ]; then
    $DRY_RUN ssh "$GIRAR_HOST" task run ${TASK_RUN_TEST_ONLY:---commit} ${TASK_RUN_HURRY:+--hurry} ${TASK_RUN_UNHURRY:+--unhurry} ${TASK_RUN_FAIL_LATE:+--fail-late} ${girar_message:+-m "$girar_message"} "$TASKID"
fi

fi

: <<'__EOF__'

=head1	NAME

girar-task-add-git - girar helper for building a git/gear repository.

=head1	SYNOPSIS

B<girar-task-add-git>, B<girar-task-for-each-git>, B<girar-build-git>
[B<-c|--commit|-C|--commit-no-edit>]
[B<--no-edit>]
[B<--no-commit>]
[B<-E|--expect-git-branch> I<local git branch>]
[B<-k|--kill-before>]
[B<-K|--kill-after>]
[B<-p|--prefix> I<prefix>]
[B<-r|--push-related-tags>]
[B<--no-push-related-tags>]
[B<--gitery-name|--gitery-path> I<gitery name or path>]
[B<--cm|--commit-message> I<commit message>]
[B<--tm|--tag-message> I<tag message>]
[B<-t|--tag> I<tag>]
[B<-T|--auto-tag>]
[B<--no-auto-tag>]
[B<--try-tag>]
[B<--no-try-tag>]
[B<-a|--add-to-task|--task> I<task ID>]
[B<-A|--add>]
[B<-B|--before|--before-subtask> I<before_subtask_id>]
[B<-D|--deps> I<comma separated list>]
[B<-S|--share>]
[B<--gm|--girar-message|--gyle-message> I<message>]
[B<-O|--no-test-only>]
[B<--test-only>]
[B<--unhurry>]
[B<--hurry>]
[B<--fail-early|--fail-late>]
[B<-H|--gitery> I<ssh gitery alias>]
[B<-R|--girar> I<ssh girar(gule) alias>]
[B<-W|--webery> I<tasks web site>]
[B<--web-tasks-url> I<tasks web site url>]
[B<-b|--branch> I<repository>]
[B<--dry-run>]
[B<-P|--profile> I<profile>]
[B<-h|--help>]
[B<-v|--verbose>]
[B<-q|--quiet>]

[</path/to/gear-repository.git> ...]

=head1	DESCRIPTION

B<girar-task-add-git>, B<girar-task-for-each-git>, B<girar-build-git> -
girar helper for git/gear repository. It checks if all changes are
added to git index, commits them (--commit mode) or
checks if all changes are commited (--no-commit mode),
(optionally) creates a tag in current git repository,
remotely clones gitery:/gears/ repository, pushes the tag to gitery:,
and either adds package build with the tag to a specified task with -a option,
or current task, with -A option, or builds a package from the tag.
It also can remove the remote repository (with -K option).

The scripts differ in their default behaviour depending on their name.
B<girar-task-add-*> add the arguments to the specified or to the last task,
B<girar-task-for-each-*> create and run separate tasks for each argument,
B<girar-build-*> create and run the arguments in one big task.

=head1	OPTIONS

=over

=item  Git/Gear repository options.

=over

=item   B<-c|--commit>, B<--no-edit>

Commit. If modified files are found, call gear-commit.
If B<--no-edit> is present, call gear-commit with --no-edit option.
The modified files should be added to git index. If not, the script
will abort to prevent accidental modifications to be commited.
B<--no-commit> disables B<-c|--commit>.

=item   B<-C|--commit-no-edit>

Shortcut option. Same as B<-c|--commit> B<--no-edit> above.

=item	B<-E|--expect-git-branch> I<git branch name>

Name of the local git branch. Default is none.
If provided, the script will check that we are on the branch
and abort if we are not.

=item	B<-k|--kill-before>

Try to kill remote git repository before upload (useful for robotic and nmu builds).

=item	B<-K|--kill-after>

Kill remote git repository after upload (useful for robotic and nmu builds).

=item	B<--cm|--tag-message> I<tag message>

Specifies a message for git tag I<tag>. Default is tag name.

=item	B<--cm|--commit-message> I<commit message>

Specifies a message for git commit. Default is none (git will ask itself).

=item	B<--gitery-name|--gitery-path> I<name or path on gitery>

Specifies a repository name or path on gitery.
Sometimes the name on gitery differs from the name of local git repository.
It also can be used to run a task from a tag in a repository of another maintainer.
Together with -R <alias> it can be used to run task from an alias.
Default is to guess from current gear repository.
If a path a specified, then git init-db / clone / push is skipped.

=item	B<-p|--prefix> I<prefix>

Prefix to add before gitery repository name.
Useful to distinguish among automated and own repositories on gitery.
By default prefix is "00-tmp-".

=item	B<-r|--push-related-tags>

Push related tags as well. Push all tags that are ancestors of the current build tag.
Useful when intermediate tags, like v@version@, are created.
Disabled by default. If enabled in config, is disabled by B<--no-push-related-tags>.

=item	B<-t|--tag> [I<tag>]

Call git tag [I<tag>]. Default is %VERSION-%RELEASE.
If B<-t> or B<-T> is not specified then the last commit is expected to be a tag.

=item	B<-T|--auto-tag>

Call git tag %VERSION-%RELEASE.
If B<-t> or B<-T> is not specified then the last commit is expected to be a tag.
B<--no-auto-tag> disables B<-T|--auto-tag>.

=item	B<--try-tag>

If the auto tag already exists, B<--try-tag> adds I<.tryN> to the tag where N
is 2 or more such that I<tag.tryN> does not exist.
B<--no-try-tag> disables B<--try-tag>.

=back


=item  Add to task options.

=over

=item	B<-a|--add-to-task|--task> [I<task ID>]

Specifies the girar task to add.
Also enables "task add" mode, see below.

=item	B<-A|--add>

Enables "task add" mode. In this mode, the argument(s) are added
to the current or the specified task. This disables "for each" mode
and stops "build" mode from creating a separate task.

=item	[B<-B|--before|--before-subtask> I<before_subtask_id>]

I<before_subtask_id> is used in the extended format of girar-task add command:
girar-task add [<task_id> [<before_subtask_id>]] srpm <filename>

=back


=item  Run task options.

=over

=item	B<-D|--deps> I<dep1,...,depN>

Comma separated list of task dependencies to add.

=item	B<-S|--share>

Create and run a shared task. Disabled by default.
Also, B<--no-share> disables it.


=item	B<--gm|--girar-message|--gyle-message> I<message>

Specifies a girar task message.

=item	B<--test-only>

Run task --test-only

=item	B<--commit|-O|--no-test-only>

Do not run task --test-only (default).

=item	B<--hurry>

Run task with --hurry (undocumented girar option)

=item	B<--no-hurry>

Remove --hurry from run command line,
B<--no-hurry> option does not set --unhurry.

=item	B<--unhurry>

Run task with --unhurry (undocumented girar option)

=item	B<--fail-early>

Stop building the task after the first error.

=item	B<--fail-late>

Do not stop building the task after the first error.

=back


=item	B<-b|--branch> I<repository branch>

Name of the repository branch. Values: sisyphus|p8|..
Default is sisyphus.

=item	B<-R|--girar> I<girar(gyle) ssh alias>

By default, gyle.altlinux.org account should be configured as girar or gyle in ~/.ssh/config.
If you do not follow that convention, use -R <your girar ssh alias> option.

=item	B<-H|--gitery> I<gitery ssh alias>

Alternative gitery or ssh alias for gitery, for example, git.e2k.
If not specified, by default, gitery is used where ssh account is
required and git.altlinux.org is used where http:// is enough.

=item	B<-W|--webery> I<tasks web site>

Alternative site that hosts girar tasks.
If not specified, by default, git.altlinux.org is used.

=item	[B<--web-tasks-url> I<tasks web site url>]

The default URL for web task site is http://I<tasks web site>.
See --webery for details. B<--web-tasks-url> overrides this URL.

=item	B<--dry-run>

Echo state-changing commands instead of doing them. An extra safety.
Also a bit useful for debugging.

=item	B<-P|--profile> I<profile>

Name of the configuration profile. The profile is loaded as
/etc/girar-nmu/I<profile> and $HOME/.config/girar-nmu/I<profile>.
Note that default configuration is stored in
/etc/girar-nmu/default and $HOME/.config/girar-nmu/default.

=item	B<-V|--version>

Print version and exit.

=item	B<-v|--verbose>

Verbose. Prints extra information. Multiple -v accumulate.
-v -v -v set debug mode (set -x).

=item	B<-q|--quiet>

Quiet. Print no warnings.

=item	B<-h|--help>

Display this help and exit.


=back

=head1	AUTHOR

Written by Igor Vlasenko <viy@altlinux.org>.

=head1	COPYING

Copyright (c) 2010-2022 Igor Vlasenko, ALT Linux Team.

This is free software; you can redistribute it and/or modify it under the terms
of the GNU General Public License as published by the Free Software Foundation;
either version 2 of the License, or (at your option) any later version.

=cut

__EOF__
