git-remote-annex: Display full url when using remote with the shorthand url
This commit is contained in:
parent
04a256a0f8
commit
19418e81ee
7 changed files with 76 additions and 20 deletions
|
@ -107,17 +107,23 @@ commonFieldParsers =
|
||||||
(FieldDesc "name for the special remote")
|
(FieldDesc "name for the special remote")
|
||||||
, optionalStringParser sameasNameField HiddenField
|
, optionalStringParser sameasNameField HiddenField
|
||||||
, optionalStringParser sameasUUIDField HiddenField
|
, optionalStringParser sameasUUIDField HiddenField
|
||||||
, optionalStringParser typeField
|
|
||||||
(FieldDesc "type of special remote")
|
|
||||||
, autoEnableFieldParser
|
, autoEnableFieldParser
|
||||||
, costParser costField
|
, costParser costField
|
||||||
(FieldDesc "default cost of this special remote")
|
(FieldDesc "default cost of this special remote")
|
||||||
|
, optionalStringParser preferreddirField
|
||||||
|
(FieldDesc "directory whose content is preferred")
|
||||||
|
] ++ essentialFieldParsers
|
||||||
|
|
||||||
|
{- Parsers for fields that are common to all special remotes, and are
|
||||||
|
- also essential to include in eg, annex:: urls. -}
|
||||||
|
essentialFieldParsers :: [RemoteConfigFieldParser]
|
||||||
|
essentialFieldParsers =
|
||||||
|
[ optionalStringParser typeField
|
||||||
|
(FieldDesc "type of special remote")
|
||||||
, yesNoParser exportTreeField (Just False)
|
, yesNoParser exportTreeField (Just False)
|
||||||
(FieldDesc "export trees of files to this remote")
|
(FieldDesc "export trees of files to this remote")
|
||||||
, yesNoParser importTreeField (Just False)
|
, yesNoParser importTreeField (Just False)
|
||||||
(FieldDesc "import trees of files from this remote")
|
(FieldDesc "import trees of files from this remote")
|
||||||
, optionalStringParser preferreddirField
|
|
||||||
(FieldDesc "directory whose content is preferred")
|
|
||||||
]
|
]
|
||||||
|
|
||||||
autoEnableFieldParser :: RemoteConfigFieldParser
|
autoEnableFieldParser :: RemoteConfigFieldParser
|
||||||
|
|
|
@ -22,10 +22,12 @@ import qualified Git.Remote
|
||||||
import qualified Git.Remote.Remove
|
import qualified Git.Remote.Remove
|
||||||
import qualified Git.Version
|
import qualified Git.Version
|
||||||
import qualified Annex.SpecialRemote as SpecialRemote
|
import qualified Annex.SpecialRemote as SpecialRemote
|
||||||
|
import qualified Annex.SpecialRemote.Config as SpecialRemote
|
||||||
import qualified Annex.Branch
|
import qualified Annex.Branch
|
||||||
import qualified Annex.BranchState
|
import qualified Annex.BranchState
|
||||||
import qualified Types.Remote as Remote
|
import qualified Types.Remote as Remote
|
||||||
import qualified Logs.Remote
|
import qualified Logs.Remote
|
||||||
|
import qualified Remote.External
|
||||||
import Remote.Helper.Encryptable (parseEncryptionMethod)
|
import Remote.Helper.Encryptable (parseEncryptionMethod)
|
||||||
import Annex.Transfer
|
import Annex.Transfer
|
||||||
import Backend.GitRemoteAnnex
|
import Backend.GitRemoteAnnex
|
||||||
|
@ -72,17 +74,18 @@ run (remotename:url:[]) =
|
||||||
Right src -> do
|
Right src -> do
|
||||||
repo <- getRepo
|
repo <- getRepo
|
||||||
state <- Annex.new repo
|
state <- Annex.new repo
|
||||||
Annex.eval state (run' src)
|
Annex.eval state (run' src 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"
|
||||||
|
|
||||||
run' :: SpecialRemoteConfig -> Annex ()
|
run' :: SpecialRemoteConfig -> String -> Annex ()
|
||||||
run' src = do
|
run' src url = do
|
||||||
sab <- startAnnexBranch
|
sab <- startAnnexBranch
|
||||||
-- Prevent any usual git-annex output to stdout, because
|
-- Prevent any usual git-annex output to stdout, because
|
||||||
-- the output of this command is being parsed by git.
|
-- the output of this command is being parsed by git.
|
||||||
doQuietAction $
|
doQuietAction $
|
||||||
withSpecialRemote src sab $ \rmt -> do
|
withSpecialRemote src sab $ \rmt -> do
|
||||||
|
reportFullUrl url rmt
|
||||||
ls <- lines <$> liftIO getContents
|
ls <- lines <$> liftIO getContents
|
||||||
go rmt ls emptyState
|
go rmt ls emptyState
|
||||||
where
|
where
|
||||||
|
@ -464,6 +467,50 @@ parseSpecialRemoteUrl url remotename = case parseURI url of
|
||||||
v = if null sv then sv else drop 1 sv
|
v = if null sv then sv else drop 1 sv
|
||||||
in (Proposed (unEscapeString k), Proposed (unEscapeString v))
|
in (Proposed (unEscapeString k), Proposed (unEscapeString v))
|
||||||
|
|
||||||
|
getSpecialRemoteUrl :: Remote -> Annex (Maybe String)
|
||||||
|
getSpecialRemoteUrl rmt = do
|
||||||
|
rcp <- Remote.configParser (Remote.remotetype rmt)
|
||||||
|
(unparsedRemoteConfig (Remote.config rmt))
|
||||||
|
return $ genSpecialRemoteUrl rmt rcp
|
||||||
|
|
||||||
|
genSpecialRemoteUrl :: Remote -> RemoteConfigParser -> Maybe String
|
||||||
|
genSpecialRemoteUrl rmt rcp
|
||||||
|
-- Fields that are accepted by remoteConfigRestPassthrough
|
||||||
|
-- are not necessary to include in the url, except perhaps for
|
||||||
|
-- external special remotes. If an external special remote sets
|
||||||
|
-- some such fields, cannot generate an url.
|
||||||
|
| Remote.typename (Remote.remotetype rmt) == Remote.typename Remote.External.remote
|
||||||
|
&& any (`notElem` knownfields) (M.keys c) = Nothing
|
||||||
|
| otherwise = Just $
|
||||||
|
"annex::" ++ fromUUID (Remote.uuid rmt) ++ "?" ++
|
||||||
|
intercalate "&" (map configpair cs)
|
||||||
|
where
|
||||||
|
configpair (k, v) = conv k ++ "=" ++ conv v
|
||||||
|
conv = escapeURIString isUnescapedInURIComponent
|
||||||
|
. fromProposedAccepted
|
||||||
|
|
||||||
|
cs = M.toList $ M.filterWithKey (\k _ -> k `elem` safefields) c
|
||||||
|
c = unparsedRemoteConfig $ Remote.config rmt
|
||||||
|
|
||||||
|
-- Hidden fields are used for internal stuff like ciphers
|
||||||
|
-- that should not be included in the url.
|
||||||
|
safefields = map parserForField $
|
||||||
|
filter (\p -> fieldDesc p /= HiddenField) ps
|
||||||
|
|
||||||
|
knownfields = map parserForField ps
|
||||||
|
|
||||||
|
ps = SpecialRemote.essentialFieldParsers
|
||||||
|
++ remoteConfigFieldParsers rcp
|
||||||
|
|
||||||
|
reportFullUrl :: String -> Remote -> Annex ()
|
||||||
|
reportFullUrl url rmt =
|
||||||
|
when (url == "annex::") $
|
||||||
|
getSpecialRemoteUrl rmt >>= \case
|
||||||
|
Nothing -> noop
|
||||||
|
Just fullurl ->
|
||||||
|
liftIO $ hPutStrLn stderr $
|
||||||
|
"Full remote url: " ++ fullurl
|
||||||
|
|
||||||
-- Runs an action with a Remote as specified by the SpecialRemoteConfig.
|
-- Runs an action with a Remote as specified by the SpecialRemoteConfig.
|
||||||
withSpecialRemote :: SpecialRemoteConfig -> StartAnnexBranch -> (Remote -> Annex a) -> Annex a
|
withSpecialRemote :: SpecialRemoteConfig -> StartAnnexBranch -> (Remote -> Annex a) -> Annex a
|
||||||
withSpecialRemote (ExistingSpecialRemote remotename) _ a =
|
withSpecialRemote (ExistingSpecialRemote remotename) _ a =
|
||||||
|
|
|
@ -157,6 +157,7 @@ describeOtherParamsFor c t = do
|
||||||
( maybeAddJSONField "whatelse" $ M.fromList $ mkjson l
|
( maybeAddJSONField "whatelse" $ M.fromList $ mkjson l
|
||||||
, liftIO $ forM_ l $ \(p, fd, vd) -> case fd of
|
, liftIO $ forM_ l $ \(p, fd, vd) -> case fd of
|
||||||
HiddenField -> return ()
|
HiddenField -> return ()
|
||||||
|
DeprecatedField -> return ()
|
||||||
FieldDesc d -> do
|
FieldDesc d -> do
|
||||||
putStrLn p
|
putStrLn p
|
||||||
putStrLn ("\t" ++ d)
|
putStrLn ("\t" ++ d)
|
||||||
|
@ -171,6 +172,7 @@ describeOtherParamsFor c t = do
|
||||||
mkjson = mapMaybe $ \(p, fd, vd) ->
|
mkjson = mapMaybe $ \(p, fd, vd) ->
|
||||||
case fd of
|
case fd of
|
||||||
HiddenField -> Nothing
|
HiddenField -> Nothing
|
||||||
|
DeprecatedField -> Nothing
|
||||||
FieldDesc d -> Just
|
FieldDesc d -> Just
|
||||||
( T.pack p
|
( T.pack p
|
||||||
, M.fromList
|
, M.fromList
|
||||||
|
|
|
@ -58,7 +58,7 @@ noChunks _ = False
|
||||||
|
|
||||||
chunkConfigParsers :: [RemoteConfigFieldParser]
|
chunkConfigParsers :: [RemoteConfigFieldParser]
|
||||||
chunkConfigParsers =
|
chunkConfigParsers =
|
||||||
[ optionalStringParser chunksizeField HiddenField -- deprecated
|
[ optionalStringParser chunksizeField DeprecatedField
|
||||||
, optionalStringParser chunkField
|
, optionalStringParser chunkField
|
||||||
(FieldDesc "size of chunks (eg, 1MiB)")
|
(FieldDesc "size of chunks (eg, 1MiB)")
|
||||||
]
|
]
|
||||||
|
|
|
@ -51,6 +51,8 @@ data RemoteConfigFieldParser = RemoteConfigFieldParser
|
||||||
data FieldDesc
|
data FieldDesc
|
||||||
= FieldDesc String
|
= FieldDesc String
|
||||||
| HiddenField
|
| HiddenField
|
||||||
|
| DeprecatedField
|
||||||
|
deriving (Eq)
|
||||||
|
|
||||||
newtype ValueDesc = ValueDesc String
|
newtype ValueDesc = ValueDesc String
|
||||||
|
|
||||||
|
|
|
@ -20,8 +20,8 @@ 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 configuring the url of an existing special remote, a
|
But you don't need to generate such an url yourself. Instead, you can use
|
||||||
shorter url of "annex::" is sufficient. For example:
|
the shorthand url of "annex::" with an existing special remote.
|
||||||
|
|
||||||
git-annex initremote foo type=directory encryption=none directory=/mnt/foo
|
git-annex initremote foo type=directory encryption=none directory=/mnt/foo
|
||||||
git config remote.foo.url annex::
|
git config remote.foo.url annex::
|
||||||
|
@ -32,6 +32,10 @@ special remote. To make [[git-annex-initremote]](1) and
|
||||||
[[git-annex-enableremote]](1) configure the url, pass them the `--with-url`
|
[[git-annex-enableremote]](1) configure the url, pass them the `--with-url`
|
||||||
option.
|
option.
|
||||||
|
|
||||||
|
When using the shorthand "annex::" url, the full url will be displayed
|
||||||
|
each time you git pull or push, when it's possible for git-annex to
|
||||||
|
determine it.
|
||||||
|
|
||||||
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
|
||||||
the special remote. That is typically done by setting environment
|
the special remote. That is typically done by setting environment
|
||||||
|
|
|
@ -10,20 +10,15 @@ will be available to users who don't use datalad.
|
||||||
|
|
||||||
This is implememented and working. Remaining todo list for it:
|
This is implememented and working. Remaining todo list for it:
|
||||||
|
|
||||||
|
* When git clone is used with an annex:: url that is for a directory
|
||||||
|
special remote and is missing directory=, for example, it does
|
||||||
|
not display any useful error message. git fetch does, but it seems
|
||||||
|
git clone eats git-remote-annex stderr.
|
||||||
|
|
||||||
* Cloning from an annex:: url with importtree=yes doesn't work
|
* Cloning from an annex:: url with importtree=yes doesn't work
|
||||||
(with or without exporttree=yes). This is because the ContentIdentifier
|
(with or without exporttree=yes). This is because the ContentIdentifier
|
||||||
db is not populated. It should be possible to work around this.
|
db is not populated. It should be possible to work around this.
|
||||||
|
|
||||||
* It would be nice if git-annex could generate an annex:: url
|
|
||||||
for a special remote and show it to the user, eg when
|
|
||||||
they have set the shorthand "annex::" url, so they know the full url.
|
|
||||||
`git-annex info $remote` could also display it.
|
|
||||||
Currently, the user has to remember how the special remote was
|
|
||||||
configured and replicate it all in the url.
|
|
||||||
|
|
||||||
There are some difficulties to doing this, including that
|
|
||||||
RemoteConfig can have hidden fields that should be omitted.
|
|
||||||
|
|
||||||
* datalad-annex supports cloning from the web special remote,
|
* datalad-annex supports cloning from the web special remote,
|
||||||
using an url that contains the result of pushing to eg, a directory
|
using an url that contains the result of pushing to eg, a directory
|
||||||
special remote.
|
special remote.
|
||||||
|
|
Loading…
Reference in a new issue