summaryrefslogtreecommitdiff
path: root/Remote/GitLFS.hs
diff options
context:
space:
mode:
authorJoey Hess <joeyh@joeyh.name>2019-08-03 12:51:16 -0400
committerJoey Hess <joeyh@joeyh.name>2019-08-03 12:51:16 -0400
commit28c0395d619eb6b491fbc34b3b58ef1cabc0b7a3 (patch)
tree65e96103cdb961919ce513cfe7d8c9963a88962b /Remote/GitLFS.hs
parent5be0a35dae638fb8d90f5a5cdffbf5967648b685 (diff)
start at retieval from LFS
Doesn't yet download the content, which will need to support resuming.
Diffstat (limited to 'Remote/GitLFS.hs')
-rw-r--r--Remote/GitLFS.hs55
1 files changed, 35 insertions, 20 deletions
diff --git a/Remote/GitLFS.hs b/Remote/GitLFS.hs
index 78049ce3fd..02dee87e25 100644
--- a/Remote/GitLFS.hs
+++ b/Remote/GitLFS.hs
@@ -21,23 +21,20 @@ import Remote.Helper.Special
import Remote.Helper.ExportImport
import Remote.Helper.Git
import Remote.Helper.Http
-import qualified Remote.Helper.Ssh as Ssh
import Annex.Ssh
import Annex.UUID
import Utility.SshHost
import qualified Utility.GitLFS as LFS
import Backend.Hash
import Utility.Hash
-import Utility.FileSize
import Crypto
import Control.Concurrent.STM
import Data.String
-import Network.HTTP.Client
+import Network.HTTP.Client hiding (port)
import Network.HTTP.Types
import System.Log.Logger
import qualified Data.Map as M
-import qualified Network.URI as URI
import qualified Data.ByteString.Lazy as L
import qualified Data.Text as T
import qualified Data.Text.Encoding as E
@@ -56,13 +53,13 @@ remote = RemoteType
gen :: Git.Repo -> UUID -> RemoteConfig -> RemoteGitConfig -> Annex (Maybe Remote)
gen r u c gc = do
- handle <- liftIO $ newTVarIO $ LFSHandle Nothing Nothing r gc
+ h <- liftIO $ newTVarIO $ LFSHandle Nothing Nothing r gc
cst <- remoteCost gc expensiveRemoteCost
return $ Just $ specialRemote' specialcfg c
- (simplyPrepare $ store handle)
- (simplyPrepare $ retrieve handle)
- (simplyPrepare $ remove handle)
- (simplyPrepare $ checkKey handle)
+ (simplyPrepare $ store h)
+ (simplyPrepare $ retrieve h)
+ (simplyPrepare $ remove h)
+ (simplyPrepare $ checkKey h)
(this cst)
where
this cst = Remote
@@ -206,8 +203,10 @@ getLFSEndpoint tro hv = do
LFS.RequestDownload -> downloadEndpoint
LFS.RequestUpload -> uploadEndpoint
-makeAPIRequest :: Request -> Annex (Response L.ByteString)
-makeAPIRequest req = do
+-- Make an API request that is expected to have a small response body.
+-- Not for use in downloading an object.
+makeSmallAPIRequest :: Request -> Annex (Response L.ByteString)
+makeSmallAPIRequest req = do
uo <- getUrlOptions
let req' = applyRequest uo req
liftIO $ debugM "git-lfs" (show req')
@@ -225,7 +224,7 @@ sendTransferRequest
sendTransferRequest req endpoint =
case LFS.startTransferRequest endpoint req of
Just httpreq -> do
- httpresp <- makeAPIRequest $ setRequestCheckStatus httpreq
+ httpresp <- makeSmallAPIRequest $ setRequestCheckStatus httpreq
return $ case LFS.parseTransferResponse (responseBody httpresp) of
LFS.ParsedTransferResponse resp -> Right resp
LFS.ParsedTransferResponseError tro -> Left $
@@ -317,17 +316,33 @@ store h = fileStorer $ \k src p -> getLFSEndpoint LFS.RequestUpload h >>= \case
Nothing -> giveup "unable to parse git-lfs server upload url"
Just [] -> noop -- server already has it
Just reqs -> forM_ reqs $
- makeAPIRequest . setRequestCheckStatus
+ makeSmallAPIRequest . setRequestCheckStatus
failederr e = do
warning (show e)
return False
retrieve :: TVar LFSHandle -> Retriever
-retrieve h = byteRetriever $ \k sink -> getLFSEndpoint LFS.RequestDownload h >>= \case
- Nothing -> return False
- Just endpoint -> do
- liftIO $ print ("endpoint", endpoint)
- return False
+retrieve h = fileRetriever $ \dest k p -> getLFSEndpoint LFS.RequestDownload h >>= \case
+ Nothing -> giveup "unable to connect to git-lfs endpoint"
+ Just endpoint -> mkDownloadRequest k >>= \case
+ Nothing -> giveup "unable to download this object from git-lfs"
+ Just req -> sendTransferRequest req endpoint >>= \case
+ Left err -> giveup (show err)
+ Right resp -> case LFS.objects resp of
+ [] -> giveup "git-lfs server did not provide a way to download this object"
+ (tro:_) -> receive dest p tro
+
+ where
+ receive dest p tro = case LFS.resp_error tro of
+ Just err -> giveup $ T.unpack $ LFS.respobjerr_message err
+ Nothing -> case LFS.resp_actions tro of
+ Nothing -> giveup "git-lfs server did not provide a way to download this object"
+ Just op -> case LFS.downloadOperationRequest op of
+ Nothing -> giveup "unable to parse git-lfs server download url"
+ Just req ->
+ -- TODO stream to file
+ -- TODO resume and append if the file already exists
+ giveup "TODO"
checkKey :: TVar LFSHandle -> CheckPresent
checkKey h key = getLFSEndpoint LFS.RequestDownload h >>= \case
@@ -338,7 +353,7 @@ checkKey h key = getLFSEndpoint LFS.RequestDownload h >>= \case
Nothing -> return False
Just req -> case LFS.startTransferRequest endpoint req of
Nothing -> giveup "unable to parse git-lfs endpoint url"
- Just httpreq -> go =<< makeAPIRequest httpreq
+ Just httpreq -> go =<< makeSmallAPIRequest httpreq
where
go httpresp
| responseStatus httpresp == status200 =
@@ -365,6 +380,6 @@ retrieveCheap :: Key -> AssociatedFile -> FilePath -> Annex Bool
retrieveCheap _ _ _ = return False
remove :: TVar LFSHandle -> Remover
-remove h key = do
+remove _h _key = do
warning "git-lfs does not support removing content"
return False