module Ignore.Builder
( CheckerBuilderT
, runCheckerBuilder
, registerGlob, registerGlobGit, registerRegex
)
where
import Ignore.Types
import Control.Applicative
import Control.Monad.Writer
#if MIN_VERSION_mtl(2,2,0)
import Control.Monad.Except
#else
import Control.Monad.Error
#endif
import Text.Regex.PCRE.Heavy ((=~))
import qualified Data.Text as T
import qualified Data.Text.Encoding as T
import qualified Text.Regex.PCRE.Heavy as Re
import qualified System.FilePath.Glob as G
#if MIN_VERSION_mtl(2,2,0)
type ErrorT = ExceptT
runErrorT :: ExceptT e m a -> m (Either e a)
runErrorT = runExceptT
#endif
newtype CheckerBuilderT m a
= CheckerBuilderT { unCheckerBuilderT :: ErrorT String (WriterT FileIgnoredChecker m) a }
deriving (Monad, Functor, Applicative, Alternative, MonadIO, MonadError String)
runCheckerBuilder :: Monad m => CheckerBuilderT m () -> m (Either String FileIgnoredChecker)
runCheckerBuilder cb =
do (res, out) <- runWriterT (runErrorT $ unCheckerBuilderT cb)
case res of
Left err ->
return $ Left err
Right () ->
return $ Right out
registerGlobGit :: Monad m => T.Text -> CheckerBuilderT m ()
registerGlobGit pat
| not ("/" `T.isInfixOf` pat) =
do registerGlob pat
registerGlob ("**/" <> pat <> "/**")
registerGlob ("**/" <> pat)
| otherwise = registerGlob pat
registerGlob :: Monad m => T.Text -> CheckerBuilderT m ()
registerGlob globPattern =
CheckerBuilderT $
case G.tryCompileWith G.compDefault (T.unpack globPattern) of
Left err -> throwError ("Failed to compile glob pattern " ++ T.unpack globPattern ++ ": " ++ err)
Right pat ->
do let simplified = G.simplify pat
lift $ tell $ FileIgnoredChecker (G.matchWith G.matchPosix simplified)
registerRegex :: Monad m => T.Text -> CheckerBuilderT m ()
registerRegex rePattern =
CheckerBuilderT $
case Re.compileM (T.encodeUtf8 rePattern) [] of
Left err -> throwError ("Failed to compile regex pattern " ++ T.unpack rePattern ++ ": " ++ err)
Right pat ->
lift $ tell $ FileIgnoredChecker (=~ pat)