#!/bin/sh -efu
#
# Copyright (C) 2006-2007  Alexey I. Froloff <raorn@altlinux.org>
# Copyright (C) 2006-2008  Dmitry V. Levin <ldv@altlinux.org>
# Copyright (C) 2006  Alexey Gladkov <legion@altlinux.org>
#
# gear-hsh-build - build packages from gear repositories with hasher
#
# This file 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.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
#

. gear-sh-functions

print_version()
{
    cat <<EOF
$PROG version $PROG_VERSION
Written by Alexey I. Froloff <raorn@altlinux.org>

Copyright (C) 2006-2007  Alexey I. Froloff <raorn@altlinux.org>
Copyright (C) 2006-2008  Dmitry V. Levin <ldv@altlinux.org>
Copyright (C) 2006  Alexey Gladkov <legion@altlinux.org>
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
EOF
    exit
}

show_help()
{
    cat <<EOF
Usage: $PROG [OPTIONS...] -- REPOSITORY... [-- HASHER_OPTIONS...]

This program will build package(s) from your gear repository(es) with
hasher.  REPOSITORY is a path to git directory (/path/to/repo.git or
/path/to/repo/.git) with optional tree-ish separated by \`\`#''
(/path/to/repo#tree-ish).  You can specify additional hasher options
after repository list.

Options:
  --cleanup-repo            cleanup hasher repo after build;
  --export-dir=DIR          write built packages to specified directory;
  --hasher=FILE             path to hasher binary;
  --prefix=DIR              path to hasher workdir;
  --repo=DIR                repository directory;
  --sisyphus                export packages to sisyphus-like START_DIR;
  --target=ARCH             target architecture;
  -q, --quiet               try to be more quiet;
  -v, --verbose             print a message for each action;
  -V, --version             print program version and exit;
  -h, --help                show this text and exit.

Report bugs to http://bugzilla.altlinux.org/

EOF
    exit
}

target=
prefix=
# source user config if any
hasher_config="$HOME/.hasher/config"
if [ -s "$hasher_config" ]; then
	. "$hasher_config"
fi
[ -n "$target" ] || target="$(uname -m)"

cleanup_repo=
hasher="hsh"
outdir=
repo="$(mktemp -u "build-XXXXXXXXXX")"
sisyphus=
repos=
indir=

cleanup_handler()
{
	if [ "$*" = 0 ]; then
		if [ -n "$cleanup_repo" ]; then
			rm -rf $verbose -- "$indir"
		else
			message "You may add \`\`rpm file:$indir $target hasher'' to your sources.list"
		fi
	else
		[ -z "$indir" ] ||
			message "Build failed.  You may wish to check \`\`$indir'' for leftovers."
	fi
}

TEMP=$(getopt -n $PROG -o +h,q,V,v -l cleanup-repo,export-dir:,hasher:,prefix:,repo:,sisyphus,target:,help,quiet,verbose,version -- "$@")
eval set -- "$TEMP"

while :; do
	case "$1" in
		--) shift; break
			;;
		--cleanup-repo) cleanup_repo=1
			;;
		--export-dir) outdir="$(opt_check_dir "$1" "$2")"; shift
			;;
		--hasher) hasher="$2"; shift
			;;
		--prefix) prefix="$(opt_check_dir "$1" "$2")"; shift
			;;
		--repo) repo="$2"; shift
			;;
		--sisyphus) sisyphus=1
			;;
		--target) target="$2"; shift
			;;
		-h|--help) show_help
			;;
		-q|--quiet) quiet=-q; verbose=
			;;
		-v|--verbose) verbose=-v; quiet=
			;;
		-V|--version) print_version
			;;
		*) fatal "Unrecognized option: $1"
			;;
	esac
	shift
done

[ -n "$prefix" ] ||
	fatal "Can't operate with empty prefix"

if [ -z "$outdir" ]; then
	[ -z "$cleanup_repo" ] ||
		fatal "--cleanup-repo without --export-dir doesn't makes sense"
	[ -z "$sisyphus" ] ||
		fatal "--sisyphus without --export-dir doesn't makes sense"
fi

indir="$prefix/$repo"
if [ -z "${repo##/*}" ]; then
	if [ -n "$cleanup_repo" ]; then
		message "--repo is absolute, refusing to --cleanup-repo"
		cleanup_repo=
	fi
	indir="$repo"
fi

while [ $# -gt 0 ]; do
	case "$1" in
		--) shift; break
			;;
		*) repos="${repos:+$repos
}$1"
			;;
	esac
	shift
done

[ -n "$repos" ] || {
	repos="$(git rev-parse --git-dir)"
	verbose "No repositories given, assuming $repos..."
}

install_cleanup_handler cleanup_handler

save_IFS="$IFS"
IFS="
"
for git_repo in $repos; do
	IFS="$save_IFS"
	if [ -z "${git_repo##*\#*}" ]; then
		git_dir="${git_repo%%\#*}"
		git_tree="${git_repo#*\#}"
	else
		git_dir="$git_repo"
		git_tree=
	fi
	[ -d "$git_dir" ] || continue
	git_dir="$(readlink -ev -- "$git_dir")"
	message "Building $git_dir${git_tree:+ with tag $git_tree}..."
	export GIT_DIR="$git_dir"
	run_command gear $quiet $verbose ${git_tree:+--tree="$git_tree"} --hasher -- "$hasher" $quiet $verbose "$@" --target="$target" --repo="$repo" -- "$prefix"
	save_IFS="$IFS"
	IFS="
"
done
IFS="$save_IFS"

if [ -n "$outdir" ]; then
	verbose "Exporting packages to $outdir..."
	rpms="$indir/$target/RPMS.hasher"
	srpms="$indir/SRPMS.hasher"
	if [ -n "$sisyphus" ]; then
		mkdir -p "$outdir/RPMS"
		mkdir -p "$outdir/SRPMS"
		rpms_out="$outdir/RPMS"
		srpms_out="$outdir/SRPMS"
	else
		rpms_out="$outdir"
		srpms_out="$outdir"
	fi

	find "$rpms" -mindepth 1 -maxdepth 1 -type f -name '*.rpm' -print0 |
		xargs -r0 cp -f $verbose --target-directory="$rpms_out" --
	find "$srpms" -mindepth 1 -maxdepth 1 -type f -name '*.rpm' -print0 |
		xargs -r0 cp -f $verbose --target-directory="$srpms_out" --
fi
