krank-0.1.0: app/Main.hs
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE TemplateHaskell #-}
import System.Environment (getArgs)
import System.Exit (exitFailure)
import System.IO (hPutStrLn, stderr)
import Control.Exception.Safe
import Control.Applicative (optional)
import Data.Semigroup ((<>))
import Data.Text (unpack)
import qualified Options.Applicative as Opt
import Options.Applicative ((<**>), many)
import Control.Monad.Reader
import PyF
import Krank
import Krank.Formatter
import Krank.Types
data KrankOpts = KrankOpts {
codeFilePaths :: [FilePath],
krankConfig :: KrankConfig
}
filesToParse :: Opt.Parser [FilePath]
filesToParse = many (Opt.argument Opt.str (Opt.metavar "FILES..."))
githubKeyToParse :: Opt.Parser (Maybe GithubKey)
githubKeyToParse = optional (
GithubKey <$> (
Opt.strOption $
Opt.long "issuetracker-githubkey"
<> Opt.metavar "DEVELOPER_KEY"
<> Opt.help "A github developer key to allow for more API calls for the IssueTracker checker"))
optionsParser :: Opt.Parser KrankOpts
optionsParser = KrankOpts
<$> filesToParse
<*> (KrankConfig
<$> githubKeyToParse
<*> (Opt.switch $ Opt.long "dry-run"
<> Opt.help "Perform a dry run. Parse file, but do not execute HTTP requests")
)
opts :: Opt.ParserInfo KrankOpts
opts = Opt.info (optionsParser <**> Opt.helper)
( Opt.fullDesc
<> Opt.progDesc "Checks the comments in FILES"
<> Opt.header "krank - a comment linter / analytics tool" )
runKrank :: FilePath -> KrankConfig -> IO ()
runKrank path options = do
violations <- runReaderT (processFile path) options
putStr . unpack . showViolations $ violations
main :: IO ()
main = do
options <- Opt.execParser opts
(flip mapM_) (codeFilePaths options) $ \path -> do
(runKrank path (krankConfig options))
`catchAnyDeep` (\(SomeException e) -> hPutStrLn stderr [fmt|Error when processing {path}: {show e}|])