aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Joey Hess <joey@kitenet.net>2010-12-31 15:46:33 -0400
committerGravatar Joey Hess <joey@kitenet.net>2010-12-31 15:46:33 -0400
commiteac433a84ad397e371300343b7cd30b7741ee023 (patch)
treeb3e02fa4f6942657f622c4790d9fb4d2d2a17e95
parent60df4e5728b8af804f06c39ef3b897af12247ceb (diff)
use git-annex-shell configlist
-rw-r--r--Annex.hs4
-rw-r--r--Command/Move.hs7
-rw-r--r--GitRepo.hs35
-rw-r--r--Remotes.hs68
4 files changed, 66 insertions, 48 deletions
diff --git a/Annex.hs b/Annex.hs
index 6e5198e8e..55f9edb36 100644
--- a/Annex.hs
+++ b/Annex.hs
@@ -47,7 +47,7 @@ new gitrepo allbackends = do
where
prep = do
-- read git config and update state
- gitrepo' <- liftIO $ Git.configRead gitrepo Nothing
+ gitrepo' <- liftIO $ Git.configRead gitrepo
Annex.gitRepoChange gitrepo'
{- performs an action in the Annex monad -}
@@ -136,5 +136,5 @@ setConfig key value = do
g <- Annex.gitRepo
liftIO $ Git.run g ["config", key, value]
-- re-read git config and update the repo's state
- g' <- liftIO $ Git.configRead g Nothing
+ g' <- liftIO $ Git.configRead g
Annex.gitRepoChange g'
diff --git a/Command/Move.hs b/Command/Move.hs
index e872d86fe..4291d221a 100644
--- a/Command/Move.hs
+++ b/Command/Move.hs
@@ -7,6 +7,7 @@
module Command.Move where
+import Control.Monad (when)
import Control.Monad.State (liftIO)
import Command
@@ -20,6 +21,7 @@ import qualified GitRepo as Git
import qualified Remotes
import UUID
import Messages
+import Utility
command :: [Command]
command = [Command "move" paramPath seek
@@ -134,10 +136,11 @@ fromPerform move key = do
else return Nothing -- fail
fromCleanup :: Bool -> Git.Repo -> Key -> CommandCleanup
fromCleanup True remote key = do
- ok <- Remotes.onRemote remote "dropkey"
+ ok <- Remotes.onRemote remote boolSystem False "dropkey"
["--quiet", "--force",
"--backend=" ++ backendName key,
keyName key]
- remoteHasKey remote key False
+ when ok $
+ remoteHasKey remote key False
return ok
fromCleanup False _ _ = return True
diff --git a/GitRepo.hs b/GitRepo.hs
index 2c2ad7b53..9dfce0d35 100644
--- a/GitRepo.hs
+++ b/GitRepo.hs
@@ -24,6 +24,8 @@ module GitRepo (
configGet,
configMap,
configRead,
+ hConfigRead,
+ configStore,
configTrue,
gitCommandLine,
run,
@@ -141,11 +143,7 @@ assertUrl repo action =
then action
else error $ "acting on local git repo " ++ repoDescribe repo ++
" not supported"
-assertSsh :: Repo -> a -> a
-assertSsh repo action =
- if repoIsSsh repo
- then action
- else error $ "unsupported url in repo " ++ repoDescribe repo
+
bare :: Repo -> Bool
bare repo = case Map.lookup "core.bare" $ config repo of
Just v -> configTrue v
@@ -276,11 +274,9 @@ pipeNullSplit repo params = do
where
split0 s = filter (not . null) $ split "\0" s
-{- Runs git config and populates a repo with its config.
- -
- - For a ssh repository, a list of ssh options may optionally be specified. -}
-configRead :: Repo -> Maybe [String] -> IO Repo
-configRead repo@(Repo { location = Dir d }) _ = do
+{- Runs git config and populates a repo with its config. -}
+configRead :: Repo -> IO Repo
+configRead repo@(Repo { location = Dir d }) = do
{- Cannot use pipeRead because it relies on the config having
been already read. Instead, chdir to the repo. -}
cwd <- getCurrentDirectory
@@ -288,19 +284,18 @@ configRead repo@(Repo { location = Dir d }) _ = do
(\_ -> changeWorkingDirectory cwd) $
pOpen ReadFromPipe "git" ["config", "--list"] $
hConfigRead repo
-configRead repo sshopts = assertSsh repo $ do
- pOpen ReadFromPipe "ssh" params $ hConfigRead repo
- where
- params = case sshopts of
- Nothing -> [urlHost repo, command]
- Just l -> l ++ [urlHost repo, command]
- command = "cd " ++ shellEscape (urlPath repo) ++
- " && git config --list"
+configRead r = assertLocal r $ error "internal"
+
+{- Reads git config from a handle and populates a repo with it. -}
hConfigRead :: Repo -> Handle -> IO Repo
hConfigRead repo h = do
val <- hGetContentsStrict h
- let r = repo { config = configParse val }
- return r { remotes = configRemotes r }
+ return $ configStore repo val
+
+{- Parses a git config and returns a version of the repo using it. -}
+configStore :: Repo -> String -> Repo
+configStore repo s = r { remotes = configRemotes r }
+ where r = repo { config = configParse s }
{- Checks if a string fron git config is a true value. -}
configTrue :: String -> Bool
diff --git a/Remotes.hs b/Remotes.hs
index ca65c99ff..841fe947f 100644
--- a/Remotes.hs
+++ b/Remotes.hs
@@ -25,6 +25,7 @@ import qualified Data.Map as Map
import Data.String.Utils
import System.Directory hiding (copyFile)
import System.Posix.Directory
+import System.Cmd.Utils
import Data.List (intersect, sortBy)
import Control.Monad (when, unless, filterM)
@@ -112,16 +113,14 @@ inAnnex r key = if Git.repoIsUrl r
else liftIO (try checklocal ::IO (Either IOException Bool))
where
checklocal = do
- -- run a local check by making an Annex monad
- -- using the remote
+ -- run a local check inexpensively,
+ -- by making an Annex monad using the remote
a <- Annex.new r []
Annex.eval a (Core.inAnnex key)
checkremote = do
showNote ("checking " ++ Git.repoDescribe r ++ "...")
- inannex <- onRemote r "inannex"
+ inannex <- onRemote r boolSystem False "inannex"
["--backend=" ++ backendName key, keyName key]
- -- XXX Note that ssh failing and the file not existing
- -- are not currently differentiated.
return $ Right inannex
{- Cost Ordered list of remotes. -}
@@ -199,24 +198,29 @@ byName name = do
- config for a specified remote, and updates state. If successful, it
- returns the updated git repo. -}
tryGitConfigRead :: Git.Repo -> Annex (Either Git.Repo Git.Repo)
-tryGitConfigRead r = do
- sshoptions <- repoConfig r "ssh-options" ""
- if Map.null $ Git.configMap r
- then do
- -- configRead can fail due to IO error or
- -- for other reasons; catch all possible exceptions
- result <- liftIO (try (Git.configRead r $ Just $ words sshoptions)::IO (Either SomeException Git.Repo))
+tryGitConfigRead r
+ | not $ Map.null $ Git.configMap r = return $ Right r -- already read
+ | Git.repoIsSsh r = store $ onRemote r pipedconfig r "configlist" []
+ | Git.repoIsUrl r = return $ Left r
+ | otherwise = store $ safely $ Git.configRead r
+ where
+ -- Reading config can fail due to IO error or
+ -- for other reasons; catch all possible exceptions.
+ safely a = do
+ result <- liftIO (try (a)::IO (Either SomeException Git.Repo))
case result of
- Left _ -> return $ Left r
- Right r' -> do
- g <- Annex.gitRepo
- let l = Git.remotes g
- let g' = Git.remotesAdd g $
- exchange l r'
- Annex.gitRepoChange g'
- return $ Right r'
- else return $ Right r -- config already read
- where
+ Left _ -> return r
+ Right r' -> return r'
+ pipedconfig cmd params = safely $
+ pOpen ReadFromPipe cmd params $
+ Git.hConfigRead r
+ store a = do
+ r' <- a
+ g <- Annex.gitRepo
+ let l = Git.remotes g
+ let g' = Git.remotesAdd g $ exchange l r'
+ Annex.gitRepoChange g'
+ return $ Right r'
exchange [] _ = []
exchange (old:ls) new =
if Git.repoRemoteName old == Git.repoRemoteName new
@@ -268,10 +272,26 @@ remoteCopyFile recv r src dest = do
-- inplace makes rsync resume partial files
options = ["-p", "--progress", "--inplace"]
-onRemote :: Git.Repo -> String -> [String] -> Annex Bool
-onRemote r command params = runCmd r "git-annex-shell" (command:dir:params)
+{- Uses a supplied function to run a git-annex-shell command on a remote. -}
+onRemote
+ :: Git.Repo
+ -> (String -> [String] -> IO a)
+ -> a
+ -> String
+ -> [String]
+ -> Annex a
+onRemote r with errorval command params
+ | not $ Git.repoIsUrl r = liftIO $ with shellcmd shellopts
+ | Git.repoIsSsh r = do
+ sshoptions <- repoConfig r "ssh-options" ""
+ liftIO $ with "ssh" $
+ words sshoptions ++ [Git.urlHost r, sshcmd]
+ | otherwise = return errorval
where
dir = Git.workTree r
+ shellcmd = "git-annex-shell"
+ shellopts = command:dir:params
+ sshcmd = shellcmd ++ " " ++ unwords (map shellEscape shellopts)
{- Runs a command in a remote, using ssh if necessary.
- (Honors annex-ssh-options.) -}