2011-01-16 16:05:05 -04:00
|
|
|
{- git-annex command line parsing and dispatch
|
2010-11-02 19:04:24 -04:00
|
|
|
-
|
|
|
|
- Copyright 2010 Joey Hess <joey@kitenet.net>
|
|
|
|
-
|
|
|
|
- Licensed under the GNU GPL version 3 or higher.
|
|
|
|
-}
|
|
|
|
|
2010-12-30 15:06:26 -04:00
|
|
|
module CmdLine (
|
2010-12-30 16:52:24 -04:00
|
|
|
dispatch,
|
2010-12-30 20:08:22 -04:00
|
|
|
usage,
|
2011-01-16 16:05:05 -04:00
|
|
|
shutdown
|
2010-12-30 15:06:26 -04:00
|
|
|
) where
|
2010-11-02 19:04:24 -04:00
|
|
|
|
2011-01-16 16:05:05 -04:00
|
|
|
import System.IO.Error (try)
|
2010-11-02 19:04:24 -04:00
|
|
|
import System.Console.GetOpt
|
|
|
|
|
2011-10-05 16:02:51 -04:00
|
|
|
import Common.Annex
|
2010-11-02 19:04:24 -04:00
|
|
|
import qualified Annex
|
2011-10-04 00:40:47 -04:00
|
|
|
import qualified Annex.Queue
|
2011-06-30 13:16:57 -04:00
|
|
|
import qualified Git
|
2011-10-04 00:40:47 -04:00
|
|
|
import Annex.Content
|
2010-11-02 19:04:24 -04:00
|
|
|
import Command
|
2010-12-30 16:52:24 -04:00
|
|
|
import Options
|
2011-08-17 14:14:43 -04:00
|
|
|
import Init
|
2010-11-02 19:04:24 -04:00
|
|
|
|
2010-12-30 16:52:24 -04:00
|
|
|
{- Runs the passed command line. -}
|
2011-06-02 02:40:43 -04:00
|
|
|
dispatch :: [String] -> [Command] -> [Option] -> String -> Git.Repo -> IO ()
|
|
|
|
dispatch args cmds options header gitrepo = do
|
2011-03-12 15:30:17 -04:00
|
|
|
setupConsole
|
2011-07-05 18:31:46 -04:00
|
|
|
state <- Annex.new gitrepo
|
2010-12-30 15:44:15 -04:00
|
|
|
(actions, state') <- Annex.run state $ parseCmd args header cmds options
|
2011-03-19 18:33:39 -04:00
|
|
|
tryRun state' $ [startup] ++ actions ++ [shutdown]
|
2010-12-30 15:44:15 -04:00
|
|
|
|
2010-12-08 14:07:49 -04:00
|
|
|
{- Parses command line, stores configure flags, and returns a
|
|
|
|
- list of actions to be run in the Annex monad. -}
|
2010-12-30 15:06:26 -04:00
|
|
|
parseCmd :: [String] -> String -> [Command] -> [Option] -> Annex [Annex Bool]
|
|
|
|
parseCmd argv header cmds options = do
|
2011-07-15 03:12:05 -04:00
|
|
|
(flags, params) <- liftIO getopt
|
2010-12-30 16:52:24 -04:00
|
|
|
when (null params) $ error $ "missing command" ++ usagemsg
|
2010-11-06 17:06:19 -04:00
|
|
|
case lookupCmd (head params) of
|
2010-12-30 16:52:24 -04:00
|
|
|
[] -> error $ "unknown command" ++ usagemsg
|
2010-12-30 14:19:16 -04:00
|
|
|
[command] -> do
|
2010-12-08 14:07:49 -04:00
|
|
|
_ <- sequence flags
|
2011-08-17 14:14:43 -04:00
|
|
|
checkCmdEnviron command
|
2011-03-19 18:58:49 -04:00
|
|
|
prepCommand command (drop 1 params)
|
2010-12-30 14:19:16 -04:00
|
|
|
_ -> error "internal error: multiple matching commands"
|
2010-11-02 19:04:24 -04:00
|
|
|
where
|
|
|
|
getopt = case getOpt Permute options argv of
|
2010-12-30 16:52:24 -04:00
|
|
|
(flags, params, []) ->
|
|
|
|
return (flags, params)
|
|
|
|
(_, _, errs) ->
|
|
|
|
ioError (userError (concat errs ++ usagemsg))
|
2010-12-30 14:19:16 -04:00
|
|
|
lookupCmd cmd = filter (\c -> cmd == cmdname c) cmds
|
2010-12-30 16:52:24 -04:00
|
|
|
usagemsg = "\n\n" ++ usage header cmds options
|
2010-12-30 15:06:26 -04:00
|
|
|
|
2011-08-17 14:14:43 -04:00
|
|
|
{- Checks that the command can be run in the current environment. -}
|
|
|
|
checkCmdEnviron :: Command -> Annex ()
|
2011-08-17 18:38:26 -04:00
|
|
|
checkCmdEnviron command = when (cmdusesrepo command) ensureInitialized
|
2011-08-17 14:14:43 -04:00
|
|
|
|
2010-12-30 15:06:26 -04:00
|
|
|
{- Usage message with lists of commands and options. -}
|
|
|
|
usage :: String -> [Command] -> [Option] -> String
|
|
|
|
usage header cmds options =
|
2010-12-30 16:52:24 -04:00
|
|
|
usageInfo (header ++ "\n\nOptions:") options ++
|
|
|
|
"\nCommands:\n" ++ cmddescs
|
2010-12-30 15:06:26 -04:00
|
|
|
where
|
|
|
|
cmddescs = unlines $ map (indent . showcmd) cmds
|
|
|
|
showcmd c =
|
|
|
|
cmdname c ++
|
2010-12-30 15:15:22 -04:00
|
|
|
pad (longest cmdname + 1) (cmdname c) ++
|
2010-12-30 15:06:26 -04:00
|
|
|
cmdparams c ++
|
2010-12-30 15:15:22 -04:00
|
|
|
pad (longest cmdparams + 2) (cmdparams c) ++
|
2010-12-30 15:06:26 -04:00
|
|
|
cmddesc c
|
|
|
|
pad n s = replicate (n - length s) ' '
|
2010-12-30 15:15:22 -04:00
|
|
|
longest f = foldl max 0 $ map (length . f) cmds
|
2011-01-16 16:05:05 -04:00
|
|
|
|
|
|
|
{- Runs a list of Annex actions. Catches IO errors and continues
|
|
|
|
- (but explicitly thrown errors terminate the whole command).
|
|
|
|
-}
|
2011-01-25 21:49:04 -04:00
|
|
|
tryRun :: Annex.AnnexState -> [Annex Bool] -> IO ()
|
2011-07-15 03:12:05 -04:00
|
|
|
tryRun = tryRun' 0
|
|
|
|
tryRun' :: Integer -> Annex.AnnexState -> [Annex Bool] -> IO ()
|
|
|
|
tryRun' errnum state (a:as) = do
|
2011-04-07 13:59:31 -04:00
|
|
|
result <- try $ Annex.run state $ do
|
2011-10-04 00:40:47 -04:00
|
|
|
Annex.Queue.flushWhenFull
|
2011-10-02 11:42:34 -04:00
|
|
|
a
|
2011-01-16 16:05:05 -04:00
|
|
|
case result of
|
|
|
|
Left err -> do
|
2011-07-05 14:58:33 -04:00
|
|
|
Annex.eval state $ do
|
|
|
|
showErr err
|
2011-09-06 13:46:08 -04:00
|
|
|
showEndFail
|
2011-07-15 03:12:05 -04:00
|
|
|
tryRun' (errnum + 1) state as
|
|
|
|
Right (True,state') -> tryRun' errnum state' as
|
|
|
|
Right (False,state') -> tryRun' (errnum + 1) state' as
|
|
|
|
tryRun' errnum _ [] = when (errnum > 0) $ error $ show errnum ++ " failed"
|
2011-01-16 16:05:05 -04:00
|
|
|
|
|
|
|
{- Actions to perform each time ran. -}
|
|
|
|
startup :: Annex Bool
|
2011-08-17 14:14:43 -04:00
|
|
|
startup = return True
|
2011-01-16 16:05:05 -04:00
|
|
|
|
|
|
|
{- Cleanup actions. -}
|
2011-01-29 23:32:32 -04:00
|
|
|
shutdown :: Annex Bool
|
|
|
|
shutdown = do
|
2011-06-22 21:19:52 -04:00
|
|
|
saveState
|
2011-10-02 11:42:34 -04:00
|
|
|
liftIO Git.reap -- zombies from long-running git processes
|
2011-01-29 23:32:32 -04:00
|
|
|
return True
|