renameremote: Better handling of case where there are multiple special remotes with a name

Instead of renaming one at random, error out and ask that a uuid be
specified.

Sponsored-by: Brett Eisenberg on Patreon
This commit is contained in:
Joey Hess 2022-01-05 15:24:02 -04:00
parent 58afb00f6e
commit e416635021
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
5 changed files with 16 additions and 15 deletions

View file

@ -30,10 +30,10 @@ import qualified Data.Map as M
- -
- Remotes that are not dead come first in the list - Remotes that are not dead come first in the list
- when a name appears multiple times. -} - when a name appears multiple times. -}
findExisting :: RemoteName -> Annex (Maybe (UUID, RemoteConfig, Maybe (ConfigFrom UUID))) findExisting :: RemoteName -> Annex [(UUID, RemoteConfig, Maybe (ConfigFrom UUID))]
findExisting name = do findExisting name = do
(a, b) <- findExisting' name (a, b) <- findExisting' name
return (headMaybe (a++b)) return (a++b)
{- Dead remotes with the name are in the second list, all others in the {- Dead remotes with the name are in the second list, all others in the
- first list. -} - first list. -}

View file

@ -55,9 +55,9 @@ makeRsyncRemote :: RemoteName -> String -> Annex String
makeRsyncRemote name location = makeRemote name location $ const $ void $ makeRsyncRemote name location = makeRemote name location $ const $ void $
go =<< Annex.SpecialRemote.findExisting name go =<< Annex.SpecialRemote.findExisting name
where where
go Nothing = setupSpecialRemote name Rsync.remote config Nothing go [] = setupSpecialRemote name Rsync.remote config Nothing
(Nothing, R.Init, Annex.SpecialRemote.newConfig name Nothing mempty mempty) Nothing (Nothing, R.Init, Annex.SpecialRemote.newConfig name Nothing mempty mempty) Nothing
go (Just (u, c, mcu)) = setupSpecialRemote name Rsync.remote config Nothing go ((u, c, mcu):_) = setupSpecialRemote name Rsync.remote config Nothing
(Just u, R.Enable c, c) mcu (Just u, R.Enable c, c) mcu
config = M.fromList config = M.fromList
[ (encryptionField, Proposed "shared") [ (encryptionField, Proposed "shared")
@ -86,16 +86,16 @@ initSpecialRemote name remotetype mcreds config = go 0
go n = do go n = do
let fullname = if n == 0 then name else name ++ show n let fullname = if n == 0 then name else name ++ show n
Annex.SpecialRemote.findExisting fullname >>= \case Annex.SpecialRemote.findExisting fullname >>= \case
Nothing -> setupSpecialRemote fullname remotetype config mcreds [] -> setupSpecialRemote fullname remotetype config mcreds
(Nothing, R.Init, Annex.SpecialRemote.newConfig fullname Nothing mempty mempty) Nothing (Nothing, R.Init, Annex.SpecialRemote.newConfig fullname Nothing mempty mempty) Nothing
Just _ -> go (n + 1) _ -> go (n + 1)
{- Enables an existing special remote. -} {- Enables an existing special remote. -}
enableSpecialRemote :: SpecialRemoteMaker enableSpecialRemote :: SpecialRemoteMaker
enableSpecialRemote name remotetype mcreds config = enableSpecialRemote name remotetype mcreds config =
Annex.SpecialRemote.findExisting name >>= \case Annex.SpecialRemote.findExisting name >>= \case
Nothing -> error $ "Cannot find a special remote named " ++ name [] -> error $ "Cannot find a special remote named " ++ name
Just (u, c, mcu) -> setupSpecialRemote' False name remotetype config mcreds (Just u, R.Enable c, c) mcu ((u, c, mcu):_) -> setupSpecialRemote' False name remotetype config mcreds (Just u, R.Enable c, c) mcu
setupSpecialRemote :: RemoteName -> RemoteType -> R.RemoteConfig -> Maybe CredPair -> (Maybe UUID, R.SetupStage, R.RemoteConfig) -> Maybe (Annex.SpecialRemote.ConfigFrom UUID) -> Annex RemoteName setupSpecialRemote :: RemoteName -> RemoteType -> R.RemoteConfig -> Maybe CredPair -> (Maybe UUID, R.SetupStage, R.RemoteConfig) -> Maybe (Annex.SpecialRemote.ConfigFrom UUID) -> Annex RemoteName
setupSpecialRemote = setupSpecialRemote' True setupSpecialRemote = setupSpecialRemote' True

View file

@ -3,7 +3,7 @@ git-annex (8.20211232) UNRELEASED; urgency=medium
* export: When a non-annexed symlink is in the tree to be exported, skip it. * export: When a non-annexed symlink is in the tree to be exported, skip it.
* import: When the previously exported tree contained a non-annexed symlink, * import: When the previously exported tree contained a non-annexed symlink,
preserve it in the imported tree so it does not get deleted. preserve it in the imported tree so it does not get deleted.
* enableremote: Better handling of the unusual case where * enableremote, renameremote: Better handling of the unusual case where
multiple special remotes have been initialized with the same name. multiple special remotes have been initialized with the same name.
-- Joey Hess <id@joeyh.name> Mon, 03 Jan 2022 14:01:14 -0400 -- Joey Hess <id@joeyh.name> Mon, 03 Jan 2022 14:01:14 -0400

View file

@ -64,7 +64,7 @@ seek o = withWords (commandAction . (start o)) (cmdparams o)
start :: InitRemoteOptions -> [String] -> CommandStart start :: InitRemoteOptions -> [String] -> CommandStart
start _ [] = giveup "Specify a name for the remote." start _ [] = giveup "Specify a name for the remote."
start o (name:ws) = ifM (isJust <$> findExisting name) start o (name:ws) = ifM (not . null <$> findExisting name)
( giveup $ "There is already a special remote named \"" ++ name ++ ( giveup $ "There is already a special remote named \"" ++ name ++
"\". (Use enableremote to enable an existing special remote.)" "\". (Use enableremote to enable an existing special remote.)"
, ifM (isJust <$> Remote.byNameOnly name) , ifM (isJust <$> Remote.byNameOnly name)

View file

@ -1,6 +1,6 @@
{- git-annex command {- git-annex command
- -
- Copyright 2019 Joey Hess <id@joeyh.name> - Copyright 2019-2021 Joey Hess <id@joeyh.name>
- -
- Licensed under the GNU AGPL version 3 or higher. - Licensed under the GNU AGPL version 3 or higher.
-} -}
@ -28,19 +28,20 @@ seek = withWords (commandAction . start)
start :: [String] -> CommandStart start :: [String] -> CommandStart
start ps@(oldname:newname:[]) = Annex.SpecialRemote.findExisting oldname >>= \case start ps@(oldname:newname:[]) = Annex.SpecialRemote.findExisting oldname >>= \case
Just (u, cfg, mcu) -> Annex.SpecialRemote.findExisting newname >>= \case ((u, cfg, mcu):[]) -> Annex.SpecialRemote.findExisting newname >>= \case
Just _ -> giveup $ "The name " ++ newname ++ " is already used by a special remote." [] -> go u cfg mcu
Nothing -> go u cfg mcu _ -> giveup $ "The name " ++ newname ++ " is already used by a special remote."
-- Support lookup by uuid or description as well as remote name, -- Support lookup by uuid or description as well as remote name,
-- as a fallback when there is nothing with the name in the -- as a fallback when there is nothing with the name in the
-- special remote log. -- special remote log.
Nothing -> Remote.nameToUUID' oldname >>= \case [] -> Remote.nameToUUID' oldname >>= \case
Left e -> giveup e Left e -> giveup e
Right u -> do Right u -> do
m <- Logs.Remote.remoteConfigMap m <- Logs.Remote.remoteConfigMap
case M.lookup u m of case M.lookup u m of
Nothing -> giveup "That is not a special remote." Nothing -> giveup "That is not a special remote."
Just cfg -> go u cfg Nothing Just cfg -> go u cfg Nothing
_ -> giveup $ "There are multiple special remotes named " ++ oldname ++ ". Provide instead the uuid or description of the remote to rename."
where where
ai = ActionItemOther Nothing ai = ActionItemOther Nothing
si = SeekInput ps si = SeekInput ps