2013-09-07 22:38:00 +00:00
|
|
|
{- Utilities for git remotes.
|
|
|
|
-
|
2024-06-30 15:14:13 +00:00
|
|
|
- Copyright 2011-2024 Joey Hess <id@joeyh.name>
|
2013-09-07 22:38:00 +00:00
|
|
|
-
|
2019-03-13 19:48:14 +00:00
|
|
|
- Licensed under the GNU AGPL version 3 or higher.
|
2013-09-07 22:38:00 +00:00
|
|
|
-}
|
|
|
|
|
|
|
|
module Remote.Helper.Git where
|
|
|
|
|
2016-01-20 20:36:33 +00:00
|
|
|
import Annex.Common
|
2013-09-07 22:38:00 +00:00
|
|
|
import qualified Git
|
2023-08-16 19:54:54 +00:00
|
|
|
import qualified Git.GCrypt
|
2014-01-13 18:41:10 +00:00
|
|
|
import Types.Availability
|
2015-01-13 22:11:03 +00:00
|
|
|
import qualified Types.Remote as Remote
|
2023-03-01 19:55:58 +00:00
|
|
|
import qualified Utility.RawFilePath as R
|
2023-08-16 19:54:54 +00:00
|
|
|
import qualified Git.Config
|
2024-06-30 15:14:13 +00:00
|
|
|
import Logs.Proxy
|
|
|
|
import Types.Cluster
|
2015-01-13 22:11:03 +00:00
|
|
|
|
|
|
|
import Data.Time.Clock.POSIX
|
2023-03-01 19:55:58 +00:00
|
|
|
import System.PosixCompat.Files (modificationTime)
|
2024-06-30 15:14:13 +00:00
|
|
|
import qualified Data.Map as M
|
|
|
|
import qualified Data.Set as S
|
2013-09-07 22:38:00 +00:00
|
|
|
|
|
|
|
repoCheap :: Git.Repo -> Bool
|
|
|
|
repoCheap = not . Git.repoIsUrl
|
|
|
|
|
|
|
|
localpathCalc :: Git.Repo -> Maybe FilePath
|
2014-01-13 18:41:10 +00:00
|
|
|
localpathCalc r
|
2023-08-16 19:48:09 +00:00
|
|
|
| not (Git.repoIsLocal r) && not (Git.repoIsLocalUnknown r) = Nothing
|
2019-12-09 17:49:05 +00:00
|
|
|
| otherwise = Just $ fromRawFilePath $ Git.repoPath r
|
2013-09-07 22:38:00 +00:00
|
|
|
|
2023-08-16 19:54:54 +00:00
|
|
|
{- Checks relatively inexpensively if a repository is available for use. -}
|
|
|
|
repoAvail :: Git.Repo -> Annex Availability
|
|
|
|
repoAvail r
|
|
|
|
| Git.repoIsHttp r = return GloballyAvailable
|
|
|
|
| Git.GCrypt.isEncrypted r = do
|
|
|
|
g <- gitRepo
|
|
|
|
liftIO $ do
|
|
|
|
er <- Git.GCrypt.encryptedRemote g r
|
|
|
|
if Git.repoIsLocal er || Git.repoIsLocalUnknown er
|
|
|
|
then checklocal er
|
|
|
|
else return GloballyAvailable
|
|
|
|
| Git.repoIsUrl r = return GloballyAvailable
|
|
|
|
| Git.repoIsLocalUnknown r = return Unavailable
|
|
|
|
| otherwise = checklocal r
|
|
|
|
where
|
|
|
|
checklocal r' = ifM (liftIO $ isJust <$> catchMaybeIO (Git.Config.read r'))
|
|
|
|
( return LocallyAvailable
|
|
|
|
, return Unavailable
|
|
|
|
)
|
2013-09-07 22:38:00 +00:00
|
|
|
|
|
|
|
{- Avoids performing an action on a local repository that's not usable.
|
|
|
|
- Does not check that the repository is still available on disk. -}
|
2014-08-08 23:18:08 +00:00
|
|
|
guardUsable :: Git.Repo -> Annex a -> Annex a -> Annex a
|
|
|
|
guardUsable r fallback a
|
|
|
|
| Git.repoIsLocalUnknown r = fallback
|
2013-09-07 22:38:00 +00:00
|
|
|
| otherwise = a
|
2014-10-21 18:36:09 +00:00
|
|
|
|
2015-01-13 22:11:03 +00:00
|
|
|
gitRepoInfo :: Remote -> Annex [(String, String)]
|
|
|
|
gitRepoInfo r = do
|
2019-12-09 17:49:05 +00:00
|
|
|
d <- fromRawFilePath <$> fromRepo Git.localGitDir
|
2023-03-01 19:55:58 +00:00
|
|
|
mtimes <- liftIO $ mapM (\p -> modificationTime <$> R.getFileStatus (toRawFilePath p))
|
2023-08-15 16:57:41 +00:00
|
|
|
=<< emptyWhenDoesNotExist (dirContentsRecursive (d </> "refs" </> "remotes" </> Remote.name r))
|
2015-01-13 22:11:03 +00:00
|
|
|
let lastsynctime = case mtimes of
|
|
|
|
[] -> "never"
|
|
|
|
_ -> show $ posixSecondsToUTCTime $ realToFrac $ maximum mtimes
|
2018-06-04 18:31:55 +00:00
|
|
|
repo <- Remote.getRepo r
|
2024-06-30 15:14:13 +00:00
|
|
|
let proxied = Git.Config.boolConfig $ isJust $
|
|
|
|
remoteAnnexProxiedBy (Remote.gitconfig r)
|
|
|
|
proxies <- getProxies
|
|
|
|
let proxying = S.toList $ fromMaybe mempty $
|
|
|
|
M.lookup (Remote.uuid r) proxies
|
|
|
|
let iscluster = isClusterUUID . proxyRemoteUUID
|
|
|
|
let proxyname p = Remote.name r ++ "-" ++ proxyRemoteName p
|
|
|
|
let proxynames = map proxyname $ filter (not . iscluster) proxying
|
|
|
|
let clusternames = map proxyname $ filter iscluster proxying
|
|
|
|
return $ catMaybes
|
|
|
|
[ Just ("repository location", Git.repoLocation repo)
|
|
|
|
, Just ("last synced", lastsynctime)
|
|
|
|
, Just ("proxied", proxied)
|
|
|
|
, if isClusterUUID (Remote.uuid r)
|
|
|
|
then Just ("cluster", Git.Config.boolConfig True)
|
|
|
|
else Nothing
|
|
|
|
, if null clusternames
|
|
|
|
then Nothing
|
|
|
|
else Just ("gateway to cluster", unwords clusternames)
|
|
|
|
, if null proxynames
|
|
|
|
then Nothing
|
|
|
|
else Just ("proxying", unwords proxynames)
|
2015-01-13 22:11:03 +00:00
|
|
|
]
|