shake-0.15: src/Run.hs
module Run(main) where
import Development.Make.All
import Development.Ninja.All
import System.Environment
import Development.Shake
import Development.Shake.FilePath
import General.Timing
import Data.List.Extra
import Control.Monad.Extra
import Control.Exception.Extra
import Data.Maybe
import qualified System.Directory as IO
import System.Console.GetOpt
import System.Process
import System.Exit
import General.Extra
main :: IO ()
main = do
resetTimings
args <- getArgs
withArgs ("--no-time":args) $
shakeArgsWith shakeOptions{shakeCreationCheck=False} flags $ \opts targets -> do
let tool = listToMaybe [x | Tool x <- opts]
(mode, makefile) <- case reverse [x | UseMakefile x <- opts] of
x:_ -> return (modeMakefile x, x)
_ -> findMakefile
case mode of
Ninja -> runNinja makefile targets tool
_ | isJust tool -> error "--tool flag is not supported without a .ninja Makefile"
Exe -> do exitOnFailure =<< rawSystem (toNative makefile) args; return Nothing
Haskell -> do exitOnFailure =<< rawSystem "runhaskell" (makefile:args); return Nothing
Make -> fmap Just $ runMakefile makefile targets
exitOnFailure :: ExitCode -> IO ()
exitOnFailure x = when (x /= ExitSuccess) $ exitWith x
data Flag = UseMakefile FilePath
| Tool String
flags = [Option "f" ["file","makefile"] (ReqArg (Right . UseMakefile) "FILE") "Read FILE as a makefile."
,Option "t" ["tool"] (ReqArg (Right . Tool) "TOOL") "Ninja-compatible tools."
]
data Mode = Make | Ninja | Haskell | Exe
modeMakefile :: FilePath -> Mode
modeMakefile x | takeExtension x == ".ninja" = Ninja
| takeExtension x `elem` [".hs",".lhs"] = Haskell
| otherwise = Make
findMakefile :: IO (Mode, FilePath)
findMakefile = do
let files = [(Exe,".shake" </> "shake" <.> exe)
,(Haskell,"Shakefile.hs"),(Haskell,"Shakefile.lhs")
,(Make,"makefile"),(Make,"Makefile")
,(Ninja,"build.ninja")]
res <- findM (fmap (either (const False) id) . try_ . IO.doesFileExist . snd) files
case res of
Just x -> return x
Nothing -> do
let Just (p1,p2) = unsnoc ["`" ++ x ++ "'" | (_,x) <- files]
errorIO $ "Could not find " ++ intercalate ", " p1 ++ " or " ++ p2