#!/bin/bash set -eu set -o pipefail ## Helper Functions function loud { echo "$ $@" $@ } function stack { $HOME/.local/bin/stack --no-terminal "$@" } # Source: https://github.com/travis-ci/travis-build/blob/fc4ae8a2ffa1f2b3a2f62533bbc4f8a9be19a8ae/lib/travis/build/script/templates/header.sh#L104-L123 RED="\033[31;1m" GREEN="\033[32;1m" RESET="\033[0m" function travis_retry { local result=0 local count=1 while [ $count -le 3 ]; do [ $result -ne 0 ] && { echo -e "\n${RED}The command \"$@\" failed. Retrying, $count of 3.${RESET}\n" >&2 } set +e "$@" result=$? set -e [ $result -eq 0 ] && break count=$(($count + 1)) sleep 1 done [ $count -eq 4 ] && { echo "\n${RED}The command \"$@\" failed 3 times.${RESET}\n" >&2 } return $result } function prevent_timeout { local cmd="$@" $cmd & local cmd_pid=$! poke_stdout & local poke_pid=$! wait $cmd_pid exit_code=$? kill $poke_pid (wait $poke_pid 2>/dev/null) || true return $exit_code } function poke_stdout { # Print an invisible character every minute while true; do echo -ne "\xE2\x80\x8B" sleep 60 done } function pastebin { curl -s -F 'clbin=<-' https://clbin.com } ## Setup Stages function install_smt { local smt="$1" mkdir -p "${HOME}/.local/bin" loud curl "http://goto.ucsd.edu/~gridaphobe/$smt" -o "${HOME}/.local/bin/$smt" loud chmod a+x "${HOME}/.local/bin/$smt" } function install_stack { local stack_version="$1" mkdir -p "${HOME}/.local/bin" mkdir -p '/tmp/stack' pushd '/tmp/stack' local dir_name="stack-${stack_version}-x86_64-linux" local archive_name="${dir_name}.tar.gz" local stack_url="https://github.com/commercialhaskell/stack/releases/download/v${stack_version}/${archive_name}" loud wget "${stack_url}" loud tar -xzvf "./${archive_name}" loud cp "./${dir_name}/stack" "${HOME}/.local/bin/stack" loud chmod a+x "${HOME}/.local/bin/stack" popd } function configure_stack { local ghc_version="$1" echo "Configuring stack.yaml for ${ghc_version}..." cat << EOF > 'stack.yaml' resolver: ${ghc_version} packages: - ./liquid-fixpoint - . EOF loud cat stack.yaml } function setup_ghc { loud stack setup loud stack ghc -- --version } function install_dependencies { echo "Solving dependency constraints..." loud stack update loud stack solver --update-config echo "Installing dependencies..." loud stack build liquidhaskell --only-dependencies --test --no-run-tests --no-haddock-deps } ## Building & Testing Stages function do_build { loud stack build liquidhaskell --test --no-run-tests --haddock --no-haddock-deps --flag liquidhaskell:devel } function do_test { local tests="$1" local smt="$2" local test_runner="$(stack path --dist-dir)/build/test/test" loud prevent_timeout stack exec -- "${test_runner}" --pattern "$tests/" --smtsolver "$smt" -j2 +RTS -N2 -RTS } function dump_fail_logs { find tests/logs/cur -type f -name '*log.fail' -print0 | while IFS= read -r -d $'\0' file; do echo "${file}:" echo " $(pastebin < "${file}")" done } ## Run Test Stage stage="$1" shift $stage "$@"