exchangealgebra-0.6.0.0: test/compile-fail/check.sh
#!/usr/bin/env bash
# From the repository root:
# stack build --test --bench --no-run-benchmarks
# bash test/compile-fail/check.sh
# Set STACK_ARGS to the global stack options used for that build (for example
# "--system-ghc --no-install-ghc" in CI) so the check reads the same package db.
# Compile as an external installed-package client with source lookup disabled.
# Logs and compiler artifacts live in a temporary directory removed on exit.
set -euo pipefail
admission_root=$(cd "$(dirname "$0")/../.." && pwd)
admission_tmp=$(mktemp -d "${TMPDIR:-/tmp}/ea-admission-boundary.XXXXXX")
trap 'rm -rf "$admission_tmp"' EXIT
read -r -a admission_stack_args <<< "${STACK_ARGS:-}"
compile() {
local snippet=$1
stack ${admission_stack_args[@]+"${admission_stack_args[@]}"} \
--stack-yaml "$admission_root/stack.yaml" exec -- ghc \
-fno-code -fforce-recomp -v0 -Wdeprecations -fdiagnostics-color=never -i \
-hide-all-packages -package base -package text -package containers \
-package exchangealgebra -outputdir "$admission_tmp" \
"$admission_root/test/compile-fail/$snippet.hs" \
> "$admission_tmp/$snippet.log" 2>&1
}
reject() {
local snippet=$1
local reason=$2
if compile "$snippet"; then
printf '[FAIL] %s compiled unexpectedly\n' "$snippet"
exit 1
fi
if ! grep -Eq "$reason" "$admission_tmp/$snippet.log"; then
printf '[FAIL] %s failed for an unexpected reason\n' "$snippet"
cat "$admission_tmp/$snippet.log"
exit 1
fi
printf '[PASS] %s rejected for the intended reason\n' "$snippet"
}
cd "$admission_tmp"
if ! compile PublicClient; then
cat "$admission_tmp/PublicClient.log"
exit 1
fi
printf '[PASS] public API client compiled\n'
if ! compile PublicExplicitImportClient; then
cat "$admission_tmp/PublicExplicitImportClient.log"
exit 1
fi
printf '[PASS] explicit-import client compiled\n'
reject Constructor 'Data constructor not in scope:.*Admitted|Not in scope:.*Admitted|Illegal term-level use of the type constructor.*Admitted'
reject AdmissionFailureConstructor 'Data constructor not in scope:.*AdmissionFailure|Not in scope:.*AdmissionFailure|Illegal term-level use of the type constructor.*AdmissionFailure'
reject RecordUpdate 'not a record selector|not a record field|Not in scope: record field.*admittedJournal'
reject Coerce "Couldn't match (representation|type)|Could not deduce.*Coercible"
reject RawDerivation "Couldn't match.*(Admitted|Journal)|Expected:.*Admitted"
reject HiddenModule 'hidden module'
if ! grep -Fq 'ExchangeAlgebra.IO.Input.Admission.Representation' "$admission_tmp/HiddenModule.log"; then
printf '[FAIL] HiddenModule rejected a module other than the admission internal module\n'
cat "$admission_tmp/HiddenModule.log"
exit 1
fi
reject AlgConstructor 'non-bidirectional pattern synonym|not bidirectional'
reject AlgRecordUpdate 'non-bidirectional pattern synonym|not a record selector|not a record field'
reject AlgHiddenConstructor 'does not export any children|does not export.*(Single|Liner)'
# Deprecated APIs remain usable, and their warning survives public rule-module re-export.
warn_deprecated() {
local snippet=$1
local identifier=$2
if ! compile "$snippet"; then
printf '[FAIL] %s did not compile\n' "$snippet"
cat "$admission_tmp/$snippet.log"
exit 1
fi
if ! grep -Eq "In the use of [‘'\"]([^‘’'\"]*\\.)?${identifier}[’'\"]" \
"$admission_tmp/$snippet.log"; then
printf '[FAIL] %s compiled without the expected deprecation warning\n' "$snippet"
cat "$admission_tmp/$snippet.log"
exit 1
fi
printf '[PASS] %s compiled with the expected deprecation warning\n' "$snippet"
}
warn_deprecated DeprecatedTransfer scaleBy