module Development.Hake.FunSet ( base , file , task , rule , ruleV , ruleSS , dflt , mkfl , systemE ) where import System.Directory (doesFileExist) import System.Cmd (rawSystem) import System.Exit (ExitCode(ExitSuccess)) import Data.List (isSuffixOf) import Data.Function.Tools (const2) import Control.Monad.Reader (lift, asks) import Control.Monad.Tools (whenM) import Control.Applicative ((<$>)) import Development.Hake.Types (Rule, CommandRet, MadeFromList, Commands, Targets, Sources, getSrcs, getUpdateStatus) import Development.Hake.HiddenTools (abortIfFailure, changeSuffix, defaultTrgtStr) base :: Targets -> Sources -> ( String -> [ String ] -> MadeFromList -> IO ExitCode ) -> Rule base trgts srcs cmdsGen = (trgts, srcs, cmd) where cmd :: Commands cmd t s = cmdGenToCmd $ cmdsGen t s cmdGenToCmd :: (MadeFromList -> IO ExitCode) -> CommandRet cmdGenToCmd cg = do mfl <- asks snd lift $ cg mfl dflt :: [ String ] -> Rule dflt trgts = ( (==defaultTrgtStr), const trgts, const2 $ return ExitSuccess ) file :: [String] -> [String] -> [[String]] -> Rule file trgts srcs cmd = ( \f -> or $ map (==f) trgts, const srcs, const2 $ abortIfFailure $ map systemEInner cmd ) task :: String -> [[String]] -> Rule task trgts cmd = ( (==trgts), const [], const2 $ abortIfFailure $ map systemEInner cmd ) rule :: String -> String -> (String -> [String] -> [[String]]) -> Rule rule trgt src cmd = ( isSuffixOf trgt, \dst -> [changeSuffix trgt src dst ], \t s -> abortIfFailure $ map systemEInner $ cmd t s ) ruleV :: String -> [String] -> [String] -> (String -> [String] -> [[String]]) -> Rule ruleV trgt srcs cmmns cmd = ( isSuffixOf trgt, \dst -> map (flip (changeSuffix trgt) dst) srcs ++ cmmns, \t s -> abortIfFailure $ map systemEInner $ cmd t s ) ruleSS :: String -> String -> (String -> [String] -> [ (String, [[String]]) ]) -> Rule ruleSS trgt src cmds = ( isSuffixOf trgt, \dst -> [ changeSuffix trgt src dst ], \t s -> do [ srcSrc ] <- getSrcs $ head s abortIfFailure $ map systemEInner $ snd $ head $ filter ( flip isSuffixOf srcSrc . fst ) $ cmds t s ) mkfl :: String -> [ String ] -> Rule mkfl trgt cont = ( (==trgt), const [], \t -> const $ do whenM (getUpdateStatus `orM` lift (not <$> doesFileExist trgt)) $ do lift $ putStrLn $ "make file `" ++ trgt ++ "' (hake)" lift $ writeFile t $ unlines cont return ExitSuccess ) orM :: Monad m => m Bool -> m Bool -> m Bool orM p1 p2 = do b1 <- p1 b2 <- p2 return $ b1 || b2 systemE :: [ String ] -> IO ExitCode systemE cmd = putStrLn (unwords cmd) >> rawSystem (head cmd) (tail cmd) systemEInner :: [ String ] -> CommandRet systemEInner cmd = lift $ putStrLn (unwords cmd) >> rawSystem (head cmd) (tail cmd)