Hello community, here is the log from the commit of package ghc-yaml for openSUSE:Factory checked in at 2016-02-23 16:57:47 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/ghc-yaml (Old) and /work/SRC/openSUSE:Factory/.ghc-yaml.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "ghc-yaml" Changes: -------- --- /work/SRC/openSUSE:Factory/ghc-yaml/ghc-yaml.changes 2016-01-28 17:25:04.000000000 +0100 +++ /work/SRC/openSUSE:Factory/.ghc-yaml.new/ghc-yaml.changes 2016-02-23 16:59:36.000000000 +0100 @@ -1,0 +2,8 @@ +Tue Feb 16 20:01:56 UTC 2016 - [email protected] + +- update to 0.8.16 +* Add env variable parsing. loadYamlSettings can read config values from the + environment with Yaml that specifies an env var. The syntax is + var: _env:ENV_VAR:default + +------------------------------------------------------------------- Old: ---- yaml-0.8.15.3.tar.gz New: ---- yaml-0.8.16.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ ghc-yaml.spec ++++++ --- /var/tmp/diff_new_pack.RY0k9z/_old 2016-02-23 16:59:37.000000000 +0100 +++ /var/tmp/diff_new_pack.RY0k9z/_new 2016-02-23 16:59:37.000000000 +0100 @@ -18,7 +18,7 @@ %global pkg_name yaml Name: ghc-yaml -Version: 0.8.15.3 +Version: 0.8.16 Release: 0 Summary: Support for parsing and rendering YAML documents License: BSD-3-Clause @@ -38,6 +38,7 @@ BuildRequires: ghc-resourcet-devel BuildRequires: ghc-rpm-macros BuildRequires: ghc-scientific-devel +BuildRequires: ghc-semigroups-devel BuildRequires: ghc-text-devel BuildRequires: ghc-transformers-devel BuildRequires: ghc-unordered-containers-devel ++++++ yaml-0.8.15.3.tar.gz -> yaml-0.8.16.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yaml-0.8.15.3/ChangeLog.md new/yaml-0.8.16/ChangeLog.md --- old/yaml-0.8.15.3/ChangeLog.md 2016-01-18 15:53:27.000000000 +0100 +++ new/yaml-0.8.16/ChangeLog.md 2016-02-15 10:17:58.000000000 +0100 @@ -1,3 +1,10 @@ +## 0.8.16 + +Add env variable parsing. `loadYamlSettings` can read config values from the environment with Yaml that specifies an env var. +The syntax is + +`var: _env:ENV_VAR:default` + ## 0.8.15.3 * Give a warning when compiling with GHCJS diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yaml-0.8.15.3/Data/Yaml/Config.hs new/yaml-0.8.16/Data/Yaml/Config.hs --- old/yaml-0.8.15.3/Data/Yaml/Config.hs 1970-01-01 01:00:00.000000000 +0100 +++ new/yaml-0.8.16/Data/Yaml/Config.hs 2016-02-15 10:17:58.000000000 +0100 @@ -0,0 +1,143 @@ +{-# LANGUAGE CPP #-} +{-# LANGUAGE OverloadedStrings #-} +-- | Functionality for using YAML as configuration files +-- +-- In particular, merging environment variables with yaml values +-- +-- 'loadYamlSettings' is a high-level API for loading YAML and merging environment variables. +-- A yaml value of @_env:ENV_VAR:default@ will lookup the environment variable @ENV_VAR@. +-- +-- On a historical note, this code was taken directly from the yesod web framework's configuration module. +module Data.Yaml.Config + ( applyCurrentEnv + , getCurrentEnv + , applyEnvValue + , loadYamlSettings + , EnvUsage + , ignoreEnv + , useEnv + , requireEnv + , useCustomEnv + , requireCustomEnv + ) where + + +#if __GLASGOW_HASKELL__ < 710 +import Control.Applicative ((<$>)) +import Data.Monoid +#endif +import Data.Semigroup +import Data.List.NonEmpty (nonEmpty) +import Data.Aeson +import qualified Data.HashMap.Strict as H +import Data.Text (Text, pack) +import System.Environment (getEnvironment) +import Control.Arrow ((***)) +import Control.Monad (forM) +import Control.Exception (throwIO) +import Data.Text.Encoding (encodeUtf8) +import qualified Data.Yaml as Y +import Data.Maybe (fromMaybe) +import qualified Data.Text as T + +newtype MergedValue = MergedValue { getMergedValue :: Value } + +instance Semigroup MergedValue where + MergedValue x <> MergedValue y = MergedValue $ mergeValues x y + +-- | Left biased +mergeValues :: Value -> Value -> Value +mergeValues (Object x) (Object y) = Object $ H.unionWith mergeValues x y +mergeValues x _ = x + +applyEnvValue :: Bool -- ^ require an environment variable to be present? + -> H.HashMap Text Text -> Value -> Value +applyEnvValue requireEnv' env = + goV + where + goV (Object o) = Object $ goV <$> o + goV (Array a) = Array (goV <$> a) + goV (String t1) = fromMaybe (String t1) $ do + t2 <- T.stripPrefix "_env:" t1 + let (name, t3) = T.break (== ':') t2 + mdef = fmap parseValue $ T.stripPrefix ":" t3 + Just $ case H.lookup name env of + Just val -> + -- If the default value parses as a String, we treat the + -- environment variable as a raw value and do not parse it. + -- This means that things like numeric passwords just work. + -- However, for originally numerical or boolean values (e.g., + -- port numbers), we still perform a normal YAML parse. + -- + -- For details, see: + -- https://github.com/yesodweb/yesod/issues/1061 + case mdef of + Just (String _) -> String val + _ -> parseValue val + Nothing -> + case mdef of + Just val | not requireEnv' -> val + _ -> Null + goV v = v + + parseValue val = fromMaybe (String val) $ Y.decode $ encodeUtf8 val + +getCurrentEnv :: IO (H.HashMap Text Text) +getCurrentEnv = fmap (H.fromList . map (pack *** pack)) getEnvironment + +applyCurrentEnv :: Bool -- ^ require an environment variable to be present? + -> Value -> IO Value +applyCurrentEnv requireEnv' orig = flip (applyEnvValue requireEnv') orig <$> getCurrentEnv + +data EnvUsage = IgnoreEnv + | UseEnv + | RequireEnv + | UseCustomEnv (H.HashMap Text Text) + | RequireCustomEnv (H.HashMap Text Text) + +ignoreEnv, useEnv, requireEnv :: EnvUsage +ignoreEnv = IgnoreEnv +useEnv = UseEnv +requireEnv = RequireEnv + +useCustomEnv, requireCustomEnv :: H.HashMap Text Text -> EnvUsage +useCustomEnv = UseCustomEnv +requireCustomEnv = RequireCustomEnv + +-- | Load the settings from the following three sources: +-- +-- * Run time config files +-- +-- * Run time environment variables +-- +-- * The default compile time config file +loadYamlSettings + :: FromJSON settings + => [FilePath] -- ^ run time config files to use, earlier files have precedence + -> [Value] -- ^ any other values to use, usually from compile time config. overridden by files + -> EnvUsage + -> IO settings +loadYamlSettings runTimeFiles compileValues envUsage = do + runValues <- forM runTimeFiles $ \fp -> do + eres <- Y.decodeFileEither fp + case eres of + Left e -> do + putStrLn $ "loadYamlSettings: Could not parse file as YAML: " ++ fp + throwIO e + Right value -> return value + + value' <- + case nonEmpty $ map MergedValue $ runValues ++ compileValues of + Nothing -> error "loadYamlSettings: No configuration provided" + Just ne -> return $ getMergedValue $ sconcat ne + value <- + case envUsage of + IgnoreEnv -> return $ applyEnvValue False mempty value' + UseEnv -> applyCurrentEnv False value' + RequireEnv -> applyCurrentEnv True value' + UseCustomEnv env -> return $ applyEnvValue False env value' + RequireCustomEnv env -> return $ applyEnvValue True env value' + + case fromJSON value of + Error s -> error $ "Could not convert to AppSettings: " ++ s + Success settings -> return settings diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yaml-0.8.15.3/yaml.cabal new/yaml-0.8.16/yaml.cabal --- old/yaml-0.8.15.3/yaml.cabal 2016-01-18 15:53:27.000000000 +0100 +++ new/yaml-0.8.16/yaml.cabal 2016-02-15 10:17:58.000000000 +0100 @@ -1,5 +1,5 @@ name: yaml -version: 0.8.15.3 +version: 0.8.16 license: BSD3 license-file: LICENSE author: Michael Snoyman <[email protected]>, Anton Ageev <[email protected]>,Kirill Simonov @@ -53,10 +53,12 @@ , filepath , directory , enclosed-exceptions + , semigroups exposed-modules: Text.Libyaml Data.Yaml Data.Yaml.Aeson Data.Yaml.Builder + Data.Yaml.Config Data.Yaml.Pretty Data.Yaml.Parser Data.Yaml.Include
