diff options
author | Joey Hess <joey@kitenet.net> | 2010-10-31 15:09:50 -0400 |
---|---|---|
committer | Joey Hess <joey@kitenet.net> | 2010-10-31 15:09:50 -0400 |
commit | 28b5a9fa2048f4e6425cc1d8dbe13b0e4c36a15b (patch) | |
tree | 74be5b9da486ed2f711f65aa57697ea248f4abbf | |
parent | 40729e4bfdf4fe9753705a5a7a93cf1e0012a92c (diff) |
changelog
-rw-r--r-- | Commands.hs | 146 |
1 files changed, 76 insertions, 70 deletions
diff --git a/Commands.hs b/Commands.hs index 2af8874e5..fb76e5502 100644 --- a/Commands.hs +++ b/Commands.hs @@ -11,12 +11,9 @@ import System.Console.GetOpt import Control.Monad.State (liftIO) import System.Posix.Files import System.Directory -import System.Path import Data.String.Utils import Control.Monad (filterM) import Monad (when, unless) -import List -import IO import qualified GitRepo as Git import qualified Annex @@ -50,19 +47,19 @@ type SubCmdCleanup = Annex Bool {- Runs a subcommand through its three stages. -} doSubCmd :: String -> SubCmdStart -> String -> Annex Bool doSubCmd cmdname start param = do - res <- start param :: Annex (Maybe SubCmdPerform) - case (res) of + startres <- start param :: Annex (Maybe SubCmdPerform) + case (startres) of Nothing -> return True Just perform -> do showStart cmdname param - res <- perform :: Annex (Maybe SubCmdCleanup) - case (res) of + performres <- perform :: Annex (Maybe SubCmdCleanup) + case (performres) of Nothing -> do showEndFail return False Just cleanup -> do - res <- cleanup - if (res) + cleanupres <- cleanup + if (cleanupres) then do showEndOk return True @@ -76,7 +73,7 @@ doSubCmd cmdname start param = do data SubCmdWants = FilesInGit | FilesNotInGit | FilesMissing | Description | Keys | Tempfile | FilesToBeCommitted -data SubCommand = Command { +data SubCommand = SubCommand { subcmdname :: String, subcmdaction :: SubCmdStart, subcmdwants :: SubCmdWants, @@ -84,27 +81,27 @@ data SubCommand = Command { } subCmds :: [SubCommand] subCmds = [ - (Command "add" addStart FilesNotInGit + (SubCommand "add" addStart FilesNotInGit "add files to annex") - , (Command "get" getStart FilesInGit + , (SubCommand "get" getStart FilesInGit "make content of annexed files available") - , (Command "drop" dropStart FilesInGit + , (SubCommand "drop" dropStart FilesInGit "indicate content of files not currently wanted") - , (Command "move" moveStart FilesInGit + , (SubCommand "move" moveStart FilesInGit "transfer content of files to/from another repository") - , (Command "init" initStart Description + , (SubCommand "init" initStart Description "initialize git-annex with repository description") - , (Command "unannex" unannexStart FilesInGit + , (SubCommand "unannex" unannexStart FilesInGit "undo accidential add command") - , (Command "fix" fixStart FilesInGit + , (SubCommand "fix" fixStart FilesInGit "fix up symlinks to point to annexed content") - , (Command "pre-commit" fixStart FilesToBeCommitted + , (SubCommand "pre-commit" fixStart FilesToBeCommitted "fix up symlinks before they are committed") - , (Command "fromkey" fromKeyStart FilesMissing + , (SubCommand "fromkey" fromKeyStart FilesMissing "adds a file using a specific key") - , (Command "dropkey" dropKeyStart Keys + , (SubCommand "dropkey" dropKeyStart Keys "drops annexed content for specified keys") - , (Command "setkey" setKeyStart Tempfile + , (SubCommand "setkey" setKeyStart Tempfile "sets annexed content for a key using a temp file") ] @@ -131,6 +128,7 @@ options = [ storebool n b = Annex.flagChange n $ FlagBool b storestring n s = Annex.flagChange n $ FlagString s +header :: String header = "Usage: git-annex " ++ (join "|" $ map subcmdname subCmds) {- Usage message with lists of options and subcommands. -} @@ -162,7 +160,7 @@ findWanted FilesNotInGit params repo = do findWanted FilesInGit params repo = do files <- mapM (Git.inRepo repo) params return $ foldl (++) [] files -findWanted FilesMissing params repo = do +findWanted FilesMissing params _ = do files <- liftIO $ filterM missing params return $ files where @@ -186,15 +184,17 @@ parseCmd argv state = do when (null params) $ error usage case lookupCmd (params !! 0) of [] -> error usage - [Command name action want _] -> do - f <- findWanted want (drop 1 params) + [SubCommand { subcmdname = name, subcmdaction = action, + subcmdwants = want, subcmddesc = _ }] -> do + files <- findWanted want (drop 1 params) (TypeInternals.repo state) let actions = map (doSubCmd name action) $ - filter notstate f - let configactions = map (\f -> do - f + filter notstate files + let configactions = map (\flag -> do + flag return True) flags return (configactions, actions) + _ -> error "internal error: multiple matching subcommands" where -- never include files from the state directory notstate f = stateLoc /= take (length stateLoc) f @@ -214,11 +214,10 @@ addStart file = notAnnexed file $ do else return $ Just $ addPerform file addPerform :: FilePath -> Annex (Maybe SubCmdCleanup) addPerform file = do - g <- Annex.gitRepo stored <- Backend.storeFileKey file case (stored) of Nothing -> return Nothing - Just (key, backend) -> return $ Just $ addCleanup file key + Just (key, _) -> return $ Just $ addCleanup file key addCleanup :: FilePath -> Key -> Annex Bool addCleanup file key = do logStatus key ValuePresent @@ -239,8 +238,10 @@ unannexPerform :: FilePath -> Key -> Backend -> Annex (Maybe SubCmdCleanup) unannexPerform file key backend = do -- force backend to always remove Annex.flagChange "force" $ FlagBool True - Backend.removeKey backend key - return $ Just $ unannexCleanup file key + ok <- Backend.removeKey backend key + if (ok) + then return $ Just $ unannexCleanup file key + else return Nothing unannexCleanup :: FilePath -> Key -> Annex Bool unannexCleanup file key = do logStatus key ValueMissing @@ -259,9 +260,9 @@ getStart file = isAnnexed file $ \(key, backend) -> do inannex <- inAnnex key if (inannex) then return Nothing - else return $ Just $ getPerform file key backend -getPerform :: FilePath -> Key -> Backend -> Annex (Maybe SubCmdCleanup) -getPerform file key backend = do + else return $ Just $ getPerform key backend +getPerform :: Key -> Backend -> Annex (Maybe SubCmdCleanup) +getPerform key backend = do ok <- getViaTmp key (Backend.retrieveKeyFile backend key) if (ok) then return $ Just $ return True -- no cleanup needed @@ -331,15 +332,15 @@ setKeyPerform tmpfile key = do ok <- liftIO $ boolSystem "mv" [tmpfile, loc] if (not ok) then error "mv failed!" - else return $ Just $ setKeyCleanup tmpfile key -setKeyCleanup :: FilePath -> Key -> Annex Bool -setKeyCleanup tmpfile key = do + else return $ Just $ setKeyCleanup key +setKeyCleanup :: Key -> Annex Bool +setKeyCleanup key = do logStatus key ValuePresent return True {- Fixes the symlink to an annexed file. -} fixStart :: FilePath -> Annex (Maybe SubCmdPerform) -fixStart file = isAnnexed file $ \(key, backend) -> do +fixStart file = isAnnexed file $ \(key, _) -> do link <- calcGitLink file key l <- liftIO $ readSymbolicLink file if (link == l) @@ -373,9 +374,9 @@ initPerform description = do initCleanup :: Annex Bool initCleanup = do g <- Annex.gitRepo - log <- uuidLog - liftIO $ Git.run g ["add", log] - liftIO $ Git.run g ["commit", "-m", "git annex init", log] + logfile <- uuidLog + liftIO $ Git.run g ["add", logfile] + liftIO $ Git.run g ["commit", "-m", "git annex init", logfile] return True {- Adds a file pointing at a manually-specified key -} @@ -411,9 +412,9 @@ moveStart file = do toName <- Annex.flagGet "torepository" case (fromName, toName) of ("", "") -> error "specify either --from or --to" - ("", to) -> moveToStart file - (from, "") -> moveFromStart file - (_, _) -> error "only one of --from or --to can be specified" + ("", _) -> moveToStart file + (_ , "") -> moveFromStart file + (_ , _) -> error "only one of --from or --to can be specified" {- Moves the content of an annexed file to another repository, - removing it from the current repository, and updates locationlog @@ -427,13 +428,13 @@ moveStart file = do - allow it to be dropped. -} moveToStart :: FilePath -> Annex (Maybe SubCmdPerform) -moveToStart file = isAnnexed file $ \(key, backend) -> do +moveToStart file = isAnnexed file $ \(key, _) -> do ishere <- inAnnex key if (not ishere) then return Nothing -- not here, so nothing to do - else return $ Just $ moveToPerform file key -moveToPerform :: FilePath -> Key -> Annex (Maybe SubCmdCleanup) -moveToPerform file key = do + else return $ Just $ moveToPerform key +moveToPerform :: Key -> Annex (Maybe SubCmdCleanup) +moveToPerform key = do -- checking the remote is expensive, so not done in the start step remote <- Remotes.commandLineRemote isthere <- Remotes.inAnnex remote key @@ -452,18 +453,21 @@ moveToPerform file key = do moveToCleanup :: Git.Repo -> Key -> FilePath -> Annex Bool moveToCleanup remote key tmpfile = do -- Tell remote to use the transferred content. - Remotes.runCmd remote "git-annex" ["setkey", "--quiet", + ok <- Remotes.runCmd remote "git-annex" ["setkey", "--quiet", "--backend=" ++ (backendName key), "--key=" ++ keyName key, tmpfile] - -- Record that the key is present on the remote. - g <- Annex.gitRepo - remoteuuid <- getUUID remote - log <- liftIO $ logChange g key remoteuuid ValuePresent - Annex.queue "add" [] log - -- Cleanup on the local side is the same as done for the - -- drop subcommand. - dropCleanup key + if ok + then do + -- Record that the key is present on the remote. + g <- Annex.gitRepo + remoteuuid <- getUUID remote + logfile <- liftIO $ logChange g key remoteuuid ValuePresent + Annex.queue "add" [] logfile + -- Cleanup on the local side is the same as done for the + -- drop subcommand. + dropCleanup key + else return False {- Moves the content of an annexed file from another repository to the current - repository and updates locationlog information on both. @@ -472,15 +476,14 @@ moveToCleanup remote key tmpfile = do - from the other repository. -} moveFromStart :: FilePath -> Annex (Maybe SubCmdPerform) -moveFromStart file = isAnnexed file $ \(key, backend) -> do - g <- Annex.gitRepo +moveFromStart file = isAnnexed file $ \(key, _) -> do remote <- Remotes.commandLineRemote l <- Remotes.keyPossibilities key if (elem remote l) - then return $ Just $ moveFromPerform file key + then return $ Just $ moveFromPerform key else return Nothing -moveFromPerform :: FilePath -> Key -> Annex (Maybe SubCmdCleanup) -moveFromPerform file key = do +moveFromPerform :: Key -> Annex (Maybe SubCmdCleanup) +moveFromPerform key = do remote <- Remotes.commandLineRemote ishere <- inAnnex key if (ishere) @@ -493,22 +496,25 @@ moveFromPerform file key = do else return Nothing -- fail moveFromCleanup :: Git.Repo -> Key -> Annex Bool moveFromCleanup remote key = do - Remotes.runCmd remote "git-annex" ["dropkey", "--quiet", "--force", + ok <- Remotes.runCmd remote "git-annex" ["dropkey", "--quiet", "--force", "--backend=" ++ (backendName key), keyName key] - -- Record locally that the key is not on the remote. - remoteuuid <- getUUID remote - g <- Annex.gitRepo - log <- liftIO $ logChange g key remoteuuid ValueMissing - Annex.queue "add" [] log - return True + when ok $ do + -- Record locally that the key is not on the remote. + remoteuuid <- getUUID remote + g <- Annex.gitRepo + logfile <- liftIO $ logChange g key remoteuuid ValueMissing + Annex.queue "add" [] logfile + return ok -- helpers +notAnnexed :: FilePath -> Annex (Maybe a) -> Annex (Maybe a) notAnnexed file a = do r <- Backend.lookupFile file case (r) of - Just v -> return Nothing + Just _ -> return Nothing Nothing -> a +isAnnexed :: FilePath -> ((Key, Backend) -> Annex (Maybe a)) -> Annex (Maybe a) isAnnexed file a = do r <- Backend.lookupFile file case (r) of |