#!/bin/sh
# Script to demonstrate how apt-get always installs latest version
# of a dependency even if a package calls for an earlier version,
# and how to work around this using pinning.
# See also https://bugs.launchpad.net/ubuntu/+source/apt/+bug/1238982

set -e
set -x

do_build() {
    sudo apt-get install dpkg-dev devscripts debhelper

    for dir in myapp-1.0 mylib-1.0 mylib-2.0
    do
	cd $dir
	debuild -b -uc -us
	cd ..
    done

    sudo rm -f /etc/apt/sources.list.d/mydebs.list
    for v in 1 2
    do
	dir=$HOME/mydebs$v
        subdir=dists/lucid/main/binary-amd64
	rm -rf $dir
	mkdir -p $dir/$subdir
	eval cp my*${v}*deb $dir/$subdir
	(cd $dir; dpkg-scanpackages $subdir /dev/null | gzip -9c > $subdir/Packages.gz)
	echo "deb [arch=amd64] file:/home/$LOGNAME/mydebs$v lucid main" | sudo tee -a /etc/apt/sources.list.d/mydebs.list
    done

    cat > mylibs.pref <<_EOF_
Package: mylib
Pin: version 1.0
Pin-Priority: 1001
_EOF_
    sudo cp mylibs.pref /etc/apt/preferences.d/mylibs.pref
}

do_install() {
    sudo apt-get update
    apt-cache policy myapp mylib
    sudo apt-get install myapp

    # Unless you create /etc/apt/preferences.d/mylibs.pref as above, this fails with:
    #
    # myapp:
    #   Installed: (none)
    #   Candidate: 1.0
    #   Version table:
    #      1.0 0
    #         500 file:/home/dank/mydebs1/ lucid/main Packages
    # mylib:
    #   Installed: (none)
    #   Candidate: 2.0
    #   Version table:
    #      2.0 0
    #         500 file:/home/dank/mydebs2/ lucid/main Packages
    #      1.0 0
    #         500 file:/home/dank/mydebs1/ lucid/main Packages
    # Reading package lists... Done
    # Building dependency tree
    # Reading state information... Done
    # Some packages could not be installed. This may mean that you have
    # requested an impossible situation or if you are using the unstable
    # distribution that some required packages have not yet been created
    # or been moved out of Incoming.
    # The following information may help to resolve the situation:
    #
    # The following packages have unmet dependencies:
    #   myapp: Depends: mylib (= 1.0) but 2.0 is to be installed
    # E: Broken packages
}

do_clean() {
    rm -f *.deb *.changes *.build
    for dir in myapp-1.0 mylib-1.0 mylib-2.0
    do
        cd $dir
        debuild clean
        cd ..
    done
    sudo rm /etc/apt/preferences.d/mylibs.pref
    sudo apt-get remove mylib myapp
}

case $1 in
build) do_build;;
install) do_install;;
clean) do_clean;;
*) echo "usage: $0 build|install|clean"; exit 1;;
esac
