env-guard (empty) → 0.1
raw patch · 7 files changed
+361/−0 lines, 7 filesdep +basedep +doctest
Dependencies added: base, doctest
Files
- CHANGELOG.md +5/−0
- LICENSE +21/−0
- README.md +16/−0
- env-guard.cabal +46/−0
- src/System/Environment/Guard.hs +126/−0
- src/System/Environment/Guard/Lifted.hs +126/−0
- test/doctest/Main.hs +21/−0
+ CHANGELOG.md view
@@ -0,0 +1,5 @@+# Revision history for env-guard++## 0.1 -- 2022-06-29++* First version. Released on an unsuspecting world.
+ LICENSE view
@@ -0,0 +1,21 @@+MIT License++Copyright (c) 2022 Thomas Bidne++Permission is hereby granted, free of charge, to any person obtaining a copy+of this software and associated documentation files (the "Software"), to deal+in the Software without restriction, including without limitation the rights+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+copies of the Software, and to permit persons to whom the Software is+furnished to do so, subject to the following conditions:++The above copyright notice and this permission notice shall be included in all+copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+SOFTWARE.
+ README.md view
@@ -0,0 +1,16 @@+<div align="center">++# env-guard++[](https://hackage.haskell.org/package/env-guard)+[](https://opensource.org/licenses/MIT)++[](https://github.com/tbidne/env-guard/actions/workflows/nix_ci.yaml)+[](https://github.com/tbidne/env-guard/actions/workflows/stack_ci.yaml)+[](https://github.com/tbidne/env-guard/actions/workflows/style_ci.yaml)++[](https://github.com/tbidne/env-guard/actions/workflows/ghc_8-10.yaml)+[](https://github.com/tbidne/env-guard/actions/workflows/ghc_9-0.yaml)+[](https://github.com/tbidne/env-guard/actions/workflows/ghc_9-2.yaml)++</div>
+ env-guard.cabal view
@@ -0,0 +1,46 @@+cabal-version: 2.4+name: env-guard+version: 0.1+license: MIT+license-file: LICENSE+tested-with: GHC ==8.10.7 || ==9.0.2 || ==9.2.3+copyright: 2022 Thomas Bidne+author: Thomas Bidne+maintainer: tbidne@protonmail.com+homepage: https://github.com/tbidne/env-guard/+bug-reports: https://github.com/tbidne/env-guard/issues+synopsis:+ Conditionally running IO actions based on environment variables.++description:+ This package provides functions for validating presence / contents of+ environment variables, and conditionally running IO actions based on the+ result.++category: System, Environment+extra-source-files:+ CHANGELOG.md+ README.md++source-repository head+ type: git+ location: https://github.com/tbidne/env-guard++library+ exposed-modules:+ System.Environment.Guard+ System.Environment.Guard.Lifted++ build-depends: base >=4.14.0.0 && <4.17+ hs-source-dirs: src+ default-language: Haskell2010++test-suite doctest+ type: exitcode-stdio-1.0+ main-is: Main.hs+ build-depends:+ , base+ , doctest >=0.16.3 && <0.21++ hs-source-dirs: test/doctest+ default-language: Haskell2010
+ src/System/Environment/Guard.hs view
@@ -0,0 +1,126 @@+{-# LANGUAGE LambdaCase #-}++-- | Functions for conditionally running 'IO' actions based on an environment+-- variable.+--+-- @since 0.1+module System.Environment.Guard+ ( -- * Checking environment variable is set+ guardSet,+ guardSet_,++ -- * Checking environment variable match+ guardExpected,+ guardExpected_,++ -- * Checking environment variable predicate+ guardPredicate,+ guardPredicate_,+ )+where++import Control.Monad (void)+import Data.Char (toLower)+import System.Environment (lookupEnv)++-- $setup+-- >>> import Data.Functor (($>))+-- >>> import System.Environment (setEnv)++-- | @'guardSet' var io@ runs @io@ iff+--+-- 1. The environment variable @var@ is set.+--+-- @+-- 'guardSet' var === 'guardPredicate' var ('const' 'True')+-- @+--+-- ==== __Examples__+--+-- >>> guardSet "NOT_SET" (putStrLn "ran io" $> True)+-- Nothing+--+-- >>> setEnv "SET" "foo"+-- >>> guardSet "SET" (putStrLn "ran io" $> True)+-- ran io+-- Just True+--+-- @since 0.1+guardSet :: String -> IO a -> IO (Maybe a)+guardSet var = guardPredicate var (const True)++-- | Variant of 'guardSet' that ignores the return value.+--+-- @since 0.1+guardSet_ :: String -> IO a -> IO ()+guardSet_ var = void . guardSet var++-- | @'guardExpected' var expected io@ runs @io@ iff+--+-- 1. The environment variable @var@ is set.+-- 2. @var@'s value equals @expected@. This is __case-insensitive__.+--+-- @+-- 'guardExpected' var expected === 'guardPredicate' var (\\a b -> 'fmap' 'toLower' a == 'fmap' 'toLower' b)+-- @+--+-- ==== __Examples__+--+-- >>> guardExpected "NOT_SET" "val" (putStrLn "ran io" $> True)+-- Nothing+--+-- >>> setEnv "WRONG_VAL" "good_val"+-- >>> guardExpected "WRONG_VAL" "bad_val" (putStrLn "ran io" $> True)+-- Nothing+--+-- >>> setEnv "WILL_RUN" "val"+-- >>> guardExpected "WILL_RUN" "VAL" (putStrLn "ran io" $> True)+-- ran io+-- Just True+--+-- @since 0.1+guardExpected :: String -> String -> IO a -> IO (Maybe a)+guardExpected var expected = guardPredicate var (eqCaseInsensitive expected)++-- | Variant of 'guardExpected_' that ignores the return value.+--+-- @since 0.1+guardExpected_ :: String -> String -> IO a -> IO ()+guardExpected_ var expected = void . guardExpected var expected++-- | Variant of 'guardPredicate' that ignores the return value.+--+-- @since 0.1+guardPredicate_ :: String -> (String -> Bool) -> IO a -> IO ()+guardPredicate_ var p = void . guardPredicate var p++-- | This is the most general way to check an environment variable.+-- @'guardPredicate' var p io@ runs @io@ iff+--+-- 1. The environment variable @var@ is set.+-- 2. @var@'s value satisfies predicate @p@.+--+-- ==== __Examples__+--+-- >>> guardPredicate "NOT_SET" (const True) (putStrLn "ran io" $> True)+-- Nothing+--+-- >>> setEnv "CASE_WRONG" "VAL"+-- >>> guardPredicate "CASE_WRONG" (== "val") (putStrLn "ran io" $> True)+-- Nothing+--+-- >>> setEnv "WILL_RUN" "VAL"+-- >>> guardPredicate "WILL_RUN" (== "VAL") (putStrLn "ran io" $> True)+-- ran io+-- Just True+--+-- @since 0.1+guardPredicate :: String -> (String -> Bool) -> IO a -> IO (Maybe a)+guardPredicate var p io =+ lookupEnv var+ >>= \case+ Just result | p result -> Just <$> io+ _ -> pure Nothing++eqCaseInsensitive :: String -> String -> Bool+eqCaseInsensitive a b = fmap toLower a == fmap toLower b
+ src/System/Environment/Guard/Lifted.hs view
@@ -0,0 +1,126 @@+{-# LANGUAGE LambdaCase #-}++-- | "System.Environment.Guard" for 'MonadIO'.+--+-- @since 0.1+module System.Environment.Guard.Lifted+ ( -- * Checking environment variable is set+ guardSet,+ guardSet_,++ -- * Checking environment variable match+ guardExpected,+ guardExpected_,++ -- * Checking environment variable predicate+ guardPredicate,+ guardPredicate_,+ )+where++import Control.Monad (void)+import Control.Monad.IO.Class (MonadIO (..))+import Data.Char (toLower)+import System.Environment (lookupEnv)++-- $setup+-- >>> import Data.Functor (($>))+-- >>> import System.Environment (setEnv)++-- | @'guardSet' var io@ runs @io@ iff+--+-- 1. The environment variable @var@ is set.+--+-- @+-- 'guardSet' var === 'guardPredicate' var ('const' 'True')+-- @+--+-- ==== __Examples__+--+-- >>> guardSet "NOT_SET" (putStrLn "ran io" $> True)+-- Nothing+--+-- >>> setEnv "SET" "foo"+-- >>> guardSet "SET" (putStrLn "ran io" $> True)+-- ran io+-- Just True+--+-- @since 0.1+guardSet :: MonadIO m => String -> m a -> m (Maybe a)+guardSet var = guardPredicate var (const True)++-- | Variant of 'guardSet' that ignores the return value.+--+-- @since 0.1+guardSet_ :: MonadIO m => String -> m a -> m ()+guardSet_ var = void . guardSet var++-- | @'guardExpected' var expected io@ runs @io@ iff+--+-- 1. The environment variable @var@ is set.+-- 2. @var@'s value equals @expected@. This is __case-insensitive__.+--+-- @+-- 'guardExpected' var expected === 'guardPredicate' var (\\a b -> 'fmap' 'toLower' a == 'fmap' 'toLower' b)+-- @+--+-- ==== __Examples__+--+-- >>> guardExpected "NOT_SET" "val" (putStrLn "ran io" $> True)+-- Nothing+--+-- >>> setEnv "WRONG_VAL" "good_val"+-- >>> guardExpected "WRONG_VAL" "bad_val" (putStrLn "ran io" $> True)+-- Nothing+--+-- >>> setEnv "WILL_RUN" "val"+-- >>> guardExpected "WILL_RUN" "VAL" (putStrLn "ran io" $> True)+-- ran io+-- Just True+--+-- @since 0.1+guardExpected :: MonadIO m => String -> String -> m a -> m (Maybe a)+guardExpected var expected = guardPredicate var (eqCaseInsensitive expected)++-- | Variant of 'guardExpected_' that ignores the return value.+--+-- @since 0.1+guardExpected_ :: MonadIO m => String -> String -> m a -> m ()+guardExpected_ var expected = void . guardExpected var expected++-- | Variant of 'guardPredicate' that ignores the return value.+--+-- @since 0.1+guardPredicate_ :: MonadIO m => String -> (String -> Bool) -> m a -> m ()+guardPredicate_ var p = void . guardPredicate var p++-- | This is the most general way to check an environment variable.+-- @'guardPredicate' var p io@ runs @io@ iff+--+-- 1. The environment variable @var@ is set.+-- 2. @var@'s value satisfies predicate @p@.+--+-- ==== __Examples__+--+-- >>> guardPredicate "NOT_SET" (const True) (putStrLn "ran io" $> True)+-- Nothing+--+-- >>> setEnv "CASE_WRONG" "VAL"+-- >>> guardPredicate "CASE_WRONG" (== "val") (putStrLn "ran io" $> True)+-- Nothing+--+-- >>> setEnv "WILL_RUN" "VAL"+-- >>> guardPredicate "WILL_RUN" (== "VAL") (putStrLn "ran io" $> True)+-- ran io+-- Just True+--+-- @since 0.1+guardPredicate :: MonadIO m => String -> (String -> Bool) -> m a -> m (Maybe a)+guardPredicate var p io =+ liftIO (lookupEnv var)+ >>= \case+ Just result | p result -> Just <$> io+ _ -> pure Nothing++eqCaseInsensitive :: String -> String -> Bool+eqCaseInsensitive a b = fmap toLower a == fmap toLower b
+ test/doctest/Main.hs view
@@ -0,0 +1,21 @@+module Main (main) where++import System.Environment (lookupEnv)+import Test.DocTest (doctest)+import Prelude++main :: IO ()+main = do+ shouldRun <- lookupEnv "RUN_DOCTEST"+ case shouldRun of+ Just _ -> doctest args+ _ -> putStrLn "*** Doctests Disabled ***"+ where+ args = files++files :: [String]+files =+ [ "-isrc",+ "src/System/Environment/Guard.hs",+ "src/System/Environment/Guard/Lifted.hs"+ ]