gdritter repos GRUtils / master scripts / ghc-wrapper
master

Tree @master (Download .tar.gz)

ghc-wrapper @masterraw · history · blame

#!/bin/bash -e

# ghc wrapper script (for managing installed GHC versions)
# this is a small script I use that allows multiple simultaneous ghc
# installations. This makes the following assumptions about how
# you want to set up your system:
# - GHC version {X} is installed with prefix ~/install/ghc-${X}
# - A file naming the current selected GHC version is placed
#   at ~/.current-ghc
# - cabal is configured to point to this script instead of ghc
# - If using fetch, then mktemp must result in a directory to which
#   this script can write, as well
# This script is being run as a user that can read and modify things
# in your $HOME directory.

if [[ "$1" = "list" ]]; then
    for f in $(ls ~/install/ | grep ghc); do
        # It's possible (for various reasons) for /none/ of the
        # current versions to be selected, in which case all of
        # them will be prefixed by a -; otherwise, the one that
        # is selected will be prefixed by a +.
        if [[ "$f" = "$(cat ~/.current-ghc)" ]]; then
            echo "+" $f
        else
            echo "-" $f
        fi
    done
elif [[ "$1" = "set" ]]; then
    MATCHES=($(ls ~/install | grep ghc | grep -e "$2"))
    if [[ -z $MATCHES ]]; then
        # There is nothing in ~/install that matches that version
        echo "Unknown GHC version: $2"
    elif [ "${#MATCHES[@]}" -eq "1" ]; then
        # There is exactly one relevant match---we can use that one!
        echo "Setting GHC version to $MATCHES"
        echo $MATCHES >~/.current-ghc
    else
        # The regex given matches too many versions.
        echo "Ambiguous GHC version: argument matches"
        for f in "${MATCHES[@]}"; do
            echo "  " $f
        done
    fi
elif [[ "$1" = "fetch" ]]; then
    VERSION="$2"
    URL="https://www.haskell.org/ghc/dist/$VERSION/ghc-$VERSION-src.tar.xz"
    LOC=$(mktemp -d)
    (
        echo "Attempting to fetch $URL..." &&
        curl -L "$URL" >"$LOC/ghc.tar.xz" &&
        cd "$LOC" &&
        echo "...tarball fetched; unpacking..." &&
        tar -xf "ghc.tar.xz" &&
        cd "$LOC/ghc-$VERSION" &&
        echo "Creating $HOME/install/ghc-$VERSION" &&
        mkdir -p "$HOME/install/ghc-$VERSION" &&
        ./configure --prefix="$HOME/install/ghc-$VERSION" &&
        echo "... starting build process..." &&
        make &&
        make install &&
        echo "...finished!"
    )
elif [[ "$1" = "--wrapper-help" ]]; then
    cat <<EOF
$0 [wrapper script]
Usage:
  $0 list              List installed versions of ghc
  $0 set [regex]       Set current GHC to the version that uniquely
                          matches the supplied regex
  $0 fetch [version]   Fetch, build, and install the specified version
                          of GHC. (Does not change the current version.)
  $0 --wrapper-help    See this help menu
  $0 [anything else]   Use GHC normally

This wrapper script assumes that you'll always install your GHC versions
to ~/install/ghc-{VERSION}, and will store the currently selected GHC version
in ~/.current-ghc.

WARNING: This script is quite brittle and makes a lot of assumptions about
how you lay things out! While I suspect it shouldn't actively break anything,
be careful about using it!
EOF
elif [ ! -e ~/.current-ghc ]; then
    # we haven't run this script before and don't have a .current-ghc, and
    # we rely on having a binary _somewhere_, so let's use a default one
    exec /usr/bin/ghc "$@"
elif [ ! -e /home/gdritter/install/$(cat ~/.current-ghc)/bin/$(basename $0) ]; then
    # we HAVE a .current-ghc but it doesn't exist, so let's also default to
    # the one in /usr/bin
    exec /usr/bin/ghc "$@"
else
   exec /home/gdritter/install/$(cat ~/.current-ghc)/bin/$(basename $0) "$@"
fi