module Main where
import Query
import Stats
import Control.Applicative
import Control.Monad
import Control.Arrow
import Data.Maybe
import System
import System.Console.GetOpt
import System.FilePath
import System.Directory
usage = unlines ["Report generator\nCopyright 2009-2010, Bart Spaans\n",
"Usage: report [OPTIONS] LOGFILE [QUERYFILE..]]\n"]
data Options = Options {
interactive :: Bool
, askOptions :: Bool
, lang :: [(String, String)]
, proj :: [(String, String)]
, home :: Maybe (IO String)
, format :: [String]
, commands :: [String]
}
defaultOptions :: Options
defaultOptions = Options { interactive = False
, lang = []
, proj = []
, home = Just (getHomeDirectory)
, askOptions = False
, format = []
, commands = []
}
options :: [ OptDescr (Options -> IO Options) ]
options = [Option "h" ["help"] (NoArg outputHelp) "Output command info"
, Option "f" ["format"] (ReqArg setFormat "FORMAT") "Set default format (csv, html, text, xhtml)"
, Option "H" ["home"] (ReqArg setHome "HOME") "Set HOME directory"
, Option "i" ["interactive"] (NoArg setInteractive) "Start interactive query session"
, Option "l" ["language"] (ReqArg setLanguage "PATH") "Set languages directory"
, Option "q" ["query"] (ReqArg addCommand "QUERY") "Evaluate query."
, Option "p" ["project"] (ReqArg setProject "PATH") "Set projects directory"
]
addCommand c opt = return opt { commands = c : commands opt }
outputHelp _ = putStrLn (usageInfo usage options) >> exitWith ExitSuccess
setFormat f opt = return opt { format = f : format opt }
setHome h opt = return opt { home = Just (return h) }
setInteractive opt = return opt { interactive = True }
setLanguage path opt = return opt { lang = parseDescription path : (lang opt) }
setProject path opt = return opt { proj = parseDescription path : (proj opt) }
makeStatOptions :: Options -> IO StatOptions
makeStatOptions opts = do h <- fromMaybe (return "none") $ home opts
return SO { languages = toMatches $ lang opts
, projects = toMatches $ proj opts
, homePath = h }
makePO :: Options -> E PrintOptions
makePO = setPrinters . format
main = do
args <- getArgs
let (actions, nonOpts, msgs) = getOpt RequireOrder options args
when (msgs /= []) (error $ concat msgs)
opts <- foldl (>>=) (return defaultOptions) actions
so <- makeStatOptions opts
po <- case makePO opts of { Failed s -> error s ; Ok a -> return a }
if null nonOpts then putStrLn usage else exec' so po opts nonOpts
exec' so po opts nonOpts=
do stats <- statsFromFile (head nonOpts) so
let i = interactiveQueries po stats
if not . null $ commands opts
then putStr $ execute' emptyEnv po (commands opts) stats
else when (length nonOpts <= 1) (i emptyEnv)
if length nonOpts > 1
then do co <- commandsFromFiles emptyEnv (tail nonOpts)
case co of
Failed s -> error s
Ok (st, e) -> do putStr $ execute emptyEnv po co stats
when (interactive opts) (i e)
else when (interactive opts) (i emptyEnv)