6a91471923
Fix regression that prevented external special remotes from using GETCONFIG to query values like "name". (Introduced in version 7.20200202.7.)
72 lines
2.4 KiB
Haskell
72 lines
2.4 KiB
Haskell
{- git-annex remote config types
|
|
-
|
|
- Copyright 2020 Joey Hess <id@joeyh.name>
|
|
-
|
|
- Licensed under the GNU AGPL version 3 or higher.
|
|
-}
|
|
|
|
{-# LANGUAGE GADTs #-}
|
|
|
|
module Types.RemoteConfig where
|
|
|
|
import qualified Data.Map as M
|
|
import qualified Data.Set as S
|
|
import Data.Typeable
|
|
|
|
import Types.ProposedAccepted
|
|
|
|
type RemoteConfigField = ProposedAccepted String
|
|
|
|
{- What the user provides to configure the remote, and what is stored for
|
|
- later; a bunch of fields and values. -}
|
|
type RemoteConfig = M.Map RemoteConfigField (ProposedAccepted String)
|
|
|
|
{- Before being used a RemoteConfig has to be parsed. -}
|
|
data ParsedRemoteConfig = ParsedRemoteConfig
|
|
{ parsedRemoteConfigMap :: M.Map RemoteConfigField RemoteConfigValue
|
|
, unparsedRemoteConfig :: RemoteConfig
|
|
}
|
|
|
|
{- Remotes can have configuration values of many types, so use Typeable
|
|
- to let them all be stored in here. -}
|
|
data RemoteConfigValue where
|
|
RemoteConfigValue :: Typeable v => v -> RemoteConfigValue
|
|
|
|
{- Parse a field's value provided by the user into a RemoteConfigValue.
|
|
-
|
|
- The RemoteConfig is provided to the parser function for cases
|
|
- where multiple fields need to be looked at. However, it's important
|
|
- that, when a parser looks at an additional field in that way, the
|
|
- parser list contains a dedicated parser for that field as well.
|
|
- Presence of fields that are not included in this list will cause
|
|
- a parse failure.
|
|
-}
|
|
data RemoteConfigFieldParser = RemoteConfigFieldParser
|
|
{ parserForField :: RemoteConfigField
|
|
, valueParser :: Maybe (ProposedAccepted String) -> RemoteConfig -> Either String (Maybe RemoteConfigValue)
|
|
, fieldDesc :: FieldDesc
|
|
, valueDesc :: Maybe ValueDesc
|
|
}
|
|
|
|
data FieldDesc
|
|
= FieldDesc String
|
|
| HiddenField
|
|
|
|
newtype ValueDesc = ValueDesc String
|
|
|
|
data RemoteConfigParser = RemoteConfigParser
|
|
{ remoteConfigFieldParsers :: [RemoteConfigFieldParser]
|
|
, remoteConfigRestPassthrough :: Maybe (RemoteConfigField -> Bool, [(String, FieldDesc)])
|
|
}
|
|
|
|
mkRemoteConfigParser :: Monad m => [RemoteConfigFieldParser] -> RemoteConfig -> m RemoteConfigParser
|
|
mkRemoteConfigParser l _ = pure (RemoteConfigParser l Nothing)
|
|
|
|
addRemoteConfigParser :: [RemoteConfigFieldParser] -> RemoteConfigParser -> RemoteConfigParser
|
|
addRemoteConfigParser l rpc = rpc
|
|
{ remoteConfigFieldParsers =
|
|
remoteConfigFieldParsers rpc ++ filter isnew l
|
|
}
|
|
where
|
|
s = S.fromList (map parserForField (remoteConfigFieldParsers rpc))
|
|
isnew p = not (S.member (parserForField p) s)
|