{-# LANGUAGE CPP #-} module Run ( doctest #ifdef TEST , doctest_ , Summary , stripOptGhc #endif ) where import Data.List import Control.Monad (when, unless) import System.Exit (exitFailure, exitSuccess) import System.IO import System.Environment (getEnvironment) import Control.Applicative import qualified Control.Exception as E import Panic import Parse import Help import Runner import qualified Interpreter ghcPackageDbFlag :: String #if __GLASGOW_HASKELL__ >= 706 ghcPackageDbFlag = "-package-db" #else ghcPackageDbFlag = "-package-conf" #endif -- | Run doctest with given list of arguments. -- -- Example: -- -- >>> doctest ["-iexample/src", "example/src/Example.hs"] -- Examples: 2 Tried: 2 Errors: 0 Failures: 0 -- -- This can be used to create a Cabal test suite that runs doctest for your -- project. doctest :: [String] -> IO () doctest args | "--help" `elem` args = putStr usage | "--version" `elem` args = printVersion | otherwise = do -- Look up the HASKELL_PACKAGE_SANDBOX environment variable and, if -- present, add it to the list of package databases GHC searches. -- Intended to make testing from inside sandboxes such as cabal-dev -- simpler. packageConf <- lookup "HASKELL_PACKAGE_SANDBOX" <$> getEnvironment let addPackageConf = case packageConf of Nothing -> id Just p -> \rest -> ghcPackageDbFlag : p : rest i <- Interpreter.interpreterSupported unless i $ do hPutStrLn stderr "WARNING: GHC does not support --interactive, skipping tests" exitSuccess let (f, args_) = stripOptGhc args when f $ do hPutStrLn stderr "WARNING: --optghc is deprecated, doctest now accepts arbitrary GHC options\ndirectly." hFlush stderr r <- doctest_ (addPackageConf args_) `E.catch` \e -> do case fromException e of Just (UsageError err) -> do hPutStrLn stderr ("doctest: " ++ err) hPutStrLn stderr "Try `doctest --help' for more information." exitFailure _ -> E.throwIO e when (not $ isSuccess r) exitFailure isSuccess :: Summary -> Bool isSuccess s = sErrors s == 0 && sFailures s == 0 -- | -- Strip --optghc from GHC options. This is for backward compatibility with -- previous versions of doctest. -- -- A boolean is returned with the stripped arguments. It is True if striping -- occurred. stripOptGhc :: [String] -> (Bool, [String]) stripOptGhc = go where go args = case args of [] -> (False, []) "--optghc" : opt : rest -> (True, opt : snd (go rest)) opt : rest -> maybe (fmap (opt :)) (\x (_, xs) -> (True, x :xs)) (stripPrefix "--optghc=" opt) (go rest) doctest_ :: [String] -> IO Summary doctest_ args = do -- get examples from Haddock comments modules <- getDocTests args Interpreter.withInterpreter args $ \repl -> do runModules repl modules