add annex: url parser

Changed the format of the url to use annex: rather than annex::

The reason is that in the future, might want to support an url that
includes an uriAuthority part, eg:

annex://foo@example.com:42/358ff77e-0bc3-11ef-bc49-872e6695c0e3?type=directory&encryption=none&directory=/mnt/foo/"

To parse that foo@example.com:42 as an uriAuthority it needs to start with
annex: rather than annex::

That would also need something to be done with uriAuthority, and also
the uriPath (the UUID) is prefixed with "/" in that example. So the
current parser won't handle that example currently. But this leaves the
possibility for expansion.

Sponsored-by: Joshua Antonishen on Patreon
This commit is contained in:
Joey Hess 2024-05-06 14:50:41 -04:00
parent 4b94fc371e
commit f4ba6e0c1e
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
2 changed files with 38 additions and 8 deletions

View file

@ -11,11 +11,14 @@ import Annex.Common
import qualified Annex
import qualified Git.CurrentRepo
import Annex.UUID
import Network.URI
run :: [String] -> IO ()
run (_remotename:url:[]) = do
state <- Annex.new =<< Git.CurrentRepo.get
Annex.eval state (run' url)
run (_remotename:url:[]) = case parseSpecialRemoteUrl url of
Left e -> giveup e
Right src -> do
state <- Annex.new =<< Git.CurrentRepo.get
Annex.eval state (run' url)
run (_remotename:[]) = giveup "remote url not configured"
run _ = giveup "expected remote name and url parameters"
@ -109,3 +112,30 @@ splitLine l =
let (c, sv) = break (== ' ') l
v = if null sv then sv else drop 1 sv
in (c, v)
data SpecialRemoteConfig = SpecialRemoteConfig
{ specialRemoteUUID :: UUID
, specialRemoteParams :: [(String, String)]
}
deriving (Show)
-- The url for a special remote looks like
-- annex:uuid?param=value&param=value...
parseSpecialRemoteUrl :: String -> Either String SpecialRemoteConfig
parseSpecialRemoteUrl s = case parseURI s of
Nothing -> Left "URL parse failed"
Just u -> case uriScheme u of
"annex:" -> case uriPath u of
"" -> Left "annex: URL did not include a UUID"
(':':_) -> Left "annex: URL malformed"
p -> Right $ SpecialRemoteConfig
{ specialRemoteUUID = toUUID p
, specialRemoteParams = parsequery u
}
_ -> Left "Not an annex: URL"
where
parsequery u = map parsekv $ splitc '&' (drop 1 (uriQuery u))
parsekv s =
let (k, sv) = break (== '=') s
v = if null sv then sv else drop 1 sv
in (unEscapeString k, unEscapeString v)