{-# options_haddock prune #-}
module Polysemy.Process.Executable where
import Path (Abs, File, Path, Rel, toFilePath)
import qualified Path.IO as Path
import Path.IO (executable, getPermissions)
checkExecutable ::
Member (Embed IO) r =>
Text ->
Path Abs File ->
Sem r (Either Text (Path Abs File))
checkExecutable :: forall (r :: [(* -> *) -> * -> *]).
Member (Embed IO) r =>
Text -> Path Abs File -> Sem r (Either Text (Path Abs File))
checkExecutable Text
name Path Abs File
path =
IO Permissions -> Sem r (Either Text Permissions)
forall (r :: [(* -> *) -> * -> *]) a.
Member (Embed IO) r =>
IO a -> Sem r (Either Text a)
tryAny (Path Abs File -> IO Permissions
forall (m :: * -> *) b t. MonadIO m => Path b t -> m Permissions
getPermissions Path Abs File
path) Sem r (Either Text Permissions)
-> (Either Text Permissions -> Either Text (Path Abs File))
-> Sem r (Either Text (Path Abs File))
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> \case
Right (Permissions -> Bool
executable -> Bool
True) ->
Path Abs File -> Either Text (Path Abs File)
forall a b. b -> Either a b
Right Path Abs File
path
Right Permissions
_ ->
Text -> Either Text (Path Abs File)
forall a b. a -> Either a b
Left (Text -> Text
message Text
"executable")
Left Text
_ ->
Text -> Either Text (Path Abs File)
forall a b. a -> Either a b
Left (Text -> Text
message Text
"a readable file")
where
message :: Text -> Text
message Text
what =
Text
"specified path for `" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
name Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"` is not " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
what Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
": " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
pathText
pathText :: Text
pathText =
FilePath -> Text
forall a. ToText a => a -> Text
toText (Path Abs File -> FilePath
forall b t. Path b t -> FilePath
toFilePath Path Abs File
path)
resolveExecutable ::
Member (Embed IO) r =>
Path Rel File ->
Maybe (Path Abs File) ->
Sem r (Either Text (Path Abs File))
resolveExecutable :: forall (r :: [(* -> *) -> * -> *]).
Member (Embed IO) r =>
Path Rel File
-> Maybe (Path Abs File) -> Sem r (Either Text (Path Abs File))
resolveExecutable Path Rel File
exe = \case
Just Path Abs File
path ->
Text -> Path Abs File -> Sem r (Either Text (Path Abs File))
forall (r :: [(* -> *) -> * -> *]).
Member (Embed IO) r =>
Text -> Path Abs File -> Sem r (Either Text (Path Abs File))
checkExecutable Text
name Path Abs File
path
Maybe (Path Abs File)
Nothing ->
IO (Maybe (Path Abs File))
-> Sem r (Either Text (Maybe (Path Abs File)))
forall (r :: [(* -> *) -> * -> *]) a.
Member (Embed IO) r =>
IO a -> Sem r (Either Text a)
tryAny (Path Rel File -> IO (Maybe (Path Abs File))
forall (m :: * -> *).
MonadIO m =>
Path Rel File -> m (Maybe (Path Abs File))
Path.findExecutable Path Rel File
exe) Sem r (Either Text (Maybe (Path Abs File)))
-> (Either Text (Maybe (Path Abs File))
-> Either Text (Path Abs File))
-> Sem r (Either Text (Path Abs File))
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> \case
Right (Just Path Abs File
path) ->
Path Abs File -> Either Text (Path Abs File)
forall a b. b -> Either a b
Right Path Abs File
path
Either Text (Maybe (Path Abs File))
_ ->
Text -> Either Text (Path Abs File)
forall a b. a -> Either a b
Left (Text
"could not find executable `" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
name Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"` in `$PATH`.")
where
name :: Text
name =
FilePath -> Text
forall a. ToText a => a -> Text
toText (Path Rel File -> FilePath
forall b t. Path b t -> FilePath
toFilePath Path Rel File
exe)