chromatin-0.1.0.0: lib/Chromatin/Run.hs
module Chromatin.Run(
runRplugin,
RunRpluginResult(..),
pypiPluginPackage,
) where
import Control.Monad.IO.Class (liftIO)
import Data.List.Split (linesBy)
import Data.MessagePack (Object)
import UnliftIO.Exception (catch)
import System.FilePath ((</>))
import qualified System.FilePath.Glob as Glob (globDir1, compile)
import Neovim (NeovimException, toObject, fromObject', vim_call_function')
import qualified Neovim as NeovimException (NeovimException(ErrorMessage, ErrorResult))
import qualified Data.Map as Map (fromList)
import Chromatin.Data.Rplugin (Rplugin(Rplugin))
import Chromatin.Data.RpluginName (RpluginName(RpluginName))
import Chromatin.Data.ActiveRplugin (ActiveRplugin(ActiveRplugin))
import Chromatin.Data.RpluginSource (RpluginSource(Stack, Pypi))
import Chromatin.Data.Chromatin (Chromatin)
import Chromatin.Rebuild.Build (venvDir)
data RunRpluginResult =
Success ActiveRplugin
|
Failure [String]
deriving (Show, Eq)
jobstartFailure :: NeovimException -> Either String a
jobstartFailure (NeovimException.ErrorMessage doc) = Left (show doc)
jobstartFailure (NeovimException.ErrorResult obj) = Left (show obj)
unsafeJobstart :: [Object] -> Chromatin Int
unsafeJobstart args = do
result <- vim_call_function' "jobstart" args
fromObject' result
jobstart :: [Object] -> Chromatin (Either String Int)
jobstart args =
catch (Right <$> unsafeJobstart args) (return . jobstartFailure)
runRpluginStack :: RpluginName -> FilePath -> Chromatin (Either String Int)
runRpluginStack (RpluginName name) path = do
let opts = Map.fromList [("cwd", toObject path), ("rpc", toObject True)]
jobstart [toObject $ "stack exec " ++ name, toObject opts]
pypiPluginExecutable :: RpluginName -> Chromatin FilePath
pypiPluginExecutable name = do
dir <- venvDir name
return $ dir </> "bin" </> "ribosome_start_plugin"
pypiSiteDir :: RpluginName -> Chromatin (Maybe FilePath)
pypiSiteDir name = do
venv <- venvDir name
matches <- liftIO $ Glob.globDir1 (Glob.compile "python3.?") (venv </> "lib")
return $ case matches of
dir : _ -> Just $ dir </> "site-packages"
_ -> Nothing
pypiPluginPackage :: RpluginName -> Chromatin (Maybe FilePath)
pypiPluginPackage rpluginName@(RpluginName name) = do
dir <- pypiSiteDir rpluginName
return $ fmap (</> name) dir
runRpluginPypi :: RpluginName -> Chromatin (Either String Int)
runRpluginPypi rpluginName@(RpluginName name) = do
dir <- venvDir rpluginName
let exe = dir </> "bin" </> "python"
let opts = Map.fromList [("rpc", toObject True)]
start <- pypiPluginExecutable rpluginName
mayPackage <- pypiPluginPackage rpluginName
case mayPackage of
Just package ->
jobstart [toObject [toObject exe, toObject start, toObject package], toObject opts]
Nothing -> return $ Left $ "no `lib/python` directory in virtualenv for `" ++ name ++ "`"
runRplugin' :: RpluginName -> RpluginSource -> Chromatin (Either String Int)
runRplugin' name (Stack path) = runRpluginStack name path
runRplugin' name (Pypi _) = runRpluginPypi name
runRplugin' _ _ = return (Left "NI")
runRplugin :: Rplugin -> Chromatin RunRpluginResult
runRplugin rplugin@(Rplugin name source) = do
result <- runRplugin' name source
return $ case result of
Right channelId -> Success (ActiveRplugin channelId rplugin)
Left err -> Failure (linesBy (=='\n') err)