-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Tools for specifying and parsing configurations -- @package configuration-tools @version 0.2.13 -- | This module contains a Setup.hs script that hooks into the -- cabal build process at the end of the configuration phase and -- generates a module with package information for each component of the -- cabal package. -- -- The modules are created in the autogen build directory where -- also the Path_ module is created by cabal's simple build -- setup. This is usually the directory ./dist/build/autogen. -- -- For a library component the module is named just PkgInfo. For -- all other components the module is named -- PkgInfo_COMPONENT_NAME where COMPONENT_NAME is the -- name of the component with - characters replaced by -- _. -- -- For instance, if a cabal package contains a library and an executable -- that is called my-app, the following modules are created: -- PkgInfo and PkgInfo_my_app. -- --

Usage as Setup Script

-- -- There are three ways how this module can be used: -- --
    --
  1. Copy the code of this module into a file called Setup.hs -- in the root directory of your package.
  2. --
  3. If the configuration-tools package is already installed in -- the system where the build is done, following code can be used as -- Setup.hs script:
    module Main (main) where import
    --   Configuration.Utils.Setup
  4. --
  5. For usage within a more complex Setup.hs script you shall -- import this module qualified and use the mkPkgInfoModules -- function. For example:
    module Main (main) where import qualified
    --   Configuration.Utils.Setup as ConfTools main :: IO () main =
    --   defaultMainWithHooks (ConfTools.mkPkgInfoModules simpleUserHooks)
    --   
  6. --
-- -- With all methods the field Build-Type in the package -- description (cabal) file must be set to Custom: -- --
--   Build-Type: Custom
--   
-- --

Integration With Configuration.Utils

-- -- You can integrate the information provided by the PkgInfo -- modules with the command line interface of an application by importing -- the respective module for the component and using the -- runWithPkgInfoConfiguration function from the module -- Configuration.Utils as show in the following example: -- --
--   {-# LANGUAGE OverloadedStrings #-}
--   {-# LANGUAGE FlexibleInstances #-}
--   
--   module Main
--   ( main
--   ) where
--   
--   import Configuration.Utils
--   import PkgInfo
--   
--   instance FromJSON (() -> ()) where parseJSON _ = pure id
--   
--   mainInfo :: ProgramInfo ()
--   mainInfo = programInfo "Hello World" (pure id) ()
--   
--   main :: IO ()
--   main = runWithPkgInfoConfiguration mainInfo pkgInfo . const $ putStrLn "hello world"
--   
-- -- With that the resulting application supports the following additional -- command line options: -- -- module Configuration.Utils.Setup -- | Include this function when your setup doesn't contain any extra -- functionality. main :: IO () -- | Modifies the given record of hooks by adding functionality that -- creates a package info module for each component of the cabal package. -- -- This function is intended for usage in more complex Setup.hs -- scripts. If your setup doesn't contain any other function you can just -- import the main function from this module. -- -- The modules are created in the autogen build directory where -- also the Path_ module is created by cabal's simple build -- setup. This is usually the directory ./dist/build/autogen. -- -- For a library component the module is named just PkgInfo. For -- all other components the module is named -- PkgInfo_COMPONENT_NAME where COMPONENT_NAME is the -- name of the component with - characters replaced by -- _. mkPkgInfoModules :: UserHooks -> UserHooks module Configuration.Utils.Internal lens :: (σ -> α) -> (σ -> β -> τ) -> Lens σ τ α β over :: ((α -> Identity β) -> σ -> Identity τ) -> (α -> β) -> σ -> τ set :: ((α -> Identity β) -> σ -> Identity τ) -> β -> σ -> τ view :: MonadReader σ μ => ((α -> Const α α) -> σ -> Const α σ) -> μ α -- | This is the same type as the type from the lens library with the same -- name. -- -- In case it is already import from the lens package this should be -- hidden from the import. type Lens' σ α = Lens σ σ α α -- | This is the same type as the type from the lens library with the same -- name. -- -- In case it is already import from the lens package this should be -- hidden from the import. type Lens σ τ α β = forall φ. Functor φ => (α -> φ β) -> σ -> φ τ type Iso' σ α = Iso σ σ α α -- | This is the same type as the type from the lens library with the same -- name. -- -- In case it is already import from the lens package this should be -- hidden from the import. type Iso σ τ α β = forall π φ. (Profunctor π, Functor φ) => π α (φ β) -> π σ (φ τ) iso :: (σ -> α) -> (β -> τ) -> Iso σ τ α β (&) :: α -> (α -> β) -> β (<&>) :: Functor φ => φ α -> (α -> β) -> φ β sshow :: (Show α, IsString τ) => α -> τ exceptT :: Monad μ => (ε -> μ β) -> (α -> μ β) -> ExceptT ε μ α -> μ β errorT :: Monad μ => ExceptT Text μ α -> μ α fmapL :: (α -> β) -> Either α γ -> Either β γ -- | Utilities for validating configuration values module Configuration.Utils.Validation -- | A validation function. The type in the MonadWriter is excpected -- to be a Foldable structure for collecting warnings. type ConfigValidation α λ = forall μ. (MonadIO μ, Functor μ, Applicative μ, MonadError Text μ, MonadWriter (λ Text) μ) => α -> μ () -- | Validates that a value is an HTTP or HTTPS URL validateHttpOrHttpsUrl :: MonadError Text m => Text -> String -> m () -- | Validates that a value is an HTTP URL validateHttpUrl :: MonadError Text m => Text -> String -> m () -- | Validates that a value is an HTTPS URL validateHttpsUrl :: MonadError Text m => Text -> String -> m () -- | Validates that a value is an URI without a fragment identifier validateUri :: MonadError Text m => Text -> String -> m () -- | Validates that a value is an absolute URI without a fragment -- identifier validateAbsoluteUri :: MonadError Text m => Text -> String -> m () -- | Validates that a value is an absolute URI with an optional fragment -- identifier validateAbsoluteUriFragment :: MonadError Text m => Text -> String -> m () validateIPv4 :: MonadError Text m => Text -> String -> m () validateIPv6 :: MonadError Text m => Text -> String -> m () validatePort :: (MonadError Text m, Integral n, Show n) => Text -> n -> m () validateNonEmpty :: (MonadError Text m, Eq α, Monoid α) => Text -> α -> m () validateLength :: (MonadError Text m, Foldable φ) => Text -> Int -> φ α -> m () validateMinLength :: (MonadError Text m, Foldable φ) => Text -> Int -> φ α -> m () validateMaxLength :: (MonadError Text m, Foldable φ) => Text -> Int -> φ α -> m () validateMinMaxLength :: (MonadError Text m, Foldable φ) => Text -> Int -> Int -> φ α -> m () validateFilePath :: MonadError Text m => Text -> FilePath -> m () validateFile :: (MonadError Text m, MonadIO m) => Text -> FilePath -> m () validateFileReadable :: (MonadError Text m, MonadIO m) => Text -> FilePath -> m () validateFileWritable :: (MonadError Text m, MonadIO m) => Text -> FilePath -> m () -- | Validates if the given executable name can be found in the system and -- can be executed. validateExecutable :: (Functor m, MonadError Text m, MonadIO m) => Text -> FilePath -> m () validateDirectory :: (MonadError Text m, MonadIO m) => Text -> FilePath -> m () -- | Validate that the input is a config file validateConfigFile :: (MonadIO m, MonadError Text m) => String -> m () validateFalse :: MonadError Text m => Text -> Bool -> m () validateTrue :: MonadError Text m => Text -> Bool -> m () validateBool :: MonadError Text m => Text -> Bool -> Bool -> m () validateNonNegative :: (MonadError Text m, Ord α, Num α) => Text -> α -> m () validatePositive :: (MonadError Text m, Ord α, Num α) => Text -> α -> m () validateNonPositive :: (MonadError Text m, Ord α, Num α) => Text -> α -> m () validateNegative :: (MonadError Text m, Ord α, Num α) => Text -> α -> m () validateNonNull :: (MonadError Text m, Eq α, Num α) => Text -> α -> m () validateLess :: (MonadError Text m, Ord α, Show α) => Text -> α -> α -> m () validateLessEq :: (MonadError Text m, Ord α, Show α) => Text -> α -> α -> m () validateGreater :: (MonadError Text m, Ord α, Show α) => Text -> α -> α -> m () validateGreaterEq :: (MonadError Text m, Ord α, Show α) => Text -> α -> α -> m () validateRange :: (MonadError Text m, Ord α, Show α) => Text -> (α, α) -> α -> m () -- | This module provides tools for defining Maybe configuration types. module Configuration.Utils.Maybe -- | Command line parser for record Maybe values -- --

Example:

-- --
--   data Setting = Setting
--       { _setA ∷ !Int
--       , _setB ∷ !String
--       }
--       deriving (Show, Read, Eq, Ord, Typeable)
--   
--   $(makeLenses ''Setting)
--   
--   defaultSetting ∷ Setting
--   defaultSetting = Setting
--       { _setA = 0
--       , _setB = 1
--       }
--   
--   instance ToJSON Setting where
--       toJSON setting = object
--          [ "a" .= _setA setting
--          , "b" .= _setB setting
--          ]
--   
--   instance FromJSON (Setting → Setting) where
--       parseJSON = withObject "Setting" $ \o → id
--           <$< setA ..: "a" % o
--           <*< setB ..: "b" % o
--   
--   instance FromJSON Setting where
--      parseJSON v = parseJSON v <*> pure defaultSetting
--   
--   pSetting ∷ MParser Setting
--   pSetting = id
--       <$< setA .:: option auto
--           % short 'a'
--           <> metavar "INT"
--           <> help "set a"
--       <*< setB .:: option auto
--           % short 'b'
--           <> metavar "INT"
--           <> help "set b"
--   
--   -- | Use 'Setting' as 'Maybe' in a configuration:
--   --
--   data Config = Config
--       { _maybeSetting ∷ !(Maybe Setting)
--       }
--       deriving (Show, Read, Eq, Ord, Typeable)
--   
--   $(makeLenses ''Config)
--   
--   defaultConfig ∷ Config
--   defaultConfig = Config
--       { _maybeSetting = defaultSetting
--       }
--   
--   instance ToJSON Config where
--       toJSON config = object
--           [ "setting" .= maybeSetting
--           ]
--   
--   instance FromJSON (Config → Config) where
--       parseJSON = withObject "Config" $ \o → id
--           <$< maybeSetting %.: "setting" % o
--   
--   pConfig ∷ MParser Config
--   pConfig = id
--       <$< maybeSetting %:: (maybeOption defaultSetting
--           <$> pEnableSetting
--           <*> pSetting)
--     where
--       pEnableSetting = boolOption
--           % long "setting-enable"
--           <> value False
--           <> help "Enable configuration flags for setting"
--   
maybeOption :: a -> Bool -> (a -> a) -> Maybe a -> Maybe a instance (FromJSON (a -> a), FromJSON a) => FromJSON (Maybe a -> Maybe a) -- | Useful operators for defining functions in an applicative context module Configuration.Utils.Operators -- | This operator is an alternative for $ with a higher precedence. -- It is suitable for usage within applicative style code without the -- need to add parenthesis. (%) :: (α -> β) -> α -> β -- | This operator is a UTF-8 version of % which is an alternative -- for $ with a higher precedence. It is suitable for usage within -- applicative style code without the need to add parenthesis. -- -- The hex value of the UTF-8 character × is 0x00d7. -- -- In VIM type: Ctrl-V u 00d7 -- -- You may also define a key binding by adding something like the -- following line to your vim configuration file: -- --
--   iabbrev <buffer> >< ×
--   
(×) :: (α -> β) -> α -> β -- | Functional composition for applicative functors. (<*<) :: Applicative φ => φ (β -> γ) -> φ (α -> β) -> φ (α -> γ) -- | Functional composition for applicative functors with its arguments -- flipped. (>*>) :: Applicative φ => φ (α -> β) -> φ (β -> γ) -> φ (α -> γ) -- | Applicative functional composition between a pure function and an -- applicative function. (<$<) :: Functor φ => (β -> γ) -> φ (α -> β) -> φ (α -> γ) -- | Applicative functional composition between a pure function and an -- applicative function with its arguments flipped. (>$>) :: Functor φ => φ (α -> β) -> (β -> γ) -> φ (α -> γ) -- | Functional composition for applicative functors. -- -- This is a rather popular operator. Due to conflicts (for instance with -- the lens package) it may have to be imported qualified. -- | Deprecated: use <*< instead (<.>) :: Applicative φ => φ (β -> γ) -> φ (α -> β) -> φ (α -> γ) -- | For people who like nicely aligned code and do not mind messing with -- editor key-maps: here a version of <.> that uses a -- unicode symbol -- -- The hex value of the UTF-8 character ⊙ is 0x2299. -- -- A convenient VIM key-map is: -- --
--   iabbrev <buffer> ../ ⊙
--   
-- | Deprecated: use <*< instead (⊙) :: Applicative φ => φ (β -> γ) -> φ (α -> β) -> φ (α -> γ) -- | This module provides tools for defining command line parsers for -- configuration types. -- -- Unlike normal command line parsers the parsers for -- configuration types are expected to yield an update function that -- takes a value and updates the value with the settings from the command -- line. -- -- Assuming that -- -- -- -- usually the operators .:: and %:: are all that is needed -- from this module. -- -- The module Configuration.Utils.Monoid provides tools for the -- case that a simple type is a container with a monoid instance, -- such as List or HashMap. -- -- The module Configuration.Utils.Maybe explains the usage of -- optional Maybe values in configuration types. module Configuration.Utils.CommandLine -- | Type of option parsers that yield a modification function. type MParser α = Parser (α -> α) -- | An operator for applying a setter to an option parser that yields a -- value. -- -- Example usage: -- --
--   data Auth = Auth
--       { _user ∷ !String
--       , _pwd ∷ !String
--       }
--   
--   user ∷ Functor φ ⇒ (String → φ String) → Auth → φ Auth
--   user f s = (\u → s { _user = u }) <$> f (_user s)
--   
--   pwd ∷ Functor φ ⇒ (String → φ String) → Auth → φ Auth
--   pwd f s = (\p → s { _pwd = p }) <$> f (_pwd s)
--   
--   -- or with lenses and TemplateHaskell just:
--   -- $(makeLenses ''Auth)
--   
--   pAuth ∷ MParser Auth
--   pAuth = id
--      <$< user .:: strOption
--          × long "user"
--          ⊕ short 'u'
--          ⊕ help "user name"
--      <*< pwd .:: strOption
--          × long "pwd"
--          ⊕ help "password for user"
--   
(.::) :: (Alternative φ, Applicative φ) => Lens' α β -> φ β -> φ (α -> α) -- | An operator for applying a setter to an option parser that yields a -- modification function. -- -- Example usage: -- --
--   data HttpURL = HttpURL
--       { _auth ∷ !Auth
--       , _domain ∷ !String
--       }
--   
--   auth ∷ Functor φ ⇒ (Auth → φ Auth) → HttpURL → φ HttpURL
--   auth f s = (\u → s { _auth = u }) <$> f (_auth s)
--   
--   domain ∷ Functor φ ⇒ (String → φ String) → HttpURL → φ HttpURL
--   domain f s = (\u → s { _domain = u }) <$> f (_domain s)
--   
--   path ∷ Functor φ ⇒ (String → φ String) → HttpURL → φ HttpURL
--   path f s = (\u → s { _path = u }) <$> f (_path s)
--   
--   -- or with lenses and TemplateHaskell just:
--   -- $(makeLenses ''HttpURL)
--   
--   pHttpURL ∷ MParser HttpURL
--   pHttpURL = id
--       <$< auth %:: pAuth
--       <*< domain .:: strOption
--           × long "domain"
--           ⊕ short 'd'
--           ⊕ help "HTTP domain"
--   
(%::) :: (Alternative φ, Applicative φ) => Lens' α β -> φ (β -> β) -> φ (α -> α) boolReader :: (Eq a, Show a, FoldCase a, IsString a, IsString e, Monoid e) => a -> Either e Bool -- | The boolOption is an alternative to switch. -- -- Using switch with command line parsers that overwrite settings -- from a configuration file is problematic: the absence of the -- switch is interpreted as setting the respective configuration -- value to False. So there is no way to specify on the command -- line that the value from the configuration file shall be used. Some -- command line UIs use two different options for those values, for -- instance --enable-feature and --disable-feature. -- This option instead expects a Boolean value. Beside that it behaves -- like any other option. boolOption :: Mod OptionFields Bool -> Parser Bool -- | An alternative syntax for boolOption for options with long -- names. -- -- Instead of taking a boolean argument the presence of the option acts -- as a switch to set the respective configuration setting to -- True. If the option is not present the setting is left -- unchanged. -- -- In addition for long option names a respective unset flag is -- provided. For instance for a flag --verbose there will also -- be a flag --no-verbose. -- -- This can still be used with short option names only, but no unset -- flag would be provided. boolOption_ :: Mod FlagFields Bool -> Parser Bool -- | An option parser for flags that are enabled via the flag name prefixed -- with --enable- and disabled via the flag name prefix -- --disable-. The prefixes are applied to all long option -- names. Short option names are parsed unchanged and and cause the flag -- to be enabled. -- -- This resembles the style of flags that is used for instances with -- Cabal. enableDisableFlag :: Mod FlagFields Bool -> Parser Bool fileOption :: Mod OptionFields String -> Parser FilePath eitherReadP :: Text -> ReadP a -> Text -> Either Text a -- | The distinction between appending on the left and appending on the -- right is important for monoids that are sensitive to ordering such as -- List. It is also of relevance for monoids with set semantics -- with non-extensional equality such as HashMap. module Configuration.Utils.Monoid -- | Update a value by appending on the left. Under normal circumstances -- you'll never use this type directly but only its FromJSON -- instance. See the leftMonoidalUpdate for an example. data LeftMonoidalUpdate α -- | Update a value by appending on the left. -- --
--   newtype RoutingTable = RoutingTable { _routingTableMap ∷ HashMap T.Text T.Text }
--   
--   $(makeLenses ''RoutingTable)
--   
--   instance FromJSON (RoutingTable → RoutingTable) where
--       parseJSON = withObject "RoutingTable" $ \o → id
--           <$< routingTableMap . from leftMonoidalUpdate %.: "route_map" % o
--   
leftMonoidalUpdate :: Iso (LeftMonoidalUpdate α) (LeftMonoidalUpdate β) α β -- | This is the same as from leftMonoidalUpdate but doesn't -- depend on the lens Library. fromLeftMonoidalUpdate :: Iso α β (LeftMonoidalUpdate α) (LeftMonoidalUpdate β) -- | Update a value by appending on the left. -- --
--   newtype RoutingTable = RoutingTable { _routingTableMap ∷ HashMap T.Text T.Text }
--   
--   $(makeLenses ''RoutingTable)
--   
--   pRoutingTable ∷ MParser RoutingTable
--   pRoutingTable = routingTableMap %:: pLeftMonoidalUpdate pRoute
--     where
--       pRoute = option (eitherReader readRoute)
--           % long "route"
--           <> help "add a route to the routing table; the APIROUTE part must not contain a colon character"
--           <> metavar "APIROUTE:APIURL"
--   
--       readRoute s = case break (== ':') s of
--           (a,':':b) → fmapL T.unpack $ do
--               validateNonEmpty "APIROUTE" a
--               validateHttpOrHttpsUrl "APIURL" b
--               return $ HM.singleton (T.pack a) (T.pack b)
--           _ → Left "missing colon between APIROUTE and APIURL"
--   
--       fmapL f = either (Left . f) Right
--   
pLeftMonoidalUpdate :: Monoid α => Parser α -> MParser α -- | Update a value by appending on the right. Under normal circumstances -- you'll never use this type directly but only its FromJSON -- instance. See the leftMonoidalUpdate for an example. data RightMonoidalUpdate α -- | Update a value by appending on the right. See -- leftMonoidalUpdate for an usage example. rightMonoidalUpdate :: Iso (RightMonoidalUpdate α) (RightMonoidalUpdate β) α β -- | This is the same as from rightMonoidalUpdate but doesn't -- depend on the lens Library. fromRightMonoidalUpdate :: Iso α β (RightMonoidalUpdate α) (RightMonoidalUpdate β) -- | Update a value by appending on the right. See -- pLeftMonoidalUpdate for an usage example. pRightMonoidalUpdate :: Monoid α => Parser α -> MParser α instance Monoid α => Monoid (LeftMonoidalUpdate α) instance Monoid α => Monoid (RightMonoidalUpdate α) instance (FromJSON α, Monoid α) => FromJSON (RightMonoidalUpdate α -> RightMonoidalUpdate α) instance (FromJSON α, Monoid α) => FromJSON (LeftMonoidalUpdate α -> LeftMonoidalUpdate α) -- | This module provides means for defining and using HTTPS certificate -- validation polices for HTTPS requests. module Configuration.Utils.Internal.HttpsCertPolicy data HttpsCertPolicy HttpsCertPolicy :: !Bool -> !(HashMap ServiceID Fingerprint) -> HttpsCertPolicy -- | disable certificate validation _certPolicyInsecure :: HttpsCertPolicy -> !Bool -- | a whitelist for services with trusted certificates _certPolicyHostFingerprints :: HttpsCertPolicy -> !(HashMap ServiceID Fingerprint) certPolicyInsecure :: Lens' HttpsCertPolicy Bool certPolicyHostFingerprints :: Lens' HttpsCertPolicy (HashMap ServiceID Fingerprint) defaultHttpsCertPolicy :: HttpsCertPolicy pHttpsCertPolicy :: Text -> MParser HttpsCertPolicy -- | Make an HTTP request with a given certificate validation policy. -- -- NOTE that the HTTP request is strictly loaded into memory. -- -- NOTE that this implementation opens a new TCP connection for each -- single request. HTTPS certificates validation results are not cached -- between different requests. simpleHttpWithValidationPolicy :: Text -> HttpsCertPolicy -> IO (Response ByteString) httpWithValidationPolicy :: Request -> HttpsCertPolicy -> IO (Response ByteString) -- | The Haskell tls library provides only limited means for -- providing user friendly error messages. In particular we'd like to -- provide the user with fingerprints of the reject certificate for -- self-signed certificates. Also we want to provide the user with some -- guidance what a particular failure may indicate with respect to -- security of the connection. -- -- Here we employ a hack for better error handling: Based on the -- assumption that we initialize a new connection Manager and -- also a new certificate cache for each request, we write the -- certificate that is received from the server in the TLS handshake to -- an IORef. If the handshakes fails later on because the -- certificate is rejected we can recover the rejected certificate from -- the IORef. -- -- What we really want are exceptions that can be consumed -- programatically. In particular exceptions should include rejected -- certificates. newtype VerboseTlsException VerboseTlsException :: Text -> VerboseTlsException instance Typeable HttpsCertPolicy instance Typeable VerboseTlsException instance Show HttpsCertPolicy instance Eq HttpsCertPolicy instance Eq VerboseTlsException instance Ord VerboseTlsException instance Exception VerboseTlsException instance Show VerboseTlsException -- | This module provides tools for defining configuration file parsers via -- instances of FromJSON. -- -- Unlike normal FromJSON instances the parsers for -- configuration files are expected to yield an update function that -- takes a value and updates the value with the settings from the -- configuration file. -- -- Assuming that -- -- -- -- usually the operators ..: and %.: are all that is needed -- from this module. -- -- The module Configuration.Utils.Monoid provides tools for the -- case that a simple type is a container with a monoid instance, -- such as List or HashMap. -- -- The module Configuration.Utils.Maybe explains the usage of -- optional Maybe values in configuration types. module Configuration.Utils.ConfigFile -- | A JSON Value parser for a property of a given Object -- that updates a setter with the parsed value. -- --
--   data Auth = Auth
--       { _userId ∷ !Int
--       , _pwd ∷ !String
--       }
--   
--   userId ∷ Functor φ ⇒ (Int → φ Int) → Auth → φ Auth
--   userId f s = (\u → s { _userId = u }) <$> f (_userId s)
--   
--   pwd ∷ Functor φ ⇒ (String → φ String) → Auth → φ Auth
--   pwd f s = (\p → s { _pwd = p }) <$> f (_pwd s)
--   
--   -- or with lenses and TemplateHaskell just:
--   -- $(makeLenses ''Auth)
--   
--   instance FromJSON (Auth → Auth) where
--       parseJSON = withObject "Auth" $ \o → id
--           <$< setProperty user "user" p o
--           <*< setProperty pwd "pwd" parseJSON o
--         where
--           p = withText "user" $ \case
--               "alice" → pure (0 ∷ Int)
--               "bob" → pure 1
--               e → fail $ "unrecognized user " ⊕ e
--   
setProperty :: Lens' α β -> Text -> (Value -> Parser β) -> Object -> Parser (α -> α) -- | A variant of the setProperty that uses the default -- parseJSON method from the FromJSON instance to parse the -- value of the property. Its usage pattern mimics the usage pattern of -- the .: operator from the aeson library. -- --
--   data Auth = Auth
--       { _user ∷ !String
--       , _pwd ∷ !String
--       }
--   
--   user ∷ Functor φ ⇒ (String → φ String) → Auth → φ Auth
--   user f s = (\u → s { _user = u }) <$> f (_user s)
--   
--   pwd ∷ Functor φ ⇒ (String → φ String) → Auth → φ Auth
--   pwd f s = (\p → s { _pwd = p }) <$> f (_pwd s)
--   
--   -- or with lenses and TemplateHaskell just:
--   -- $(makeLenses ''Auth)
--   
--   instance FromJSON (Auth → Auth) where
--       parseJSON = withObject "Auth" $ \o → id
--           <$< user ..: "user" × o
--           <*< pwd ..: "pwd" × o
--   
(..:) :: FromJSON β => Lens' α β -> Text -> Object -> Parser (α -> α) -- | This operator requires that a value is explicitly provided in a -- configuration file, thus preventing the default value from being used. -- Otherwise this operator does the same as '(..:)'. (!..:) :: FromJSON β => Lens' α β -> Text -> Object -> Parser (α -> α) -- | A JSON parser for a function that modifies a property of a given -- Object and updates a setter with the parsed function. -- --
--   data HttpURL = HttpURL
--       { _auth ∷ !Auth
--       , _domain ∷ !String
--       }
--   
--   auth ∷ Functor φ ⇒ (Auth → φ Auth) → HttpURL → φ HttpURL
--   auth f s = (\u → s { _auth = u }) <$> f (_auth s)
--   
--   domain ∷ Functor φ ⇒ (String → φ String) → HttpURL → φ HttpURL
--   domain f s = (\u → s { _domain = u }) <$> f (_domain s)
--   
--   path ∷ Functor φ ⇒ (String → φ String) → HttpURL → φ HttpURL
--   path f s = (\u → s { _path = u }) <$> f (_path s)
--   
--   -- or with lenses and TemplateHaskell just:
--   -- $(makeLenses ''HttpURL)
--   
--   instance FromJSON (HttpURL → HttpURL) where
--       parseJSON = withObject "HttpURL" $ \o → id
--           <$< auth %.: "auth" × o
--           <*< domain ..: "domain" × o
--   
updateProperty :: Lens' α β -> Text -> (Value -> Parser (β -> β)) -> Object -> Parser (α -> α) -- | A variant of updateProperty that used the FromJSON -- instance for the update function. It mimics the aeson operator -- .:. It creates a parser that modifies a setter with a parsed -- function. -- --
--   data HttpURL = HttpURL
--       { _auth ∷ !Auth
--       , _domain ∷ !String
--       }
--   
--   auth ∷ Functor φ ⇒ (Auth → φ Auth) → HttpURL → φ HttpURL
--   auth f s = (\u → s { _auth = u }) <$> f (_auth s)
--   
--   domain ∷ Functor φ ⇒ (String → φ String) → HttpURL → φ HttpURL
--   domain f s = (\u → s { _domain = u }) <$> f (_domain s)
--   
--   path ∷ Functor φ ⇒ (String → φ String) → HttpURL → φ HttpURL
--   path f s = (\u → s { _path = u }) <$> f (_path s)
--   
--   -- or with lenses and TemplateHaskell just:
--   -- $(makeLenses ''HttpURL)
--   
--   instance FromJSON (HttpURL → HttpURL) where
--       parseJSON = withObject "HttpURL" $ \o → id
--           <$< auth %.: "auth" × o
--           <*< domain ..: "domain" × o
--   
(%.:) :: FromJSON (β -> β) => Lens' α β -> Text -> Object -> Parser (α -> α) data ConfigFile ConfigFileRequired :: !Text -> ConfigFile getConfigFile :: ConfigFile -> !Text ConfigFileOptional :: !Text -> ConfigFile getConfigFile :: ConfigFile -> !Text -- | An internal type for the meta configuration that specifies how -- the configuration files are loaded and parsed. data ConfigFilesConfig ConfigFilesConfig :: !HttpsCertPolicy -> ConfigFilesConfig _cfcHttpsPolicy :: ConfigFilesConfig -> !HttpsCertPolicy cfcHttpsPolicy :: Lens' ConfigFilesConfig HttpsCertPolicy defaultConfigFilesConfig :: ConfigFilesConfig pConfigFilesConfig :: MParser ConfigFilesConfig dropAndUncaml :: Int -> String -> String instance Typeable ConfigFile instance Typeable ConfigFilesConfig instance Show ConfigFile instance Read ConfigFile instance Eq ConfigFile instance Ord ConfigFile instance Show ConfigFilesConfig instance Eq ConfigFilesConfig module Configuration.Utils.Internal.ConfigFileReader parseConfigFiles :: (ConfigFileParser μ, FromJSON (α -> α)) => ConfigFilesConfig -> α -> [ConfigFile] -> μ α readConfigFile :: (ConfigFileParser μ, FromJSON (α -> α)) => ConfigFilesConfig -> ConfigFile -> μ (α -> α) data ConfigFileFormat Yaml :: ConfigFileFormat Json :: ConfigFileFormat Other :: ConfigFileFormat loadLocal :: (Functor μ, MonadIO μ, MonadError Text μ, FromJSON (α -> α)) => ConfigFile -> μ (α -> α) isRemote :: ConfigFile -> Bool loadRemote :: (ConfigFileParser μ, FromJSON (α -> α)) => ConfigFilesConfig -> ConfigFile -> μ (α -> α) yamlMimeType :: IsString s => [s] -- | Defined in RFC 4627 jsonMimeType :: IsString s => [s] contentType :: ByteString -> ConfigFileFormat requestHeaders :: Lens' Request RequestHeaders instance Typeable ConfigFileFormat instance Show ConfigFileFormat instance Read ConfigFileFormat instance Eq ConfigFileFormat instance Ord ConfigFileFormat instance Enum ConfigFileFormat instance Bounded ConfigFileFormat instance Generic ConfigFileFormat instance Datatype D1ConfigFileFormat instance Constructor C1_0ConfigFileFormat instance Constructor C1_1ConfigFileFormat instance Constructor C1_2ConfigFileFormat instance NFData ConfigFileFormat -- | This module provides a collection of utilities on top of the packages -- optparse-applicative, aeson, and yaml, for configuring libraries and -- applications in a composable way. -- -- The main feature is the integration of command line option parsing and -- configuration files. -- -- The purpose is to make management of configurations easy by providing -- an idiomatic style of defining and deploying configurations in a -- modular and composable way. -- --

Usage

-- -- The module provides operators and functions that make the -- implementation of these entities easy for the common case that the -- configurations are encoded mainly as nested records. -- -- For each data type that is used as as component in a configuration -- type the following must be provided: -- --
    --
  1. a default value,
  2. --
  3. a FromJSON instance that yields a function that -- takes a value and updates that value with the parsed values,
  4. --
  5. a ToJSON instance, and
  6. --
  7. a command line options parser that yields a function that -- takes a value and updates that value with the values provided as -- command line options.
  8. --
-- -- In addition to the above optionally a validation function may -- be provided that (recursively) validates a configuration value and -- returns either an error or a (possibly empty) list-like structure of -- warnings. -- -- The modules -- -- -- -- contain tools and examples for defining above prerequisites for using -- a type in a configuration type. -- -- The provided functions and operators assume that lenses for the -- configuration record types are provided. -- -- The module Configuration.Utils.Monoid provides tools for the -- case that a simple type is a container with a monoid instance, -- such as List or HashMap. -- -- The module Configuration.Utils.Maybe explains the usage of -- optional Maybe values in configuration types. -- --

Usage Example

-- -- Beside the examples that are provided in the haddock documentation -- there is a complete usage example in the file -- example/Example.hs of the cabal package. module Configuration.Utils type ProgramInfo α = ProgramInfoValidate α [] -- | Smart constructor for ProgramInfo. -- -- piHelpHeader and piHelpFooter are set to Nothing. -- The function piValidateConfiguration is set to const -- (return []) programInfo :: String -> MParser α -> α -> ProgramInfo α -- | Program Description piDescription :: Lens' (ProgramInfoValidate α λ) String -- | Help header piHelpHeader :: Lens' (ProgramInfoValidate α λ) (Maybe String) -- | Help footer piHelpFooter :: Lens' (ProgramInfoValidate α λ) (Maybe String) -- | Options parser for configuration piOptionParser :: Lens' (ProgramInfoValidate α λ) (MParser α) -- | Default configuration piDefaultConfiguration :: Lens' (ProgramInfoValidate α λ) α -- | Configuration files that are loaded in order before any command line -- argument is evaluated. piConfigurationFiles :: Lens' (ProgramInfoValidate α λ) [ConfigFile] -- | A validation function. The type in the MonadWriter is excpected -- to be a Foldable structure for collecting warnings. type ConfigValidation α λ = forall μ. (MonadIO μ, Functor μ, Applicative μ, MonadError Text μ, MonadWriter (λ Text) μ) => α -> μ () -- | Smart constructor for ProgramInfo. -- -- piHelpHeader and piHelpFooter are set to Nothing. programInfoValidate :: String -> MParser α -> α -> ConfigValidation α λ -> ProgramInfoValidate α λ -- | Run an IO action with a configuration that is obtained by updating the -- given default configuration the values defined via command line -- arguments. -- -- In addition to the options defined by the given options parser the -- following options are recognized: -- -- -- -- As long as the package wasn't build with -f-remote-configs -- the following two options are available. They affect how configuration -- files are loaded from remote URLs. -- -- runWithConfiguration :: (FromJSON (α -> α), ToJSON α, Foldable λ, Monoid (λ Text)) => ProgramInfoValidate α λ -> (α -> IO ()) -> IO () -- | Information about the cabal package. The format is: -- --
--   (info message, detailed info message, version string, license text)
--   
-- -- See the documentation of Configuration.Utils.Setup for a way -- how to generate this information automatically from the package -- description during the build process. type PkgInfo = (String, String, String, String) -- | Run an IO action with a configuration that is obtained by updating the -- given default configuration the values defined via command line -- arguments. -- -- In addition to the options defined by the given options parser the -- following options are recognized: -- -- -- -- As long as the package wasn't build with -f-remote-configs -- the following two options are available. They affect how configuration -- files are loaded from remote URLs. -- -- runWithPkgInfoConfiguration :: (FromJSON (α -> α), ToJSON α, Foldable λ, Monoid (λ Text)) => ProgramInfoValidate α λ -> PkgInfo -> (α -> IO ()) -> IO () -- | Parse the command line arguments. -- -- Any warnings from the configuration function are discarded. The -- options --print-config and --help are just ignored. parseConfiguration :: (Applicative m, MonadIO m, MonadBaseControl IO m, MonadError Text m, FromJSON (α -> α), ToJSON α, Foldable λ, Monoid (λ Text)) => Text -> ProgramInfoValidate α λ -> [String] -> m α -- | This is the same type as the type from the lens library with the same -- name. -- -- In case it is already import from the lens package this should be -- hidden from the import. type Lens' σ α = Lens σ σ α α -- | This is the same type as the type from the lens library with the same -- name. -- -- In case it is already import from the lens package this should be -- hidden from the import. type Lens σ τ α β = forall φ. Functor φ => (α -> φ β) -> σ -> φ τ data ProgramInfoValidate α λ -- | Validation Function -- -- The Right result is interpreted as a Foldable structure -- of warnings. piValidateConfiguration :: Lens' (ProgramInfoValidate α λ) (ConfigValidationFunction α λ) -- | A newtype wrapper around a validation function. The only purpose of -- this type is to avoid ImpredicativeTypes when storing the -- function in the ProgramInfoValidate record. newtype ConfigValidationFunction α λ ConfigValidationFunction :: ConfigValidation α λ -> ConfigValidationFunction α λ runConfigValidation :: ConfigValidationFunction α λ -> ConfigValidation α λ -- | Lens for simultaneous query and update of piOptionParser -- and piDefaultConfiguration. This supports to change the type of -- ProgramInfo with over and set. piOptionParserAndDefaultConfiguration :: Lens (ProgramInfoValidate α λ) (ProgramInfoValidate β γ) (MParser α, α, ConfigValidationFunction α λ) (MParser β, β, ConfigValidationFunction β γ) module Configuration.Utils.Http -- | In order to make TLS optional this type should be used wrapped into a -- Maybe. data HttpServiceTLSConfiguration hstcCertFile :: Lens' HttpServiceTLSConfiguration FilePath hstcKeyFile :: Lens' HttpServiceTLSConfiguration FilePath defaultHttpServiceTLSConfiguration :: HttpServiceTLSConfiguration -- | This option parser does not allow to enable or disable usage of TLS. -- The option will have effect only when TLS usage is configured in the -- configuration file or the default configuration. -- -- FIXME: print a warning and exit when one of these options is provided -- even though TLS is turned off. pHttpServiceTLSConfiguration :: String -> MParser HttpServiceTLSConfiguration validateHttpServiceTLSConfiguration :: ConfigValidation HttpServiceTLSConfiguration λ -- | We restrict services to use either HTTP or HTTPS but not both. -- -- TLS can be turned off explicitely in the configuration file by setting -- the respective section to null. It can not be turned on or -- off via command line options. But once it is turned on the values for -- the certificate and key file can be changed by command line options. data HttpServiceConfiguration hscHost :: Lens' HttpServiceConfiguration ByteString hscPort :: Lens' HttpServiceConfiguration Int hscUseTLS :: Lens' HttpServiceConfiguration (Maybe HttpServiceTLSConfiguration) defaultHttpServiceConfiguration :: HttpServiceConfiguration pHttpServiceConfiguration :: String -> MParser HttpServiceConfiguration validateHttpServiceConfiguration :: ConfigValidation HttpServiceConfiguration DList data HttpClientConfiguration hccHost :: Lens' HttpClientConfiguration ByteString hccPort :: Lens' HttpClientConfiguration Int hccUseTLS :: Lens' HttpClientConfiguration Bool defaultHttpClientConfiguration :: HttpClientConfiguration pHttpClientConfiguration :: String -> MParser HttpClientConfiguration validateHttpClientConfiguration :: ConfigValidation HttpClientConfiguration λ httpService2clientConfiguration :: HttpServiceConfiguration -> HttpClientConfiguration instance Show HttpServiceTLSConfiguration instance Read HttpServiceTLSConfiguration instance Eq HttpServiceTLSConfiguration instance Ord HttpServiceTLSConfiguration instance Show HttpServiceConfiguration instance Read HttpServiceConfiguration instance Eq HttpServiceConfiguration instance Ord HttpServiceConfiguration instance Show HttpClientConfiguration instance Read HttpClientConfiguration instance Eq HttpClientConfiguration instance Ord HttpClientConfiguration instance ToJSON HttpClientConfiguration instance FromJSON (HttpClientConfiguration -> HttpClientConfiguration) instance ToJSON HttpServiceConfiguration instance FromJSON (HttpServiceConfiguration -> HttpServiceConfiguration) instance ToJSON HttpServiceTLSConfiguration instance FromJSON HttpServiceTLSConfiguration instance FromJSON (HttpServiceTLSConfiguration -> HttpServiceTLSConfiguration)