ide-backend 0.9.0.3 → 0.9.0.4
raw patch · 2 files changed
+103/−1 lines, 2 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
Files
- IdeSession/ExeCabalServer.hs +101/−0
- ide-backend.cabal +2/−1
+ IdeSession/ExeCabalServer.hs view
@@ -0,0 +1,101 @@+-- | Run Cabal functions upon receiving RPC requests, log output and provide+-- Progress updates.+module IdeSession.ExeCabalServer (+ exeCabalEngine+ ) where++import Control.Concurrent.Async (async, wait)+import System.Exit (ExitCode)+import System.IO.Error (isEOFError)+import System.Posix.IO.ByteString+import qualified Control.Exception as Ex+import qualified Data.ByteString as BSS+import qualified Data.Text.Encoding as E+import qualified System.IO as IO++import IdeSession.Cabal+import IdeSession.RPC.Server+import IdeSession.Types.Progress+import IdeSession.Util++-- | Handle RPC requests by calling Cabal functions, keeping track+-- of progress and passing the results.+exeCabalEngine :: FilePath -> RpcConversation -> IO ()+exeCabalEngine _errorLog conv@RpcConversation{..} = do+ -- Start handling RPC calls+ let go = do+ req <- get+ exitCode <- runExeCabal conv req+ put $ ExeCabalDone exitCode+ go -- not long-running, but we can't exit or RPC would crash++ go++-- | Run the cabal functions inside the executable.+runExeCabal :: RpcConversation -> ExeCabalRequest -> IO ExitCode+runExeCabal conv req = do+ -- Create pipe+ (stdOutputRd, stdOutputWr) <- createPipe++ -- Backup stdout, then replace stdout with the pipe's write end+ (exitCode, stdoutThread) <- swizzleStdout stdOutputWr $ do+ -- Convert the read end to a handle+ stdOutputRdHandle <- fdToHandle stdOutputRd+ IO.hSetBuffering stdOutputRdHandle IO.LineBuffering++ let stdoutLog = case req of+ ReqExeBuild buildExeArgs _ -> beStdoutLog buildExeArgs+ ReqExeDoc buildExeArgs -> beStdoutLog buildExeArgs+ ReqExeCc runCcArgs -> rcStdoutLog runCcArgs+ ReqExeLic licenseArgs -> liStdoutLog licenseArgs+ stdoutThread <- async $ readStdout conv stdOutputRdHandle stdoutLog++ exitCode <- case req of+ ReqExeBuild buildExeArgs modArgs ->+ configureAndBuild buildExeArgs modArgs+ ReqExeDoc buildExeArgs ->+ configureAndHaddock buildExeArgs+ ReqExeCc runCcArgs ->+ runComponentCc runCcArgs+ ReqExeLic licenseArgs ->+ buildLicsFromPkgs True licenseArgs++ return (exitCode, stdoutThread)++ -- Closing the write end of the stdout pipe will cause the stdout+ -- thread to terminate after it processed all remaining output;+ -- wait for this to happen+ closeFd stdOutputWr+ wait stdoutThread++ return exitCode++readStdout :: RpcConversation -> IO.Handle -> FilePath -> IO ()+readStdout RpcConversation{..} stdOutputRdHandle stdoutLog = do+ logHandle <- IO.openFile stdoutLog IO.WriteMode+ let go = do+ res <- Ex.try $ BSS.hGetLine stdOutputRdHandle+ case res of+ Left ex -> if isEOFError ex then return () else Ex.throw ex+ Right bs -> do+ progressCallback bs+ BSS.hPut logHandle bs+ BSS.hPut logHandle (BSS.singleton (0x0a)) -- \n+ go+ go+ IO.hClose logHandle+ where+ progressCallback :: BSS.ByteString -> IO ()+ progressCallback ghcMsg = do+ let ghcMsg' = E.decodeUtf8 ghcMsg+ case parseProgressMessage ghcMsg' of+ Right (step, numSteps, msg) ->+ put $ ExeCabalProgress $ Progress {+ progressStep = step+ , progressNumSteps = numSteps+ , progressParsedMsg = Just msg+ , progressOrigMsg = Just ghcMsg'+ }+ _ ->+ -- Ignore messages we cannot parse+ return ()
ide-backend.cabal view
@@ -1,5 +1,5 @@ name: ide-backend-version: 0.9.0.3+version: 0.9.0.4 synopsis: An IDE backend library description: See README.md for more details license: MIT@@ -72,6 +72,7 @@ executable ide-backend-exe-cabal main-is: ide-backend-exe-cabal.hs+ other-modules: IdeSession.ExeCabalServer build-depends: ide-backend, ide-backend-common, base ==4.*,