Hello community, here is the log from the commit of package ghc-read-env-var for openSUSE:Factory checked in at 2017-08-31 20:58:17 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/ghc-read-env-var (Old) and /work/SRC/openSUSE:Factory/.ghc-read-env-var.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "ghc-read-env-var" Thu Aug 31 20:58:17 2017 rev:4 rq:513465 version:1.0.0.0 Changes: -------- --- /work/SRC/openSUSE:Factory/ghc-read-env-var/ghc-read-env-var.changes 2017-04-14 13:36:41.680094896 +0200 +++ /work/SRC/openSUSE:Factory/.ghc-read-env-var.new/ghc-read-env-var.changes 2017-08-31 20:58:18.939802411 +0200 @@ -1,0 +2,5 @@ +Thu Jul 27 14:07:14 UTC 2017 - psimons@suse.com + +- Update to version 1.0.0.0. + +------------------------------------------------------------------- Old: ---- read-env-var-0.1.0.1.tar.gz New: ---- read-env-var-1.0.0.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ ghc-read-env-var.spec ++++++ --- /var/tmp/diff_new_pack.poWzCg/_old 2017-08-31 20:58:19.747688901 +0200 +++ /var/tmp/diff_new_pack.poWzCg/_new 2017-08-31 20:58:19.759687215 +0200 @@ -19,7 +19,7 @@ %global pkg_name read-env-var %bcond_with tests Name: ghc-%{pkg_name} -Version: 0.1.0.1 +Version: 1.0.0.0 Release: 0 Summary: Functions for safely reading environment variables License: BSD-3-Clause @@ -27,7 +27,9 @@ Url: https://hackage.haskell.org/package/%{pkg_name} Source0: https://hackage.haskell.org/package/%{pkg_name}-%{version}/%{pkg_name}-%{version}.tar.gz BuildRequires: ghc-Cabal-devel +BuildRequires: ghc-exceptions-devel BuildRequires: ghc-rpm-macros +BuildRequires: ghc-transformers-devel BuildRoot: %{_tmppath}/%{name}-%{version}-build %if %{with tests} BuildRequires: ghc-Glob-devel ++++++ read-env-var-0.1.0.1.tar.gz -> read-env-var-1.0.0.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/read-env-var-0.1.0.1/LICENSE new/read-env-var-1.0.0.0/LICENSE --- old/read-env-var-0.1.0.1/LICENSE 2016-04-07 08:10:46.000000000 +0200 +++ new/read-env-var-1.0.0.0/LICENSE 2017-03-22 03:23:42.000000000 +0100 @@ -1,4 +1,4 @@ -Copyright Author name here (c) 2016 +Copyright Dennis Gosnell (c) 2016 All rights reserved. @@ -27,4 +27,4 @@ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/read-env-var-0.1.0.1/read-env-var.cabal new/read-env-var-1.0.0.0/read-env-var.cabal --- old/read-env-var-0.1.0.1/read-env-var.cabal 2016-08-15 19:56:50.000000000 +0200 +++ new/read-env-var-1.0.0.0/read-env-var.cabal 2017-03-22 15:06:37.000000000 +0100 @@ -1,5 +1,5 @@ name: read-env-var -version: 0.1.0.1 +version: 1.0.0.0 synopsis: Functions for safely reading environment variables. description: Please see README.md homepage: https://github.com/cdepillabout/read-env-var#readme @@ -16,7 +16,9 @@ library hs-source-dirs: src exposed-modules: System.ReadEnvVar - build-depends: base >= 4.6 && < 5 + build-depends: base >= 4.7 && < 5 + , exceptions + , transformers default-language: Haskell2010 ghc-options: -Wall diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/read-env-var-0.1.0.1/src/System/ReadEnvVar.hs new/read-env-var-1.0.0.0/src/System/ReadEnvVar.hs --- old/read-env-var-0.1.0.1/src/System/ReadEnvVar.hs 2016-08-15 19:55:31.000000000 +0200 +++ new/read-env-var-1.0.0.0/src/System/ReadEnvVar.hs 2017-03-22 14:53:20.000000000 +0100 @@ -1,3 +1,4 @@ +{-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE CPP #-} {-| @@ -9,12 +10,37 @@ Portability : POSIX This Haskell module exports functions for safely reading environment variables. + +The @lookupEnv*@ functions are for reading in 'String'-like environment +variables (like hostnames, passwords, etc.), while the @readEnv*@ functions are +for reading in Haskell datatypes (like 'Int', 'Double', etc). + +Most of these functions run in 'MonadIO'. This means that they can be used +from any monad that implements 'MonadIO'. This makes it easier to run in a +monad transformer stack. If you're not familiar with 'MonadIO', you can just +think of all the functions as being 'IO' actions. + +The 'lookupEnv', 'lookupEnvDef', and 'lookupEnvEx' functions all use 'IsString' +to generalize the return type. This makes it more general than +"System.Environment"\'s 'Env.lookupEnv'. It makes it possible to read in +things other than 'String's, like +<https://hackage.haskell.org/package/text/docs/Data-Text.html Text> or +<https://hackage.haskell.org/package/bytestring/docs/Data-ByteString.html ByteString>. -} module System.ReadEnvVar - ( readEnvVar - , readEnvVarDef + ( lookupEnv , lookupEnvDef + , readEnv + , readEnvDef + -- * Unsafe functions + , EnvVarDoesNotExistException(..) + , lookupEnvEx + , readEnvEx + , EnvVarCannotBeReadException(..) + , readEnvEx' + -- * Re-exports + , setEnv ) where #if __GLASGOW_HASKELL__ < 710 @@ -23,69 +49,277 @@ import Control.Applicative #endif +import Control.Exception (Exception) +import Control.Monad.Catch (MonadThrow(throwM)) +import Control.Monad.IO.Class (MonadIO(liftIO)) +import Data.Data (Data) import Data.Maybe (fromMaybe) import Data.String (IsString(fromString)) -import System.Environment (lookupEnv) +import Data.Typeable (Typeable) +import System.Environment (setEnv) +import qualified System.Environment as Env import Text.Read (readMaybe) -- | Lookup a value from an environment variable and read it in with -- 'readMaybe'. If the environment variable doesn't exist, or it can't be --- 'read', use the default value. +-- 'read', return the default value. Like 'readEnv' but with a default +-- value. -- --- Note that this does not read string values as one would expect. +-- Read an environment variable that exists: -- --- >>> import System.Environment (setEnv) -- >>> setEnv "TEST_ENV_VAR1" "1000" --- >>> readEnvVarDef "TEST_ENV_VAR1" 5 :: IO Int +-- >>> readEnvDef "TEST_ENV_VAR1" 5 :: IO Int -- 1000 --- >>> readEnvVarDef "THIS_ENV_VAR_WILL_NOT_EXIST" 5 :: IO Int +-- +-- Try reading an environment variable that does not exist. Returns the +-- default value: +-- +-- >>> readEnvDef "THIS_ENV_VAR_WILL_NOT_EXIST" 5 :: IO Int -- 5 +-- +-- Try reading an environment variable that cannot be 'read'. Returns the +-- default value: +-- +-- >>> setEnv "BAD_ENV_VAR" "not an int" +-- >>> readEnvDef "BAD_ENV_VAR" 10 :: IO Int +-- 10 +-- +-- Note that this __DOES NOT__ read string values as one might expect: +-- -- >>> setEnv "TEST_ENV_VAR2" "some string 1" --- >>> readEnvVarDef "TEST_ENV_VAR2" "def val" :: IO String +-- >>> readEnvDef "TEST_ENV_VAR2" "def val" :: IO String -- "def val" +-- +-- It will read string values as if they were Haskell strings: +-- -- >>> setEnv "TEST_ENV_VAR3" "\"some string 1\"" --- >>> readEnvVarDef "TEST_ENV_VAR3" "def val" :: IO String +-- >>> readEnvDef "TEST_ENV_VAR3" "def val" :: IO String -- "some string 1" -readEnvVarDef :: Read a - => String -- ^ environment variable to lookup - -> a -- ^ default value to use if the environment variable - -- either does not exist, or cannot be 'read' - -> IO a -readEnvVarDef envVar def = fromMaybe def <$> readEnvVar envVar +readEnvDef + :: (MonadIO m, Read a) + => String -- ^ environment variable to lookup + -> a -- ^ default value to return if the environment variable + -- either does not exist, or cannot be 'read' + -> m a +readEnvDef envVar def = do + maybeEnv <- readEnv envVar + return $ fromMaybe def maybeEnv -- | Lookup a value from an environment variable and read it in with -- 'readMaybe'. -- --- Note that this does not read string values as one would expect. +-- Read an environment variable that exists: -- --- >>> import System.Environment (setEnv) -- >>> setEnv "TEST_ENV_VAR" "2000" --- >>> readEnvVar "TEST_ENV_VAR" :: IO (Maybe Int) +-- >>> readEnv "TEST_ENV_VAR" :: IO (Maybe Int) -- Just 2000 --- >>> readEnvVar "THIS_ENV_VAR_WILL_NOT_EXIST" :: IO (Maybe Int) +-- +-- Try reading an environment variable that does not exist. Returns 'Nothing': +-- +-- >>> readEnv "THIS_ENV_VAR_WILL_NOT_EXIST" :: IO (Maybe Int) -- Nothing +-- +-- Try reading an environment variable that cannot be 'read'. Returns +-- 'Nothing': +-- +-- >>> setEnv "BAD_ENV_VAR" "not an int" +-- >>> readEnv "BAD_ENV_VAR" :: IO (Maybe Int) +-- Nothing +-- +-- Note that this __DOES NOT__ read string values as one might expect: +-- -- >>> setEnv "TEST_ENV_VAR2" "some string 1" --- >>> readEnvVar "TEST_ENV_VAR2" :: IO (Maybe String) +-- >>> readEnv "TEST_ENV_VAR2" :: IO (Maybe String) -- Nothing +-- +-- It will read string values as if they were Haskell strings: +-- -- >>> setEnv "TEST_ENV_VAR3" "\"some string 1\"" --- >>> readEnvVar "TEST_ENV_VAR3" :: IO (Maybe String) +-- >>> readEnv "TEST_ENV_VAR3" :: IO (Maybe String) -- Just "some string 1" -readEnvVar :: Read a - => String -- ^ environment variable to lookup - -> IO (Maybe a) -readEnvVar = fmap (>>= readMaybe) . lookupEnv +readEnv + :: (MonadIO m, Read a) + => String -- ^ environment variable to lookup + -> m (Maybe a) +readEnv envVar = do + maybeEnv <- liftIO (Env.lookupEnv envVar) + return $ maybeEnv >>= readMaybe -- | Like 'lookupEnv' but take a default value. -- --- >>> import System.Environment (setEnv) +-- Lookup an environment variable that exists: +-- -- >>> setEnv "TEST_ENV_VAR" "foo" -- >>> lookupEnvDef "TEST_ENV_VAR" "bar" :: IO String -- "foo" +-- +-- Lookup an environment variable that doesn't exist. Return the default +-- value: +-- -- >>> lookupEnvDef "THIS_ENV_VAR_WILL_NOT_EXIST" "bar" :: IO String -- "bar" -lookupEnvDef :: IsString a - => String -- ^ environment variable to lookup - -> a -- ^ default value to use if environment variable not defined - -> IO a -lookupEnvDef envVar defaultValue = - pure . maybe defaultValue fromString =<< lookupEnv envVar +lookupEnvDef + :: (IsString a, MonadIO m) + => String -- ^ environment variable to lookup + -> a -- ^ default value to return if environment variable not defined + -> m a +lookupEnvDef envVar defaultValue = do + maybeEnv <- liftIO $ Env.lookupEnv envVar + return $ maybe defaultValue fromString maybeEnv + +-- | Like "System.Environment"\'s 'Env.lookupEnv', but using 'IsString' to make +-- it more general. +-- +-- Lookup an environment variable that exists: +-- +-- >>> setEnv "TEST_ENV_VAR" "foo" +-- >>> lookupEnv "TEST_ENV_VAR" :: IO (Maybe String) +-- Just "foo" +-- +-- Lookup an environment variable that doesn't exist. Return 'Nothing': +-- +-- >>> lookupEnv "THIS_ENV_VAR_WILL_NOT_EXIST" :: IO (Maybe String) +-- Nothing +lookupEnv + :: (IsString a, MonadIO m) + => String + -> m (Maybe a) +lookupEnv envVar = do + maybeEnv <- liftIO $ Env.lookupEnv envVar + return $ fmap fromString maybeEnv + +-- | 'Exception' thrown by 'lookupEnvEx' and 'readEnvEx' when the +-- environment variable being read doesn't exist. +data EnvVarDoesNotExistException = + -- | The 'String' is the name of the environment variable that does not + -- exist. + EnvVarDoesNotExistException String + deriving (Data, Eq, Ord, Read, Show, Typeable) + +instance Exception EnvVarDoesNotExistException + +-- | Like 'lookupEnv', but instead of returning a 'Maybe', throw an +-- 'EnvVarDoesNotExistException' if the environment variable does not exist. +-- The exception is thrown with 'throwM' from 'MonadThrow'. +-- +-- Lookup an environment variable that exists: +-- +-- >>> setEnv "TEST_ENV_VAR" "foo" +-- >>> lookupEnvEx "TEST_ENV_VAR" :: IO String +-- "foo" +-- +-- Lookup an environment variable that doesn't exist. Throws +-- 'EnvVarDoesNotExistException'. +-- +-- >>> lookupEnvEx "THIS_ENV_VAR_WILL_NOT_EXIST" :: IO String +-- *** Exception: EnvVarDoesNotExistException "THIS_ENV_VAR_WILL_NOT_EXIST" +lookupEnvEx + :: (IsString a, MonadIO m, MonadThrow m) + => String + -> m a +lookupEnvEx envVar = do + maybeEnv <- liftIO (Env.lookupEnv envVar) + case maybeEnv of + Nothing -> throwM $ EnvVarDoesNotExistException envVar + Just env -> return $ fromString env + +-- | Lookup a value from an environment variable and read it in with +-- 'readMaybe'. Throw an 'EnvVarDoesNotExistException' if the environment +-- variable does not exist. The exception is thrown with 'throwM' from +-- 'MonadThrow'. +-- +-- Read an environment variable that exists: +-- +-- >>> setEnv "TEST_ENV_VAR" "2000" +-- >>> readEnvEx "TEST_ENV_VAR" :: IO (Maybe Int) +-- Just 2000 +-- +-- Try reading an environment variable that does not exist. Throws +-- 'EnvVarDoesNotExistException': +-- +-- >>> readEnvEx "THIS_ENV_VAR_WILL_NOT_EXIST" :: IO (Maybe Int) +-- *** Exception: EnvVarDoesNotExistException "THIS_ENV_VAR_WILL_NOT_EXIST" +-- +-- Try reading an environment variable that cannot be 'read'. Returns +-- 'Nothing': +-- +-- >>> setEnv "BAD_ENV_VAR" "not an int" +-- >>> readEnvEx "BAD_ENV_VAR" :: IO (Maybe Int) +-- Nothing +-- +-- Note that this __DOES NOT__ read string values as one might expect: +-- +-- >>> setEnv "TEST_ENV_VAR2" "some string 1" +-- >>> readEnvEx "TEST_ENV_VAR2" :: IO (Maybe String) +-- Nothing +-- +-- It will read string values as if they were Haskell strings: +-- +-- >>> setEnv "TEST_ENV_VAR3" "\"some string 1\"" +-- >>> readEnvEx "TEST_ENV_VAR3" :: IO (Maybe String) +-- Just "some string 1" +readEnvEx + :: (MonadIO m, Read a, MonadThrow m) + => String -- ^ environment variable to lookup + -> m (Maybe a) +readEnvEx envVar = do + maybeEnv <- liftIO (Env.lookupEnv envVar) + case maybeEnv of + Nothing -> throwM $ EnvVarDoesNotExistException envVar + Just env -> return $ readMaybe env + +-- | 'Exception' thrown by 'readEnvEx'' when the environment variable +-- cannot be 'read'. +data EnvVarCannotBeReadException = + -- | The first 'String' is the name of the environment variable that cannot + -- be 'read'. + EnvVarCannotBeReadException String + deriving (Data, Eq, Ord, Read, Show, Typeable) + +instance Exception EnvVarCannotBeReadException + +-- | Just like 'readEnvEx', but also throw an exception when the environment +-- variable cannot be 'read'. +-- +-- This can throw both 'EnvVarCannotBeReadException' and +-- 'EnvVarDoesNotExistException' with 'throwM'. +-- +-- Read an environment variable that exists: +-- +-- >>> setEnv "TEST_ENV_VAR" "2000" +-- >>> readEnvEx' "TEST_ENV_VAR" :: IO Int +-- 2000 +-- +-- Try reading an environment variable that does not exist. Throws +-- 'EnvVarDoesNotExistException': +-- +-- >>> readEnvEx' "THIS_ENV_VAR_WILL_NOT_EXIST" :: IO Int +-- *** Exception: EnvVarDoesNotExistException "THIS_ENV_VAR_WILL_NOT_EXIST" +-- +-- Try reading an environment variable that cannot be 'read'. Throws +-- 'EnvVarCannotBeReadException': +-- +-- >>> setEnv "BAD_ENV_VAR" "not an int" +-- >>> readEnvEx' "BAD_ENV_VAR" :: IO Int +-- *** Exception: EnvVarCannotBeReadException "BAD_ENV_VAR" +-- +-- Note that this __DOES NOT__ read string values as one might expect: +-- +-- >>> setEnv "TEST_ENV_VAR2" "some string 1" +-- >>> readEnvEx' "TEST_ENV_VAR2" :: IO String +-- *** Exception: EnvVarCannotBeReadException "TEST_ENV_VAR2" +-- +-- It will read string values as if they were Haskell strings: +-- +-- >>> setEnv "TEST_ENV_VAR3" "\"some string 1\"" +-- >>> readEnvEx' "TEST_ENV_VAR3" :: IO String +-- "some string 1" +readEnvEx' + :: (MonadIO m, Read a, MonadThrow m) + => String -- ^ environment variable to lookup + -> m a +readEnvEx' envVar = do + maybeEnv <- readEnvEx envVar + case maybeEnv of + Nothing -> throwM $ EnvVarCannotBeReadException envVar + Just env -> return env