{-# LANGUAGE LambdaCase #-} module Hpack.Options where import Control.Monad import System.FilePath import System.Directory data ParseResult = Help | PrintVersion | PrintNumericVersion | Run Options | ParseError deriving (Eq, Show) data Verbose = Verbose | NoVerbose deriving (Eq, Show) data Force = Force | NoForce deriving (Eq, Show) data Options = Options { optionsVerbose :: Verbose , optionsForce :: Force , optionsToStdout :: Bool , optionsConfigDir :: Maybe FilePath , optionsConfigFile :: FilePath } deriving (Eq, Show) parseOptions :: FilePath -> [String] -> IO ParseResult parseOptions defaultConfigFile xs = case xs of ["--version"] -> return PrintVersion ["--numeric-version"] -> return PrintNumericVersion ["--help"] -> return Help _ -> case targets of Just (target, toStdout) -> do (dir, file) <- splitDirectory defaultConfigFile target return $ Run (Options verbose force toStdout dir file) Nothing -> return ParseError where silentFlag = "--silent" forceFlags = ["--force", "-f"] flags = silentFlag : forceFlags verbose = if silentFlag `elem` xs then NoVerbose else Verbose force = if any (`elem` xs) forceFlags then Force else NoForce ys = filter (`notElem` flags) xs targets = case ys of ["-"] -> Just (Nothing, True) ["-", "-"] -> Nothing [dir] -> Just (Just dir, False) [dir, "-"] -> Just (Just dir, True) [] -> Just (Nothing, False) _ -> Nothing splitDirectory :: FilePath -> Maybe FilePath -> IO (Maybe FilePath, FilePath) splitDirectory defaultFileName = \ case Nothing -> return (Nothing, defaultFileName) (Just p) -> do isDirectory <- doesDirectoryExist p return $ if isDirectory then (Just p, defaultFileName) else let file = takeFileName p dir = takeDirectory p in (guard (p /= file) >> Just dir, if null file then defaultFileName else file)