{-# 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 path = liftIO $ B.readFile path >>= parseConfiguration
parseConfiguration :: MonadThrow m
=> B.ByteString
-> m PtConfiguration
parseConfiguration = Y.decodeThrow
makeConfiguration :: MonadThrow m
=> PtConfiguration
-> m CtConfiguration
makeConfiguration pt = do
cRunMode <- lastOrError CkRunMode (cRunMode pt)
cSourcePaths <- lastOrError CkSourcePaths (cSourcePaths pt)
cExcludedPaths <- lastOrError CkExcludedPaths (cExcludedPaths pt)
cTemplateSource <- lastOrError CkTemplateSource (cTemplateSource pt)
cLicenseHeaders <- makeHeadersConfig (cLicenseHeaders pt)
cHeaderFnConfigs <- makeHeaderFnConfigs (cHeaderFnConfigs pt)
cVariables <- pure $ cVariables pt
pure Configuration { .. }
makeHeadersConfig :: MonadThrow m
=> PtHeadersConfig
-> m CtHeadersConfig
makeHeadersConfig pt = do
hscC <- makeHeaderConfig C (hscC pt)
hscCpp <- makeHeaderConfig CPP (hscCpp pt)
hscCss <- makeHeaderConfig CSS (hscCss pt)
hscHaskell <- makeHeaderConfig Haskell (hscHaskell pt)
hscHtml <- makeHeaderConfig HTML (hscHtml pt)
hscJava <- makeHeaderConfig Java (hscJava pt)
hscJs <- makeHeaderConfig JS (hscJs pt)
hscPureScript <- makeHeaderConfig PureScript (hscPureScript pt)
hscRust <- makeHeaderConfig Rust (hscRust pt)
hscScala <- makeHeaderConfig Scala (hscScala pt)
hscShell <- makeHeaderConfig Shell (hscShell pt)
pure HeadersConfig { .. }
makeHeaderConfig :: MonadThrow m
=> FileType
-> PtHeaderConfig
-> m CtHeaderConfig
makeHeaderConfig fileType pt = do
hcFileExtensions <- lastOrError (CkFileExtensions fileType)
(hcFileExtensions pt)
hcMarginAfter <- lastOrError (CkMarginAfter fileType) (hcMarginAfter pt)
hcMarginBefore <- lastOrError (CkMarginBefore fileType) (hcMarginBefore pt)
hcPutAfter <- lastOrError (CkPutAfter fileType) (hcPutAfter pt)
hcPutBefore <- lastOrError (CkPutBefore fileType) (hcPutBefore pt)
hcHeaderSyntax <- lastOrError (CkHeaderSyntax fileType) (hcHeaderSyntax pt)
pure HeaderConfig { .. }
makeHeaderFnConfigs :: MonadThrow m => PtHeaderFnConfigs -> m CtHeaderFnConfigs
makeHeaderFnConfigs pt = do
hfcsUpdateCopyright <- makeHeaderFnConfig (pt ^. hfcsUpdateCopyrightL)
makeUpdateCopyrightConfig
pure HeaderFnConfigs { .. }
makeHeaderFnConfig :: MonadThrow m
=> PtHeaderFnConfig c
-> (c 'Partial -> m (c 'Complete))
-> m (CtHeaderFnConfig c)
makeHeaderFnConfig pt fn = do
hfcEnabled <- lastOrError CkEnabled (pt ^. hfcEnabledL)
hfcConfig <- fn $ pt ^. hfcConfigL
pure HeaderFnConfig { .. }
makeUpdateCopyrightConfig :: MonadThrow m
=> PtUpdateCopyrightConfig
-> m CtUpdateCopyrightConfig
makeUpdateCopyrightConfig pt = do
let uccSelectedAuthors = lastOrNothing $ pt ^. uccSelectedAuthorsL
pure UpdateCopyrightConfig { .. }
lastOrError :: MonadThrow m => ConfigurationKey -> Last a -> m a
lastOrError key (Last a) = maybe (throwM $ MissingConfiguration key) pure a
lastOrNothing :: Last (Maybe a) -> Maybe a
lastOrNothing (Last a) = fromMaybe Nothing a