module Development.Hake.RunHake (
runHake
) where
import System.Exit (ExitCode(ExitSuccess), exitWith)
import System.Directory (createDirectory, doesDirectoryExist,
doesFileExist)
import System.Directory.Tools (doesNotExistOrOldThan)
import System.FilePath (takeFileName)
import System.Process (runProcess, waitForProcess)
import Control.Monad (when)
import Control.Monad.Tools (unlessM, filterM)
import Data.Function.Tools (applyWhen, apply2way)
import YJTools.Tribial (ghcMake, updateFile)
import Text.RegexPR (gsubRegexPR, ggetbrsRegexPR)
import Development.Hake.Variables (defaultTrgtStr, hakefileUpdateOption,
hakeDir, commentPair, srcSuffix, exeEscPairs)
runHake :: FilePath -> FilePath -> [ FilePath ] -> [ String ] -> IO ExitCode
runHake src exe othrs args = do
let bin = foldr (uncurry gsubRegexPR) exe exeEscPairs
binPath = hakeDir ++ bin
binSrc = hakeDir ++ bin ++ srcSuffix
mapM_ errorNotExist $ src : othrs
unlessM (doesDirectoryExist hakeDir) $ createDirectory hakeDir
othrsUD
<- fmap or $ flip mapM othrs
$ apply2way (updateFile commentPair) id $
(hakeDir ++) . takeFileName
hakefileUD <- updateFile commentPair src binSrc
modUD <-
if null othrs
then do mods <- getModules src
fmap or $ flip mapM mods
$ apply2way (updateFile commentPair) id $
(hakeDir ++)
else return False
notUpdated <- doesNotExistOrOldThan binPath binSrc
when (othrsUD || hakefileUD || notUpdated || modUD) $ do
ec <- ghcMake bin hakeDir
when (ec /= ExitSuccess) $ exitWith ec
let args_ = applyWhen (othrsUD || hakefileUD) (hakefileUpdateOption:) $
applyWhen (null $ filter (notElem '=') args) (defaultTrgtStr:) args
runProcess binPath args_ Nothing Nothing Nothing Nothing Nothing
>>= waitForProcess
errorNotExist :: FilePath -> IO ()
errorNotExist fp = unlessM (doesFileExist fp) $
error $ "runHake: " ++ fp ++ " does not exist"
getModules :: FilePath -> IO [ FilePath ]
getModules hf = do
cont <- readFile hf
let mods_ = map (!!1) $ ggetbrsRegexPR "^import\\s+([^\n\\([:blank:]]+)" cont
mods <- filterM doesFileExist $ map (++".hs") mods_
return mods