module Iris.Tool
(
Tool (..)
, ToolSelector (..)
, defaultToolSelector
, ToolCheckResult (..)
, checkTool
) where
import Data.String (IsString (..))
import Data.Text (Text)
import System.Directory (findExecutable)
import System.Process (readProcess)
import qualified Data.Text as Text
data Tool cmd = Tool
{
forall cmd. Tool cmd -> Text
toolName :: Text
, forall cmd. Tool cmd -> Maybe (ToolSelector cmd)
toolSelector :: Maybe (ToolSelector cmd)
}
instance IsString (Tool cmd) where
fromString :: String -> Tool cmd
fromString :: String -> Tool cmd
fromString String
s = Tool
{ toolName :: Text
toolName = forall a. IsString a => String -> a
fromString String
s
, toolSelector :: Maybe (ToolSelector cmd)
toolSelector = forall a. Maybe a
Nothing
}
data ToolSelector cmd = ToolSelector
{
forall cmd. ToolSelector cmd -> cmd -> Text -> Bool
toolSelectorFunction :: cmd -> Text -> Bool
, forall cmd. ToolSelector cmd -> Maybe Text
toolSelectorVersionArg :: Maybe Text
}
defaultToolSelector :: ToolSelector cmd
defaultToolSelector :: forall cmd. ToolSelector cmd
defaultToolSelector = ToolSelector
{ toolSelectorFunction :: cmd -> Text -> Bool
toolSelectorFunction = \cmd
_cmd Text
_version -> Bool
True
, toolSelectorVersionArg :: Maybe Text
toolSelectorVersionArg = forall a. Maybe a
Nothing
}
data ToolCheckResult
= ToolNotFound Text
| ToolWrongVersion Text
| ToolOk
deriving stock
( Int -> ToolCheckResult -> ShowS
[ToolCheckResult] -> ShowS
ToolCheckResult -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ToolCheckResult] -> ShowS
$cshowList :: [ToolCheckResult] -> ShowS
show :: ToolCheckResult -> String
$cshow :: ToolCheckResult -> String
showsPrec :: Int -> ToolCheckResult -> ShowS
$cshowsPrec :: Int -> ToolCheckResult -> ShowS
Show
, ToolCheckResult -> ToolCheckResult -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ToolCheckResult -> ToolCheckResult -> Bool
$c/= :: ToolCheckResult -> ToolCheckResult -> Bool
== :: ToolCheckResult -> ToolCheckResult -> Bool
$c== :: ToolCheckResult -> ToolCheckResult -> Bool
Eq
)
checkTool :: cmd -> Tool cmd -> IO ToolCheckResult
checkTool :: forall cmd. cmd -> Tool cmd -> IO ToolCheckResult
checkTool cmd
cmd Tool{Maybe (ToolSelector cmd)
Text
toolSelector :: Maybe (ToolSelector cmd)
toolName :: Text
toolSelector :: forall cmd. Tool cmd -> Maybe (ToolSelector cmd)
toolName :: forall cmd. Tool cmd -> Text
..} = String -> IO (Maybe String)
findExecutable (Text -> String
Text.unpack Text
toolName) forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Maybe String
Nothing -> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ Text -> ToolCheckResult
ToolNotFound Text
toolName
Just String
exe -> case Maybe (ToolSelector cmd)
toolSelector of
Maybe (ToolSelector cmd)
Nothing -> forall (f :: * -> *) a. Applicative f => a -> f a
pure ToolCheckResult
ToolOk
Just ToolSelector{Maybe Text
cmd -> Text -> Bool
toolSelectorVersionArg :: Maybe Text
toolSelectorFunction :: cmd -> Text -> Bool
toolSelectorVersionArg :: forall cmd. ToolSelector cmd -> Maybe Text
toolSelectorFunction :: forall cmd. ToolSelector cmd -> cmd -> Text -> Bool
..} -> case Maybe Text
toolSelectorVersionArg of
Maybe Text
Nothing -> forall (f :: * -> *) a. Applicative f => a -> f a
pure ToolCheckResult
ToolOk
Just Text
versionArg -> do
String
toolVersionOutput <- String -> [String] -> String -> IO String
readProcess String
exe [Text -> String
Text.unpack Text
versionArg] String
""
let version :: Text
version = Text -> Text
Text.strip forall a b. (a -> b) -> a -> b
$ String -> Text
Text.pack String
toolVersionOutput
if cmd -> Text -> Bool
toolSelectorFunction cmd
cmd Text
version
then forall (f :: * -> *) a. Applicative f => a -> f a
pure ToolCheckResult
ToolOk
else forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ Text -> ToolCheckResult
ToolWrongVersion Text
version