module Devel.Build
( build
) where
import IdeSession
import qualified Data.ByteString.Char8 as S8
import Data.Text (unpack)
import GHC.Conc (newTVarIO)
import Control.Concurrent (forkIO, killThread, ThreadId)
import Control.Monad (unless)
# if __GLASGOW_HASKELL__ < 710
import Data.Monoid (mempty)
#endif
import Devel.Compile
import Devel.ReverseProxy (startReverseProxy)
import Devel.Watch
import Data.IORef
build :: FilePath
-> String
-> [String]
-> Bool
-> SessionConfig
-> (Int, Int)
-> Maybe IdeSession
-> Bool
-> IORef [String]
-> IO ()
build buildFile
runFunction
watchDirectories
isReverseProxy
sessionConfig
(fromProxyPort, toProxyPort)
mSession
isRebuild
iStrLst = do
(initialSession, extensionList, includeTargets, additionalWatch) <- initCompile watchDirectories sessionConfig mSession
unless isRebuild $
if isReverseProxy then
do _ <- forkIO $ startReverseProxy (fromProxyPort, toProxyPort) iStrLst
putStrLn $ "Starting devel application at http://localhost:" ++
show fromProxyPort
else
putStrLn $ "Starting app without reverse proxying at http://localhost:" ++
show fromProxyPort
(updatedSession, update) <-
if isRebuild
then return (initialSession, mempty)
else compile initialSession buildFile extensionList includeTargets
eitherSession <- finishCompile (updatedSession, update) iStrLst
let
clearLog = do
_ <- readIORef iStrLst
writeIORef iStrLst ([] :: [String])
case eitherSession of
Left _ -> do
isDirty <- newTVarIO False
_ <- forkIO $ watch isDirty includeTargets additionalWatch
_ <- checkForChange isDirty
putStrLn "\n\nRebuilding...\n\n"
_ <- shutdownSession updatedSession
_ <- clearLog
build buildFile runFunction watchDirectories False sessionConfig (fromProxyPort, toProxyPort) Nothing False iStrLst
Right session -> do
(runActionsRunResult, threadId) <- run session buildFile runFunction
isDirty <- newTVarIO False
watchId <- forkIO $ watch isDirty includeTargets additionalWatch
_ <- checkForChange isDirty
killThread watchId
_ <- clearLog
_ <- stopApp runActionsRunResult threadId
putStrLn "\n\nRebuilding...\n\n"
build buildFile runFunction watchDirectories isReverseProxy sessionConfig (fromProxyPort, toProxyPort) (Just session) True iStrLst
run :: IdeSession -> FilePath -> String -> IO (RunActions RunResult, ThreadId)
run session buildFile runFunction = do
mapFunction <- getFileMap session
buildModule <- case mapFunction buildFile of
Nothing -> fail $ "The file's module name for: " ++ show buildFile ++" couldn't be found"
Just moduleId -> return $ unpack $ moduleName moduleId
runActionsRunResult <- runStmt session buildModule runFunction
threadId <- forkIO $ loop runActionsRunResult
return (runActionsRunResult, threadId)
stopApp :: RunActions RunResult -> ThreadId -> IO ()
stopApp runResult threadId = do
interrupt runResult
killThread threadId
loop :: RunActions RunResult -> IO ()
loop res = do
runAction <- runWait res
case runAction of
Left bs -> S8.putStr bs >> loop res
Right result -> putStrLn $ "Run result: " ++ show result