{-# LANGUAGE RankNTypes #-} {-# LANGUAGE TemplateHaskell #-} module Development.Shake.TH ( checkExecutable , mkVersions , mkExecChecks , commonVersion , MBool , AVersion ) where import Control.Monad.IO.Class import Data.Maybe (isJust) import Development.Shake import Language.Haskell.TH import System.Directory (findExecutable) type MBool = forall m. MonadIO m => m Bool type AVersion = Action String commonVersion :: String -> Action String commonVersion prog = do (Stdout out) <- command mempty prog ["--version"] pure . last . words . head . lines $ out mkSigVersion :: String -> Dec mkSigVersion s = SigD (mkName $ s ++ "Version") (ConT ''AVersion) mkVersion :: String -> Dec mkVersion s = FunD (mkName $ s ++ "Version") [Clause mempty (NormalB expr) mempty] where expr = VarE 'commonVersion `AppE` (LitE $ StringL s) mkVersions :: [String] -> Q [Dec] mkVersions = pure . (=<<) g where g s = [mkVersion s, mkSigVersion s] mkSig :: String -> Dec mkSig s = SigD (mkName s) (ConT ''MBool) -- | Check for the presence of some executable. checkExecutable :: (MonadIO m) => String -> m Bool checkExecutable = fmap isJust . liftIO . findExecutable mkExecCheck :: String -> Dec mkExecCheck s = FunD (mkName s) [Clause mempty (NormalB expr) mempty] where expr = VarE 'checkExecutable `AppE` (LitE $ StringL s) mkExecChecks :: [String] -> Q [Dec] mkExecChecks = pure . (=<<) g where g s = [mkExecCheck s, mkSig s]