#!/usr/bin/env bash

RESULT=tmpfile
ROOT=..
ERRORSTATUS=0

# lookfor ( $1=what, $2=reason, $3=source module exception )
lookfor () {
    rm -f "$RESULT"
    darcs query manifest --repodir="$ROOT" | grep '\.l\?hs$' | while read f; do
        grep -Hnwe "$1" "$ROOT/$f" | grep -v "$3\.$1" | \
        grep -v ":[0-9]\+:import " | grep -Fv "ratify $1: " >> "$RESULT"
    done
    if [ -s "$RESULT" ]; then
        echo "Found the following unratified uses of $1:"
        # ugly sed expresion to fix relative paths; think pretty cat
        sed -e 's/[^:]*\/\.\///' "$RESULT"
        echo "$2"
        echo "Comment 'ratify $1: <why>' on the same line to allow it"
        echo
        ERRORSTATUS=1
    fi
    rm -f "$RESULT"
}

# On 2009-02-12 Petr Rockai explained this on darcs-users:
# The problem with Prelude readFile is that it's based on hGetContents, which
# is lazy by definition. This also means that unless you force consumption of
# the produced list, it will keep an fd open for the file, possibly
# indefinitely.  This is called a fd leak. Other than being annoying and if done
# often, leading to fd exhaustion and failure to open any new files (which is
# usually fatal), it also prevents the file to be unlinked (deleted) on win32.
#
# On the other hand, *strict* bytestring version of readFile will read the whole
# file into a contiguous buffer, *close the fd* and return. This is perfectly
# safe with regards to fd leaks. Btw., this is *not* the case with lazy
# bytestring variant of readFile, so that one is unsafe.
lookfor readFile \
        "Prelude.readFile doesn't ensure the file is closed before it is deleted!\nConsider import Data.ByteString.Char8 as B (readFile), B.readFile instead." \
        B # importing readFile from Data.ByteString as B, is allowed

lookfor hGetContents \
        "hGetContents doesn't ensure the file is closed before it is deleted!"

# look for tabs in haskell source
rm -f "$RESULT"
darcs query manifest --repodir="$ROOT" | grep '\.l\?hs$' | while read f; do
    grep -FHnwe "	" "$ROOT/$f" >> "$RESULT"
done
if [ -s "$RESULT" ]; then
    echo "Found the following lines with unwanted tabs:"
    # ugly sed expresion to fix relative paths; think pretty cat
    sed -e 's/[^:]*\/\.\///' "$RESULT"
    echo
    ERRORSTATUS=1
fi
rm -f "$RESULT"

exit "$ERRORSTATUS"

