{-# LANGUAGE DataKinds         #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards   #-}
{-# LANGUAGE TemplateHaskell   #-}

{-|
Module      : Headroom.Config
Description : Configuration handling (loading, parsing, validating)
Copyright   : (c) 2019-2022 Vaclav Svejcar
License     : BSD-3-Clause
Maintainer  : vaclav.svejcar@gmail.com
Stability   : experimental
Portability : POSIX

This module provides logic for working with the cofiguration data types.
Headroom uses the
<https://medium.com/@jonathangfischoff/the-partial-options-monoid-pattern-31914a71fc67 partial options monoid>
pattern for the configuration.
-}

module Headroom.Config
  ( -- * Loading & Parsing Configuration
    loadAppConfig
  , parseAppConfig
    -- * Processing Partial Configuration
  , makeAppConfig
  , makeHeadersConfig
  , makeHeaderConfig
  )
where

import           Data.Monoid                         ( Last(..) )
import qualified Data.Yaml                          as Y
import           Headroom.Config.Compat              ( checkCompatibility )
import           Headroom.Config.Types               ( AppConfig(..)
                                                     , ConfigurationError(..)
                                                     , ConfigurationKey(..)
                                                     , CtAppConfig
                                                     , CtHeaderConfig
                                                     , CtHeadersConfig
                                                     , CtPostProcessConfig
                                                     , CtPostProcessConfigs
                                                     , CtUpdateCopyrightConfig
                                                     , HeaderConfig(..)
                                                     , HeadersConfig(..)
                                                     , Phase(..)
                                                     , PostProcessConfig(..)
                                                     , PostProcessConfigs(..)
                                                     , PtAppConfig
                                                     , PtHeaderConfig
                                                     , PtHeadersConfig
                                                     , PtPostProcessConfig
                                                     , PtPostProcessConfigs
                                                     , PtUpdateCopyrightConfig
                                                     , UpdateCopyrightConfig(..)
                                                     )
import           Headroom.Data.Lens                  ( suffixLenses )
import           Headroom.FileType.Types             ( FileType(..) )
import           Headroom.Meta                       ( buildVersion
                                                     , configBreakingChanges
                                                     )
import           RIO
import qualified RIO.ByteString                     as B


suffixLenses ''PostProcessConfig
suffixLenses ''PostProcessConfigs
suffixLenses ''UpdateCopyrightConfig


------------------------------  PUBLIC FUNCTIONS  ------------------------------

-- | Loads and parses application configuration from given /YAML/ file.
loadAppConfig :: (MonadIO m, MonadThrow m) => FilePath -> m PtAppConfig
loadAppConfig :: FilePath -> m PtAppConfig
loadAppConfig FilePath
path = do
  ByteString
content <- IO ByteString -> m ByteString
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO ByteString -> m ByteString) -> IO ByteString -> m ByteString
forall a b. (a -> b) -> a -> b
$ FilePath -> IO ByteString
forall (m :: * -> *). MonadIO m => FilePath -> m ByteString
B.readFile FilePath
path
  Version
_       <- [Version] -> Version -> ByteString -> m Version
forall (m :: * -> *).
MonadThrow m =>
[Version] -> Version -> ByteString -> m Version
checkCompatibility [Version]
configBreakingChanges Version
buildVersion ByteString
content
  ByteString -> m PtAppConfig
forall (m :: * -> *). MonadThrow m => ByteString -> m PtAppConfig
parseAppConfig ByteString
content


-- | Parses application configuration from given raw input in /YAML/ format.
parseAppConfig :: MonadThrow m
               => ByteString    -- ^ raw input to parse
               -> m PtAppConfig -- ^ parsed application configuration
parseAppConfig :: ByteString -> m PtAppConfig
parseAppConfig = ByteString -> m PtAppConfig
forall (m :: * -> *) a.
(MonadThrow m, FromJSON a) =>
ByteString -> m a
Y.decodeThrow


-- | Makes full 'CtAppConfig' from provided 'PtAppConfig' (if valid).
makeAppConfig :: MonadThrow m
              => PtAppConfig   -- ^ source 'PtAppConfig'
              -> m CtAppConfig -- ^ full 'CtAppConfig'
makeAppConfig :: PtAppConfig -> m CtAppConfig
makeAppConfig PtAppConfig
pt = do
  RunMode
acRunMode             <- ConfigurationKey -> Last RunMode -> m RunMode
forall (m :: * -> *) a.
MonadThrow m =>
ConfigurationKey -> Last a -> m a
lastOrError ConfigurationKey
CkRunMode (PtAppConfig -> 'Partial ::: RunMode
forall (p :: Phase). AppConfig p -> p ::: RunMode
acRunMode PtAppConfig
pt)
  [FilePath]
acSourcePaths         <- ConfigurationKey -> Last [FilePath] -> m [FilePath]
forall (m :: * -> *) a.
MonadThrow m =>
ConfigurationKey -> Last a -> m a
lastOrError ConfigurationKey
CkSourcePaths (PtAppConfig -> 'Partial ::: [FilePath]
forall (p :: Phase). AppConfig p -> p ::: [FilePath]
acSourcePaths PtAppConfig
pt)
  [Regex]
acExcludedPaths       <- ConfigurationKey -> Last [Regex] -> m [Regex]
forall (m :: * -> *) a.
MonadThrow m =>
ConfigurationKey -> Last a -> m a
lastOrError ConfigurationKey
CkExcludedPaths (PtAppConfig -> 'Partial ::: [Regex]
forall (p :: Phase). AppConfig p -> p ::: [Regex]
acExcludedPaths PtAppConfig
pt)
  Bool
acExcludeIgnoredPaths <- ConfigurationKey -> Last Bool -> m Bool
forall (m :: * -> *) a.
MonadThrow m =>
ConfigurationKey -> Last a -> m a
lastOrError ConfigurationKey
CkExcludeIgnoredPaths
                                       (PtAppConfig -> 'Partial ::: Bool
forall (p :: Phase). AppConfig p -> p ::: Bool
acExcludeIgnoredPaths PtAppConfig
pt)
  Maybe LicenseType
acBuiltInTemplates   <- ConfigurationKey
-> Last (Maybe LicenseType) -> m (Maybe LicenseType)
forall (m :: * -> *) a.
MonadThrow m =>
ConfigurationKey -> Last a -> m a
lastOrError ConfigurationKey
CkBuiltInTemplates (PtAppConfig -> 'Partial ::: Maybe LicenseType
forall (p :: Phase). AppConfig p -> p ::: Maybe LicenseType
acBuiltInTemplates PtAppConfig
pt)
  [TemplateRef]
acTemplateRefs       <- [TemplateRef] -> m [TemplateRef]
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([TemplateRef] -> m [TemplateRef])
-> [TemplateRef] -> m [TemplateRef]
forall a b. (a -> b) -> a -> b
$ PtAppConfig -> [TemplateRef]
forall (p :: Phase). AppConfig p -> [TemplateRef]
acTemplateRefs PtAppConfig
pt
  CtHeadersConfig
acLicenseHeaders     <- PtHeadersConfig -> m CtHeadersConfig
forall (m :: * -> *).
MonadThrow m =>
PtHeadersConfig -> m CtHeadersConfig
makeHeadersConfig (PtAppConfig -> PtHeadersConfig
forall (p :: Phase). AppConfig p -> HeadersConfig p
acLicenseHeaders PtAppConfig
pt)
  CtPostProcessConfigs
acPostProcessConfigs <- PtPostProcessConfigs -> m CtPostProcessConfigs
forall (m :: * -> *).
MonadThrow m =>
PtPostProcessConfigs -> m CtPostProcessConfigs
makePostProcessConfigs (PtAppConfig -> PtPostProcessConfigs
forall (p :: Phase). AppConfig p -> PostProcessConfigs p
acPostProcessConfigs PtAppConfig
pt)
  Variables
acVariables          <- 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
$ PtAppConfig -> Variables
forall (p :: Phase). AppConfig p -> Variables
acVariables PtAppConfig
pt
  CtAppConfig -> m CtAppConfig
forall (f :: * -> *) a. Applicative f => a -> f a
pure AppConfig :: forall (p :: Phase).
(p ::: RunMode)
-> (p ::: [FilePath])
-> (p ::: [Regex])
-> (p ::: Bool)
-> (p ::: Maybe LicenseType)
-> [TemplateRef]
-> Variables
-> HeadersConfig p
-> PostProcessConfigs p
-> AppConfig p
AppConfig { Bool
[FilePath]
[Regex]
[TemplateRef]
Maybe LicenseType
Variables
CtHeadersConfig
CtPostProcessConfigs
RunMode
'Complete ::: Bool
'Complete ::: [FilePath]
'Complete ::: [Regex]
'Complete ::: Maybe LicenseType
'Complete ::: RunMode
acVariables :: Variables
acVariables :: Variables
acPostProcessConfigs :: CtPostProcessConfigs
acPostProcessConfigs :: CtPostProcessConfigs
acLicenseHeaders :: CtHeadersConfig
acLicenseHeaders :: CtHeadersConfig
acTemplateRefs :: [TemplateRef]
acTemplateRefs :: [TemplateRef]
acBuiltInTemplates :: 'Complete ::: Maybe LicenseType
acBuiltInTemplates :: Maybe LicenseType
acExcludeIgnoredPaths :: 'Complete ::: Bool
acExcludeIgnoredPaths :: Bool
acExcludedPaths :: 'Complete ::: [Regex]
acExcludedPaths :: [Regex]
acSourcePaths :: 'Complete ::: [FilePath]
acSourcePaths :: [FilePath]
acRunMode :: 'Complete ::: RunMode
acRunMode :: RunMode
.. }


-- | Makes full 'CtHeadersConfig' from provided 'PtHeadersConfig' (if valid).
makeHeadersConfig :: MonadThrow m
                  => PtHeadersConfig   -- ^ source 'PtHeadersConfig'
                  -> m CtHeadersConfig -- ^ full 'CtHeadersConfig'
makeHeadersConfig :: PtHeadersConfig -> m CtHeadersConfig
makeHeadersConfig 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
hscDart       <- FileType -> PtHeaderConfig -> m CtHeaderConfig
forall (m :: * -> *).
MonadThrow m =>
FileType -> PtHeaderConfig -> m CtHeaderConfig
makeHeaderConfig FileType
Dart (PtHeadersConfig -> PtHeaderConfig
forall (p :: Phase). HeadersConfig p -> HeaderConfig p
hscDart PtHeadersConfig
pt)
  CtHeaderConfig
hscGo         <- FileType -> PtHeaderConfig -> m CtHeaderConfig
forall (m :: * -> *).
MonadThrow m =>
FileType -> PtHeaderConfig -> m CtHeaderConfig
makeHeaderConfig FileType
Go (PtHeadersConfig -> PtHeaderConfig
forall (p :: Phase). HeadersConfig p -> HeaderConfig p
hscGo 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
hscKotlin     <- FileType -> PtHeaderConfig -> m CtHeaderConfig
forall (m :: * -> *).
MonadThrow m =>
FileType -> PtHeaderConfig -> m CtHeaderConfig
makeHeaderConfig FileType
Kotlin (PtHeadersConfig -> PtHeaderConfig
forall (p :: Phase). HeadersConfig p -> HeaderConfig p
hscKotlin PtHeadersConfig
pt)
  CtHeaderConfig
hscPhp        <- FileType -> PtHeaderConfig -> m CtHeaderConfig
forall (m :: * -> *).
MonadThrow m =>
FileType -> PtHeaderConfig -> m CtHeaderConfig
makeHeaderConfig FileType
PHP (PtHeadersConfig -> PtHeaderConfig
forall (p :: Phase). HeadersConfig p -> HeaderConfig p
hscPhp 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
-> 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
hscPhp :: CtHeaderConfig
hscPhp :: CtHeaderConfig
hscKotlin :: CtHeaderConfig
hscKotlin :: CtHeaderConfig
hscJs :: CtHeaderConfig
hscJs :: CtHeaderConfig
hscJava :: CtHeaderConfig
hscJava :: CtHeaderConfig
hscHtml :: CtHeaderConfig
hscHtml :: CtHeaderConfig
hscHaskell :: CtHeaderConfig
hscHaskell :: CtHeaderConfig
hscGo :: CtHeaderConfig
hscGo :: CtHeaderConfig
hscDart :: CtHeaderConfig
hscDart :: CtHeaderConfig
hscCss :: CtHeaderConfig
hscCss :: CtHeaderConfig
hscCpp :: CtHeaderConfig
hscCpp :: CtHeaderConfig
hscC :: CtHeaderConfig
hscC :: CtHeaderConfig
.. }


-- | Makes full 'CtHeaderConfig' from provided 'PtHeaderConfig' (if valid).
makeHeaderConfig :: MonadThrow m
                 => FileType         -- ^ determines file type of configuration
                 -> PtHeaderConfig   -- ^ source 'PtHeaderConfig'
                 -> m CtHeaderConfig -- ^ full 'CtHeaderConfig'
makeHeaderConfig :: FileType -> PtHeaderConfig -> m CtHeaderConfig
makeHeaderConfig 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
hcMarginTopCode <- ConfigurationKey -> Last Int -> m Int
forall (m :: * -> *) a.
MonadThrow m =>
ConfigurationKey -> Last a -> m a
lastOrError (FileType -> ConfigurationKey
CkMarginTopCode FileType
fileType) (PtHeaderConfig -> 'Partial ::: Int
forall (p :: Phase). HeaderConfig p -> p ::: Int
hcMarginTopCode PtHeaderConfig
pt)
  Int
hcMarginTopFile <- ConfigurationKey -> Last Int -> m Int
forall (m :: * -> *) a.
MonadThrow m =>
ConfigurationKey -> Last a -> m a
lastOrError (FileType -> ConfigurationKey
CkMarginTopFile FileType
fileType) (PtHeaderConfig -> 'Partial ::: Int
forall (p :: Phase). HeaderConfig p -> p ::: Int
hcMarginTopFile PtHeaderConfig
pt)
  Int
hcMarginBottomCode <- ConfigurationKey -> Last Int -> m Int
forall (m :: * -> *) a.
MonadThrow m =>
ConfigurationKey -> Last a -> m a
lastOrError (FileType -> ConfigurationKey
CkMarginBottomCode FileType
fileType)
                                    (PtHeaderConfig -> 'Partial ::: Int
forall (p :: Phase). HeaderConfig p -> p ::: Int
hcMarginBottomCode PtHeaderConfig
pt)
  Int
hcMarginBottomFile <- ConfigurationKey -> Last Int -> m Int
forall (m :: * -> *) a.
MonadThrow m =>
ConfigurationKey -> Last a -> m a
lastOrError (FileType -> ConfigurationKey
CkMarginBottomFile FileType
fileType)
                                    (PtHeaderConfig -> 'Partial ::: Int
forall (p :: Phase). HeaderConfig p -> p ::: Int
hcMarginBottomFile 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 ::: 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]
hcMarginBottomFile :: 'Complete ::: Int
hcMarginBottomFile :: Int
hcMarginBottomCode :: 'Complete ::: Int
hcMarginBottomCode :: Int
hcMarginTopFile :: 'Complete ::: Int
hcMarginTopFile :: Int
hcMarginTopCode :: 'Complete ::: Int
hcMarginTopCode :: Int
hcFileExtensions :: 'Complete ::: [Text]
hcFileExtensions :: [Text]
.. }


------------------------------  PRIVATE FUNCTIONS  -----------------------------

makePostProcessConfigs :: MonadThrow m
                       => PtPostProcessConfigs
                       -> m CtPostProcessConfigs
makePostProcessConfigs :: PtPostProcessConfigs -> m CtPostProcessConfigs
makePostProcessConfigs PtPostProcessConfigs
pt = do
  CtPostProcessConfig UpdateCopyrightConfig
ppcsUpdateCopyright <- PtPostProcessConfig UpdateCopyrightConfig
-> (UpdateCopyrightConfig 'Partial
    -> m (UpdateCopyrightConfig 'Complete))
-> m (CtPostProcessConfig UpdateCopyrightConfig)
forall (m :: * -> *) (c :: Phase -> *).
MonadThrow m =>
PtPostProcessConfig c
-> (c 'Partial -> m (c 'Complete)) -> m (CtPostProcessConfig c)
makePostProcessConfig (PtPostProcessConfigs
pt PtPostProcessConfigs
-> Getting
     (PtPostProcessConfig UpdateCopyrightConfig)
     PtPostProcessConfigs
     (PtPostProcessConfig UpdateCopyrightConfig)
-> PtPostProcessConfig UpdateCopyrightConfig
forall s a. s -> Getting a s a -> a
^. Getting
  (PtPostProcessConfig UpdateCopyrightConfig)
  PtPostProcessConfigs
  (PtPostProcessConfig UpdateCopyrightConfig)
forall (p :: Phase) (p :: Phase).
Lens
  (PostProcessConfigs p)
  (PostProcessConfigs p)
  (PostProcessConfig p UpdateCopyrightConfig)
  (PostProcessConfig p UpdateCopyrightConfig)
ppcsUpdateCopyrightL)
                                               UpdateCopyrightConfig 'Partial
-> m (UpdateCopyrightConfig 'Complete)
forall (m :: * -> *).
MonadThrow m =>
UpdateCopyrightConfig 'Partial
-> m (UpdateCopyrightConfig 'Complete)
makeUpdateCopyrightConfig
  CtPostProcessConfigs -> m CtPostProcessConfigs
forall (f :: * -> *) a. Applicative f => a -> f a
pure PostProcessConfigs :: forall (p :: Phase).
PostProcessConfig p UpdateCopyrightConfig -> PostProcessConfigs p
PostProcessConfigs { CtPostProcessConfig UpdateCopyrightConfig
ppcsUpdateCopyright :: CtPostProcessConfig UpdateCopyrightConfig
ppcsUpdateCopyright :: CtPostProcessConfig UpdateCopyrightConfig
.. }


makePostProcessConfig :: MonadThrow m
                      => PtPostProcessConfig c
                      -> (c 'Partial -> m (c 'Complete))
                      -> m (CtPostProcessConfig c)
makePostProcessConfig :: PtPostProcessConfig c
-> (c 'Partial -> m (c 'Complete)) -> m (CtPostProcessConfig c)
makePostProcessConfig PtPostProcessConfig c
pt c 'Partial -> m (c 'Complete)
fn = do
  Bool
ppcEnabled <- ConfigurationKey -> Last Bool -> m Bool
forall (m :: * -> *) a.
MonadThrow m =>
ConfigurationKey -> Last a -> m a
lastOrError ConfigurationKey
CkEnabled (PtPostProcessConfig c
pt PtPostProcessConfig c
-> Getting (Last Bool) (PtPostProcessConfig c) (Last Bool)
-> Last Bool
forall s a. s -> Getting a s a -> a
^. Getting (Last Bool) (PtPostProcessConfig c) (Last Bool)
forall (p :: Phase) (c :: Phase -> *).
Lens' (PostProcessConfig p c) (p ::: Bool)
ppcEnabledL)
  c 'Complete
ppcConfig  <- c 'Partial -> m (c 'Complete)
fn (c 'Partial -> m (c 'Complete)) -> c 'Partial -> m (c 'Complete)
forall a b. (a -> b) -> a -> b
$ PtPostProcessConfig c
pt PtPostProcessConfig c
-> Getting (c 'Partial) (PtPostProcessConfig c) (c 'Partial)
-> c 'Partial
forall s a. s -> Getting a s a -> a
^. Getting (c 'Partial) (PtPostProcessConfig c) (c 'Partial)
forall (p :: Phase) (c :: Phase -> *) (c :: Phase -> *).
Lens (PostProcessConfig p c) (PostProcessConfig p c) (c p) (c p)
ppcConfigL
  CtPostProcessConfig c -> m (CtPostProcessConfig c)
forall (f :: * -> *) a. Applicative f => a -> f a
pure PostProcessConfig :: forall (p :: Phase) (c :: Phase -> *).
(p ::: Bool) -> c p -> PostProcessConfig p c
PostProcessConfig { c 'Complete
Bool
'Complete ::: Bool
ppcConfig :: c 'Complete
ppcEnabled :: 'Complete ::: Bool
ppcConfig :: c 'Complete
ppcEnabled :: 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