--
-- | Let's go lambdabot!
--
module Main where
import Lambdabot.Main
import Lambdabot.Plugin.Haskell
import Modules (modulesInfo)
import qualified Paths_lambdabot as P
import Control.Applicative
import Control.Monad
import Control.Monad.Identity
import Data.Char
import Data.Version
import System.Console.GetOpt
import System.Environment
import System.Exit
import System.IO
flags :: [OptDescr (IO (DSum Config Identity))]
flags =
[ Option "h?" ["help"] (NoArg (usage [])) "Print this help message"
, Option "e" [] (arg "<command>" onStartupCmds strs) "Run a lambdabot command instead of a REPL"
, Option "l" [] (arg "<level>" consoleLogLevel level) "Set the logging level"
, Option "t" ["trust"] (arg "<package>" trustedPackages strs) "Trust the specified packages when evaluating code"
, Option "V" ["version"] (NoArg version) "Print the version of lambdabot"
, Option "X" [] (arg "<extension>" languageExts strs) "Set a GHC language extension for @run"
, Option "n" ["nice"] (NoArg noinsult) "Be nice (disable insulting error messages)"
] where
arg :: String -> Config t -> (String -> IO t) -> ArgDescr (IO (DSum Config Identity))
arg descr key fn = ReqArg (fmap (key ==>) . fn) descr
strs = return . (:[])
level str = case reads (map toUpper str) of
(lv, []):_ -> return lv
_ -> usage
[ "Unknown log level."
, "Valid levels are: " ++ show [DEBUG, INFO, NOTICE, WARNING, ERROR, CRITICAL, ALERT, EMERGENCY]
]
noinsult = return (enableInsults ==> False)
versionString :: String
versionString = ("lambdabot version " ++ showVersion P.version)
version :: IO a
version = do
putStrLn versionString
exitWith ExitSuccess
usage :: [String] -> IO a
usage errors = do
cmd <- getProgName
let isErr = not (null errors)
out = if isErr then stderr else stdout
mapM_ (hPutStrLn out) errors
when isErr (hPutStrLn out "")
hPutStrLn out versionString
hPutStr out (usageInfo (cmd ++ " [options]") flags)
exitWith (if isErr then ExitFailure 1 else ExitSuccess)
-- do argument handling
main :: IO ()
main = do
(config, nonOpts, errors) <- getOpt Permute flags <$> getArgs
when (not (null errors && null nonOpts)) (usage errors)
config' <- sequence config
dir <- P.getDataDir
exitWith <=< lambdabotMain modulesInfo $
[dataDir ==> dir, lbVersion ==> P.version] ++ config'
-- special online target for ghci use
online :: [String] -> IO ()
online strs = do
dir <- P.getDataDir
void $ lambdabotMain modulesInfo
[dataDir ==> dir, lbVersion ==> P.version, onStartupCmds ==> strs]