{-# LANGUAGE DataKinds #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE TemplateHaskell #-}
module Headroom.Configuration
(
loadConfiguration
, parseConfiguration
, makeConfiguration
, makeHeadersConfig
, makeHeaderConfig
)
where
import Data.Monoid ( Last(..) )
import qualified Data.Yaml as Y
import Headroom.Configuration.Types ( Configuration(..)
, ConfigurationError(..)
, ConfigurationKey(..)
, CtConfiguration
, CtHeaderConfig
, CtHeaderFnConfig
, CtHeaderFnConfigs
, CtHeadersConfig
, CtUpdateCopyrightConfig
, HeaderConfig(..)
, HeaderFnConfig(..)
, HeaderFnConfigs(..)
, HeadersConfig(..)
, Phase(..)
, PtConfiguration
, PtHeaderConfig
, PtHeaderFnConfig
, PtHeaderFnConfigs
, PtHeadersConfig
, PtUpdateCopyrightConfig
, UpdateCopyrightConfig(..)
)
import Headroom.Data.Lens ( suffixLenses )
import Headroom.FileType.Types ( FileType(..) )
import RIO
import qualified RIO.ByteString as B
suffixLenses ''HeaderFnConfig
suffixLenses ''HeaderFnConfigs
suffixLenses ''UpdateCopyrightConfig
loadConfiguration :: MonadIO m
=> FilePath
-> m PtConfiguration
loadConfiguration :: FilePath -> m PtConfiguration
loadConfiguration FilePath
path = IO PtConfiguration -> m PtConfiguration
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO PtConfiguration -> m PtConfiguration)
-> IO PtConfiguration -> m PtConfiguration
forall a b. (a -> b) -> a -> b
$ FilePath -> IO ByteString
forall (m :: * -> *). MonadIO m => FilePath -> m ByteString
B.readFile FilePath
path IO ByteString
-> (ByteString -> IO PtConfiguration) -> IO PtConfiguration
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ByteString -> IO PtConfiguration
forall (m :: * -> *).
MonadThrow m =>
ByteString -> m PtConfiguration
parseConfiguration
parseConfiguration :: MonadThrow m
=> B.ByteString
-> m PtConfiguration
parseConfiguration :: ByteString -> m PtConfiguration
parseConfiguration = ByteString -> m PtConfiguration
forall (m :: * -> *) a.
(MonadThrow m, FromJSON a) =>
ByteString -> m a
Y.decodeThrow
makeConfiguration :: MonadThrow m
=> PtConfiguration
-> m CtConfiguration
makeConfiguration :: PtConfiguration -> m CtConfiguration
makeConfiguration PtConfiguration
pt = do
RunMode
cRunMode <- ConfigurationKey -> Last RunMode -> m RunMode
forall (m :: * -> *) a.
MonadThrow m =>
ConfigurationKey -> Last a -> m a
lastOrError ConfigurationKey
CkRunMode (PtConfiguration -> 'Partial ::: RunMode
forall (p :: Phase). Configuration p -> p ::: RunMode
cRunMode PtConfiguration
pt)
[FilePath]
cSourcePaths <- ConfigurationKey -> Last [FilePath] -> m [FilePath]
forall (m :: * -> *) a.
MonadThrow m =>
ConfigurationKey -> Last a -> m a
lastOrError ConfigurationKey
CkSourcePaths (PtConfiguration -> 'Partial ::: [FilePath]
forall (p :: Phase). Configuration p -> p ::: [FilePath]
cSourcePaths PtConfiguration
pt)
[Regex]
cExcludedPaths <- ConfigurationKey -> Last [Regex] -> m [Regex]
forall (m :: * -> *) a.
MonadThrow m =>
ConfigurationKey -> Last a -> m a
lastOrError ConfigurationKey
CkExcludedPaths (PtConfiguration -> 'Partial ::: [Regex]
forall (p :: Phase). Configuration p -> p ::: [Regex]
cExcludedPaths PtConfiguration
pt)
TemplateSource
cTemplateSource <- ConfigurationKey -> Last TemplateSource -> m TemplateSource
forall (m :: * -> *) a.
MonadThrow m =>
ConfigurationKey -> Last a -> m a
lastOrError ConfigurationKey
CkTemplateSource (PtConfiguration -> 'Partial ::: TemplateSource
forall (p :: Phase). Configuration p -> p ::: TemplateSource
cTemplateSource PtConfiguration
pt)
CtHeadersConfig
cLicenseHeaders <- PtHeadersConfig -> m CtHeadersConfig
forall (m :: * -> *).
MonadThrow m =>
PtHeadersConfig -> m CtHeadersConfig
makeHeadersConfig (PtConfiguration -> PtHeadersConfig
forall (p :: Phase). Configuration p -> HeadersConfig p
cLicenseHeaders PtConfiguration
pt)
CtHeaderFnConfigs
cHeaderFnConfigs <- PtHeaderFnConfigs -> m CtHeaderFnConfigs
forall (m :: * -> *).
MonadThrow m =>
PtHeaderFnConfigs -> m CtHeaderFnConfigs
makeHeaderFnConfigs (PtConfiguration -> PtHeaderFnConfigs
forall (p :: Phase). Configuration p -> HeaderFnConfigs p
cHeaderFnConfigs PtConfiguration
pt)
Variables
cVariables <- Variables -> m Variables
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Variables -> m Variables) -> Variables -> m Variables
forall a b. (a -> b) -> a -> b
$ PtConfiguration -> Variables
forall (p :: Phase). Configuration p -> Variables
cVariables PtConfiguration
pt
CtConfiguration -> m CtConfiguration
forall (f :: * -> *) a. Applicative f => a -> f a
pure Configuration :: forall (p :: Phase).
(p ::: RunMode)
-> (p ::: [FilePath])
-> (p ::: [Regex])
-> (p ::: TemplateSource)
-> Variables
-> HeadersConfig p
-> HeaderFnConfigs p
-> Configuration p
Configuration { [FilePath]
[Regex]
Variables
CtHeadersConfig
CtHeaderFnConfigs
TemplateSource
RunMode
'Complete ::: [FilePath]
'Complete ::: [Regex]
'Complete ::: TemplateSource
'Complete ::: RunMode
cVariables :: Variables
cVariables :: Variables
cHeaderFnConfigs :: CtHeaderFnConfigs
cHeaderFnConfigs :: CtHeaderFnConfigs
cLicenseHeaders :: CtHeadersConfig
cLicenseHeaders :: CtHeadersConfig
cTemplateSource :: 'Complete ::: TemplateSource
cTemplateSource :: TemplateSource
cExcludedPaths :: 'Complete ::: [Regex]
cExcludedPaths :: [Regex]
cSourcePaths :: 'Complete ::: [FilePath]
cSourcePaths :: [FilePath]
cRunMode :: 'Complete ::: RunMode
cRunMode :: RunMode
.. }
makeHeadersConfig :: MonadThrow m
=> PtHeadersConfig
-> m CtHeadersConfig
PtHeadersConfig
pt = do
CtHeaderConfig
hscC <- FileType -> PtHeaderConfig -> m CtHeaderConfig
forall (m :: * -> *).
MonadThrow m =>
FileType -> PtHeaderConfig -> m CtHeaderConfig
makeHeaderConfig FileType
C (PtHeadersConfig -> PtHeaderConfig
forall (p :: Phase). HeadersConfig p -> HeaderConfig p
hscC PtHeadersConfig
pt)
CtHeaderConfig
hscCpp <- FileType -> PtHeaderConfig -> m CtHeaderConfig
forall (m :: * -> *).
MonadThrow m =>
FileType -> PtHeaderConfig -> m CtHeaderConfig
makeHeaderConfig FileType
CPP (PtHeadersConfig -> PtHeaderConfig
forall (p :: Phase). HeadersConfig p -> HeaderConfig p
hscCpp PtHeadersConfig
pt)
CtHeaderConfig
hscCss <- FileType -> PtHeaderConfig -> m CtHeaderConfig
forall (m :: * -> *).
MonadThrow m =>
FileType -> PtHeaderConfig -> m CtHeaderConfig
makeHeaderConfig FileType
CSS (PtHeadersConfig -> PtHeaderConfig
forall (p :: Phase). HeadersConfig p -> HeaderConfig p
hscCss PtHeadersConfig
pt)
CtHeaderConfig
hscHaskell <- FileType -> PtHeaderConfig -> m CtHeaderConfig
forall (m :: * -> *).
MonadThrow m =>
FileType -> PtHeaderConfig -> m CtHeaderConfig
makeHeaderConfig FileType
Haskell (PtHeadersConfig -> PtHeaderConfig
forall (p :: Phase). HeadersConfig p -> HeaderConfig p
hscHaskell PtHeadersConfig
pt)
CtHeaderConfig
hscHtml <- FileType -> PtHeaderConfig -> m CtHeaderConfig
forall (m :: * -> *).
MonadThrow m =>
FileType -> PtHeaderConfig -> m CtHeaderConfig
makeHeaderConfig FileType
HTML (PtHeadersConfig -> PtHeaderConfig
forall (p :: Phase). HeadersConfig p -> HeaderConfig p
hscHtml PtHeadersConfig
pt)
CtHeaderConfig
hscJava <- FileType -> PtHeaderConfig -> m CtHeaderConfig
forall (m :: * -> *).
MonadThrow m =>
FileType -> PtHeaderConfig -> m CtHeaderConfig
makeHeaderConfig FileType
Java (PtHeadersConfig -> PtHeaderConfig
forall (p :: Phase). HeadersConfig p -> HeaderConfig p
hscJava PtHeadersConfig
pt)
CtHeaderConfig
hscJs <- FileType -> PtHeaderConfig -> m CtHeaderConfig
forall (m :: * -> *).
MonadThrow m =>
FileType -> PtHeaderConfig -> m CtHeaderConfig
makeHeaderConfig FileType
JS (PtHeadersConfig -> PtHeaderConfig
forall (p :: Phase). HeadersConfig p -> HeaderConfig p
hscJs PtHeadersConfig
pt)
CtHeaderConfig
hscPureScript <- FileType -> PtHeaderConfig -> m CtHeaderConfig
forall (m :: * -> *).
MonadThrow m =>
FileType -> PtHeaderConfig -> m CtHeaderConfig
makeHeaderConfig FileType
PureScript (PtHeadersConfig -> PtHeaderConfig
forall (p :: Phase). HeadersConfig p -> HeaderConfig p
hscPureScript PtHeadersConfig
pt)
CtHeaderConfig
hscRust <- FileType -> PtHeaderConfig -> m CtHeaderConfig
forall (m :: * -> *).
MonadThrow m =>
FileType -> PtHeaderConfig -> m CtHeaderConfig
makeHeaderConfig FileType
Rust (PtHeadersConfig -> PtHeaderConfig
forall (p :: Phase). HeadersConfig p -> HeaderConfig p
hscRust PtHeadersConfig
pt)
CtHeaderConfig
hscScala <- FileType -> PtHeaderConfig -> m CtHeaderConfig
forall (m :: * -> *).
MonadThrow m =>
FileType -> PtHeaderConfig -> m CtHeaderConfig
makeHeaderConfig FileType
Scala (PtHeadersConfig -> PtHeaderConfig
forall (p :: Phase). HeadersConfig p -> HeaderConfig p
hscScala PtHeadersConfig
pt)
CtHeaderConfig
hscShell <- FileType -> PtHeaderConfig -> m CtHeaderConfig
forall (m :: * -> *).
MonadThrow m =>
FileType -> PtHeaderConfig -> m CtHeaderConfig
makeHeaderConfig FileType
Shell (PtHeadersConfig -> PtHeaderConfig
forall (p :: Phase). HeadersConfig p -> HeaderConfig p
hscShell PtHeadersConfig
pt)
CtHeadersConfig -> m CtHeadersConfig
forall (f :: * -> *) a. Applicative f => a -> f a
pure HeadersConfig :: forall (p :: Phase).
HeaderConfig p
-> HeaderConfig p
-> HeaderConfig p
-> HeaderConfig p
-> HeaderConfig p
-> HeaderConfig p
-> HeaderConfig p
-> HeaderConfig p
-> HeaderConfig p
-> HeaderConfig p
-> HeaderConfig p
-> HeadersConfig p
HeadersConfig { CtHeaderConfig
hscShell :: CtHeaderConfig
hscShell :: CtHeaderConfig
hscScala :: CtHeaderConfig
hscScala :: CtHeaderConfig
hscRust :: CtHeaderConfig
hscRust :: CtHeaderConfig
hscPureScript :: CtHeaderConfig
hscPureScript :: CtHeaderConfig
hscJs :: CtHeaderConfig
hscJs :: CtHeaderConfig
hscJava :: CtHeaderConfig
hscJava :: CtHeaderConfig
hscHtml :: CtHeaderConfig
hscHtml :: CtHeaderConfig
hscHaskell :: CtHeaderConfig
hscHaskell :: CtHeaderConfig
hscCss :: CtHeaderConfig
hscCss :: CtHeaderConfig
hscCpp :: CtHeaderConfig
hscCpp :: CtHeaderConfig
hscC :: CtHeaderConfig
hscC :: CtHeaderConfig
.. }
makeHeaderConfig :: MonadThrow m
=> FileType
-> PtHeaderConfig
-> m CtHeaderConfig
FileType
fileType PtHeaderConfig
pt = do
[Text]
hcFileExtensions <- ConfigurationKey -> Last [Text] -> m [Text]
forall (m :: * -> *) a.
MonadThrow m =>
ConfigurationKey -> Last a -> m a
lastOrError (FileType -> ConfigurationKey
CkFileExtensions FileType
fileType)
(PtHeaderConfig -> 'Partial ::: [Text]
forall (p :: Phase). HeaderConfig p -> p ::: [Text]
hcFileExtensions PtHeaderConfig
pt)
Int
hcMarginAfter <- ConfigurationKey -> Last Int -> m Int
forall (m :: * -> *) a.
MonadThrow m =>
ConfigurationKey -> Last a -> m a
lastOrError (FileType -> ConfigurationKey
CkMarginAfter FileType
fileType) (PtHeaderConfig -> 'Partial ::: Int
forall (p :: Phase). HeaderConfig p -> p ::: Int
hcMarginAfter PtHeaderConfig
pt)
Int
hcMarginBefore <- ConfigurationKey -> Last Int -> m Int
forall (m :: * -> *) a.
MonadThrow m =>
ConfigurationKey -> Last a -> m a
lastOrError (FileType -> ConfigurationKey
CkMarginBefore FileType
fileType) (PtHeaderConfig -> 'Partial ::: Int
forall (p :: Phase). HeaderConfig p -> p ::: Int
hcMarginBefore PtHeaderConfig
pt)
[Regex]
hcPutAfter <- ConfigurationKey -> Last [Regex] -> m [Regex]
forall (m :: * -> *) a.
MonadThrow m =>
ConfigurationKey -> Last a -> m a
lastOrError (FileType -> ConfigurationKey
CkPutAfter FileType
fileType) (PtHeaderConfig -> 'Partial ::: [Regex]
forall (p :: Phase). HeaderConfig p -> p ::: [Regex]
hcPutAfter PtHeaderConfig
pt)
[Regex]
hcPutBefore <- ConfigurationKey -> Last [Regex] -> m [Regex]
forall (m :: * -> *) a.
MonadThrow m =>
ConfigurationKey -> Last a -> m a
lastOrError (FileType -> ConfigurationKey
CkPutBefore FileType
fileType) (PtHeaderConfig -> 'Partial ::: [Regex]
forall (p :: Phase). HeaderConfig p -> p ::: [Regex]
hcPutBefore PtHeaderConfig
pt)
HeaderSyntax
hcHeaderSyntax <- ConfigurationKey -> Last HeaderSyntax -> m HeaderSyntax
forall (m :: * -> *) a.
MonadThrow m =>
ConfigurationKey -> Last a -> m a
lastOrError (FileType -> ConfigurationKey
CkHeaderSyntax FileType
fileType) (PtHeaderConfig -> 'Partial ::: HeaderSyntax
forall (p :: Phase). HeaderConfig p -> p ::: HeaderSyntax
hcHeaderSyntax PtHeaderConfig
pt)
CtHeaderConfig -> m CtHeaderConfig
forall (f :: * -> *) a. Applicative f => a -> f a
pure HeaderConfig :: forall (p :: Phase).
(p ::: [Text])
-> (p ::: Int)
-> (p ::: Int)
-> (p ::: [Regex])
-> (p ::: [Regex])
-> (p ::: HeaderSyntax)
-> HeaderConfig p
HeaderConfig { Int
[Text]
[Regex]
HeaderSyntax
'Complete ::: Int
'Complete ::: [Text]
'Complete ::: [Regex]
'Complete ::: HeaderSyntax
hcHeaderSyntax :: 'Complete ::: HeaderSyntax
hcHeaderSyntax :: HeaderSyntax
hcPutBefore :: 'Complete ::: [Regex]
hcPutBefore :: [Regex]
hcPutAfter :: 'Complete ::: [Regex]
hcPutAfter :: [Regex]
hcMarginBefore :: 'Complete ::: Int
hcMarginBefore :: Int
hcMarginAfter :: 'Complete ::: Int
hcMarginAfter :: Int
hcFileExtensions :: 'Complete ::: [Text]
hcFileExtensions :: [Text]
.. }
makeHeaderFnConfigs :: MonadThrow m => PtHeaderFnConfigs -> m CtHeaderFnConfigs
PtHeaderFnConfigs
pt = do
CtHeaderFnConfig UpdateCopyrightConfig
hfcsUpdateCopyright <- PtHeaderFnConfig UpdateCopyrightConfig
-> (UpdateCopyrightConfig 'Partial
-> m (UpdateCopyrightConfig 'Complete))
-> m (CtHeaderFnConfig UpdateCopyrightConfig)
forall (m :: * -> *) (c :: Phase -> *).
MonadThrow m =>
PtHeaderFnConfig c
-> (c 'Partial -> m (c 'Complete)) -> m (CtHeaderFnConfig c)
makeHeaderFnConfig (PtHeaderFnConfigs
pt PtHeaderFnConfigs
-> Getting
(PtHeaderFnConfig UpdateCopyrightConfig)
PtHeaderFnConfigs
(PtHeaderFnConfig UpdateCopyrightConfig)
-> PtHeaderFnConfig UpdateCopyrightConfig
forall s a. s -> Getting a s a -> a
^. Getting
(PtHeaderFnConfig UpdateCopyrightConfig)
PtHeaderFnConfigs
(PtHeaderFnConfig UpdateCopyrightConfig)
forall (p :: Phase) (p :: Phase).
Lens
(HeaderFnConfigs p)
(HeaderFnConfigs p)
(HeaderFnConfig p UpdateCopyrightConfig)
(HeaderFnConfig p UpdateCopyrightConfig)
hfcsUpdateCopyrightL)
UpdateCopyrightConfig 'Partial
-> m (UpdateCopyrightConfig 'Complete)
forall (m :: * -> *).
MonadThrow m =>
UpdateCopyrightConfig 'Partial
-> m (UpdateCopyrightConfig 'Complete)
makeUpdateCopyrightConfig
CtHeaderFnConfigs -> m CtHeaderFnConfigs
forall (f :: * -> *) a. Applicative f => a -> f a
pure HeaderFnConfigs :: forall (p :: Phase).
HeaderFnConfig p UpdateCopyrightConfig -> HeaderFnConfigs p
HeaderFnConfigs { CtHeaderFnConfig UpdateCopyrightConfig
hfcsUpdateCopyright :: CtHeaderFnConfig UpdateCopyrightConfig
hfcsUpdateCopyright :: CtHeaderFnConfig UpdateCopyrightConfig
.. }
makeHeaderFnConfig :: MonadThrow m
=> PtHeaderFnConfig c
-> (c 'Partial -> m (c 'Complete))
-> m (CtHeaderFnConfig c)
PtHeaderFnConfig c
pt c 'Partial -> m (c 'Complete)
fn = do
Bool
hfcEnabled <- ConfigurationKey -> Last Bool -> m Bool
forall (m :: * -> *) a.
MonadThrow m =>
ConfigurationKey -> Last a -> m a
lastOrError ConfigurationKey
CkEnabled (PtHeaderFnConfig c
pt PtHeaderFnConfig c
-> Getting (Last Bool) (PtHeaderFnConfig c) (Last Bool)
-> Last Bool
forall s a. s -> Getting a s a -> a
^. Getting (Last Bool) (PtHeaderFnConfig c) (Last Bool)
forall (p :: Phase) (c :: Phase -> *).
Lens' (HeaderFnConfig p c) (p ::: Bool)
hfcEnabledL)
c 'Complete
hfcConfig <- c 'Partial -> m (c 'Complete)
fn (c 'Partial -> m (c 'Complete)) -> c 'Partial -> m (c 'Complete)
forall a b. (a -> b) -> a -> b
$ PtHeaderFnConfig c
pt PtHeaderFnConfig c
-> Getting (c 'Partial) (PtHeaderFnConfig c) (c 'Partial)
-> c 'Partial
forall s a. s -> Getting a s a -> a
^. Getting (c 'Partial) (PtHeaderFnConfig c) (c 'Partial)
forall (p :: Phase) (c :: Phase -> *) (c :: Phase -> *).
Lens (HeaderFnConfig p c) (HeaderFnConfig p c) (c p) (c p)
hfcConfigL
CtHeaderFnConfig c -> m (CtHeaderFnConfig c)
forall (f :: * -> *) a. Applicative f => a -> f a
pure HeaderFnConfig :: forall (p :: Phase) (c :: Phase -> *).
(p ::: Bool) -> c p -> HeaderFnConfig p c
HeaderFnConfig { c 'Complete
Bool
'Complete ::: Bool
hfcConfig :: c 'Complete
hfcEnabled :: 'Complete ::: Bool
hfcConfig :: c 'Complete
hfcEnabled :: Bool
.. }
makeUpdateCopyrightConfig :: MonadThrow m
=> PtUpdateCopyrightConfig
-> m CtUpdateCopyrightConfig
makeUpdateCopyrightConfig :: UpdateCopyrightConfig 'Partial
-> m (UpdateCopyrightConfig 'Complete)
makeUpdateCopyrightConfig UpdateCopyrightConfig 'Partial
pt = do
let uccSelectedAuthors :: Maybe (NonEmpty Text)
uccSelectedAuthors = Last (Maybe (NonEmpty Text)) -> Maybe (NonEmpty Text)
forall a. Last (Maybe a) -> Maybe a
lastOrNothing (Last (Maybe (NonEmpty Text)) -> Maybe (NonEmpty Text))
-> Last (Maybe (NonEmpty Text)) -> Maybe (NonEmpty Text)
forall a b. (a -> b) -> a -> b
$ UpdateCopyrightConfig 'Partial
pt UpdateCopyrightConfig 'Partial
-> Getting
(Last (Maybe (NonEmpty Text)))
(UpdateCopyrightConfig 'Partial)
(Last (Maybe (NonEmpty Text)))
-> Last (Maybe (NonEmpty Text))
forall s a. s -> Getting a s a -> a
^. Getting
(Last (Maybe (NonEmpty Text)))
(UpdateCopyrightConfig 'Partial)
(Last (Maybe (NonEmpty Text)))
forall (p :: Phase) (p :: Phase).
Lens
(UpdateCopyrightConfig p)
(UpdateCopyrightConfig p)
(p ::: Maybe (NonEmpty Text))
(p ::: Maybe (NonEmpty Text))
uccSelectedAuthorsL
UpdateCopyrightConfig 'Complete
-> m (UpdateCopyrightConfig 'Complete)
forall (f :: * -> *) a. Applicative f => a -> f a
pure UpdateCopyrightConfig :: forall (p :: Phase).
(p ::: Maybe (NonEmpty Text)) -> UpdateCopyrightConfig p
UpdateCopyrightConfig { Maybe (NonEmpty Text)
'Complete ::: Maybe (NonEmpty Text)
uccSelectedAuthors :: 'Complete ::: Maybe (NonEmpty Text)
uccSelectedAuthors :: Maybe (NonEmpty Text)
.. }
lastOrError :: MonadThrow m => ConfigurationKey -> Last a -> m a
lastOrError :: ConfigurationKey -> Last a -> m a
lastOrError ConfigurationKey
key (Last Maybe a
a) = m a -> (a -> m a) -> Maybe a -> m a
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (ConfigurationError -> m a
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM (ConfigurationError -> m a) -> ConfigurationError -> m a
forall a b. (a -> b) -> a -> b
$ ConfigurationKey -> ConfigurationError
MissingConfiguration ConfigurationKey
key) a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe a
a
lastOrNothing :: Last (Maybe a) -> Maybe a
lastOrNothing :: Last (Maybe a) -> Maybe a
lastOrNothing (Last Maybe (Maybe a)
a) = Maybe a -> Maybe (Maybe a) -> Maybe a
forall a. a -> Maybe a -> a
fromMaybe Maybe a
forall a. Maybe a
Nothing Maybe (Maybe a)
a