rivet-core-0.1.0.0: src/Rivet/Main.hs
module Rivet.Main where
import Prelude hiding ((*>), (++))
import Control.Applicative ((<$>))
import Control.Monad (void, when)
import Data.Char (isSpace)
import Data.Configurator
import Data.Configurator.Types
import qualified Data.HashMap.Strict as M
import Data.List (intercalate, isInfixOf)
import Data.Monoid
import qualified Data.Text as T
import Data.Time.Clock
import Data.Time.Format
import Development.Shake hiding (doesFileExist)
import System.Directory (createDirectoryIfMissing,
doesFileExist, getCurrentDirectory)
import System.Exit
import System.IO
import System.Process
import Rivet.Common
import qualified Rivet.Rules as Rules
import qualified Rivet.Tasks as Tasks
opts :: ShakeOptions
opts = shakeOptions { shakeFiles = ".shake/" }
getProjectName :: IO String
getProjectName = (reverse . takeWhile (/= '/') . reverse) <$>
getCurrentDirectory
mainWith :: [Task] -> IO ()
mainWith tasks = do
proj <- getProjectName
shakeArgsWith opts [] $ \flags targets ->
case targets of
("init":[]) -> do
e <- doesFileExist "Rivetfile"
if e
then
do putStrLn "Error: Rivetfile already exists. Only run 'rivet init' in empty directory."
return Nothing
else return $ Just $ do want ["init"]
"init" ~> Tasks.init proj
("init":_) -> do putStrLn "Usage: rivet init"
return Nothing
_ -> do conf <- load [Required "Rivetfile"]
commands <- (map (\(k,String v) -> (T.drop (length "commands.") k, v)) .
filter (\(k,v) -> (T.pack "commands.") `T.isPrefixOf` k) .
M.toList) <$> getMap conf
deps <- lookupDefault [] conf (T.pack "dependencies")
cabal <- lookupDefault "cabal " conf (T.pack "cabal-command")
return $ Just $ do
case targets of
[] -> action $ liftIO $ putStrLn "Need a task. Run `rivet tasks` to see all tasks."
("test":_) -> want ["test"]
("db:new":_:[]) -> want ["db:new"]
("db:new":_) -> action $ liftIO (putStrLn "usage: rivet db:new migration_name")
("model:new":[]) -> action $ liftIO (putStrLn "usage: rivet model:new ModelName [field_name:field_type]*")
("model:new":_) -> want ["model:new"]
("db:migrate":_:[]) -> want ["db:migrate"]
("db:migrate":_:_) -> action $ liftIO (putStrLn "usage: rivet db:migrate [env]")
("db:migrate:down":_:[]) -> want ["db:migrate:down"]
("db:migrate:down":_:_) -> action $ liftIO (putStrLn "usage: rivet db:migrate:down [env]")
("db:status":_:[]) -> want ["db:status"]
("db:status":_:_) -> action $ liftIO (putStrLn "usage: rivet db:status [env]")
(target:args) ->
do mapM_ (\t ->
if taskName t == target
then if length args == taskNumArgs t
then want [taskName t]
else action $ liftIO (putStrLn $
"usage: rivet " ++
taskName t ++ " " ++
taskUsage t)
else return ())
tasks
when (not (target `elem` (map taskName tasks))) $ want targets
Rules.addCommands commands
Rules.addDependencies cabal deps
Rules.addBinary cabal proj
mapM_ (\t -> taskName t ~> taskBody t proj conf (tail targets)) tasks
"cabal.sandbox.config" *> \_ -> cmd "cabal sandbox init"
"run" ~> Tasks.run proj
"test" ~> Tasks.test cabal targets
"db" ~> Tasks.db proj conf
"db:test" ~> Tasks.dbTest proj conf
"db:create" ~> Tasks.dbCreate proj conf
"db:new" ~> Tasks.dbNew targets
"db:migrate" ~> Tasks.dbMigrate cabal proj conf (tail targets)
"db:migrate:down" ~> Tasks.dbMigrateDown cabal proj conf (tail targets)
"db:status" ~> Tasks.dbStatus cabal proj conf (tail targets)
"repl" ~> Tasks.repl cabal
"setup" ~> Tasks.setup cabal
"crypt:edit" ~> Tasks.cryptEdit proj
"crypt:show" ~> Tasks.cryptShow
"crypt:setpass" ~> Tasks.cryptSetPass proj
"tasks" ~> liftIO (mapM_ (putStrLn . ("rivet " ++)) $
["init"
,"run"
,"test [pattern]"
,"db"
,"db:test"
,"db:create"
,"db:new migration_name"
,"db:migrate"
,"db:migrate:down"
,"db:status"
,"model:new ModelName"
,"repl"
,"setup"
] ++ map taskName tasks)