#!/bin/bash
#   pbuilder -- personal Debian package builder
#   Copyright (C) 2001,2002,2003,2005-2007 Junichi Uekawa
#   Copyright (C) 2007 Loïc Minier
#
#   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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
#
# module to satisfy build dependencies; common functions


function package_versions() {
	local PACKAGE="$1"
	( $CHROOTEXEC /usr/bin/apt-cache show "$PACKAGE" ) | sed -n 's/^Version: \(.*\)$/\1/p'
}

function candidate_version() {
	local PACKAGE="$1"
	LC_ALL=C $CHROOTEXEC apt-cache policy "$PACKAGE" | sed -n 's/ *Candidate: *\(.*\)/\1/p'
}

function checkbuilddep_versiondeps () {
    local PACKAGE="$1"
    local COMPARESTRING="$2"
    local DEPSVERSION="$3"
    local PACKAGEVERSIONS=$( package_versions "$PACKAGE" | xargs)
    # no versioned provides.
    if [ "${FORCEVERSION}" = "yes" ]; then
	return 0;
    fi
    for PACKAGEVERSION in $PACKAGEVERSIONS ; do
      if dpkg --compare-versions "$PACKAGEVERSION" "$COMPARESTRING" "$DEPSVERSION"; then
	# satisfies depends
	return 0;
      fi
    done
    echo "      Tried versions: $PACKAGEVERSIONS"
    # cannot satisfy depends
    return 1;
}

get_control_re() {
    control="$1"
    re="$2"

    cat "$control" |
        awk '
        BEGIN { source=1 }
        /^$/ { source=0 }
        /^Source:/ { source=1 }
        /^[^ ]*:/ { p=0 }
        tolower($0) ~ /^'"$re"':/ { p=1 }
        { if (p && source) { print $0 } }' |
        sed 's/^[^: ]*://'
}

function checkbuilddep_archdeps () {
    # returns FALSE on INSTALL
    local INSTALLPKG="$1"
    local ARCH="$2"
    # architectures listed between [ and ] for this dep
    local DEP_ARCHES="$(echo "$INSTALLPKG" | sed 's/.*\[\(.*\)\].*/\1/')"
    # check for !$ARCH in DEP_ARCHES
    if echo "$DEP_ARCHES" | egrep -q "(^|[[:space:]/]+)\![[:space:]/]*$ARCH($|[[:space:]/]+)"; then
	return 0;
    fi
    # check for a "!" which would mean there's a !<otherarch> and hence $ARCH
    # is included
    if ! echo "$DEP_ARCHES" | grep -q '!'; then
        # check for $ARCH in DEP_ARCHES
	if ! echo "$DEP_ARCHES" | egrep -q "(^|[[:space:]/]+)$ARCH($|[[:space:]/]+)"; then
	    return 0;
	fi
    fi
    return 1;
}

function checkbuilddep_provides () {
    local PACKAGENAME="$1"
    # PROVIDED needs to be used outside of this function.
    PROVIDED=$($CHROOTEXEC /usr/bin/apt-cache showpkg $PACKAGENAME | awk '{p=0}/^Reverse Provides:/,/^$/{p=1}{if(p && ($0 !~ "Reverse Provides:")){PACKAGE=$1}} END{print PACKAGE}')
}

# returns either "package=version", to append to an apt-get install line, or
# package
function versioneddep_to_aptcmd () {
	local INSTALLPKG="$1"

	local PACKAGE
	local PACKAGE_WITHVERSION
	local PACKAGEVERSIONS
	local CANDIDATE_VERSION
	local COMPARESTRING
	local DEPSVERSION

	PACKAGE="$(echo "$INSTALLPKG" | sed -e 's/^[/]*//' -e 's/[[/(].*//')"
	PACKAGE_WITHVERSION="$PACKAGE"

	# if not versionned, we skip directly to outputting $PACKAGE
	if echo "$INSTALLPKG" | grep '[(]' > /dev/null; then
	    # package versions returned by APT, in reversed order
	    PACKAGEVERSIONS="$( package_versions "$PACKAGE" | tac | xargs )"
	    CANDIDATE_VERSION="$( candidate_version "$PACKAGE" )"

	    COMPARESTRING="$(echo "$INSTALLPKG" | tr "/" " " | sed 's/^.*( *\(<<\|<=\|>=\|=\|<\|>>\|>\) *\(.*\)).*$/\1/')"
	    DEPSVERSION="$(echo "$INSTALLPKG" | tr "/" " " | sed 's/^.*( *\(<<\|<=\|>=\|=\|<\|>>\|>\) *\(.*\)).*$/\2/')"
	    # if strictly versionned, we skip to outputting that version
	    if [ "=" = "$COMPARESTRING" ]; then
		PACKAGE_WITHVERSION="$PACKAGE=$DEPSVERSION"
	    else
		# try the candidate version, then all available versions (asc)
		for VERSION in $CANDIDATE_VERSION $PACKAGEVERSIONS; do
		    if dpkg --compare-versions "$VERSION" "$COMPARESTRING" "$DEPSVERSION"; then
			if [ $VERSION != $CANDIDATE_VERSION ]; then
			    PACKAGE_WITHVERSION="$PACKAGE=$VERSION"
			fi
			break;
		    fi
		done
	    fi
	fi

	echo "$PACKAGE_WITHVERSION"
}

function print_help () {
    # print out help message
    cat <<EOF
pbuilder-satisfydepends -- satisfy dependencies
Copyright 2002-2007  Junichi Uekawa <dancer@debian.org>

--help:        give help
--control:     specify control file (debian/control, *.dsc)
--chroot:      operate inside chroot
--binary-all:  include binary-all
--binary-arch: include binary-arch only
--echo:        echo mode, do nothing. (--force-version required for most operation)
--force-version: skip version check.
--continue-fail: continue even when failed.

EOF
}

