#!/bin/sh -e
#
# Copyright (C) 2000-2006  Dmitry V. Levin <ldv@altlinux.org>
#
# Generates and adds/updates BuildRequires tag in specfiles.
#
# This program 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#

PROG="${0##*/}"

ESSENTIAL='/etc/buildreqs/packages/essential'
IGNORE='/etc/buildreqs/packages/ignore.d'
FILEREQ='/usr/bin/filereq'
PACKAGEREQ='/usr/bin/packagereq'
export RPM='/bin/rpm'
DEFSTAGE=c
STAGE=
RPMARG="--nodeps --define '__buildreqs 1' --define '__nprocs 1'"
NEWTERM=dumb

Info()
{
	printf %s\\n "${0##*/}: $*" >&2
}

Fatal()
{
	printf %s\\n "${0##*/}: $*" >&2
	exit 1
}

show_usage()
{
	[ -z "$*" ] || Info "$*"
	echo "Try \`$PROG --help' for more information." >&2
	exit 1
}

show_help()
{
	cat <<EOF
buildreq - generates and adds/updates BuildRequires tag in specfiles.

buildreq is free software, covered by the GNU General Public License.
buildreq comes with ABSOLUTELY NO WARRANTY, see license for details.

Usage: $PROG [options] <specfile> [ <specfile>]*

Valid options are:
-e ESSENTIAL, --essential=ESSENTIAL     filename where to get list of
                                        essential packages;
-i IGNORE, --ignore=IGNORE              filename where to get list of
                                        packages to ignore;
-f FILEREQ, --filereq=FILEREQ           path to FILEREQ;
-p PACKAGEREQ, --packagereq=PACKAGEREQ  path to PACKAGEREQ;
-r RPM, --rpm=RPM                       path to RPM;
-b STAGE                                RPM build stage;
--args=args                             additional arguments for RPM;
--define='<name> <body>'                define macro <name> with value <body>;
--reset-args                            reset arguments list for RPM;
-t TERM, --term=TERM                    redefine TERM variable;
--trace-file=FILE                       trace the usage of FILE;
--trace-package=PACKAGE                 trace the usage of PACKAGE files;
-h, --help                              show this text.

Default file with list of essential packages is $ESSENTIAL.
Default file with list of packages to ignore is $IGNORE.
Default path to FILEREQ is $FILEREQ.
Default path to PACKAGEREQ is $PACKAGEREQ.
Default path to RPM is $RPM.
Default RPM build stage is: $DEFSTAGE.
Default arguments for RPM are: $RPMARG.
Default TERM value is $NEWTERM.

EOF
	exit
}

TEMP=`getopt -n $PROG -o b:e:f:i:p:r:t:h -l essential:,filereq:,ignore:,packagereq:,rpm:,args:,define:,reset-args,term:,trace-file:,trace-package:,help -- "$@"` || show_usage
eval set -- "$TEMP"

TRACE_FILES=
TRACE_PACKAGES=

while :; do
	case "$1" in
		-b) shift; STAGE="$1"; shift
			;;
		-e|--essential) shift; ESSENTIAL="$1"; shift
			;;
		-f|--filereq) shift; FILEREQ="$1"; shift
			;;
		-i|--ignore) shift; IGNORE="$1"; shift
			;;
		-p|--packagereq) shift; PACKAGEREQ="$1"; shift
			;;
		-r|--rpm) shift; RPM="$1"; shift
			;;
		--args) shift; RPMARG="$RPMARG $1"; shift
			;;
		--define) shift; RPMARG="$RPMARG --define '$1'"; shift
			;;
		--reset-args) RPMARG=; shift
			;;
		-t|--term) shift; NEWTERM="$1"; shift
			;;
		--trace-file) shift
			[ -z "$TRACE_FILES" ] && TRACE_FILES="$1" ||
			TRACE_FILES="$(printf %s\\n%s\\n "$TRACE_FILES" "$1")"
			export TRACE_FILES
			shift
			;;
		--trace-package) shift
			[ -z "$TRACE_PACKAGES" ] && TRACE_PACKAGES="$1" ||
			TRACE_PACKAGES="$(printf %s\\n%s\\n "$TRACE_PACKAGES" "$1")"
			export TRACE_PACKAGES
			shift
			;;
		-h|--help) show_help
			;;
		--) shift; break
			;;
		*) echo "$PROG: unrecognized option: $1" >&2; exit 1
			;;
	esac
done

# At least one argument, please.
[ "$#" -ge 1 ] || show_usage 'Insufficient arguments.'

REQFILE="$(mktemp -t "$PROG.XXXXXXXXXX")"

exit_handler()
{
	local rc=$?
	trap - EXIT
	rm -f -- "$REQFILE"
	exit $rc
}

trap exit_handler HUP PIPE INT QUIT TERM EXIT

Quote()
{
	printf %s "$*" |sed -e 's/[\&;()<>!|{}$?*`"'\''[:space:]]/\\&/g' || return 1
}

for SPEC in "$@"; do
	if [ -z "$STAGE" ]; then
		SPEC_STAGE=`sed -ne 's/^# Automatically added by buildreq on [^(]*(-b\([a-z]\))$/\1/p' -- "$SPEC" |tail -1`
	else
		SPEC_STAGE="$STAGE"
	fi
	eval \
		"$(Quote "TERM=$NEWTERM")" \
		"$(Quote "$PACKAGEREQ")" \
		-o "$(Quote "$REQFILE")" \
		-e "$(Quote "$ESSENTIAL")" \
		-i "$(Quote "$IGNORE")" \
		-f "$(Quote "$FILEREQ")" \
		-- "$RPM" "-b${SPEC_STAGE:-$DEFSTAGE} $RPMARG" "$(Quote "$SPEC")"
	TMPFILE="$(mktemp -t "$PROG.XXXXXXXXXX")"
	: >"$TMPFILE"
	REQS="$(cat "$REQFILE" |xargs echo -n)"
	LC_ALL=C /usr/share/buildreqs/filter_spec -v "reqs=$REQS" "stage=$SPEC_STAGE" <"$SPEC" >>"$TMPFILE"
	if ! cmp -s "$SPEC" "$TMPFILE"; then
		cat "$TMPFILE" >"$SPEC"
	fi
	rm -f "$TMPFILE"
done
