@@ -6,6 +6,7 @@ import qualified Control.Exception as Exception
66import Control.Monad
77import Control.Monad.IO.Class
88import Control.Monad.Trans.Maybe
9+import Control.DeepSeq (force)
910import Data.List ( isSuffixOf, isPrefixOf )
1011import qualified Data.Map as DB
1112import Data.Maybe
@@ -25,7 +26,7 @@ import OpenSSL.Digest ( digestString, digestByName )
2526import System.Directory ( doesDirectoryExist, doesFileExist, createDirectoryIfMissing, getHomeDirectory, getDirectoryContents )
2627import System.Exit ( exitFailure )
2728import System.FilePath ( (</>), (<.>) )
28−import System.IO ( hPutStrLn, stderr, hPutStr )
29+import System.IO
2930
3031data Package = Package
3132 { pkgSource :: DerivationSource
@@ -206,12 +207,13 @@ hpackDirectory dir = do
206207
207208cabalFromFile :: Bool -> FilePath -> MaybeT IO Cabal.GenericPackageDescription
208209cabalFromFile failHard file =
209− -- readFile throws an error if it's used on binary files which contain sequences
210+ -- hGetContents throws an error if it's used on files which contain sequences
210211 -- that do not represent valid characters. To catch that exception, we need to
211− -- wrap the whole block in `catchIO`, because of lazy IO. The `case` will force
212− -- the reading of the file, so we will always catch the expression here.
212+ -- wrap the whole block in `catchIO`.
213213 MaybeT $ handleIO (\err -> Nothing <$ hPutStrLn stderr ("*** parsing cabal file: " ++ show err)) $ do
214− buf <- readFile file
214+ buf <- withFile file ReadMode $ \ h -> do
215+ hSetEncoding h utf8
216+ hGetContents h >>= Exception.evaluate . force
215217 let hash = printSHA256 (digestString (digestByName "sha256") buf)
216218 case parseGenericPackageDescription buf of
217219 ParseFailed perr -> if failHard