git-annex/Command.hs

124 lines
3.6 KiB
Haskell
Raw Normal View History

2011-09-15 20:57:02 +00:00
{- git-annex command infrastructure
-
2011-09-19 05:37:04 +00:00
- Copyright 2010-2011 Joey Hess <joey@kitenet.net>
-
- Licensed under the GNU GPL version 3 or higher.
-}
module Command (
command,
noRepo,
2012-09-16 00:46:38 +00:00
noCommit,
noMessages,
withOptions,
next,
stop,
stopUnless,
prepCommand,
doCommand,
whenAnnexed,
ifAnnexed,
isBareRepo,
numCopies,
numCopiesCheck,
checkAuto,
2011-11-11 05:52:58 +00:00
module ReExported
) where
2011-10-05 20:02:51 +00:00
import Common.Annex
2010-11-04 17:28:49 +00:00
import qualified Backend
import qualified Annex
import qualified Git
import qualified Remote
2011-11-11 05:52:58 +00:00
import Types.Command as ReExported
import Types.Option as ReExported
2011-11-11 05:52:58 +00:00
import Seek as ReExported
import Checks as ReExported
import Usage as ReExported
2011-10-15 20:21:08 +00:00
import Logs.Trust
import Config
import Annex.CheckAttr
{- Generates a normal command -}
command :: String -> String -> [CommandSeek] -> CommandSection -> String -> Command
command = Command [] Nothing commonChecks False False
2012-09-16 00:46:38 +00:00
{- Indicates that a command doesn't need to commit any changes to
- the git-annex branch. -}
noCommit :: Command -> Command
noCommit c = c { cmdnocommit = True }
{- Indicates that a command should not output anything other than what
- it directly sends to stdout. (--json can override this). -}
noMessages :: Command -> Command
noMessages c = c { cmdnomessages = True }
{- Adds a fallback action to a command, that will be run if it's used
- outside a git repository. -}
noRepo :: IO () -> Command -> Command
noRepo a c = c { cmdnorepo = Just a }
2010-11-04 17:28:49 +00:00
{- Adds options to a command. -}
withOptions :: [Option] -> Command -> Command
withOptions o c = c { cmdoptions = o }
2011-05-15 06:02:46 +00:00
{- For start and perform stages to indicate what step to run next. -}
next :: a -> Annex (Maybe a)
next a = return $ Just a
{- Or to indicate nothing needs to be done. -}
stop :: Annex (Maybe a)
stop = return Nothing
{- Stops unless a condition is met. -}
stopUnless :: Annex Bool -> Annex (Maybe a) -> Annex (Maybe a)
stopUnless c a = ifM c ( a , stop )
2011-10-31 00:04:15 +00:00
{- Prepares to run a command via the check and seek stages, returning a
- list of actions to perform to run the command. -}
prepCommand :: Command -> [String] -> Annex [CommandCleanup]
prepCommand Command { cmdseek = seek, cmdcheck = c } params = do
2011-11-11 05:52:58 +00:00
mapM_ runCheck c
2011-10-31 00:04:15 +00:00
map doCommand . concat <$> mapM (\s -> s params) seek
2010-11-04 17:28:49 +00:00
{- Runs a command through the start, perform and cleanup stages -}
doCommand :: CommandStart -> CommandCleanup
2011-05-15 16:25:58 +00:00
doCommand = start
2012-11-11 04:51:07 +00:00
where
start = stage $ maybe skip perform
perform = stage $ maybe failure cleanup
cleanup = stage $ status
stage = (=<<)
skip = return True
failure = showEndFail >> return False
status r = showEndResult r >> return r
2010-11-04 17:28:49 +00:00
{- Modifies an action to only act on files that are already annexed,
- and passes the key and backend on to it. -}
2011-12-31 08:11:39 +00:00
whenAnnexed :: (FilePath -> (Key, Backend) -> Annex (Maybe a)) -> FilePath -> Annex (Maybe a)
whenAnnexed a file = ifAnnexed file (a file) (return Nothing)
2011-12-31 08:11:39 +00:00
ifAnnexed :: FilePath -> ((Key, Backend) -> Annex a) -> Annex a -> Annex a
ifAnnexed file yes no = maybe no yes =<< Backend.lookupFile file
isBareRepo :: Annex Bool
isBareRepo = fromRepo Git.repoIsLocalBare
numCopies :: FilePath -> Annex (Maybe Int)
numCopies file = do
forced <- Annex.getState Annex.forcenumcopies
case forced of
Just n -> return $ Just n
Nothing -> readish <$> checkAttr "annex.numcopies" file
numCopiesCheck :: FilePath -> Key -> (Int -> Int -> v) -> Annex v
numCopiesCheck file key vs = do
numcopiesattr <- numCopies file
needed <- getNumCopies numcopiesattr
have <- trustExclude UnTrusted =<< Remote.keyLocations key
return $ length have `vs` needed
checkAuto :: Annex Bool -> Annex Bool
checkAuto checker = ifM (Annex.getState Annex.auto)
( checker , return True )