#!/bin/bash
#
# --- T2-COPYRIGHT-NOTE-BEGIN ---
# This copyright note is auto-generated by ./scripts/Create-CopyPatch.
# 
# T2 SDE: scripts/Emerge-Pkg
# Copyright (C) 2004 - 2005 The T2 SDE Project
# 
# More information can be found in the files COPYING and README.
# 
# 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; version 2 of the License. A copy of the
# GNU General Public License can be found in the file COPYING.
# --- T2-COPYRIGHT-NOTE-END ---

exec 2>&1

blacklist=" 00-dirtree binutils gcc glibc glibc32 uclibc linux24 linux26 linux-header "

options=''
config=default
deps=fast
debug=0
downloadonly=0
verbose=1
ignore_chksum=1
update=1
dryrun=0
force=0
rebuild=1
repositories=""
system=0
depth=0

#
# ----  Functions
#

. scripts/functions.in

help_msg() {
	spacer="                 "
	echo
	echo "Usage: Emerge-Pkg [ -cfg <config> ] [ -dry-run ] [ -force ] [ -noupdate ]"
	echo "$spacer [ -consider-chksum ] [ -norebuild ]"
	echo "$spacer [ -deps=none|fast|indirect ] [ -download-only ]"
	echo "$spacer [ -repository repository-name ] [ -system ] [ pkg-name(s) ]"
	echo
	echo "pkg-name(s) are only optional if a repository is specified."
	echo
}

#
# ---- Parse options + config
#

if [ $# = 0 ]; then
	help_msg
	exit 1
fi

while [ "$1" ] ; do
	case "$1" in
		-cfg)     options="$options $1 $2" ; config="$2" ; shift ;;
		-deps=*)  deps=${1/-deps=/} ;;
		-dry-run) dryrun=1 ;;
		-force)	  force=1 ;;
		-debug)   debug=1 ;;
		-noupdate) update=0 ;;
		-consider-chksum) ignore_chksum=0 ;;
		-norebuild) rebuild=0 ;;
		-download-only) downloadonly=1 ;;
		-repository) repositories="$repositories $2"
		             deps=none ; shift ;;
		-prefix) options="$options -prefix $2" ; shift ;;
		-system) system=1 ; deps=none ;;
		-*) help_msg ; exit 1 ;;
		*)  break ;;
	esac
	shift
done

. ./scripts/parse-config

add_if_req()
{
	[ "$verbose" = 1 ] && echo -n "$1"

	if [  $depth != 0  -a "$blacklist" != "${blacklist/ $package /}" ]; then
                [ $verbose = 1 ] && echo " Automatic update avoided."
	else
		[ $verbose = 1 ] && echo " Added."
		var_append deplist " " "$package"
		[ $deps = indirect ] && dep4pkg "$package"
	fi
}

add_if_updated()
{
	local package=$1

	# some variable name mangling ...
	local var=__BEEN_HERE_${package//-/_}
	var=${var//+/_}
	eval local x=\$$var
	if [ "$x" = 1 ]; then
		[ $debug = 1 ] && echo "already been at $package ..."
		return
	else
		eval $var=1
	fi

	[ $verbose = 1 ] && echo -n "checking $package ..."
	confdir=""
        for x in package/*/$package/$package.desc; do
            if [ -f "$x" ]; then
		if [ "$confdir" ]; then
		  echo " Error: Package in multiple trees!"
		  return
		fi
		confdir=${x/$package.desc/}
            fi
        done
        if [ -z "$confdir" ]; then
		echo " Error: No such package."
		return
	fi

        if [ ! -f /var/adm/packages/$package ]; then
		add_if_req ' Not installed.'
		return
        fi

	o_ver=$(grep '^Package Name and Version' \
	        /var/adm/packages/$package | cut -f6 -d' ')
	n_ver=$(grep '^\[V\] ' $confdir/$package.desc | cut -f2 -d' ')
	if [ "$o_ver" != "$n_ver" -a "$n_ver" != "0000" ]; then
		add_if_req " New version ($o_ver -> $n_ver)."
		return
	fi

	o_ck=$(grep '^\(ROCK Linux\|T2\) Package Source Checksum' \
	       /var/adm/packages/$package | sed 's,.*: ,,')
	n_ck=$( pkgchksum package/*/$package )
	if [ $ignore_chksum = 0 -a "$o_ck" != "$n_ck" ]; then
		add_if_req " New source checksum."
		return
	fi

	if [ -f /var/adm/cache/$package ] &&
	   grep -q '\[BUILDTIME\] .* ERROR' \
	   /var/adm/cache/$package; then
		[ $verbose = 1 ] && echo -n " Former build was broken."
		if [ $rebuild = 1 ]; then
			add_if_req ''
		else
			[ $verbose = 1 ] && echo " Skipped."
		fi
		return
	fi

	if [ $force = 1 -a $depth = 0 ]; then
		add_if_req ' Build forced.'
		return
	fi

	if [ $debug = 1 ]; then
		echo " Installed and up-to-date."
	else
		echo -ne \
"\r                                                                          \r"
	fi
}

dep4pkg()
{
	: $(( depth++ ))
	for x in `grep '\[DEP\]' package/*/$1/$1.cache 2>/dev/null |
	          cut -d ' ' -f 2`; do
		add_if_updated $x
	done
	: $(( depth-- ))
}

# the remaining arguments are packages to be built
for x in $*; do
	add_if_updated $x
done

# packages from repositories
for x in $repositories ; do
	for x in `egrep "^X .* $x .*" config/$config/packages |
	         cut -d ' ' -f 5`; do
		add_if_updated $x
	done
done

# all packages if a system update
if [ $system -eq 1 ]; then
	for x in `grep "^X" config/$config/packages | cut -d ' ' -f 5`; do
		add_if_updated $x
	done
fi

case $deps in 
  fast|indirect)
        # we have to create a complete dependency graph ...
	tmp=`mktemp`
	for x in $deplist ; do
        	dep4pkg $x
	done
	;;
  none)
	;;
  *)
	echo "Unknown dependency resolution mode. Valid are none and fast."
	exit 1
esac

# sort by priority
deplist=`echo -n $deplist | tr '\n' ' ' | tr -s ' '`
deplist=`grep "^. .* .* .* \\(${deplist// /\\|}\\) " \
         config/$config/packages | sort -k 3 | cut -d ' ' -f 5 | tr '\n' ' '`

echo "Packages scheduled to build: ${deplist:-none}"

[ $dryrun = 1 ] && exit

# the deplist is quite unsorted (in alphabetically sorted chunks)
# so we need to work arround this here ...

[ $update = 1 ] && options="$options -update"

. config/$config/config

for package in $deplist ; do
	if ./scripts/Download $package ; then [ $downloadonly != 1 ] && \
		if ! ./scripts/Build-Pkg $options $package; then
			if [ $SDECFG_ABORT_ON_ERROR_AFTER -gt 8 ]; then
				echo "Aborting further builds due to config setting ABORT_ON_ERROR_AFTER."
				exit 1
			fi
		fi
	else
		echo "The download for package $package failed!"
		exit 1
	fi
done

