clean up remote.log handling

This commit is contained in:
Joey Hess 2011-03-29 13:49:54 -04:00
parent a3b6586902
commit 05751d55cd
6 changed files with 55 additions and 47 deletions

View file

@ -29,12 +29,12 @@ start :: CommandStartString
start params = notBareRepo $ do
when (null ws) $ error "Specify a name for the remote"
showStart "initremote" name
r <- Remote.configGet name
(u, c) <- case r of
m <- Remote.readRemoteLog
(u, c) <- case findByName name m of
Just t -> return t
Nothing -> do
uuid <- liftIO $ genUUID
return $ (uuid, M.empty)
return $ (uuid, M.insert nameKey name M.empty)
return $ Just $ perform name u $ M.union config c
where
@ -46,3 +46,17 @@ perform :: String -> UUID -> M.Map String String -> CommandPerform
perform name uuid config = do
liftIO $ putStrLn $ show $ (uuid, config)
return Nothing
findByName :: String -> M.Map UUID (M.Map String String) -> Maybe (UUID, M.Map String String)
findByName n m = if null matches then Nothing else Just $ head matches
where
matches = filter (matching . snd) $ M.toList m
matching c = case M.lookup nameKey c of
Nothing -> False
Just n'
| n' == n -> True
| otherwise -> False
{- The name of a configured remote is stored in its config using this key. -}
nameKey :: String
nameKey = "name"

View file

@ -21,7 +21,7 @@ module Remote (
remotesWithUUID,
remotesWithoutUUID,
configGet,
readRemoteLog,
configSet,
keyValToMap
) where
@ -71,7 +71,8 @@ genList = do
if null rs
then do
rs' <- runGenerators
Annex.changeState $ \s -> s { Annex.remotes = rs' }
rs'' <- getConfigs rs'
Annex.changeState $ \s -> s { Annex.remotes = rs'' }
return rs'
else return rs
@ -132,51 +133,47 @@ remoteLog = do
g <- Annex.gitRepo
return $ gitStateDir g ++ "remote.log"
{- Reads the uuid and config of the specified remote from the remoteLog. -}
configGet :: String -> Annex (Maybe (UUID, M.Map String String))
configGet n = do
rs <- readRemoteLog
let matches = filter (matchName n) rs
case matches of
[] -> return Nothing
((u, _, c):_) -> return $ Just (u, c)
{- Load stored config into remotes.
-
- This way, the log is read once, lazily, so if no remotes access
- their config, no work is done.
-}
getConfigs :: [Remote Annex] -> Annex [Remote Annex]
getConfigs rs = do
m <- readRemoteLog
return $ map (get m) rs
where
get m r = r { config = M.lookup (uuid r) m }
{- Changes or adds a remote's config in the remoteLog. -}
configSet :: String -> UUID -> M.Map String String -> Annex ()
configSet n u c = do
rs <- readRemoteLog
let others = filter (not . matchName n) rs
writeRemoteLog $ (u, n, c):others
{- Adds or updates a remote's config in the log. -}
configSet :: UUID -> M.Map String String -> Annex ()
configSet u c = do
m <- readRemoteLog
l <- remoteLog
liftIO $ writeFile l $ unlines $ map toline $ M.toList $ M.insert u c m
where
toline (u', c') = u' ++ " " ++ (unwords $ mapToKeyVal c')
matchName :: String -> (UUID, String, M.Map String String) -> Bool
matchName n (_, n', _) = n == n'
readRemoteLog :: Annex [(UUID, String, M.Map String String)]
{- Map of remotes by uuid containing key/value config maps. -}
readRemoteLog :: Annex (M.Map UUID (M.Map String String))
readRemoteLog = do
l <- remoteLog
s <- liftIO $ catch (readFile l) ignoreerror
return $ remoteLogParse s
where
ignoreerror _ = return []
ignoreerror _ = return ""
writeRemoteLog :: [(UUID, String, M.Map String String)] -> Annex ()
writeRemoteLog rs = do
l <- remoteLog
liftIO $ writeFile l $ unlines $ map toline rs
where
toline (u, n, c) = u ++ " " ++ n ++ (unwords $ mapToKeyVal c)
remoteLogParse :: String -> [(UUID, String, M.Map String String)]
remoteLogParse s = catMaybes $ map parseline $ filter (not . null) $ lines s
remoteLogParse :: String -> M.Map UUID (M.Map String String)
remoteLogParse s =
M.fromList $ catMaybes $ map parseline $ filter (not . null) $ lines s
where
parseline l
| length w > 2 = Just (u, n, c)
| length w > 2 = Just (u, c)
| otherwise = Nothing
where
w = words l
u = w !! 0
n = w !! 1
c = keyValToMap $ drop 2 w
c = keyValToMap $ tail w
{- Given Strings like "key=value", generates a Map. -}
keyValToMap :: [String] -> M.Map String String

View file

@ -12,7 +12,7 @@ module Remote.Git (
import Control.Exception.Extensible
import Control.Monad.State (liftIO)
import qualified Data.Map as Map
import qualified Data.Map as M
import System.Cmd.Utils
import Control.Monad (filterM, liftM)
@ -68,7 +68,6 @@ genRemote r = do
removeKey = dropKey r,
hasKey = inAnnex r,
hasKeyCheap = not (Git.repoIsUrl r),
hasConfig = False,
config = Nothing,
setup = \_ -> return ()
}
@ -77,7 +76,7 @@ genRemote r = do
- returns the updated repo. -}
tryGitConfigRead :: Git.Repo -> Annex Git.Repo
tryGitConfigRead r
| not $ Map.null $ Git.configMap r = return r -- already read
| not $ M.null $ Git.configMap r = return r -- already read
| Git.repoIsSsh r = store $ onRemote r (pipedconfig, r) "configlist" []
| Git.repoIsUrl r = return r
| otherwise = store $ safely $ Git.configRead r

View file

@ -12,7 +12,7 @@ import Network.AWS.S3Object
import Network.AWS.S3Bucket
import Network.AWS.AWSResult
import qualified Data.ByteString.Lazy.Char8 as L
import qualified Data.Map as Map
import qualified Data.Map as M
import Data.String.Utils
import Control.Monad (filterM, liftM, when)
import Control.Monad.State (liftIO)
@ -51,8 +51,8 @@ gen = do
findS3Remotes :: Git.Repo -> [Git.Repo]
findS3Remotes r = map construct remotepairs
where
remotepairs = Map.toList $ filterremotes $ Git.configMap r
filterremotes = Map.filterWithKey (\k _ -> s3remote k)
remotepairs = M.toList $ filterremotes $ Git.configMap r
filterremotes = M.filterWithKey (\k _ -> s3remote k)
construct (k,_) = Git.repoRemoteNameSet Git.repoFromUnknown k
s3remote k = startswith "remote." k && endswith ".annex-s3-bucket" k
@ -68,7 +68,6 @@ genRemote r u = do
removeKey = error "TODO",
hasKey = error "TODO",
hasKeyCheap = False,
hasConfig = True,
config = Nothing,
setup = \_ -> return ()
}

View file

@ -47,8 +47,7 @@ data Remote a = Remote {
-- Some remotes can check hasKey without an expensive network
-- operation.
hasKeyCheap :: Bool,
-- a Remote may have a persistent configuration store
hasConfig :: Bool,
-- a Remote can have a persistent configuration store
config :: Maybe (M.Map String String),
-- initializes or changes the config of a remote
setup :: M.Map String String -> a ()

View file

@ -36,8 +36,8 @@ Holds persistent configuration settings for [[special_remotes]] such as
Amazon S3.
The file format is one line per remote, starting with the uuid of the
remote, followed by a space, the name of the remote, a space, and then
a series of key=value pairs, each separated by whitespace.
remote, followed by a space, and then a series of key=value pairs,
each separated by whitespace.
## `.git-annex/trust.log`