{-# LANGUAGE CPP #-} {-# LANGUAGE DeriveFunctor #-} module Options ( Result(..) , Run(..) , defaultMagic , defaultFastMode , defaultPreserveIt , defaultVerbose , parseOptions #ifdef TEST , usage , info , versionInfo #endif ) where import Prelude () import Prelude.Compat import Data.List.Compat import Data.Maybe import qualified Paths_doctest import Data.Version (showVersion) import Config as GHC import Interpreter (ghc) usage :: String usage = unlines [ "Usage:" , " doctest [ --fast | --preserve-it | --no-magic | --verbose | GHC OPTION | MODULE ]..." , " doctest --help" , " doctest --version" , " doctest --info" , "" , "Options:" , " --fast disable :reload between example groups" , " --preserve-it preserve the `it` variable between examples" , " --verbose print each test as it is run" , " --help display this help and exit" , " --version output version information and exit" , " --info output machine-readable version information and exit" ] version :: String version = showVersion Paths_doctest.version ghcVersion :: String ghcVersion = GHC.cProjectVersion versionInfo :: String versionInfo = unlines [ "doctest version " ++ version , "using version " ++ ghcVersion ++ " of the GHC API" , "using " ++ ghc ] info :: String info = "[ " ++ (intercalate "\n, " . map show $ [ ("version", version) , ("ghc_version", ghcVersion) , ("ghc", ghc) ]) ++ "\n]\n" data Result a = Output String | Result a deriving (Eq, Show, Functor) type Warning = String data Run = Run { runWarnings :: [Warning] , runOptions :: [String] , runMagicMode :: Bool , runFastMode :: Bool , runPreserveIt :: Bool , runVerbose :: Bool } deriving (Eq, Show) defaultMagic :: Bool defaultMagic = True defaultFastMode :: Bool defaultFastMode = False defaultPreserveIt :: Bool defaultPreserveIt = False defaultVerbose :: Bool defaultVerbose = False parseOptions :: [String] -> Result Run parseOptions args | "--help" `elem` args = Output usage | "--info" `elem` args = Output info | "--version" `elem` args = Output versionInfo | otherwise = case fmap (fmap (fmap stripOptGhc)) . fmap (fmap stripVerbose) . fmap stripPreserveIt . stripFast <$> stripNoMagic args of (magicMode, (fastMode, (preserveIt, (verbose, (warning, xs))))) -> Result (Run (maybeToList warning) xs magicMode fastMode preserveIt verbose) stripNoMagic :: [String] -> (Bool, [String]) stripNoMagic = stripFlag (not defaultMagic) "--no-magic" stripFast :: [String] -> (Bool, [String]) stripFast = stripFlag (not defaultFastMode) "--fast" stripPreserveIt :: [String] -> (Bool, [String]) stripPreserveIt = stripFlag (not defaultPreserveIt) "--preserve-it" stripVerbose :: [String] -> (Bool, [String]) stripVerbose = stripFlag (not defaultVerbose) "--verbose" stripFlag :: Bool -> String -> [String] -> (Bool, [String]) stripFlag enableIt flag args = ((flag `elem` args) == enableIt, filter (/= flag) args) stripOptGhc :: [String] -> (Maybe Warning, [String]) stripOptGhc = go where go args = case args of [] -> (Nothing, []) "--optghc" : opt : rest -> (Just warning, opt : snd (go rest)) opt : rest -> maybe (fmap (opt :)) (\x (_, xs) -> (Just warning, x : xs)) (stripPrefix "--optghc=" opt) (go rest) warning = "WARNING: --optghc is deprecated, doctest now accepts arbitrary GHC options\ndirectly."