@@ -1,24 +1,102 @@
11#!/usr/bin/env bash
22# bin/compile <build-dir> <cache-dir> <env-dir>
33
4−set -eo pipefail
4+set -e
5+set -o pipefail
56
67# Heroku-provided params
78BUILD_DIR="$1"
89CACHE_DIR="$2"
910ENV_DIR="$3"
1011
11−mkdir $BUILD_DIR $CACHE_DIR
12−build=$(cd $BUILD_DIR && pwd)
13−cache=$(cd $CACHE_DIR && pwd)
12+# Default configuration which you can change by setting environment variables
13+PREBUILT=${PREBUILT:-https://s3.amazonaws.com/heroku-ghc}
1414
15−cd $cache
16−curl -sL https://github.com/commercialhaskell/stack/releases/download/v0.1.3.1/stack-0.1.3.1-x86_64-linux.gz | gunzip > stack
17−chmod a+x $cache/stack
18−export PATH=$cache/stack:$PATH
19−cd -
15+function export_env_dir() {
16+ blacklist_regex="^(PATH|GIT_DIR|CPATH|CPPATH|LD_PRELOAD|LIBRARY_PATH)$"
17+ if [ -d "$ENV_DIR" ]; then
18+ echo "-----> Exporting config vars"
19+ for e in $(ls "$ENV_DIR"); do
20+ echo "$e" | grep -qvE "$blacklist_regex" &&
21+ export "$e=$(cat $ENV_DIR/$e)"
22+ :
23+ done
24+ fi
25+}
2026
21−cd $build
27+export_env_dir
28+
29+WORK_DIR=/app
30+PROFILE_PATH="$BUILD_DIR/.profile.d/haskell.sh"
31+
32+mkdir -p $WORK_DIR/vendor
33+mkdir -p $(dirname $PROFILE_PATH)
34+
35+########## gmp #####################################################
36+mkdir -p $WORK_DIR/vendor/ghc-libs
37+if [ ! -e $CACHE_DIR/libgmp-6.0.0a ]; then
38+ PREBUILT_LIB_URL=$PREBUILT/heroku-libgmp-6.0.0a.tar.gz # contains ghc-libs directories
39+ echo "-----> Installing prebuilt libgmp-6.0.0a into cache"
40+ mkdir -p $CACHE_DIR/libgmp-6.0.0a
41+ curl -# -L "$PREBUILT_LIB_URL" | tar xz -C $CACHE_DIR/libgmp-6.0.0a
42+fi
43+echo "-----> Restoring libgmp-6.0.0a files from cache"
44+find $CACHE_DIR/libgmp-6.0.0a/ghc-libs/ -exec cp -rP '{}' $WORK_DIR/vendor/ghc-libs/ \;
45+
46+# Usage: $ set-env key value
47+function set-env (){
48+ echo "export $1=$2" >> $PROFILE_PATH
49+}
50+
51+# Usage: $ set-default-env key value
52+function set-default-env (){
53+ echo "export $1=\${$1:-$2}" >> $PROFILE_PATH
54+}
55+
56+export LANG=en_US.UTF-8
57+export LIBRARY_PATH=$WORK_DIR/vendor/ghc-libs:/usr/lib:$LIBRARY_PATH
58+export LD_LIBRARY_PATH=$LIBRARY_PATH
59+export PATH=$WORK_DIR/.local/bin:$WORK_DIR/vendor/bin:$PATH
60+
61+########## stack ###################################################
62+mkdir -p $WORK_DIR/vendor/bin
63+if [ ! -e $CACHE_DIR/stack ]; then
64+ echo "-----> Downloading Stack"
65+ curl -# -L https://github.com/commercialhaskell/stack/releases/download/v0.1.3.1/stack-0.1.3.1-x86_64-linux.gz | gunzip > $CACHE_DIR/stack
66+ cp $CACHE_DIR/stack $WORK_DIR/vendor/bin/stack
67+ chmod a+x $WORK_DIR/vendor/bin/stack
68+else
69+ echo "-----> Restoring Stack"
70+ rm -f $WORK_DIR/vendor/bin/stack
71+ cp $CACHE_DIR/stack $WORK_DIR/vendor/bin/stack
72+ chmod a+x $WORK_DIR/vendor/bin/stack
73+fi
74+
75+if [ -e $CACHE_DIR/.stack ]; then
76+ echo "-----> Restoring .stack"
77+ rm -fr $WORK_DIR/.stack
78+ cp -R $CACHE_DIR/.stack $WORK_DIR
79+fi
80+
81+########## project build ###########################################
82+
83+echo "-----> Stack"
84+cd $BUILD_DIR
2285stack setup
23−stack build
86+stack build --copy-bins
87+
88+echo "-----> Caching .stack"
89+rm -fr $CACHE_DIR/.stack
90+cp -R $WORK_DIR/.stack $CACHE_DIR
91+
92+# Set context environment variables.
93+set-env PATH "/app/.local/bin:$PATH"
94+
95+set-default-env LIBRARY_PATH /app/vendor/ghc-libs:/usr/lib
96+set-default-env LD_LIBRARY_PATH /app/vendor/ghc-libs:/usr/lib
2497
98+echo "-----> Making GHC binaries available to Heroku command line"
99+mkdir -p $BUILD_DIR/vendor
100+mkdir -p $BUILD_DIR/.local
101+mv $WORK_DIR/vendor/ghc-libs $BUILD_DIR/vendor
102+mv $WORK_DIR/.local/bin $BUILD_DIR/.local