{-| Configuration and command-line arguments -} module Config ( Action(..) , parseArgs , usage , Usage , unUsage ) where import Data.Monoid ( Monoid(..) ) import Config.Store ( ParseStore, psConst, psArgStr , storeDocumentation ) import Config.GetOpt ( optSpec, noArgs ) import Config.Types ( Usage(..), strUsage, ActionSpec(..) , parseArgsG, CommandResult(..) ) import Config.Format ( twoColumn, indent ) import qualified Config.Command.Scan as Scan import qualified Config.Command.Report as Report import qualified Report as Report import qualified Config.Command.Run as Run import State.Types ( State ) import qualified State.Mem ( new ) import qualified State.Disk ( new ) import qualified State.SQLite ( new ) data Action = Help Usage | RunServer Run.Config | Report Report.ReportConfig | Scan Scan.Config parseArgs :: [String] -> Either Usage Action parseArgs args = case parseArgsG commands args of BadCommand u -> Left $ usage `mappend` u HelpRequest u -> Right $ Help u CommandFailed u -> Left u CommandOk x -> Right $ x -- |Add the preamble to the usage information and turn it into a String unUsage :: Int -> Usage -> String unUsage n u = let (Usage f) = strUsage preamble `mappend` u in unlines $ f n where preamble = "Web-based document review system, based on the system used for \ \Real World Haskell " usage :: Usage usage = mconcat [ Usage cmds , strUsage "Use --help for help on any individual command." , Usage $ storeDocumentation stores ] where cmds n = "Commands:":indent 2 (twoColumn (n - 2) $ map showCmd $ commands) showCmd as = (asName as, asDescr as) commands :: [ActionSpec Action] commands = [ optSpec "run" RunServer (Run.opts stores) Run.mkCfg "Run the HTTP server for Web-based document review, that can serve \ \the static content, the AJAX API for adding and displaying comments, \ \and the Atom feed and HTML comment viewing API" , optSpec "scan" Scan (Scan.opts stores) Scan.mkCfg "Scan a set of documents for commentable items and (optionally) update \ \a store" , optSpec "report" Report Report.opts Report.mkCfg "Process a set of binary log files and produce a usage report" , optSpec "help" Help [] (noArgs usage) "Show this help text" ] stores :: [ ParseStore (IO State) ] stores = [ psConst "mem" State.Mem.new "Use an ephemeral in-memory store (data will be lost when \ \the process ends)" , psArgStr "fs" "DIRECTORY" State.Disk.new "Store data in flat files in the specified directory. This \ \store is not ACID (has known race conditions and updates \ \are not atomic)" , psArgStr "sqlite" "DBNAME" State.SQLite.new "Store data in a SQLite database specified by DBNAME. Uses \ \the syntax of the SQLite API" ]