read-env-var-1.0.0.0: Functions for safely reading environment variables.

Copyright(c) Dennis Gosnell 2016
LicenseBSD-style (see LICENSE file)
Maintainercdep.illabout@gmail.com
Stabilityexperimental
PortabilityPOSIX
Safe HaskellSafe
LanguageHaskell2010

System.ReadEnvVar

Contents

Description

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 lookupEnv. It makes it possible to read in things other than Strings, like Text or ByteString.

Synopsis

Documentation

lookupEnv :: (IsString a, MonadIO m) => String -> m (Maybe a) Source #

Like System.Environment's 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

lookupEnvDef Source #

Arguments

:: (IsString a, MonadIO m) 
=> String

environment variable to lookup

-> a

default value to return if environment variable not defined

-> m a 

Like lookupEnv but take a default value.

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"

readEnv Source #

Arguments

:: (MonadIO m, Read a) 
=> String

environment variable to lookup

-> m (Maybe a) 

Lookup a value from an environment variable and read it in with readMaybe.

Read an environment variable that exists:

>>> setEnv "TEST_ENV_VAR" "2000"
>>> readEnv "TEST_ENV_VAR" :: IO (Maybe Int)
Just 2000

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"
>>> 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\""
>>> readEnv "TEST_ENV_VAR3" :: IO (Maybe String)
Just "some string 1"

readEnvDef Source #

Arguments

:: (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 

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, return the default value. Like readEnv but with a default value.

Read an environment variable that exists:

>>> setEnv "TEST_ENV_VAR1" "1000"
>>> readEnvDef "TEST_ENV_VAR1" 5 :: IO Int
1000

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"
>>> 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\""
>>> readEnvDef "TEST_ENV_VAR3" "def val" :: IO String
"some string 1"

Unsafe functions

data EnvVarDoesNotExistException Source #

Exception thrown by lookupEnvEx and readEnvEx when the environment variable being read doesn't exist.

Constructors

EnvVarDoesNotExistException String

The String is the name of the environment variable that does not exist.

Instances

Eq EnvVarDoesNotExistException Source # 
Data EnvVarDoesNotExistException Source # 

Methods

gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> EnvVarDoesNotExistException -> c EnvVarDoesNotExistException #

gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c EnvVarDoesNotExistException #

toConstr :: EnvVarDoesNotExistException -> Constr #

dataTypeOf :: EnvVarDoesNotExistException -> DataType #

dataCast1 :: Typeable (* -> *) t => (forall d. Data d => c (t d)) -> Maybe (c EnvVarDoesNotExistException) #

dataCast2 :: Typeable (* -> * -> *) t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c EnvVarDoesNotExistException) #

gmapT :: (forall b. Data b => b -> b) -> EnvVarDoesNotExistException -> EnvVarDoesNotExistException #

gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> EnvVarDoesNotExistException -> r #

gmapQr :: (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> EnvVarDoesNotExistException -> r #

gmapQ :: (forall d. Data d => d -> u) -> EnvVarDoesNotExistException -> [u] #

gmapQi :: Int -> (forall d. Data d => d -> u) -> EnvVarDoesNotExistException -> u #

gmapM :: Monad m => (forall d. Data d => d -> m d) -> EnvVarDoesNotExistException -> m EnvVarDoesNotExistException #

gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> EnvVarDoesNotExistException -> m EnvVarDoesNotExistException #

gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> EnvVarDoesNotExistException -> m EnvVarDoesNotExistException #

Ord EnvVarDoesNotExistException Source # 
Read EnvVarDoesNotExistException Source # 
Show EnvVarDoesNotExistException Source # 
Exception EnvVarDoesNotExistException Source # 

lookupEnvEx :: (IsString a, MonadIO m, MonadThrow m) => String -> m a Source #

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"

readEnvEx Source #

Arguments

:: (MonadIO m, Read a, MonadThrow m) 
=> String

environment variable to lookup

-> m (Maybe a) 

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"

data EnvVarCannotBeReadException Source #

Exception thrown by readEnvEx' when the environment variable cannot be read.

Constructors

EnvVarCannotBeReadException String

The first String is the name of the environment variable that cannot be read.

Instances

Eq EnvVarCannotBeReadException Source # 
Data EnvVarCannotBeReadException Source # 

Methods

gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> EnvVarCannotBeReadException -> c EnvVarCannotBeReadException #

gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c EnvVarCannotBeReadException #

toConstr :: EnvVarCannotBeReadException -> Constr #

dataTypeOf :: EnvVarCannotBeReadException -> DataType #

dataCast1 :: Typeable (* -> *) t => (forall d. Data d => c (t d)) -> Maybe (c EnvVarCannotBeReadException) #

dataCast2 :: Typeable (* -> * -> *) t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c EnvVarCannotBeReadException) #

gmapT :: (forall b. Data b => b -> b) -> EnvVarCannotBeReadException -> EnvVarCannotBeReadException #

gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> EnvVarCannotBeReadException -> r #

gmapQr :: (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> EnvVarCannotBeReadException -> r #

gmapQ :: (forall d. Data d => d -> u) -> EnvVarCannotBeReadException -> [u] #

gmapQi :: Int -> (forall d. Data d => d -> u) -> EnvVarCannotBeReadException -> u #

gmapM :: Monad m => (forall d. Data d => d -> m d) -> EnvVarCannotBeReadException -> m EnvVarCannotBeReadException #

gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> EnvVarCannotBeReadException -> m EnvVarCannotBeReadException #

gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> EnvVarCannotBeReadException -> m EnvVarCannotBeReadException #

Ord EnvVarCannotBeReadException Source # 
Read EnvVarCannotBeReadException Source # 
Show EnvVarCannotBeReadException Source # 
Exception EnvVarCannotBeReadException Source # 

readEnvEx' Source #

Arguments

:: (MonadIO m, Read a, MonadThrow m) 
=> String

environment variable to lookup

-> m a 

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"

Re-exports

setEnv :: String -> String -> IO () #

setEnv name value sets the specified environment variable to value.

On Windows setting an environment variable to the empty string removes that environment variable from the environment. For the sake of compatibility we adopt that behavior. In particular

setEnv name ""

has the same effect as

unsetEnv name

If you don't care about Windows support and want to set an environment variable to the empty string use System.Posix.Env.setEnv from the unix package instead.

Throws IOException if name is the empty string or contains an equals sign.

Since: 4.7.0.0