-------------------------------------------------------------------------------- {-# LANGUAGE DeriveDataTypeable #-} module Main ( main ) where -------------------------------------------------------------------------------- import Control.Monad (forM_) import Data.List (intercalate) import Data.Version (Version(..)) import Prelude hiding (readFile) import System.Console.CmdArgs import System.IO (hPutStrLn, stderr) import System.IO.Strict (readFile) -------------------------------------------------------------------------------- import Language.Haskell.Stylish -------------------------------------------------------------------------------- data StylishArgs = StylishArgs { config :: Maybe FilePath , verbose :: Bool , defaults :: Bool , inPlace :: Bool , files :: [FilePath] } deriving (Data, Show, Typeable) -------------------------------------------------------------------------------- stylishArgs :: StylishArgs stylishArgs = StylishArgs { config = Nothing &= typFile &= help "Configuration file" , verbose = False &= help "Run in verbose mode" , defaults = False &= help "Dump default config and exit" , inPlace = False &= help "Overwrite the given files in place" , files = [] &= typFile &= args } &= summary ("stylish-haskell-" ++ versionString version) where versionString = intercalate "." . map show . versionBranch -------------------------------------------------------------------------------- main :: IO () main = cmdArgs stylishArgs >>= stylishHaskell -------------------------------------------------------------------------------- stylishHaskell :: StylishArgs -> IO () stylishHaskell sa | defaults sa = do fileName <- defaultConfigFilePath verbose' $ "Dumping config from " ++ fileName readFile fileName >>= putStr | otherwise = do conf <- loadConfig verbose' (config sa) let steps = configSteps conf forM_ steps $ \s -> verbose' $ "Enabled " ++ stepName s ++ " step" verbose' $ "Extra language extensions: " ++ show (configLanguageExtensions conf) mapM_ (file sa conf) files' where verbose' = makeVerbose (verbose sa) files' = if null (files sa) then [Nothing] else map Just (files sa) -------------------------------------------------------------------------------- -- | Processes a single file, or stdin if no filepath is given file :: StylishArgs -> Config -> Maybe FilePath -> IO () file sa conf mfp = do contents <- maybe getContents readFile mfp let result = runSteps (configLanguageExtensions conf) mfp (configSteps conf) $ lines contents case result of Left err -> hPutStrLn stderr err >> write contents Right ok -> write $ unlines ok where write = maybe putStr (if inPlace sa then writeFile else const putStr) mfp