fully working move --from --to (not release quality)
When the destination already has a copy, it behaves the same as drop --from really, but display it as a move and implement it reusing the factored out code from fromPerform. (Note that willDropMakeItWorse never returns DropAllowed in that situation, because it's told that dest has a copy. So numcopies is always checked.) And when only the source and not the local repo or destination have a copy, do the full copy from source to local, then copy from local to dest, then drop from local, then drop from source dance. This is complicated by fromPerform being hardcoded to assume there is a local copy, but the local copy has already been dropped. That's why it uses cleanupfromsrc RemoveNever to avoid the code that makes that assumption, and finishes with a call to dropfromsrc. And, since the location log has not yet been updated, checking numcopies was not working, until I added UnVerifiedRemote dest to the list of things to check. This is not yet quite mergeable though. There are two things in the comment above fromToPerform that are not implemented yet: Checking the location log before dropping the local copy, and locking the temporary local copy for drop. Sponsored-by: Dartmouth College's DANDI project
This commit is contained in:
parent
1abd457e98
commit
f5f799f17e
1 changed files with 103 additions and 52 deletions
143
Command/Move.hs
143
Command/Move.hs
|
@ -247,43 +247,53 @@ fromOk src key
|
||||||
fromPerform :: Remote -> RemoveWhen -> Key -> AssociatedFile -> CommandPerform
|
fromPerform :: Remote -> RemoveWhen -> Key -> AssociatedFile -> CommandPerform
|
||||||
fromPerform src removewhen key afile = do
|
fromPerform src removewhen key afile = do
|
||||||
present <- inAnnex key
|
present <- inAnnex key
|
||||||
fromPerform' present src removewhen key afile
|
finish <- fromPerform' present True src key afile
|
||||||
|
finish removewhen
|
||||||
|
|
||||||
fromPerform' :: Bool -> Remote -> RemoveWhen -> Key -> AssociatedFile -> CommandPerform
|
fromPerform' :: Bool -> Bool -> Remote -> Key -> AssociatedFile -> Annex (RemoveWhen -> CommandPerform)
|
||||||
fromPerform' present src removewhen key afile = do
|
fromPerform' present updatelocationlog src key afile = do
|
||||||
showAction $ "from " ++ Remote.name src
|
showAction $ "from " ++ Remote.name src
|
||||||
destuuid <- getUUID
|
destuuid <- getUUID
|
||||||
logMove srcuuid destuuid present key $ \deststartedwithcopy ->
|
logMove (Remote.uuid src) destuuid present key $ \deststartedwithcopy ->
|
||||||
if present
|
if present
|
||||||
then dispatch removewhen deststartedwithcopy True
|
then return $ finish deststartedwithcopy True
|
||||||
else dispatch removewhen deststartedwithcopy =<< get
|
else do
|
||||||
|
got <- get
|
||||||
|
return $ finish deststartedwithcopy got
|
||||||
where
|
where
|
||||||
get = notifyTransfer Download afile $
|
get = notifyTransfer Download afile $
|
||||||
logStatusAfter key .
|
logdownload .
|
||||||
download src key afile stdRetry
|
download src key afile stdRetry
|
||||||
|
|
||||||
dispatch _ deststartedwithcopy False = do
|
logdownload a
|
||||||
|
| updatelocationlog = logStatusAfter key a
|
||||||
|
| otherwise = a
|
||||||
|
|
||||||
|
finish deststartedwithcopy False _ = do
|
||||||
logMoveCleanup deststartedwithcopy
|
logMoveCleanup deststartedwithcopy
|
||||||
stop -- copy failed
|
stop -- copy failed
|
||||||
dispatch RemoveNever deststartedwithcopy True = do
|
finish deststartedwithcopy True RemoveNever = do
|
||||||
logMoveCleanup deststartedwithcopy
|
logMoveCleanup deststartedwithcopy
|
||||||
next $ return True -- copy complete
|
next $ return True -- copy complete
|
||||||
dispatch RemoveSafe deststartedwithcopy True = lockContentShared key $ \_lck -> do
|
finish deststartedwithcopy True RemoveSafe = do
|
||||||
destuuid <- getUUID
|
destuuid <- getUUID
|
||||||
willDropMakeItWorse srcuuid destuuid deststartedwithcopy key afile >>= \case
|
lockContentShared key $ \_lck ->
|
||||||
DropAllowed -> dropremote deststartedwithcopy "moved"
|
fromDrop src destuuid deststartedwithcopy key afile id
|
||||||
|
|
||||||
|
fromDrop :: Remote -> UUID -> DestStartedWithCopy -> Key -> AssociatedFile -> ([UnVerifiedCopy] -> [UnVerifiedCopy])-> CommandPerform
|
||||||
|
fromDrop src destuuid deststartedwithcopy key afile adjusttocheck =
|
||||||
|
willDropMakeItWorse (Remote.uuid src) destuuid deststartedwithcopy key afile >>= \case
|
||||||
|
DropAllowed -> dropremote "moved"
|
||||||
DropCheckNumCopies -> do
|
DropCheckNumCopies -> do
|
||||||
(numcopies, mincopies) <- getSafestNumMinCopies afile key
|
(numcopies, mincopies) <- getSafestNumMinCopies afile key
|
||||||
(tocheck, verified) <- verifiableCopies key [Remote.uuid src]
|
(tocheck, verified) <- verifiableCopies key [Remote.uuid src]
|
||||||
verifyEnoughCopiesToDrop "" key Nothing numcopies mincopies [Remote.uuid src] verified
|
verifyEnoughCopiesToDrop "" key Nothing numcopies mincopies [Remote.uuid src] verified
|
||||||
tocheck (dropremote deststartedwithcopy . showproof) (faileddropremote deststartedwithcopy)
|
(adjusttocheck tocheck) (dropremote . showproof) faileddropremote
|
||||||
DropWorse -> faileddropremote deststartedwithcopy
|
DropWorse -> faileddropremote
|
||||||
|
where
|
||||||
srcuuid = Remote.uuid src
|
|
||||||
|
|
||||||
showproof proof = "proof: " ++ show proof
|
showproof proof = "proof: " ++ show proof
|
||||||
|
|
||||||
dropremote deststartedwithcopy reason = do
|
dropremote reason = do
|
||||||
fastDebug "Command.Move" $ unwords
|
fastDebug "Command.Move" $ unwords
|
||||||
[ "Dropping from remote"
|
[ "Dropping from remote"
|
||||||
, show src
|
, show src
|
||||||
|
@ -294,7 +304,7 @@ fromPerform' present src removewhen key afile = do
|
||||||
logMoveCleanup deststartedwithcopy
|
logMoveCleanup deststartedwithcopy
|
||||||
next $ Command.Drop.cleanupRemote key src (Command.Drop.DroppingUnused False) ok
|
next $ Command.Drop.cleanupRemote key src (Command.Drop.DroppingUnused False) ok
|
||||||
|
|
||||||
faileddropremote deststartedwithcopy = do
|
faileddropremote = do
|
||||||
showLongNote "(Use --force to override this check, or adjust numcopies.)"
|
showLongNote "(Use --force to override this check, or adjust numcopies.)"
|
||||||
showLongNote $ "Content not dropped from " ++ Remote.name src ++ "."
|
showLongNote $ "Content not dropped from " ++ Remote.name src ++ "."
|
||||||
logMoveCleanup deststartedwithcopy
|
logMoveCleanup deststartedwithcopy
|
||||||
|
@ -330,6 +340,8 @@ fromToStart removewhen afile key ai si src dest = do
|
||||||
fromToPerform src dest removewhen key afile
|
fromToPerform src dest removewhen key afile
|
||||||
|
|
||||||
{- When there is a local copy, transfer it to the dest, and drop from the src.
|
{- When there is a local copy, transfer it to the dest, and drop from the src.
|
||||||
|
-
|
||||||
|
- When the dest has a copy, drop it from the src.
|
||||||
-
|
-
|
||||||
- Otherwise, download a copy from the dest, populating the local annex
|
- Otherwise, download a copy from the dest, populating the local annex
|
||||||
- copy, but not updating location logs. Then transfer that to the dest,
|
- copy, but not updating location logs. Then transfer that to the dest,
|
||||||
|
@ -358,32 +370,70 @@ fromToStart removewhen afile key ai si src dest = do
|
||||||
- downloading it (v10) or immediately after download (v9 or older).
|
- downloading it (v10) or immediately after download (v9 or older).
|
||||||
-}
|
-}
|
||||||
fromToPerform :: Remote -> Remote -> RemoveWhen -> Key -> AssociatedFile -> CommandPerform
|
fromToPerform :: Remote -> Remote -> RemoveWhen -> Key -> AssociatedFile -> CommandPerform
|
||||||
fromToPerform src dest removewhen key afile = do
|
fromToPerform src dest removewhen key afile = go =<< inAnnex key
|
||||||
present <- inAnnex key
|
|
||||||
if present
|
|
||||||
then gopresent
|
|
||||||
else do
|
|
||||||
showAction $ "from " ++ Remote.name src
|
|
||||||
downloadsrctotemp
|
|
||||||
sendtemptodest
|
|
||||||
dropfromsrc
|
|
||||||
showAction $ "to " ++ Remote.name dest
|
|
||||||
error "TODO"
|
|
||||||
where
|
where
|
||||||
sendlocaltodest = error "TODO"
|
go True = do
|
||||||
downloadsrctotemp = error "TODO"
|
|
||||||
sendtemptodest = error "TODO"
|
|
||||||
dropfromsrc = error "TODO"
|
|
||||||
|
|
||||||
gopresent = do
|
|
||||||
haskey <- Remote.hasKey dest key
|
haskey <- Remote.hasKey dest key
|
||||||
toPerform dest RemoveNever key afile False haskey >>= \case
|
-- Prepare to drop from src later. Doing this first
|
||||||
Just cleanup -> fromPerform' True src removewhen key afile >>= \case
|
-- makes "from src" be shown consistently before
|
||||||
Just cleanup' -> return $ Just $ do
|
-- "to dest"
|
||||||
ok <- cleanup
|
dropsrc <- fromsrc True
|
||||||
ok' <- cleanup'
|
combinecleanups
|
||||||
return (ok && ok')
|
-- Send to dest, preserve local copy.
|
||||||
Nothing -> return $ Just cleanup
|
(todest RemoveNever haskey)
|
||||||
|
(\senttodest -> if senttodest
|
||||||
|
then dropsrc removewhen
|
||||||
|
else stop
|
||||||
|
)
|
||||||
|
go False = do
|
||||||
|
haskey <- Remote.hasKey dest key
|
||||||
|
case haskey of
|
||||||
|
Left err -> do
|
||||||
|
showNote err
|
||||||
|
stop
|
||||||
|
Right True -> do
|
||||||
|
showAction $ "from " ++ Remote.name src
|
||||||
|
showAction $ "to " ++ Remote.name dest
|
||||||
|
-- Drop from src, checking copies including
|
||||||
|
-- the one already in dest.
|
||||||
|
dropfromsrc id
|
||||||
|
Right False -> do
|
||||||
|
-- Get local copy from src, defer dropping
|
||||||
|
-- from src until later.
|
||||||
|
cleanupfromsrc <- fromsrc False
|
||||||
|
combinecleanups
|
||||||
|
-- Send to dest and remove local copy.
|
||||||
|
(todest RemoveSafe haskey)
|
||||||
|
(\senttodest ->
|
||||||
|
-- Drop from src, checking
|
||||||
|
-- copies including dest.
|
||||||
|
combinecleanups
|
||||||
|
(cleanupfromsrc RemoveNever)
|
||||||
|
(\_ -> if senttodest
|
||||||
|
then dropfromsrc (\l -> UnVerifiedRemote dest : l)
|
||||||
|
else stop
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
fromsrc present = fromPerform' present False src key afile
|
||||||
|
|
||||||
|
todest removewhen' = toPerform dest removewhen' key afile False
|
||||||
|
|
||||||
|
dropfromsrc adjusttocheck =
|
||||||
|
logMove (Remote.uuid src) (Remote.uuid dest) True key $ \deststartedwithcopy ->
|
||||||
|
fromDrop src (Remote.uuid dest) deststartedwithcopy key afile adjusttocheck
|
||||||
|
|
||||||
|
combinecleanups a b = a >>= \case
|
||||||
|
Just cleanupa -> b True >>= \case
|
||||||
|
Just cleanupb -> return $ Just $ do
|
||||||
|
oka <- cleanupa
|
||||||
|
okb <- cleanupb
|
||||||
|
return (oka && okb)
|
||||||
|
Nothing -> return (Just cleanupa)
|
||||||
|
Nothing -> b False >>= \case
|
||||||
|
Just cleanupb -> return $ Just $ do
|
||||||
|
void cleanupb
|
||||||
|
return False
|
||||||
Nothing -> return Nothing
|
Nothing -> return Nothing
|
||||||
|
|
||||||
{- The goal of this command is to allow the user maximum freedom to move
|
{- The goal of this command is to allow the user maximum freedom to move
|
||||||
|
@ -395,9 +445,10 @@ fromToPerform src dest removewhen key afile = do
|
||||||
- repository reduces the number of copies, and should fail if
|
- repository reduces the number of copies, and should fail if
|
||||||
- that would violate numcopies settings.
|
- that would violate numcopies settings.
|
||||||
-
|
-
|
||||||
- On the other hand, when the destination repository does not already
|
- On the other hand, when the destination repository did not start
|
||||||
- have a copy of a file, it can be dropped without making numcopies
|
- with a copy of a file, it can be dropped from the source without
|
||||||
- worse, so the move is allowed even if numcopies is not met.
|
- making numcopies worse, so the move is allowed even if numcopies
|
||||||
|
- is not met.
|
||||||
-
|
-
|
||||||
- Similarly, a file can move from an untrusted repository to another
|
- Similarly, a file can move from an untrusted repository to another
|
||||||
- untrusted repository, even if that is the only copy of the file.
|
- untrusted repository, even if that is the only copy of the file.
|
||||||
|
|
Loading…
Add table
Reference in a new issue