@@ -9,16 +9,19 @@
10-- On a historical note, this code was taken directly from the yesod web framework's configuration module.
10-- On a historical note, this code was taken directly from the yesod web framework's configuration module.
11module Data.Yaml.Config
11module Data.Yaml.Config
12− ( applyCurrentEnv
12+ ( -- * High-level
15− , loadYamlSettings
13+ loadYamlSettings
16 , EnvUsage
15 , EnvUsage
17 , ignoreEnv
16 , ignoreEnv
19 , requireEnv
18 , requireEnv
20 , useCustomEnv
19 , useCustomEnv
21 , requireCustomEnv
20 , requireCustomEnv
@@ -50,6 +53,14 @@ mergeValues :: Value -> Value -> Value
50mergeValues (Object x) (Object y) = Object $ H.unionWith mergeValues x y
53mergeValues (Object x) (Object y) = Object $ H.unionWith mergeValues x y
51mergeValues x _ = x
54mergeValues x _ = x
56+-- | Override environment variable placeholders in the given @Value@ with
57+-- values from the environment.
59+-- If the first argument is @True@, then all placeholders _must_ be provided by
60+-- the actual environment. Otherwise, default values from the @Value@ will be
53applyEnvValue :: Bool -- ^ require an environment variable to be present?
64applyEnvValue :: Bool -- ^ require an environment variable to be present?
54 -> H.HashMap Text Text -> Value -> Value
65 -> H.HashMap Text Text -> Value -> Value
55applyEnvValue requireEnv' env =
66applyEnvValue requireEnv' env =
@@ -82,26 +93,62 @@ applyEnvValue requireEnv' env =
83 parseValue val = fromMaybe (String val) $ Y.decode $ encodeUtf8 val
94 parseValue val = fromMaybe (String val) $ Y.decode $ encodeUtf8 val
96+-- | Get the actual environment as a @HashMap@ from @Text@ to @Text@.
85getCurrentEnv :: IO (H.HashMap Text Text)
99getCurrentEnv :: IO (H.HashMap Text Text)
86getCurrentEnv = fmap (H.fromList . map (pack *** pack)) getEnvironment
100getCurrentEnv = fmap (H.fromList . map (pack *** pack)) getEnvironment
102+-- | A convenience wrapper around 'applyEnvValue' and 'getCurrentEnv'
88applyCurrentEnv :: Bool -- ^ require an environment variable to be present?
105applyCurrentEnv :: Bool -- ^ require an environment variable to be present?
89 -> Value -> IO Value
106 -> Value -> IO Value
90applyCurrentEnv requireEnv' orig = flip (applyEnvValue requireEnv') orig <$> getCurrentEnv
107applyCurrentEnv requireEnv' orig = flip (applyEnvValue requireEnv') orig <$> getCurrentEnv
109+-- | Defines how we want to use the environment variables when loading a config
110+-- file. Use the smart constructors provided by this module.
92data EnvUsage = IgnoreEnv
113data EnvUsage = IgnoreEnv
94 | RequireEnv
115 | RequireEnv
95 | UseCustomEnv (H.HashMap Text Text)
116 | UseCustomEnv (H.HashMap Text Text)
96 | RequireCustomEnv (H.HashMap Text Text)
117 | RequireCustomEnv (H.HashMap Text Text)
119+-- | Do not use any environment variables, instead relying on defaults values
120+-- in the config file.
98−ignoreEnv, useEnv, requireEnv :: EnvUsage
123+ignoreEnv :: EnvUsage
99ignoreEnv = IgnoreEnv
124ignoreEnv = IgnoreEnv
126+-- | Use environment variables when available, otherwise use defaults.
100useEnv = UseEnv
130useEnv = UseEnv
132+-- | Do not use default values from the config file, but instead take all
133+-- overrides from the environment. If a value is missing, loading the file will
134+-- throw an exception.
137+requireEnv :: EnvUsage
101requireEnv = RequireEnv
138requireEnv = RequireEnv
140+-- | Same as 'useEnv', but instead of the actual environment, use the provided
141+-- @HashMap@ as the environment.
103−useCustomEnv, requireCustomEnv :: H.HashMap Text Text -> EnvUsage
144+useCustomEnv :: H.HashMap Text Text -> EnvUsage
104useCustomEnv = UseCustomEnv
145useCustomEnv = UseCustomEnv
147+-- | Same as 'requireEnv', but instead of the actual environment, use the
148+-- provided @HashMap@ as the environment.
151+requireCustomEnv :: H.HashMap Text Text -> EnvUsage
105requireCustomEnv = RequireCustomEnv
152requireCustomEnv = RequireCustomEnv
107-- | Load the settings from the following three sources:
154-- | Load the settings from the following three sources:
@@ -111,6 +158,13 @@ requireCustomEnv = RequireCustomEnv
111-- * Run time environment variables
158-- * Run time environment variables
113-- * The default compile time config file
160-- * The default compile time config file
162+-- For example, to load up settings from @config/foo.yaml@ and allow overriding
163+-- from the actual environment, you can use:
165+-- > loadYamlSettings ["config/foo.yaml"] [] useEnv
114loadYamlSettings
168loadYamlSettings
115 :: FromJSON settings
169 :: FromJSON settings
116 => [FilePath] -- ^ run time config files to use, earlier files have precedence
170 => [FilePath] -- ^ run time config files to use, earlier files have precedence