1{- git-annex remote list
2 -
3 - Copyright 2011-2020 Joey Hess <id@joeyh.name>
4 -
5 - Licensed under the GNU AGPL version 3 or higher.
6 -}
7
8module Remote.List where
9
10import qualified Data.Map as M
11
12import Annex.Common
13import qualified Annex
14import Logs.Remote
15import Types.Remote
16import Types.RemoteState
17import Annex.UUID
18import Remote.Helper.Hooks
19import Remote.Helper.ReadOnly
20import Remote.Helper.ExportImport
21import qualified Git
22
23import qualified Remote.Git
24import qualified Remote.GCrypt
25import qualified Remote.P2P
26import qualified Remote.S3
27import qualified Remote.Bup
28import qualified Remote.Directory
29import qualified Remote.Rsync
30import qualified Remote.Web
31import qualified Remote.BitTorrent
32import qualified Remote.WebDAV
33import qualified Remote.Adb
34import qualified Remote.Tahoe
35import qualified Remote.Glacier
36import qualified Remote.Ddar
37import qualified Remote.GitLFS
38import qualified Remote.HttpAlso
39import qualified Remote.Borg
40import qualified Remote.Hook
41import qualified Remote.External
42
43remoteTypes :: [RemoteType]
44remoteTypes = map adjustExportImportRemoteType
45	[ Remote.Git.remote
46	, Remote.GCrypt.remote
47	, Remote.P2P.remote
48	, Remote.S3.remote
49	, Remote.Bup.remote
50	, Remote.Directory.remote
51	, Remote.Rsync.remote
52	, Remote.Web.remote
53	, Remote.BitTorrent.remote
54	, Remote.WebDAV.remote
55	, Remote.Adb.remote
56	, Remote.Tahoe.remote
57	, Remote.Glacier.remote
58	, Remote.Ddar.remote
59	, Remote.GitLFS.remote
60	, Remote.HttpAlso.remote
61	, Remote.Borg.remote
62	, Remote.Hook.remote
63	, Remote.External.remote
64	]
65
66{- Builds a list of all available Remotes.
67 - Since doing so can be expensive, the list is cached. -}
68remoteList :: Annex [Remote]
69remoteList = do
70	rs <- Annex.getState Annex.remotes
71	if null rs
72		then remoteList' False
73		else return rs
74
75remoteList' :: Bool -> Annex [Remote]
76remoteList' autoinit = do
77	m <- remoteConfigMap
78	rs <- concat <$> mapM (process m) remoteTypes
79	Annex.changeState $ \s -> s { Annex.remotes = rs }
80	return rs
81  where
82	process m t = enumerate t autoinit
83		>>= mapM (remoteGen m t)
84		>>= return . catMaybes
85
86{- Generates a Remote. -}
87remoteGen :: M.Map UUID RemoteConfig -> RemoteType -> Git.Repo -> Annex (Maybe Remote)
88remoteGen m t g = do
89	u <- getRepoUUID g
90	gc <- Annex.getRemoteGitConfig g
91	let cu = fromMaybe u $ remoteAnnexConfigUUID gc
92	let rs = RemoteStateHandle cu
93	let c = fromMaybe M.empty $ M.lookup cu m
94	generate t g u c gc rs >>= \case
95		Nothing -> return Nothing
96		Just r -> Just <$> adjustExportImport (adjustReadOnly (addHooks r)) rs
97
98{- Updates a local git Remote, re-reading its git config. -}
99updateRemote :: Remote -> Annex (Maybe Remote)
100updateRemote remote = do
101	m <- remoteConfigMap
102	remote' <- updaterepo =<< getRepo remote
103	remoteGen m (remotetype remote) remote'
104  where
105	updaterepo r
106		| Git.repoIsLocal r || Git.repoIsLocalUnknown r =
107			Remote.Git.configRead False r
108		| otherwise = return r
109
110{- Checks if a remote is syncable using git. -}
111gitSyncableRemoteType :: RemoteType -> Bool
112gitSyncableRemoteType t = t `elem`
113	[ Remote.Git.remote
114	, Remote.GCrypt.remote
115	, Remote.P2P.remote
116	, Remote.GitLFS.remote
117	]
118