{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE TypeFamilies #-} module Imm.Dyre ( Mode(..) , defaultMode , describePaths , wrap , recompile ) where -- {{{ Imports import Imm.Pretty import Config.Dyre import Config.Dyre.Compile import Config.Dyre.Paths import System.IO -- }}} -- | How dynamic reconfiguration process should behave. data Mode = Normal | Vanilla | ForceReconfiguration | IgnoreReconfiguration deriving(Eq, Show) -- | Default mode is 'Normal', that is: use custom configuration file and recompile if change detected. defaultMode :: Mode defaultMode = Normal -- | Describe the paths used for dynamic reconfiguration describePaths :: (MonadIO m) => m (Doc AnsiStyle) describePaths = io $ do (a, b, c, d, e) <- getPaths baseParameters return $ vsep [ "Current binary" <+> equals <+> magenta (fromString a) , "Custom binary" <+> equals <+> magenta (fromString b) , "Config file" <+> equals <+> magenta (fromString c) , "Cache directory" <+> equals <+> magenta (fromString d) , "Lib directory" <+> equals <+> magenta (fromString e) ] -- | Dynamic reconfiguration settings parameters :: Mode -> (a -> IO ()) -> Params (Either String a) parameters mode main = baseParameters { configCheck = mode /= Vanilla , realMain = main' } where main' (Left e) = hPutStrLn stderr e main' (Right x) = main x baseParameters :: Params (Either String a) baseParameters = defaultParams { projectName = "imm" , showError = const Left , ghcOpts = ["-threaded"] , statusOut = hPutStrLn stderr , includeCurrentDirectory = False } wrap :: Mode -> (a -> IO ()) -> a -> IO () wrap mode result args = wrapMain (parameters mode result) (Right args) -- | Launch a recompilation of the configuration file recompile :: (MonadIO m) => m (Maybe Text) recompile = io $ do customCompile baseParameters fmap fromString <$> getErrorString baseParameters