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 Annex
import qualified Git.CurrentRepo import qualified Git.CurrentRepo
import Annex.UUID import Annex.UUID
import Network.URI
run :: [String] -> IO () run :: [String] -> IO ()
run (_remotename:url:[]) = do run (_remotename:url:[]) = case parseSpecialRemoteUrl url of
state <- Annex.new =<< Git.CurrentRepo.get Left e -> giveup e
Annex.eval state (run' url) Right src -> do
state <- Annex.new =<< Git.CurrentRepo.get
Annex.eval state (run' url)
run (_remotename:[]) = giveup "remote url not configured" run (_remotename:[]) = giveup "remote url not configured"
run _ = giveup "expected remote name and url parameters" run _ = giveup "expected remote name and url parameters"
@ -109,3 +112,30 @@ splitLine l =
let (c, sv) = break (== ' ') l let (c, sv) = break (== ' ') l
v = if null sv then sv else drop 1 sv v = if null sv then sv else drop 1 sv
in (c, v) 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)

View file

@ -4,7 +4,7 @@ git-remote-annex - remote helper program to store a git repository in a git-anne
# SYNOPSIS # SYNOPSIS
git fetch annex::uuid?param=value&param=value... git fetch annex:uuid?param=value&param=value...
# DESCRIPTION # DESCRIPTION
@ -17,13 +17,13 @@ encryption=shared or encryption=hybrid. (Since those types of encryption
rely on a cipher that is checked into the git repository, cloning from rely on a cipher that is checked into the git repository, cloning from
such a special remote would present a chicken and egg problem.) such a special remote would present a chicken and egg problem.)
The format of the remote URL is "annex::" followed by the UUID of the The format of the remote URL is "annex:" followed by the UUID of the
special remote, and then followed by all of the configuration parameters of special remote, and then followed by all of the configuration parameters of
the special remote. the special remote.
For example, to clone from a directory special remote: For example, to clone from a directory special remote:
git clone annex::358ff77e-0bc3-11ef-bc49-872e6695c0e3?type=directory&encryption=none&directory=/mnt/foo/ git clone annex:358ff77e-0bc3-11ef-bc49-872e6695c0e3?type=directory&encryption=none&directory=/mnt/foo/
When a special remote needs some additional credentials to be provided, When a special remote needs some additional credentials to be provided,
they are not included in the URL, and need to be provided when cloning from they are not included in the URL, and need to be provided when cloning from
@ -34,12 +34,12 @@ set when pulling or pushing.
As a useful shorthand, when the special remote has already been enabled, As a useful shorthand, when the special remote has already been enabled,
the configuration parameters can be omitted. For example: the configuration parameters can be omitted. For example:
git push annex::358ff77e-0bc3-11ef-bc49-872e6695c0e3 master git push annex:358ff77e-0bc3-11ef-bc49-872e6695c0e3 master
This also makes it easy to configure the url for an existing special remote, This also makes it easy to configure the url for an existing special remote,
making it usable by git: making it usable by git:
git config remote.foo.url annex::358ff77e-0bc3-11ef-bc49-872e6695c0e3 git config remote.foo.url annex:358ff77e-0bc3-11ef-bc49-872e6695c0e3
git fetch foo master git fetch foo master
Configuring the url like that is automatically done when cloning from a Configuring the url like that is automatically done when cloning from a