{-# OPTIONS_GHC -Wall #-} module Main where import Control.Monad as List (mapM_) import Control.Monad.Trans (MonadIO(liftIO)) import Data.List (intercalate, isPrefixOf) import Data.Set.Extra as Set (Set, toList) import Language.Haskell.Modules import Language.Haskell.Modules.ModuVerse (getNames) import Language.Haskell.Modules.SourceDirs (getDirs) import System.IO (hGetLine, hPutStr, hPutStrLn, stderr, stdin) main :: IO () main = runCleanT (noisily cli) cli :: MonadClean m => m () cli = liftIO (hPutStr stderr " > " >> hGetLine stdin) >>= cmd . words cmd :: MonadClean m => [String] -> m () cmd [] = cli cmd (s : args) = case filter (any (== s) . fst) cmds of [(_, f)] -> f -- No exact matches - look for prefix matches [] -> case filter (any (isPrefixOf s) . fst) cmds of [(_, f)] -> f [] -> liftIO (hPutStrLn stderr $ show s ++ " invalid - expected " ++ intercalate ", " (concatMap fst cmds)) >> cli xs -> liftIO (hPutStrLn stderr $ show s ++ " ambiguous - expected " ++ intercalate ", " (concatMap fst xs)) >> cli _ -> error $ "Internal error - multiple definitions for " ++ show s where cmds = [(["quit", "exit", "bye", "."], liftIO (hPutStrLn stderr "Exiting")), (["v"], liftIO (hPutStrLn stderr "Increasing verbosity level") >> noisily cli), (["q"], liftIO (hPutStrLn stderr "Decreasing verbosity level") >> quietly cli), (["help"], liftIO (hPutStrLn stderr "help text") >> cli), (["verse"], verse args >> cli), (["clean"], clean args >> cli), (["dir"], dir args >> cli), (["split"], split args >> cli), (["merge"], merge args >> cli)] unModuleName :: ModuleName -> String unModuleName (ModuleName x) = x verse :: MonadClean m => [String] -> m () verse [] = do modules <- getNames liftIO $ hPutStrLn stderr ("Usage: verse ...\n" ++ "Add the module or all the modules below a directory to the moduVerse\n" ++ "Currently:\n " ++ showVerse modules) verse args = do new <- mapM (liftIO . find) args List.mapM_ (List.mapM_ putModule) new modules <- getNames liftIO (hPutStrLn stderr $ "moduVerse updated:\n " ++ showVerse modules) where find s = do ms <- liftIO (findHsModules [s]) case ms of [] -> return [ModuleName s] _ -> return ms showVerse :: Set ModuleName -> String showVerse modules = "[ " ++ intercalate "\n , " (map unModuleName (toList modules)) ++ " ]" dir :: MonadClean m => [FilePath] -> m () dir [] = putDirs [] dir xs = do modifyDirs (++ xs) xs' <- getDirs liftIO (hPutStrLn stderr $ "sourceDirs updated:\n [ " ++ intercalate "\n , " xs' ++ " ]") clean :: MonadClean m => [FilePath] -> m () clean [] = liftIO $ hPutStrLn stderr "Usage: clean ..." clean args = cleanImports args >> return () split :: MonadClean m => [FilePath] -> m () split [arg] = splitModuleDecls arg >> return () split _ = liftIO $ hPutStrLn stderr "Usage: split " merge :: MonadClean m => [String] -> m () merge args = case splitAt (length args - 1) args of (inputs, [output]) -> mergeModules (map ModuleName inputs) (ModuleName output) >> return () _ -> liftIO $ hPutStrLn stderr "Usage: merge ... "