2010-10-13 19:55:18 +00:00
|
|
|
{- git-annex remote repositories -}
|
|
|
|
|
|
|
|
module Remotes (
|
|
|
|
remotesList,
|
2010-10-14 02:59:43 +00:00
|
|
|
remotesWithKey,
|
|
|
|
remoteEnsureGitConfigRead
|
2010-10-13 19:55:18 +00:00
|
|
|
) where
|
|
|
|
|
2010-10-14 01:28:47 +00:00
|
|
|
import Control.Monad.State (liftIO)
|
2010-10-14 02:59:43 +00:00
|
|
|
import qualified Data.Map as Map
|
2010-10-14 03:18:58 +00:00
|
|
|
import Data.String.Utils
|
2010-10-14 06:12:41 +00:00
|
|
|
import AbstractTypes
|
2010-10-14 06:36:41 +00:00
|
|
|
import qualified GitRepo as Git
|
2010-10-13 19:55:18 +00:00
|
|
|
import LocationLog
|
2010-10-14 03:18:58 +00:00
|
|
|
import Locations
|
2010-10-13 19:55:18 +00:00
|
|
|
import UUID
|
|
|
|
import List
|
|
|
|
|
|
|
|
{- Human visible list of remotes. -}
|
2010-10-14 06:36:41 +00:00
|
|
|
remotesList :: [Git.Repo] -> String
|
|
|
|
remotesList remotes = join " " $ map Git.repoDescribe remotes
|
2010-10-13 19:55:18 +00:00
|
|
|
|
|
|
|
{- Cost ordered list of remotes that the LocationLog indicate may have a key. -}
|
2010-10-14 06:36:41 +00:00
|
|
|
remotesWithKey :: Key -> Annex [Git.Repo]
|
2010-10-14 01:28:47 +00:00
|
|
|
remotesWithKey key = do
|
|
|
|
g <- gitAnnex
|
|
|
|
uuids <- liftIO $ keyLocations g key
|
2010-10-14 03:18:58 +00:00
|
|
|
allremotes <- remotesByCost
|
|
|
|
remotes <- reposByUUID allremotes uuids
|
|
|
|
if (0 == length remotes)
|
|
|
|
then error $ "no configured git remotes have: " ++ (keyFile key) ++ "\n" ++
|
|
|
|
"It has been seen before in these repositories:\n" ++
|
|
|
|
prettyPrintUUIDs uuids
|
|
|
|
else return remotes
|
2010-10-13 19:55:18 +00:00
|
|
|
|
|
|
|
{- Cost Ordered list of remotes. -}
|
2010-10-14 06:36:41 +00:00
|
|
|
remotesByCost :: Annex [Git.Repo]
|
2010-10-14 01:28:47 +00:00
|
|
|
remotesByCost = do
|
|
|
|
g <- gitAnnex
|
2010-10-14 06:36:41 +00:00
|
|
|
reposByCost $ Git.remotes g
|
2010-10-13 19:55:18 +00:00
|
|
|
|
|
|
|
{- Orders a list of git repos by cost. -}
|
2010-10-14 06:36:41 +00:00
|
|
|
reposByCost :: [Git.Repo] -> Annex [Git.Repo]
|
2010-10-14 01:28:47 +00:00
|
|
|
reposByCost l = do
|
|
|
|
costpairs <- mapM costpair l
|
|
|
|
return $ fst $ unzip $ sortBy bycost $ costpairs
|
2010-10-13 19:55:18 +00:00
|
|
|
where
|
2010-10-14 01:28:47 +00:00
|
|
|
costpair r = do
|
|
|
|
cost <- repoCost r
|
|
|
|
return (r, cost)
|
|
|
|
bycost (_, c1) (_, c2) = compare c1 c2
|
2010-10-13 19:55:18 +00:00
|
|
|
|
|
|
|
{- Calculates cost for a repo.
|
|
|
|
-
|
|
|
|
- The default cost is 100 for local repositories, and 200 for remote
|
|
|
|
- repositories; it can also be configured by remote.<name>.annex-cost
|
|
|
|
-}
|
2010-10-14 06:36:41 +00:00
|
|
|
repoCost :: Git.Repo -> Annex Int
|
2010-10-14 01:28:47 +00:00
|
|
|
repoCost r = do
|
|
|
|
g <- gitAnnex
|
|
|
|
if ((length $ config g r) > 0)
|
|
|
|
then return $ read $ config g r
|
2010-10-14 06:36:41 +00:00
|
|
|
else if (Git.repoIsLocal r)
|
2010-10-14 01:28:47 +00:00
|
|
|
then return 100
|
|
|
|
else return 200
|
2010-10-13 19:55:18 +00:00
|
|
|
where
|
2010-10-14 06:36:41 +00:00
|
|
|
config g r = Git.configGet g (configkey r) ""
|
|
|
|
configkey r = "remote." ++ (Git.repoRemoteName r) ++ ".annex-cost"
|
2010-10-14 02:59:43 +00:00
|
|
|
|
|
|
|
{- The git configs for the git repo's remotes is not read on startup
|
|
|
|
- because reading it may be expensive. This function ensures that it is
|
|
|
|
- read for a specified remote, and updates state. It returns the
|
|
|
|
- updated git repo also. -}
|
2010-10-14 06:36:41 +00:00
|
|
|
remoteEnsureGitConfigRead :: Git.Repo -> Annex Git.Repo
|
2010-10-14 02:59:43 +00:00
|
|
|
remoteEnsureGitConfigRead r = do
|
2010-10-14 06:36:41 +00:00
|
|
|
if (Map.null $ Git.configMap r)
|
2010-10-14 02:59:43 +00:00
|
|
|
then do
|
2010-10-14 06:36:41 +00:00
|
|
|
r' <- liftIO $ Git.configRead r
|
2010-10-14 02:59:43 +00:00
|
|
|
g <- gitAnnex
|
2010-10-14 06:36:41 +00:00
|
|
|
let l = Git.remotes g
|
|
|
|
let g' = Git.remotesAdd g $ exchange l r'
|
2010-10-14 02:59:43 +00:00
|
|
|
gitAnnexChange g'
|
|
|
|
return r'
|
|
|
|
else return r
|
|
|
|
where
|
|
|
|
exchange [] new = []
|
|
|
|
exchange (old:ls) new =
|
2010-10-14 06:36:41 +00:00
|
|
|
if ((Git.repoRemoteName old) == (Git.repoRemoteName new))
|
2010-10-14 02:59:43 +00:00
|
|
|
then new:(exchange ls new)
|
|
|
|
else old:(exchange ls new)
|