{-# LANGUAGE DataKinds            #-}
{-# LANGUAGE DeriveAnyClass       #-}
{-# LANGUAGE DeriveGeneric        #-}
{-# LANGUAGE FlexibleContexts     #-}
{-# LANGUAGE FlexibleInstances    #-}
{-# LANGUAGE LambdaCase           #-}
{-# LANGUAGE NoImplicitPrelude    #-}
{-# LANGUAGE OverloadedStrings    #-}
{-# LANGUAGE RecordWildCards      #-}
{-# LANGUAGE StandaloneDeriving   #-}
{-# LANGUAGE TemplateHaskell      #-}
{-# LANGUAGE TypeFamilies         #-}
{-# LANGUAGE TypeOperators        #-}
{-# LANGUAGE UndecidableInstances #-}

{-|
Module      : Headroom.Configuration.Types
Description : Data types for /Headroom/ configuration
Copyright   : (c) 2019-2020 Vaclav Svejcar
License     : BSD-3-Clause
Maintainer  : vaclav.svejcar@gmail.com
Stability   : experimental
Portability : POSIX

This module contains data types representing /Headroom/ configuration options.
Related logic is available in "Headroom.Configuration" module.

Data types related to /Headroom/ configuration uses the
<https://medium.com/@jonathangfischoff/the-partial-options-monoid-pattern-31914a71fc67 partial options monoid>
pattern, but instead of defining separate data type for each /phase/
(/partial/ or /complete/ configuration), the /phase/ is expressed by the 'Phase'
data type and related /closed type family/.
-}

module Headroom.Configuration.Types
  ( -- * Error Types
    ConfigurationError(..)
  , ConfigurationKey(..)
    -- * Type Families
  , Phase(..)
  , (:::)
    -- * Data Types
    -- ** Top Level Configuration
  , Configuration(..)
  , CtConfiguration
  , PtConfiguration
  , HeadersConfig(..)
  , CtHeadersConfig
  , PtHeadersConfig
  , HeaderConfig(..)
  , CtHeaderConfig
  , PtHeaderConfig
    -- ** Header Functions
  , CtUpdateCopyrightConfig
  , PtUpdateCopyrightConfig
  , UpdateCopyrightConfig(..)
  , CtHeaderFnConfig
  , PtHeaderFnConfig
  , HeaderFnConfig(..)
  , CtHeaderFnConfigs
  , PtHeaderFnConfigs
  , HeaderFnConfigs(..)
    -- ** Additional Data Types
  , HeaderSyntax(..)
  , GenMode(..)
  , LicenseType(..)
  , RunMode(..)
  , TemplateSource(..)
    -- * Lenses
  , cRunModeL
  , cSourcePathsL
  , cExcludedPathsL
  , cTemplateSourceL
  , cVariablesL
  , cLicenseHeadersL
  , cHeaderFnConfigsL
  , uccSelectedAuthorsL
  , hfcEnabledL
  , hfcConfigL
  , hfcsUpdateCopyrightL
  )
where

import           Control.Exception              ( throw )
import           Data.Aeson                     ( FromJSON(..)
                                                , Value(String)
                                                , genericParseJSON
                                                , withObject
                                                , (.!=)
                                                , (.:?)
                                                )
import           Data.Monoid                    ( Last(..) )
import           Headroom.Data.EnumExtra        ( EnumExtra(..) )
import           Headroom.Data.Lens             ( suffixLenses )
import           Headroom.Data.Regex            ( Regex(..) )
import           Headroom.FileType.Types        ( FileType )
import           Headroom.Serialization         ( aesonOptions )
import           Headroom.Types                 ( fromHeadroomError
                                                , toHeadroomError
                                                )
import           Headroom.Variables.Types       ( Variables(..) )
import           RIO
import qualified RIO.Text                      as T


------------------------------------  Phase  -----------------------------------

-- | Data type representing state of given configuration data type.
data Phase
  = Partial
  -- ^ partial configuration, could be combined with another or validated to
  -- produce the complete configuration
  | Complete
  -- ^ complete configuration, result of combining and validation of partial
  -- configuration


-- | /Closed type family/ used to express the phase of given data type.
type family (p :: Phase) ::: a where
  'Partial  ::: a = Last a
  'Complete ::: a = a


--------------------------------  HeaderSyntax  --------------------------------

-- | Syntax of the license header comment.
data HeaderSyntax
  = BlockComment !Text !Text
  -- ^ block (multi-line) comment syntax (e.g. @/* */@)
  | LineComment !Text
  -- ^ single line comment syntax (e.g. @//@)
  deriving (HeaderSyntax -> HeaderSyntax -> Bool
(HeaderSyntax -> HeaderSyntax -> Bool)
-> (HeaderSyntax -> HeaderSyntax -> Bool) -> Eq HeaderSyntax
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: HeaderSyntax -> HeaderSyntax -> Bool
$c/= :: HeaderSyntax -> HeaderSyntax -> Bool
== :: HeaderSyntax -> HeaderSyntax -> Bool
$c== :: HeaderSyntax -> HeaderSyntax -> Bool
Eq, Int -> HeaderSyntax -> ShowS
[HeaderSyntax] -> ShowS
HeaderSyntax -> String
(Int -> HeaderSyntax -> ShowS)
-> (HeaderSyntax -> String)
-> ([HeaderSyntax] -> ShowS)
-> Show HeaderSyntax
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [HeaderSyntax] -> ShowS
$cshowList :: [HeaderSyntax] -> ShowS
show :: HeaderSyntax -> String
$cshow :: HeaderSyntax -> String
showsPrec :: Int -> HeaderSyntax -> ShowS
$cshowsPrec :: Int -> HeaderSyntax -> ShowS
Show)

-- | Internal representation of the block style of 'HeaderSyntax'.
data BlockComment' = BlockComment'
  { BlockComment' -> Text
bcStartsWith :: !Text
  -- ^ starting pattern (e.g. @/*@)
  , BlockComment' -> Text
bcEndsWith   :: !Text
  -- ^ ending pattern (e.g. @*/@)
  }
  deriving (BlockComment' -> BlockComment' -> Bool
(BlockComment' -> BlockComment' -> Bool)
-> (BlockComment' -> BlockComment' -> Bool) -> Eq BlockComment'
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: BlockComment' -> BlockComment' -> Bool
$c/= :: BlockComment' -> BlockComment' -> Bool
== :: BlockComment' -> BlockComment' -> Bool
$c== :: BlockComment' -> BlockComment' -> Bool
Eq, (forall x. BlockComment' -> Rep BlockComment' x)
-> (forall x. Rep BlockComment' x -> BlockComment')
-> Generic BlockComment'
forall x. Rep BlockComment' x -> BlockComment'
forall x. BlockComment' -> Rep BlockComment' x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep BlockComment' x -> BlockComment'
$cfrom :: forall x. BlockComment' -> Rep BlockComment' x
Generic, Int -> BlockComment' -> ShowS
[BlockComment'] -> ShowS
BlockComment' -> String
(Int -> BlockComment' -> ShowS)
-> (BlockComment' -> String)
-> ([BlockComment'] -> ShowS)
-> Show BlockComment'
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [BlockComment'] -> ShowS
$cshowList :: [BlockComment'] -> ShowS
show :: BlockComment' -> String
$cshow :: BlockComment' -> String
showsPrec :: Int -> BlockComment' -> ShowS
$cshowsPrec :: Int -> BlockComment' -> ShowS
Show)

instance FromJSON BlockComment' where
  parseJSON :: Value -> Parser BlockComment'
parseJSON = Options -> Value -> Parser BlockComment'
forall a.
(Generic a, GFromJSON Zero (Rep a)) =>
Options -> Value -> Parser a
genericParseJSON Options
aesonOptions

-- | Internal representation of the line style of 'HeaderSyntax'.
newtype LineComment' = LineComment'
  { LineComment' -> Text
lcPrefixedBy :: Text
  -- ^ prefix of the comment line (e.g. @//@)
  }
  deriving (LineComment' -> LineComment' -> Bool
(LineComment' -> LineComment' -> Bool)
-> (LineComment' -> LineComment' -> Bool) -> Eq LineComment'
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: LineComment' -> LineComment' -> Bool
$c/= :: LineComment' -> LineComment' -> Bool
== :: LineComment' -> LineComment' -> Bool
$c== :: LineComment' -> LineComment' -> Bool
Eq, (forall x. LineComment' -> Rep LineComment' x)
-> (forall x. Rep LineComment' x -> LineComment')
-> Generic LineComment'
forall x. Rep LineComment' x -> LineComment'
forall x. LineComment' -> Rep LineComment' x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep LineComment' x -> LineComment'
$cfrom :: forall x. LineComment' -> Rep LineComment' x
Generic, Int -> LineComment' -> ShowS
[LineComment'] -> ShowS
LineComment' -> String
(Int -> LineComment' -> ShowS)
-> (LineComment' -> String)
-> ([LineComment'] -> ShowS)
-> Show LineComment'
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [LineComment'] -> ShowS
$cshowList :: [LineComment'] -> ShowS
show :: LineComment' -> String
$cshow :: LineComment' -> String
showsPrec :: Int -> LineComment' -> ShowS
$cshowsPrec :: Int -> LineComment' -> ShowS
Show)

instance FromJSON LineComment' where
  parseJSON :: Value -> Parser LineComment'
parseJSON = Options -> Value -> Parser LineComment'
forall a.
(Generic a, GFromJSON Zero (Rep a)) =>
Options -> Value -> Parser a
genericParseJSON Options
aesonOptions


---------------------------------  LicenseType  --------------------------------

-- | Supported type of open source license.
data LicenseType
  = Apache2
  -- ^ support for /Apache-2.0/ license
  | BSD3
  -- ^ support for /BSD-3-Clause/ license
  | GPL2
  -- ^ support for /GNU GPL2/ license
  | GPL3
  -- ^ support for /GNU GPL3/ license
  | MIT
  -- ^ support for /MIT/ license
  | MPL2
  -- ^ support for /MPL2/ license
  deriving (LicenseType
LicenseType -> LicenseType -> Bounded LicenseType
forall a. a -> a -> Bounded a
maxBound :: LicenseType
$cmaxBound :: LicenseType
minBound :: LicenseType
$cminBound :: LicenseType
Bounded, Int -> LicenseType
LicenseType -> Int
LicenseType -> [LicenseType]
LicenseType -> LicenseType
LicenseType -> LicenseType -> [LicenseType]
LicenseType -> LicenseType -> LicenseType -> [LicenseType]
(LicenseType -> LicenseType)
-> (LicenseType -> LicenseType)
-> (Int -> LicenseType)
-> (LicenseType -> Int)
-> (LicenseType -> [LicenseType])
-> (LicenseType -> LicenseType -> [LicenseType])
-> (LicenseType -> LicenseType -> [LicenseType])
-> (LicenseType -> LicenseType -> LicenseType -> [LicenseType])
-> Enum LicenseType
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: LicenseType -> LicenseType -> LicenseType -> [LicenseType]
$cenumFromThenTo :: LicenseType -> LicenseType -> LicenseType -> [LicenseType]
enumFromTo :: LicenseType -> LicenseType -> [LicenseType]
$cenumFromTo :: LicenseType -> LicenseType -> [LicenseType]
enumFromThen :: LicenseType -> LicenseType -> [LicenseType]
$cenumFromThen :: LicenseType -> LicenseType -> [LicenseType]
enumFrom :: LicenseType -> [LicenseType]
$cenumFrom :: LicenseType -> [LicenseType]
fromEnum :: LicenseType -> Int
$cfromEnum :: LicenseType -> Int
toEnum :: Int -> LicenseType
$ctoEnum :: Int -> LicenseType
pred :: LicenseType -> LicenseType
$cpred :: LicenseType -> LicenseType
succ :: LicenseType -> LicenseType
$csucc :: LicenseType -> LicenseType
Enum, Bounded LicenseType
Enum LicenseType
Eq LicenseType
Ord LicenseType
Show LicenseType
[LicenseType]
Text
Bounded LicenseType
-> Enum LicenseType
-> Eq LicenseType
-> Ord LicenseType
-> Show LicenseType
-> [LicenseType]
-> Text
-> (LicenseType -> Text)
-> (Text -> Maybe LicenseType)
-> EnumExtra LicenseType
Text -> Maybe LicenseType
LicenseType -> Text
forall a.
Bounded a
-> Enum a
-> Eq a
-> Ord a
-> Show a
-> [a]
-> Text
-> (a -> Text)
-> (Text -> Maybe a)
-> EnumExtra a
textToEnum :: Text -> Maybe LicenseType
$ctextToEnum :: Text -> Maybe LicenseType
enumToText :: LicenseType -> Text
$cenumToText :: LicenseType -> Text
allValuesToText :: Text
$callValuesToText :: Text
allValues :: [LicenseType]
$callValues :: [LicenseType]
$cp5EnumExtra :: Show LicenseType
$cp4EnumExtra :: Ord LicenseType
$cp3EnumExtra :: Eq LicenseType
$cp2EnumExtra :: Enum LicenseType
$cp1EnumExtra :: Bounded LicenseType
EnumExtra, LicenseType -> LicenseType -> Bool
(LicenseType -> LicenseType -> Bool)
-> (LicenseType -> LicenseType -> Bool) -> Eq LicenseType
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: LicenseType -> LicenseType -> Bool
$c/= :: LicenseType -> LicenseType -> Bool
== :: LicenseType -> LicenseType -> Bool
$c== :: LicenseType -> LicenseType -> Bool
Eq, Eq LicenseType
Eq LicenseType
-> (LicenseType -> LicenseType -> Ordering)
-> (LicenseType -> LicenseType -> Bool)
-> (LicenseType -> LicenseType -> Bool)
-> (LicenseType -> LicenseType -> Bool)
-> (LicenseType -> LicenseType -> Bool)
-> (LicenseType -> LicenseType -> LicenseType)
-> (LicenseType -> LicenseType -> LicenseType)
-> Ord LicenseType
LicenseType -> LicenseType -> Bool
LicenseType -> LicenseType -> Ordering
LicenseType -> LicenseType -> LicenseType
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: LicenseType -> LicenseType -> LicenseType
$cmin :: LicenseType -> LicenseType -> LicenseType
max :: LicenseType -> LicenseType -> LicenseType
$cmax :: LicenseType -> LicenseType -> LicenseType
>= :: LicenseType -> LicenseType -> Bool
$c>= :: LicenseType -> LicenseType -> Bool
> :: LicenseType -> LicenseType -> Bool
$c> :: LicenseType -> LicenseType -> Bool
<= :: LicenseType -> LicenseType -> Bool
$c<= :: LicenseType -> LicenseType -> Bool
< :: LicenseType -> LicenseType -> Bool
$c< :: LicenseType -> LicenseType -> Bool
compare :: LicenseType -> LicenseType -> Ordering
$ccompare :: LicenseType -> LicenseType -> Ordering
$cp1Ord :: Eq LicenseType
Ord, Int -> LicenseType -> ShowS
[LicenseType] -> ShowS
LicenseType -> String
(Int -> LicenseType -> ShowS)
-> (LicenseType -> String)
-> ([LicenseType] -> ShowS)
-> Show LicenseType
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [LicenseType] -> ShowS
$cshowList :: [LicenseType] -> ShowS
show :: LicenseType -> String
$cshow :: LicenseType -> String
showsPrec :: Int -> LicenseType -> ShowS
$cshowsPrec :: Int -> LicenseType -> ShowS
Show)

-----------------------------------  RunMode  ----------------------------------

-- | Represents what action should the @run@ command perform.
data RunMode
  = Add
  -- ^ /add mode/ for @run@ command
  | Check
  -- ^ /check mode/ for @run@ command
  | Drop
  -- ^ /drop mode/ for @run@ command
  | Replace
  -- ^ /replace mode/ for @run@ command
  deriving (RunMode -> RunMode -> Bool
(RunMode -> RunMode -> Bool)
-> (RunMode -> RunMode -> Bool) -> Eq RunMode
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: RunMode -> RunMode -> Bool
$c/= :: RunMode -> RunMode -> Bool
== :: RunMode -> RunMode -> Bool
$c== :: RunMode -> RunMode -> Bool
Eq, Int -> RunMode -> ShowS
[RunMode] -> ShowS
RunMode -> String
(Int -> RunMode -> ShowS)
-> (RunMode -> String) -> ([RunMode] -> ShowS) -> Show RunMode
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [RunMode] -> ShowS
$cshowList :: [RunMode] -> ShowS
show :: RunMode -> String
$cshow :: RunMode -> String
showsPrec :: Int -> RunMode -> ShowS
$cshowsPrec :: Int -> RunMode -> ShowS
Show)

instance FromJSON RunMode where
  parseJSON :: Value -> Parser RunMode
parseJSON = \case
    String Text
s -> case Text -> Text
T.toLower Text
s of
      Text
"add"     -> RunMode -> Parser RunMode
forall (f :: * -> *) a. Applicative f => a -> f a
pure RunMode
Add
      Text
"check"   -> RunMode -> Parser RunMode
forall (f :: * -> *) a. Applicative f => a -> f a
pure RunMode
Check
      Text
"drop"    -> RunMode -> Parser RunMode
forall (f :: * -> *) a. Applicative f => a -> f a
pure RunMode
Drop
      Text
"replace" -> RunMode -> Parser RunMode
forall (f :: * -> *) a. Applicative f => a -> f a
pure RunMode
Replace
      Text
_         -> String -> Parser RunMode
forall a. HasCallStack => String -> a
error (String -> Parser RunMode) -> String -> Parser RunMode
forall a b. (a -> b) -> a -> b
$ String
"Unknown run mode: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Text -> String
T.unpack Text
s
    Value
other -> String -> Parser RunMode
forall a. HasCallStack => String -> a
error (String -> Parser RunMode) -> String -> Parser RunMode
forall a b. (a -> b) -> a -> b
$ String
"Invalid value for run mode: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Value -> String
forall a. Show a => a -> String
show Value
other


-----------------------------------  GenMode  ----------------------------------

-- | Represents what action should the @gen@ command perform.
data GenMode
  = GenConfigFile
  -- ^ generate /YAML/ config file stub
  | GenLicense !(LicenseType, FileType)
  -- ^ generate license header template
  deriving (GenMode -> GenMode -> Bool
(GenMode -> GenMode -> Bool)
-> (GenMode -> GenMode -> Bool) -> Eq GenMode
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: GenMode -> GenMode -> Bool
$c/= :: GenMode -> GenMode -> Bool
== :: GenMode -> GenMode -> Bool
$c== :: GenMode -> GenMode -> Bool
Eq, Int -> GenMode -> ShowS
[GenMode] -> ShowS
GenMode -> String
(Int -> GenMode -> ShowS)
-> (GenMode -> String) -> ([GenMode] -> ShowS) -> Show GenMode
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [GenMode] -> ShowS
$cshowList :: [GenMode] -> ShowS
show :: GenMode -> String
$cshow :: GenMode -> String
showsPrec :: Int -> GenMode -> ShowS
$cshowsPrec :: Int -> GenMode -> ShowS
Show)


-------------------------------  TemplateSource  -------------------------------

-- | Source of license templates
data TemplateSource
  = TemplateFiles [FilePath]
  -- ^ templates are stored as local files
  | BuiltInTemplates LicenseType
  -- ^ use built-in templates for selected license
  deriving (TemplateSource -> TemplateSource -> Bool
(TemplateSource -> TemplateSource -> Bool)
-> (TemplateSource -> TemplateSource -> Bool) -> Eq TemplateSource
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: TemplateSource -> TemplateSource -> Bool
$c/= :: TemplateSource -> TemplateSource -> Bool
== :: TemplateSource -> TemplateSource -> Bool
$c== :: TemplateSource -> TemplateSource -> Bool
Eq, Int -> TemplateSource -> ShowS
[TemplateSource] -> ShowS
TemplateSource -> String
(Int -> TemplateSource -> ShowS)
-> (TemplateSource -> String)
-> ([TemplateSource] -> ShowS)
-> Show TemplateSource
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [TemplateSource] -> ShowS
$cshowList :: [TemplateSource] -> ShowS
show :: TemplateSource -> String
$cshow :: TemplateSource -> String
showsPrec :: Int -> TemplateSource -> ShowS
$cshowsPrec :: Int -> TemplateSource -> ShowS
Show)


----------------------------  UpdateCopyrightConfig  ---------------------------

-- | Main configuration for the "Headroom.HeaderFn.UpdateCopyright"
-- /license header function/.
data UpdateCopyrightConfig (p :: Phase) = UpdateCopyrightConfig
  { UpdateCopyrightConfig p -> p ::: Maybe (NonEmpty Text)
uccSelectedAuthors :: !(p ::: Maybe (NonEmpty Text))
  -- ^ if specified, years will be updated only in copyright statements of
  -- given authors
  }

-- | Alias for complete variant of 'UpdateCopyrightConfig'.
type CtUpdateCopyrightConfig = UpdateCopyrightConfig 'Complete

-- | Alias for partial variant of 'UpdateCopyrightConfig'.
type PtUpdateCopyrightConfig = UpdateCopyrightConfig 'Partial

deriving instance Eq CtUpdateCopyrightConfig
deriving instance Eq PtUpdateCopyrightConfig
deriving instance Show CtUpdateCopyrightConfig
deriving instance Show PtUpdateCopyrightConfig

instance FromJSON PtUpdateCopyrightConfig where
  parseJSON :: Value -> Parser PtUpdateCopyrightConfig
parseJSON = String
-> (Object -> Parser PtUpdateCopyrightConfig)
-> Value
-> Parser PtUpdateCopyrightConfig
forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject String
"PtUpdateCopyrightConfig" ((Object -> Parser PtUpdateCopyrightConfig)
 -> Value -> Parser PtUpdateCopyrightConfig)
-> (Object -> Parser PtUpdateCopyrightConfig)
-> Value
-> Parser PtUpdateCopyrightConfig
forall a b. (a -> b) -> a -> b
$ \Object
obj -> do
    Last (Maybe (NonEmpty Text))
uccSelectedAuthors <- Maybe (Maybe (NonEmpty Text)) -> Last (Maybe (NonEmpty Text))
forall a. Maybe a -> Last a
Last (Maybe (Maybe (NonEmpty Text)) -> Last (Maybe (NonEmpty Text)))
-> Parser (Maybe (Maybe (NonEmpty Text)))
-> Parser (Last (Maybe (NonEmpty Text)))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
obj Object -> Text -> Parser (Maybe (Maybe (NonEmpty Text)))
forall a. FromJSON a => Object -> Text -> Parser (Maybe a)
.:? Text
"selected-authors-only"
    PtUpdateCopyrightConfig -> Parser PtUpdateCopyrightConfig
forall (f :: * -> *) a. Applicative f => a -> f a
pure UpdateCopyrightConfig :: forall (p :: Phase).
(p ::: Maybe (NonEmpty Text)) -> UpdateCopyrightConfig p
UpdateCopyrightConfig { Last (Maybe (NonEmpty Text))
'Partial ::: Maybe (NonEmpty Text)
uccSelectedAuthors :: Last (Maybe (NonEmpty Text))
uccSelectedAuthors :: 'Partial ::: Maybe (NonEmpty Text)
.. }

instance Semigroup PtUpdateCopyrightConfig where
  PtUpdateCopyrightConfig
x <> :: PtUpdateCopyrightConfig
-> PtUpdateCopyrightConfig -> PtUpdateCopyrightConfig
<> PtUpdateCopyrightConfig
y = UpdateCopyrightConfig :: forall (p :: Phase).
(p ::: Maybe (NonEmpty Text)) -> UpdateCopyrightConfig p
UpdateCopyrightConfig
    { uccSelectedAuthors :: 'Partial ::: Maybe (NonEmpty Text)
uccSelectedAuthors = PtUpdateCopyrightConfig -> 'Partial ::: Maybe (NonEmpty Text)
forall (p :: Phase).
UpdateCopyrightConfig p -> p ::: Maybe (NonEmpty Text)
uccSelectedAuthors PtUpdateCopyrightConfig
x Last (Maybe (NonEmpty Text))
-> Last (Maybe (NonEmpty Text)) -> Last (Maybe (NonEmpty Text))
forall a. Semigroup a => a -> a -> a
<> PtUpdateCopyrightConfig -> 'Partial ::: Maybe (NonEmpty Text)
forall (p :: Phase).
UpdateCopyrightConfig p -> p ::: Maybe (NonEmpty Text)
uccSelectedAuthors PtUpdateCopyrightConfig
y
    }

instance Monoid PtUpdateCopyrightConfig where
  mempty :: PtUpdateCopyrightConfig
mempty = ('Partial ::: Maybe (NonEmpty Text)) -> PtUpdateCopyrightConfig
forall (p :: Phase).
(p ::: Maybe (NonEmpty Text)) -> UpdateCopyrightConfig p
UpdateCopyrightConfig 'Partial ::: Maybe (NonEmpty Text)
forall a. Monoid a => a
mempty


-------------------------------  HeaderFnConfig  -------------------------------

-- | Configuration for selected /license header function/.
data HeaderFnConfig (p :: Phase) c = HeaderFnConfig
  { HeaderFnConfig p c -> p ::: Bool
hfcEnabled :: !(p ::: Bool)
  -- ^ whether this function is enabled or not
  , HeaderFnConfig p c -> c p
hfcConfig  :: !(c p)
  -- ^ custom configuration of the /license header function/
  }

-- | Alias for complete variant of 'HeaderFnConfig'.
type CtHeaderFnConfig c = HeaderFnConfig 'Complete c

-- | Alias for partial variant of 'HeaderFnConfig'.
type PtHeaderFnConfig c = HeaderFnConfig 'Partial c


deriving instance (Eq (c 'Complete)) => Eq (CtHeaderFnConfig c)
deriving instance (Eq (c 'Partial)) => Eq (PtHeaderFnConfig c)
deriving instance (Show (c 'Complete)) => Show (CtHeaderFnConfig c)
deriving instance (Show (c 'Partial)) => Show (PtHeaderFnConfig c)

instance Semigroup (c 'Partial) => Semigroup (PtHeaderFnConfig c) where
  PtHeaderFnConfig c
x <> :: PtHeaderFnConfig c -> PtHeaderFnConfig c -> PtHeaderFnConfig c
<> PtHeaderFnConfig c
y = HeaderFnConfig :: forall (p :: Phase) (c :: Phase -> *).
(p ::: Bool) -> c p -> HeaderFnConfig p c
HeaderFnConfig { hfcEnabled :: 'Partial ::: Bool
hfcEnabled = PtHeaderFnConfig c -> 'Partial ::: Bool
forall (p :: Phase) (c :: Phase -> *).
HeaderFnConfig p c -> p ::: Bool
hfcEnabled PtHeaderFnConfig c
x Last Bool -> Last Bool -> Last Bool
forall a. Semigroup a => a -> a -> a
<> PtHeaderFnConfig c -> 'Partial ::: Bool
forall (p :: Phase) (c :: Phase -> *).
HeaderFnConfig p c -> p ::: Bool
hfcEnabled PtHeaderFnConfig c
y
                          , hfcConfig :: c 'Partial
hfcConfig  = PtHeaderFnConfig c -> c 'Partial
forall (p :: Phase) (c :: Phase -> *). HeaderFnConfig p c -> c p
hfcConfig PtHeaderFnConfig c
x c 'Partial -> c 'Partial -> c 'Partial
forall a. Semigroup a => a -> a -> a
<> PtHeaderFnConfig c -> c 'Partial
forall (p :: Phase) (c :: Phase -> *). HeaderFnConfig p c -> c p
hfcConfig PtHeaderFnConfig c
y
                          }

instance Monoid (c 'Partial) => Monoid (PtHeaderFnConfig c) where
  mempty :: PtHeaderFnConfig c
mempty = ('Partial ::: Bool) -> c 'Partial -> PtHeaderFnConfig c
forall (p :: Phase) (c :: Phase -> *).
(p ::: Bool) -> c p -> HeaderFnConfig p c
HeaderFnConfig 'Partial ::: Bool
forall a. Monoid a => a
mempty c 'Partial
forall a. Monoid a => a
mempty

instance (FromJSON (c 'Partial), Monoid (c 'Partial)) => FromJSON (PtHeaderFnConfig c) where
  parseJSON :: Value -> Parser (PtHeaderFnConfig c)
parseJSON = String
-> (Object -> Parser (PtHeaderFnConfig c))
-> Value
-> Parser (PtHeaderFnConfig c)
forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject String
"PtHeaderFnConfig" ((Object -> Parser (PtHeaderFnConfig c))
 -> Value -> Parser (PtHeaderFnConfig c))
-> (Object -> Parser (PtHeaderFnConfig c))
-> Value
-> Parser (PtHeaderFnConfig c)
forall a b. (a -> b) -> a -> b
$ \Object
obj -> do
    Last Bool
hfcEnabled <- Maybe Bool -> Last Bool
forall a. Maybe a -> Last a
Last (Maybe Bool -> Last Bool)
-> Parser (Maybe Bool) -> Parser (Last Bool)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
obj Object -> Text -> Parser (Maybe Bool)
forall a. FromJSON a => Object -> Text -> Parser (Maybe a)
.:? Text
"enabled"
    c 'Partial
hfcConfig  <- Object
obj Object -> Text -> Parser (Maybe (c 'Partial))
forall a. FromJSON a => Object -> Text -> Parser (Maybe a)
.:? Text
"config" Parser (Maybe (c 'Partial)) -> c 'Partial -> Parser (c 'Partial)
forall a. Parser (Maybe a) -> a -> Parser a
.!= c 'Partial
forall a. Monoid a => a
mempty
    PtHeaderFnConfig c -> Parser (PtHeaderFnConfig 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 'Partial
Last Bool
'Partial ::: Bool
hfcConfig :: c 'Partial
hfcEnabled :: Last Bool
hfcConfig :: c 'Partial
hfcEnabled :: 'Partial ::: Bool
.. }


-------------------------------  HeaderFnConfigs  ------------------------------

-- | Configuration of all known /license header functions/.
data HeaderFnConfigs (p :: Phase) = HeaderFnConfigs
  { HeaderFnConfigs p -> HeaderFnConfig p UpdateCopyrightConfig
hfcsUpdateCopyright :: !(HeaderFnConfig p UpdateCopyrightConfig)
  -- ^ configuration for the "Headroom.HeaderFn.UpdateCopyright"
  -- /license header function/
  }

-- | Alias for complete variant of 'HeaderFnConfigs'.
type CtHeaderFnConfigs = HeaderFnConfigs 'Complete

-- | Alias for partial variant of 'HeaderFnConfigs'.
type PtHeaderFnConfigs = HeaderFnConfigs 'Partial

deriving instance Eq CtHeaderFnConfigs
deriving instance Eq PtHeaderFnConfigs
deriving instance Show CtHeaderFnConfigs
deriving instance Show PtHeaderFnConfigs

instance Semigroup PtHeaderFnConfigs where
  PtHeaderFnConfigs
x <> :: PtHeaderFnConfigs -> PtHeaderFnConfigs -> PtHeaderFnConfigs
<> PtHeaderFnConfigs
y = HeaderFnConfigs :: forall (p :: Phase).
HeaderFnConfig p UpdateCopyrightConfig -> HeaderFnConfigs p
HeaderFnConfigs
    { hfcsUpdateCopyright :: HeaderFnConfig 'Partial UpdateCopyrightConfig
hfcsUpdateCopyright = PtHeaderFnConfigs -> HeaderFnConfig 'Partial UpdateCopyrightConfig
forall (p :: Phase).
HeaderFnConfigs p -> HeaderFnConfig p UpdateCopyrightConfig
hfcsUpdateCopyright PtHeaderFnConfigs
x HeaderFnConfig 'Partial UpdateCopyrightConfig
-> HeaderFnConfig 'Partial UpdateCopyrightConfig
-> HeaderFnConfig 'Partial UpdateCopyrightConfig
forall a. Semigroup a => a -> a -> a
<> PtHeaderFnConfigs -> HeaderFnConfig 'Partial UpdateCopyrightConfig
forall (p :: Phase).
HeaderFnConfigs p -> HeaderFnConfig p UpdateCopyrightConfig
hfcsUpdateCopyright PtHeaderFnConfigs
y
    }

instance Monoid PtHeaderFnConfigs where
  mempty :: PtHeaderFnConfigs
mempty = HeaderFnConfig 'Partial UpdateCopyrightConfig -> PtHeaderFnConfigs
forall (p :: Phase).
HeaderFnConfig p UpdateCopyrightConfig -> HeaderFnConfigs p
HeaderFnConfigs HeaderFnConfig 'Partial UpdateCopyrightConfig
forall a. Monoid a => a
mempty

instance FromJSON PtHeaderFnConfigs where
  parseJSON :: Value -> Parser PtHeaderFnConfigs
parseJSON = String
-> (Object -> Parser PtHeaderFnConfigs)
-> Value
-> Parser PtHeaderFnConfigs
forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject String
"PtHeaderFnConfigs" ((Object -> Parser PtHeaderFnConfigs)
 -> Value -> Parser PtHeaderFnConfigs)
-> (Object -> Parser PtHeaderFnConfigs)
-> Value
-> Parser PtHeaderFnConfigs
forall a b. (a -> b) -> a -> b
$ \Object
obj -> do
    HeaderFnConfig 'Partial UpdateCopyrightConfig
hfcsUpdateCopyright <- Object
obj Object
-> Text
-> Parser (Maybe (HeaderFnConfig 'Partial UpdateCopyrightConfig))
forall a. FromJSON a => Object -> Text -> Parser (Maybe a)
.:? Text
"update-copyright" Parser (Maybe (HeaderFnConfig 'Partial UpdateCopyrightConfig))
-> HeaderFnConfig 'Partial UpdateCopyrightConfig
-> Parser (HeaderFnConfig 'Partial UpdateCopyrightConfig)
forall a. Parser (Maybe a) -> a -> Parser a
.!= HeaderFnConfig 'Partial UpdateCopyrightConfig
forall a. Monoid a => a
mempty
    PtHeaderFnConfigs -> Parser PtHeaderFnConfigs
forall (f :: * -> *) a. Applicative f => a -> f a
pure HeaderFnConfigs :: forall (p :: Phase).
HeaderFnConfig p UpdateCopyrightConfig -> HeaderFnConfigs p
HeaderFnConfigs { HeaderFnConfig 'Partial UpdateCopyrightConfig
hfcsUpdateCopyright :: HeaderFnConfig 'Partial UpdateCopyrightConfig
hfcsUpdateCopyright :: HeaderFnConfig 'Partial UpdateCopyrightConfig
.. }


--------------------------------  Configuration  -------------------------------

-- | Application configuration.
data Configuration (p :: Phase) = Configuration
  { Configuration p -> p ::: RunMode
cRunMode         :: !(p ::: RunMode)
  -- ^ mode of the @run@ command
  , Configuration p -> p ::: [String]
cSourcePaths     :: !(p ::: [FilePath])
  -- ^ paths to source code files
  , Configuration p -> p ::: [Regex]
cExcludedPaths   :: !(p ::: [Regex])
  -- ^ excluded source paths
  , Configuration p -> p ::: TemplateSource
cTemplateSource  :: !(p ::: TemplateSource)
  -- ^ source of license templates
  , Configuration p -> Variables
cVariables       :: !Variables
  -- ^ variable values for templates
  , Configuration p -> HeadersConfig p
cLicenseHeaders  :: !(HeadersConfig p)
  -- ^ configuration of license headers
  , Configuration p -> HeaderFnConfigs p
cHeaderFnConfigs :: !(HeaderFnConfigs p)
  -- ^ configuration of license header functions
  }

-- | Alias for complete variant of 'Configuration'.
type CtConfiguration = Configuration 'Complete

-- | Alias for partial variant of 'Configuration'.
type PtConfiguration = Configuration 'Partial

deriving instance Eq CtConfiguration
deriving instance Eq PtConfiguration
deriving instance Show CtConfiguration
deriving instance Show PtConfiguration

instance FromJSON PtConfiguration where
  parseJSON :: Value -> Parser PtConfiguration
parseJSON = String
-> (Object -> Parser PtConfiguration)
-> Value
-> Parser PtConfiguration
forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject String
"PtConfiguration" ((Object -> Parser PtConfiguration)
 -> Value -> Parser PtConfiguration)
-> (Object -> Parser PtConfiguration)
-> Value
-> Parser PtConfiguration
forall a b. (a -> b) -> a -> b
$ \Object
obj -> do
    Last RunMode
cRunMode         <- Maybe RunMode -> Last RunMode
forall a. Maybe a -> Last a
Last (Maybe RunMode -> Last RunMode)
-> Parser (Maybe RunMode) -> Parser (Last RunMode)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
obj Object -> Text -> Parser (Maybe RunMode)
forall a. FromJSON a => Object -> Text -> Parser (Maybe a)
.:? Text
"run-mode"
    Last [String]
cSourcePaths     <- Maybe [String] -> Last [String]
forall a. Maybe a -> Last a
Last (Maybe [String] -> Last [String])
-> Parser (Maybe [String]) -> Parser (Last [String])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
obj Object -> Text -> Parser (Maybe [String])
forall a. FromJSON a => Object -> Text -> Parser (Maybe a)
.:? Text
"source-paths"
    Last [Regex]
cExcludedPaths   <- Maybe [Regex] -> Last [Regex]
forall a. Maybe a -> Last a
Last (Maybe [Regex] -> Last [Regex])
-> Parser (Maybe [Regex]) -> Parser (Last [Regex])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
obj Object -> Text -> Parser (Maybe [Regex])
forall a. FromJSON a => Object -> Text -> Parser (Maybe a)
.:? Text
"excluded-paths"
    Last TemplateSource
cTemplateSource  <- Maybe TemplateSource -> Last TemplateSource
forall a. Maybe a -> Last a
Last (Maybe TemplateSource -> Last TemplateSource)
-> Parser (Maybe TemplateSource) -> Parser (Last TemplateSource)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ([String] -> TemplateSource)
-> Parser (Maybe [String]) -> Parser (Maybe TemplateSource)
forall a b. (a -> b) -> Parser (Maybe a) -> Parser (Maybe b)
get [String] -> TemplateSource
TemplateFiles (Object
obj Object -> Text -> Parser (Maybe [String])
forall a. FromJSON a => Object -> Text -> Parser (Maybe a)
.:? Text
"template-paths")
    Variables
cVariables       <- (HashMap Text Text -> Variables)
-> Parser (HashMap Text Text) -> Parser Variables
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap HashMap Text Text -> Variables
Variables (Object
obj Object -> Text -> Parser (Maybe (HashMap Text Text))
forall a. FromJSON a => Object -> Text -> Parser (Maybe a)
.:? Text
"variables" Parser (Maybe (HashMap Text Text))
-> HashMap Text Text -> Parser (HashMap Text Text)
forall a. Parser (Maybe a) -> a -> Parser a
.!= HashMap Text Text
forall a. Monoid a => a
mempty)
    HeadersConfig 'Partial
cLicenseHeaders  <- Object
obj Object -> Text -> Parser (Maybe (HeadersConfig 'Partial))
forall a. FromJSON a => Object -> Text -> Parser (Maybe a)
.:? Text
"license-headers" Parser (Maybe (HeadersConfig 'Partial))
-> HeadersConfig 'Partial -> Parser (HeadersConfig 'Partial)
forall a. Parser (Maybe a) -> a -> Parser a
.!= HeadersConfig 'Partial
forall a. Monoid a => a
mempty
    PtHeaderFnConfigs
cHeaderFnConfigs <- Object
obj Object -> Text -> Parser (Maybe PtHeaderFnConfigs)
forall a. FromJSON a => Object -> Text -> Parser (Maybe a)
.:? Text
"post-process" Parser (Maybe PtHeaderFnConfigs)
-> PtHeaderFnConfigs -> Parser PtHeaderFnConfigs
forall a. Parser (Maybe a) -> a -> Parser a
.!= PtHeaderFnConfigs
forall a. Monoid a => a
mempty
    PtConfiguration -> Parser PtConfiguration
forall (f :: * -> *) a. Applicative f => a -> f a
pure Configuration :: forall (p :: Phase).
(p ::: RunMode)
-> (p ::: [String])
-> (p ::: [Regex])
-> (p ::: TemplateSource)
-> Variables
-> HeadersConfig p
-> HeaderFnConfigs p
-> Configuration p
Configuration { Last [String]
Last [Regex]
Last TemplateSource
Last RunMode
Variables
HeadersConfig 'Partial
PtHeaderFnConfigs
'Partial ::: [String]
'Partial ::: [Regex]
'Partial ::: TemplateSource
'Partial ::: RunMode
cHeaderFnConfigs :: PtHeaderFnConfigs
cLicenseHeaders :: HeadersConfig 'Partial
cVariables :: Variables
cTemplateSource :: Last TemplateSource
cExcludedPaths :: Last [Regex]
cSourcePaths :: Last [String]
cRunMode :: Last RunMode
cHeaderFnConfigs :: PtHeaderFnConfigs
cLicenseHeaders :: HeadersConfig 'Partial
cVariables :: Variables
cTemplateSource :: 'Partial ::: TemplateSource
cExcludedPaths :: 'Partial ::: [Regex]
cSourcePaths :: 'Partial ::: [String]
cRunMode :: 'Partial ::: RunMode
.. }
    where get :: (a -> b) -> Parser (Maybe a) -> Parser (Maybe b)
get = (Maybe a -> Maybe b) -> Parser (Maybe a) -> Parser (Maybe b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Maybe a -> Maybe b) -> Parser (Maybe a) -> Parser (Maybe b))
-> ((a -> b) -> Maybe a -> Maybe b)
-> (a -> b)
-> Parser (Maybe a)
-> Parser (Maybe b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap

instance Semigroup PtConfiguration where
  PtConfiguration
x <> :: PtConfiguration -> PtConfiguration -> PtConfiguration
<> PtConfiguration
y = Configuration :: forall (p :: Phase).
(p ::: RunMode)
-> (p ::: [String])
-> (p ::: [Regex])
-> (p ::: TemplateSource)
-> Variables
-> HeadersConfig p
-> HeaderFnConfigs p
-> Configuration p
Configuration
    { cRunMode :: 'Partial ::: RunMode
cRunMode         = PtConfiguration -> 'Partial ::: RunMode
forall (p :: Phase). Configuration p -> p ::: RunMode
cRunMode PtConfiguration
x Last RunMode -> Last RunMode -> Last RunMode
forall a. Semigroup a => a -> a -> a
<> PtConfiguration -> 'Partial ::: RunMode
forall (p :: Phase). Configuration p -> p ::: RunMode
cRunMode PtConfiguration
y
    , cSourcePaths :: 'Partial ::: [String]
cSourcePaths     = PtConfiguration -> 'Partial ::: [String]
forall (p :: Phase). Configuration p -> p ::: [String]
cSourcePaths PtConfiguration
x Last [String] -> Last [String] -> Last [String]
forall a. Semigroup a => a -> a -> a
<> PtConfiguration -> 'Partial ::: [String]
forall (p :: Phase). Configuration p -> p ::: [String]
cSourcePaths PtConfiguration
y
    , cExcludedPaths :: 'Partial ::: [Regex]
cExcludedPaths   = PtConfiguration -> 'Partial ::: [Regex]
forall (p :: Phase). Configuration p -> p ::: [Regex]
cExcludedPaths PtConfiguration
x Last [Regex] -> Last [Regex] -> Last [Regex]
forall a. Semigroup a => a -> a -> a
<> PtConfiguration -> 'Partial ::: [Regex]
forall (p :: Phase). Configuration p -> p ::: [Regex]
cExcludedPaths PtConfiguration
y
    , cTemplateSource :: 'Partial ::: TemplateSource
cTemplateSource  = PtConfiguration -> 'Partial ::: TemplateSource
forall (p :: Phase). Configuration p -> p ::: TemplateSource
cTemplateSource PtConfiguration
x Last TemplateSource -> Last TemplateSource -> Last TemplateSource
forall a. Semigroup a => a -> a -> a
<> PtConfiguration -> 'Partial ::: TemplateSource
forall (p :: Phase). Configuration p -> p ::: TemplateSource
cTemplateSource PtConfiguration
y
    , cVariables :: Variables
cVariables       = PtConfiguration -> Variables
forall (p :: Phase). Configuration p -> Variables
cVariables PtConfiguration
x Variables -> Variables -> Variables
forall a. Semigroup a => a -> a -> a
<> PtConfiguration -> Variables
forall (p :: Phase). Configuration p -> Variables
cVariables PtConfiguration
y
    , cLicenseHeaders :: HeadersConfig 'Partial
cLicenseHeaders  = PtConfiguration -> HeadersConfig 'Partial
forall (p :: Phase). Configuration p -> HeadersConfig p
cLicenseHeaders PtConfiguration
x HeadersConfig 'Partial
-> HeadersConfig 'Partial -> HeadersConfig 'Partial
forall a. Semigroup a => a -> a -> a
<> PtConfiguration -> HeadersConfig 'Partial
forall (p :: Phase). Configuration p -> HeadersConfig p
cLicenseHeaders PtConfiguration
y
    , cHeaderFnConfigs :: PtHeaderFnConfigs
cHeaderFnConfigs = PtConfiguration -> PtHeaderFnConfigs
forall (p :: Phase). Configuration p -> HeaderFnConfigs p
cHeaderFnConfigs PtConfiguration
x PtHeaderFnConfigs -> PtHeaderFnConfigs -> PtHeaderFnConfigs
forall a. Semigroup a => a -> a -> a
<> PtConfiguration -> PtHeaderFnConfigs
forall (p :: Phase). Configuration p -> HeaderFnConfigs p
cHeaderFnConfigs PtConfiguration
y
    }

instance Monoid PtConfiguration where
  mempty :: PtConfiguration
mempty = ('Partial ::: RunMode)
-> ('Partial ::: [String])
-> ('Partial ::: [Regex])
-> ('Partial ::: TemplateSource)
-> Variables
-> HeadersConfig 'Partial
-> PtHeaderFnConfigs
-> PtConfiguration
forall (p :: Phase).
(p ::: RunMode)
-> (p ::: [String])
-> (p ::: [Regex])
-> (p ::: TemplateSource)
-> Variables
-> HeadersConfig p
-> HeaderFnConfigs p
-> Configuration p
Configuration 'Partial ::: RunMode
forall a. Monoid a => a
mempty 'Partial ::: [String]
forall a. Monoid a => a
mempty 'Partial ::: [Regex]
forall a. Monoid a => a
mempty 'Partial ::: TemplateSource
forall a. Monoid a => a
mempty Variables
forall a. Monoid a => a
mempty HeadersConfig 'Partial
forall a. Monoid a => a
mempty PtHeaderFnConfigs
forall a. Monoid a => a
mempty


--------------------------------  HeaderConfig  --------------------------------

-- | Configuration for specific license header.
data HeaderConfig (p :: Phase) = HeaderConfig
  { HeaderConfig p -> p ::: [Text]
hcFileExtensions :: !(p ::: [Text])
  -- ^ list of file extensions (without dot)
  , HeaderConfig p -> p ::: Int
hcMarginAfter    :: !(p ::: Int)
  -- ^ number of empty lines to put after header
  , HeaderConfig p -> p ::: Int
hcMarginBefore   :: !(p ::: Int)
  -- ^ number of empty lines to put before header
  , HeaderConfig p -> p ::: [Regex]
hcPutAfter       :: !(p ::: [Regex])
  -- ^ /regexp/ patterns after which to put the header
  , HeaderConfig p -> p ::: [Regex]
hcPutBefore      :: !(p ::: [Regex])
  -- ^ /regexp/ patterns before which to put the header
  , HeaderConfig p -> p ::: HeaderSyntax
hcHeaderSyntax   :: !(p ::: HeaderSyntax)
  -- ^ syntax of the license header comment
  }

-- | Alias for complete variant of 'HeaderConfig'.
type CtHeaderConfig = HeaderConfig 'Complete

-- | Alias for partial variant of 'HeaderConfig'.
type PtHeaderConfig = HeaderConfig 'Partial

deriving instance Eq CtHeaderConfig
deriving instance Eq PtHeaderConfig
deriving instance Show CtHeaderConfig
deriving instance Show PtHeaderConfig

instance FromJSON PtHeaderConfig where
  parseJSON :: Value -> Parser PtHeaderConfig
parseJSON = String
-> (Object -> Parser PtHeaderConfig)
-> Value
-> Parser PtHeaderConfig
forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject String
"PartialHeaderConfig" ((Object -> Parser PtHeaderConfig)
 -> Value -> Parser PtHeaderConfig)
-> (Object -> Parser PtHeaderConfig)
-> Value
-> Parser PtHeaderConfig
forall a b. (a -> b) -> a -> b
$ \Object
obj -> do
    Last [Text]
hcFileExtensions <- Maybe [Text] -> Last [Text]
forall a. Maybe a -> Last a
Last (Maybe [Text] -> Last [Text])
-> Parser (Maybe [Text]) -> Parser (Last [Text])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
obj Object -> Text -> Parser (Maybe [Text])
forall a. FromJSON a => Object -> Text -> Parser (Maybe a)
.:? Text
"file-extensions"
    Last Int
hcMarginAfter    <- Maybe Int -> Last Int
forall a. Maybe a -> Last a
Last (Maybe Int -> Last Int) -> Parser (Maybe Int) -> Parser (Last Int)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
obj Object -> Text -> Parser (Maybe Int)
forall a. FromJSON a => Object -> Text -> Parser (Maybe a)
.:? Text
"margin-after"
    Last Int
hcMarginBefore   <- Maybe Int -> Last Int
forall a. Maybe a -> Last a
Last (Maybe Int -> Last Int) -> Parser (Maybe Int) -> Parser (Last Int)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
obj Object -> Text -> Parser (Maybe Int)
forall a. FromJSON a => Object -> Text -> Parser (Maybe a)
.:? Text
"margin-before"
    Last [Regex]
hcPutAfter       <- Maybe [Regex] -> Last [Regex]
forall a. Maybe a -> Last a
Last (Maybe [Regex] -> Last [Regex])
-> Parser (Maybe [Regex]) -> Parser (Last [Regex])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
obj Object -> Text -> Parser (Maybe [Regex])
forall a. FromJSON a => Object -> Text -> Parser (Maybe a)
.:? Text
"put-after"
    Last [Regex]
hcPutBefore      <- Maybe [Regex] -> Last [Regex]
forall a. Maybe a -> Last a
Last (Maybe [Regex] -> Last [Regex])
-> Parser (Maybe [Regex]) -> Parser (Last [Regex])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
obj Object -> Text -> Parser (Maybe [Regex])
forall a. FromJSON a => Object -> Text -> Parser (Maybe a)
.:? Text
"put-before"
    Maybe BlockComment'
blockComment     <- Object
obj Object -> Text -> Parser (Maybe BlockComment')
forall a. FromJSON a => Object -> Text -> Parser (Maybe a)
.:? Text
"block-comment"
    Maybe LineComment'
lineComment      <- Object
obj Object -> Text -> Parser (Maybe LineComment')
forall a. FromJSON a => Object -> Text -> Parser (Maybe a)
.:? Text
"line-comment"
    Last HeaderSyntax
hcHeaderSyntax   <- Last HeaderSyntax -> Parser (Last HeaderSyntax)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Last HeaderSyntax -> Parser (Last HeaderSyntax))
-> (Maybe HeaderSyntax -> Last HeaderSyntax)
-> Maybe HeaderSyntax
-> Parser (Last HeaderSyntax)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe HeaderSyntax -> Last HeaderSyntax
forall a. Maybe a -> Last a
Last (Maybe HeaderSyntax -> Parser (Last HeaderSyntax))
-> Maybe HeaderSyntax -> Parser (Last HeaderSyntax)
forall a b. (a -> b) -> a -> b
$ Maybe BlockComment' -> Maybe LineComment' -> Maybe HeaderSyntax
headerSyntax Maybe BlockComment'
blockComment Maybe LineComment'
lineComment
    PtHeaderConfig -> Parser PtHeaderConfig
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 { Last Int
Last [Text]
Last [Regex]
Last HeaderSyntax
'Partial ::: Int
'Partial ::: [Text]
'Partial ::: [Regex]
'Partial ::: HeaderSyntax
hcHeaderSyntax :: Last HeaderSyntax
hcPutBefore :: Last [Regex]
hcPutAfter :: Last [Regex]
hcMarginBefore :: Last Int
hcMarginAfter :: Last Int
hcFileExtensions :: Last [Text]
hcHeaderSyntax :: 'Partial ::: HeaderSyntax
hcPutBefore :: 'Partial ::: [Regex]
hcPutAfter :: 'Partial ::: [Regex]
hcMarginBefore :: 'Partial ::: Int
hcMarginAfter :: 'Partial ::: Int
hcFileExtensions :: 'Partial ::: [Text]
.. }
   where
    headerSyntax :: Maybe BlockComment' -> Maybe LineComment' -> Maybe HeaderSyntax
headerSyntax (Just (BlockComment' Text
s Text
e)) Maybe LineComment'
Nothing = HeaderSyntax -> Maybe HeaderSyntax
forall a. a -> Maybe a
Just (HeaderSyntax -> Maybe HeaderSyntax)
-> HeaderSyntax -> Maybe HeaderSyntax
forall a b. (a -> b) -> a -> b
$ Text -> Text -> HeaderSyntax
BlockComment Text
s Text
e
    headerSyntax Maybe BlockComment'
Nothing (Just (LineComment' Text
p)) = HeaderSyntax -> Maybe HeaderSyntax
forall a. a -> Maybe a
Just (HeaderSyntax -> Maybe HeaderSyntax)
-> HeaderSyntax -> Maybe HeaderSyntax
forall a b. (a -> b) -> a -> b
$ Text -> HeaderSyntax
LineComment Text
p
    headerSyntax Maybe BlockComment'
Nothing Maybe LineComment'
Nothing = Maybe HeaderSyntax
forall a. Maybe a
Nothing
    headerSyntax Maybe BlockComment'
_ Maybe LineComment'
_ = ConfigurationError -> Maybe HeaderSyntax
forall a e. Exception e => e -> a
throw ConfigurationError
MixedHeaderSyntax

instance Monoid PtHeaderConfig where
  mempty :: PtHeaderConfig
mempty = ('Partial ::: [Text])
-> ('Partial ::: Int)
-> ('Partial ::: Int)
-> ('Partial ::: [Regex])
-> ('Partial ::: [Regex])
-> ('Partial ::: HeaderSyntax)
-> PtHeaderConfig
forall (p :: Phase).
(p ::: [Text])
-> (p ::: Int)
-> (p ::: Int)
-> (p ::: [Regex])
-> (p ::: [Regex])
-> (p ::: HeaderSyntax)
-> HeaderConfig p
HeaderConfig 'Partial ::: [Text]
forall a. Monoid a => a
mempty 'Partial ::: Int
forall a. Monoid a => a
mempty 'Partial ::: Int
forall a. Monoid a => a
mempty 'Partial ::: [Regex]
forall a. Monoid a => a
mempty 'Partial ::: [Regex]
forall a. Monoid a => a
mempty 'Partial ::: HeaderSyntax
forall a. Monoid a => a
mempty

instance Semigroup PtHeaderConfig where
  PtHeaderConfig
x <> :: PtHeaderConfig -> PtHeaderConfig -> PtHeaderConfig
<> PtHeaderConfig
y = HeaderConfig :: forall (p :: Phase).
(p ::: [Text])
-> (p ::: Int)
-> (p ::: Int)
-> (p ::: [Regex])
-> (p ::: [Regex])
-> (p ::: HeaderSyntax)
-> HeaderConfig p
HeaderConfig
    { hcFileExtensions :: 'Partial ::: [Text]
hcFileExtensions = PtHeaderConfig -> 'Partial ::: [Text]
forall (p :: Phase). HeaderConfig p -> p ::: [Text]
hcFileExtensions PtHeaderConfig
x Last [Text] -> Last [Text] -> Last [Text]
forall a. Semigroup a => a -> a -> a
<> PtHeaderConfig -> 'Partial ::: [Text]
forall (p :: Phase). HeaderConfig p -> p ::: [Text]
hcFileExtensions PtHeaderConfig
y
    , hcMarginAfter :: 'Partial ::: Int
hcMarginAfter    = PtHeaderConfig -> 'Partial ::: Int
forall (p :: Phase). HeaderConfig p -> p ::: Int
hcMarginAfter PtHeaderConfig
x Last Int -> Last Int -> Last Int
forall a. Semigroup a => a -> a -> a
<> PtHeaderConfig -> 'Partial ::: Int
forall (p :: Phase). HeaderConfig p -> p ::: Int
hcMarginAfter PtHeaderConfig
y
    , hcMarginBefore :: 'Partial ::: Int
hcMarginBefore   = PtHeaderConfig -> 'Partial ::: Int
forall (p :: Phase). HeaderConfig p -> p ::: Int
hcMarginBefore PtHeaderConfig
x Last Int -> Last Int -> Last Int
forall a. Semigroup a => a -> a -> a
<> PtHeaderConfig -> 'Partial ::: Int
forall (p :: Phase). HeaderConfig p -> p ::: Int
hcMarginBefore PtHeaderConfig
y
    , hcPutAfter :: 'Partial ::: [Regex]
hcPutAfter       = PtHeaderConfig -> 'Partial ::: [Regex]
forall (p :: Phase). HeaderConfig p -> p ::: [Regex]
hcPutAfter PtHeaderConfig
x Last [Regex] -> Last [Regex] -> Last [Regex]
forall a. Semigroup a => a -> a -> a
<> PtHeaderConfig -> 'Partial ::: [Regex]
forall (p :: Phase). HeaderConfig p -> p ::: [Regex]
hcPutAfter PtHeaderConfig
y
    , hcPutBefore :: 'Partial ::: [Regex]
hcPutBefore      = PtHeaderConfig -> 'Partial ::: [Regex]
forall (p :: Phase). HeaderConfig p -> p ::: [Regex]
hcPutBefore PtHeaderConfig
x Last [Regex] -> Last [Regex] -> Last [Regex]
forall a. Semigroup a => a -> a -> a
<> PtHeaderConfig -> 'Partial ::: [Regex]
forall (p :: Phase). HeaderConfig p -> p ::: [Regex]
hcPutBefore PtHeaderConfig
y
    , hcHeaderSyntax :: 'Partial ::: HeaderSyntax
hcHeaderSyntax   = PtHeaderConfig -> 'Partial ::: HeaderSyntax
forall (p :: Phase). HeaderConfig p -> p ::: HeaderSyntax
hcHeaderSyntax PtHeaderConfig
x Last HeaderSyntax -> Last HeaderSyntax -> Last HeaderSyntax
forall a. Semigroup a => a -> a -> a
<> PtHeaderConfig -> 'Partial ::: HeaderSyntax
forall (p :: Phase). HeaderConfig p -> p ::: HeaderSyntax
hcHeaderSyntax PtHeaderConfig
y
    }


--------------------------------  HeadersConfig  -------------------------------

-- | Group of 'HeaderConfig' configurations for supported file types.
data HeadersConfig (p :: Phase) = HeadersConfig
  { HeadersConfig p -> HeaderConfig p
hscC       :: !(HeaderConfig p)
  -- ^ configuration for /C/ programming language
  , HeadersConfig p -> HeaderConfig p
hscCpp     :: !(HeaderConfig p)
  -- ^ configuration for /C++/ programming language
  , HeadersConfig p -> HeaderConfig p
hscCss     :: !(HeaderConfig p)
  -- ^ configuration for /CSS/
  , HeadersConfig p -> HeaderConfig p
hscHaskell :: !(HeaderConfig p)
  -- ^ configuration for /Haskell/ programming language
  , HeadersConfig p -> HeaderConfig p
hscHtml    :: !(HeaderConfig p)
  -- ^ configuration for /HTML/
  , HeadersConfig p -> HeaderConfig p
hscJava    :: !(HeaderConfig p)
  -- ^ configuration for /Java/ programming language
  , HeadersConfig p -> HeaderConfig p
hscJs      :: !(HeaderConfig p)
  -- ^ configuration for /JavaScript/ programming language
  , HeadersConfig p -> HeaderConfig p
hscRust    :: !(HeaderConfig p)
  -- ^ configuration for /Rust/ programming language
  , HeadersConfig p -> HeaderConfig p
hscScala   :: !(HeaderConfig p)
  -- ^ configuration for /Scala/ programming language
  , HeadersConfig p -> HeaderConfig p
hscShell   :: !(HeaderConfig p)
  -- ^ configuration for /Shell/
  }

-- | Alias for complete variant of 'HeadersConfig'.
type CtHeadersConfig = HeadersConfig 'Complete

-- | Alias for partial variant of 'HeadersConfig'.
type PtHeadersConfig = HeadersConfig 'Partial

deriving instance Eq CtHeadersConfig
deriving instance Eq PtHeadersConfig
deriving instance Show CtHeadersConfig
deriving instance Show PtHeadersConfig

instance FromJSON PtHeadersConfig where
  parseJSON :: Value -> Parser (HeadersConfig 'Partial)
parseJSON = String
-> (Object -> Parser (HeadersConfig 'Partial))
-> Value
-> Parser (HeadersConfig 'Partial)
forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject String
"PartialHeadersConfig" ((Object -> Parser (HeadersConfig 'Partial))
 -> Value -> Parser (HeadersConfig 'Partial))
-> (Object -> Parser (HeadersConfig 'Partial))
-> Value
-> Parser (HeadersConfig 'Partial)
forall a b. (a -> b) -> a -> b
$ \Object
obj -> do
    PtHeaderConfig
hscC       <- Object
obj Object -> Text -> Parser (Maybe PtHeaderConfig)
forall a. FromJSON a => Object -> Text -> Parser (Maybe a)
.:? Text
"c" Parser (Maybe PtHeaderConfig)
-> PtHeaderConfig -> Parser PtHeaderConfig
forall a. Parser (Maybe a) -> a -> Parser a
.!= PtHeaderConfig
forall a. Monoid a => a
mempty
    PtHeaderConfig
hscCpp     <- Object
obj Object -> Text -> Parser (Maybe PtHeaderConfig)
forall a. FromJSON a => Object -> Text -> Parser (Maybe a)
.:? Text
"cpp" Parser (Maybe PtHeaderConfig)
-> PtHeaderConfig -> Parser PtHeaderConfig
forall a. Parser (Maybe a) -> a -> Parser a
.!= PtHeaderConfig
forall a. Monoid a => a
mempty
    PtHeaderConfig
hscCss     <- Object
obj Object -> Text -> Parser (Maybe PtHeaderConfig)
forall a. FromJSON a => Object -> Text -> Parser (Maybe a)
.:? Text
"css" Parser (Maybe PtHeaderConfig)
-> PtHeaderConfig -> Parser PtHeaderConfig
forall a. Parser (Maybe a) -> a -> Parser a
.!= PtHeaderConfig
forall a. Monoid a => a
mempty
    PtHeaderConfig
hscHaskell <- Object
obj Object -> Text -> Parser (Maybe PtHeaderConfig)
forall a. FromJSON a => Object -> Text -> Parser (Maybe a)
.:? Text
"haskell" Parser (Maybe PtHeaderConfig)
-> PtHeaderConfig -> Parser PtHeaderConfig
forall a. Parser (Maybe a) -> a -> Parser a
.!= PtHeaderConfig
forall a. Monoid a => a
mempty
    PtHeaderConfig
hscHtml    <- Object
obj Object -> Text -> Parser (Maybe PtHeaderConfig)
forall a. FromJSON a => Object -> Text -> Parser (Maybe a)
.:? Text
"html" Parser (Maybe PtHeaderConfig)
-> PtHeaderConfig -> Parser PtHeaderConfig
forall a. Parser (Maybe a) -> a -> Parser a
.!= PtHeaderConfig
forall a. Monoid a => a
mempty
    PtHeaderConfig
hscJava    <- Object
obj Object -> Text -> Parser (Maybe PtHeaderConfig)
forall a. FromJSON a => Object -> Text -> Parser (Maybe a)
.:? Text
"java" Parser (Maybe PtHeaderConfig)
-> PtHeaderConfig -> Parser PtHeaderConfig
forall a. Parser (Maybe a) -> a -> Parser a
.!= PtHeaderConfig
forall a. Monoid a => a
mempty
    PtHeaderConfig
hscJs      <- Object
obj Object -> Text -> Parser (Maybe PtHeaderConfig)
forall a. FromJSON a => Object -> Text -> Parser (Maybe a)
.:? Text
"js" Parser (Maybe PtHeaderConfig)
-> PtHeaderConfig -> Parser PtHeaderConfig
forall a. Parser (Maybe a) -> a -> Parser a
.!= PtHeaderConfig
forall a. Monoid a => a
mempty
    PtHeaderConfig
hscRust    <- Object
obj Object -> Text -> Parser (Maybe PtHeaderConfig)
forall a. FromJSON a => Object -> Text -> Parser (Maybe a)
.:? Text
"rust" Parser (Maybe PtHeaderConfig)
-> PtHeaderConfig -> Parser PtHeaderConfig
forall a. Parser (Maybe a) -> a -> Parser a
.!= PtHeaderConfig
forall a. Monoid a => a
mempty
    PtHeaderConfig
hscScala   <- Object
obj Object -> Text -> Parser (Maybe PtHeaderConfig)
forall a. FromJSON a => Object -> Text -> Parser (Maybe a)
.:? Text
"scala" Parser (Maybe PtHeaderConfig)
-> PtHeaderConfig -> Parser PtHeaderConfig
forall a. Parser (Maybe a) -> a -> Parser a
.!= PtHeaderConfig
forall a. Monoid a => a
mempty
    PtHeaderConfig
hscShell   <- Object
obj Object -> Text -> Parser (Maybe PtHeaderConfig)
forall a. FromJSON a => Object -> Text -> Parser (Maybe a)
.:? Text
"shell" Parser (Maybe PtHeaderConfig)
-> PtHeaderConfig -> Parser PtHeaderConfig
forall a. Parser (Maybe a) -> a -> Parser a
.!= PtHeaderConfig
forall a. Monoid a => a
mempty
    HeadersConfig 'Partial -> Parser (HeadersConfig 'Partial)
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
-> HeadersConfig p
HeadersConfig { PtHeaderConfig
hscShell :: PtHeaderConfig
hscScala :: PtHeaderConfig
hscRust :: PtHeaderConfig
hscJs :: PtHeaderConfig
hscJava :: PtHeaderConfig
hscHtml :: PtHeaderConfig
hscHaskell :: PtHeaderConfig
hscCss :: PtHeaderConfig
hscCpp :: PtHeaderConfig
hscC :: PtHeaderConfig
hscShell :: PtHeaderConfig
hscScala :: PtHeaderConfig
hscRust :: PtHeaderConfig
hscJs :: PtHeaderConfig
hscJava :: PtHeaderConfig
hscHtml :: PtHeaderConfig
hscHaskell :: PtHeaderConfig
hscCss :: PtHeaderConfig
hscCpp :: PtHeaderConfig
hscC :: PtHeaderConfig
.. }


instance Semigroup PtHeadersConfig where
  HeadersConfig 'Partial
x <> :: HeadersConfig 'Partial
-> HeadersConfig 'Partial -> HeadersConfig 'Partial
<> HeadersConfig 'Partial
y = HeadersConfig :: forall (p :: Phase).
HeaderConfig p
-> HeaderConfig p
-> HeaderConfig p
-> HeaderConfig p
-> HeaderConfig p
-> HeaderConfig p
-> HeaderConfig p
-> HeaderConfig p
-> HeaderConfig p
-> HeaderConfig p
-> HeadersConfig p
HeadersConfig { hscC :: PtHeaderConfig
hscC       = HeadersConfig 'Partial -> PtHeaderConfig
forall (p :: Phase). HeadersConfig p -> HeaderConfig p
hscC HeadersConfig 'Partial
x PtHeaderConfig -> PtHeaderConfig -> PtHeaderConfig
forall a. Semigroup a => a -> a -> a
<> HeadersConfig 'Partial -> PtHeaderConfig
forall (p :: Phase). HeadersConfig p -> HeaderConfig p
hscC HeadersConfig 'Partial
y
                         , hscCpp :: PtHeaderConfig
hscCpp     = HeadersConfig 'Partial -> PtHeaderConfig
forall (p :: Phase). HeadersConfig p -> HeaderConfig p
hscCpp HeadersConfig 'Partial
x PtHeaderConfig -> PtHeaderConfig -> PtHeaderConfig
forall a. Semigroup a => a -> a -> a
<> HeadersConfig 'Partial -> PtHeaderConfig
forall (p :: Phase). HeadersConfig p -> HeaderConfig p
hscCpp HeadersConfig 'Partial
y
                         , hscCss :: PtHeaderConfig
hscCss     = HeadersConfig 'Partial -> PtHeaderConfig
forall (p :: Phase). HeadersConfig p -> HeaderConfig p
hscCss HeadersConfig 'Partial
x PtHeaderConfig -> PtHeaderConfig -> PtHeaderConfig
forall a. Semigroup a => a -> a -> a
<> HeadersConfig 'Partial -> PtHeaderConfig
forall (p :: Phase). HeadersConfig p -> HeaderConfig p
hscCss HeadersConfig 'Partial
y
                         , hscHaskell :: PtHeaderConfig
hscHaskell = HeadersConfig 'Partial -> PtHeaderConfig
forall (p :: Phase). HeadersConfig p -> HeaderConfig p
hscHaskell HeadersConfig 'Partial
x PtHeaderConfig -> PtHeaderConfig -> PtHeaderConfig
forall a. Semigroup a => a -> a -> a
<> HeadersConfig 'Partial -> PtHeaderConfig
forall (p :: Phase). HeadersConfig p -> HeaderConfig p
hscHaskell HeadersConfig 'Partial
y
                         , hscHtml :: PtHeaderConfig
hscHtml    = HeadersConfig 'Partial -> PtHeaderConfig
forall (p :: Phase). HeadersConfig p -> HeaderConfig p
hscHtml HeadersConfig 'Partial
x PtHeaderConfig -> PtHeaderConfig -> PtHeaderConfig
forall a. Semigroup a => a -> a -> a
<> HeadersConfig 'Partial -> PtHeaderConfig
forall (p :: Phase). HeadersConfig p -> HeaderConfig p
hscHtml HeadersConfig 'Partial
y
                         , hscJava :: PtHeaderConfig
hscJava    = HeadersConfig 'Partial -> PtHeaderConfig
forall (p :: Phase). HeadersConfig p -> HeaderConfig p
hscJava HeadersConfig 'Partial
x PtHeaderConfig -> PtHeaderConfig -> PtHeaderConfig
forall a. Semigroup a => a -> a -> a
<> HeadersConfig 'Partial -> PtHeaderConfig
forall (p :: Phase). HeadersConfig p -> HeaderConfig p
hscJava HeadersConfig 'Partial
y
                         , hscJs :: PtHeaderConfig
hscJs      = HeadersConfig 'Partial -> PtHeaderConfig
forall (p :: Phase). HeadersConfig p -> HeaderConfig p
hscJs HeadersConfig 'Partial
x PtHeaderConfig -> PtHeaderConfig -> PtHeaderConfig
forall a. Semigroup a => a -> a -> a
<> HeadersConfig 'Partial -> PtHeaderConfig
forall (p :: Phase). HeadersConfig p -> HeaderConfig p
hscJs HeadersConfig 'Partial
y
                         , hscRust :: PtHeaderConfig
hscRust    = HeadersConfig 'Partial -> PtHeaderConfig
forall (p :: Phase). HeadersConfig p -> HeaderConfig p
hscRust HeadersConfig 'Partial
x PtHeaderConfig -> PtHeaderConfig -> PtHeaderConfig
forall a. Semigroup a => a -> a -> a
<> HeadersConfig 'Partial -> PtHeaderConfig
forall (p :: Phase). HeadersConfig p -> HeaderConfig p
hscRust HeadersConfig 'Partial
y
                         , hscScala :: PtHeaderConfig
hscScala   = HeadersConfig 'Partial -> PtHeaderConfig
forall (p :: Phase). HeadersConfig p -> HeaderConfig p
hscScala HeadersConfig 'Partial
x PtHeaderConfig -> PtHeaderConfig -> PtHeaderConfig
forall a. Semigroup a => a -> a -> a
<> HeadersConfig 'Partial -> PtHeaderConfig
forall (p :: Phase). HeadersConfig p -> HeaderConfig p
hscScala HeadersConfig 'Partial
y
                         , hscShell :: PtHeaderConfig
hscShell   = HeadersConfig 'Partial -> PtHeaderConfig
forall (p :: Phase). HeadersConfig p -> HeaderConfig p
hscShell HeadersConfig 'Partial
x PtHeaderConfig -> PtHeaderConfig -> PtHeaderConfig
forall a. Semigroup a => a -> a -> a
<> HeadersConfig 'Partial -> PtHeaderConfig
forall (p :: Phase). HeadersConfig p -> HeaderConfig p
hscShell HeadersConfig 'Partial
y
                         }


instance Monoid PtHeadersConfig where
  mempty :: HeadersConfig 'Partial
mempty = PtHeaderConfig
-> PtHeaderConfig
-> PtHeaderConfig
-> PtHeaderConfig
-> PtHeaderConfig
-> PtHeaderConfig
-> PtHeaderConfig
-> PtHeaderConfig
-> PtHeaderConfig
-> PtHeaderConfig
-> HeadersConfig 'Partial
forall (p :: Phase).
HeaderConfig p
-> HeaderConfig p
-> HeaderConfig p
-> HeaderConfig p
-> HeaderConfig p
-> HeaderConfig p
-> HeaderConfig p
-> HeaderConfig p
-> HeaderConfig p
-> HeaderConfig p
-> HeadersConfig p
HeadersConfig PtHeaderConfig
forall a. Monoid a => a
mempty
                         PtHeaderConfig
forall a. Monoid a => a
mempty
                         PtHeaderConfig
forall a. Monoid a => a
mempty
                         PtHeaderConfig
forall a. Monoid a => a
mempty
                         PtHeaderConfig
forall a. Monoid a => a
mempty
                         PtHeaderConfig
forall a. Monoid a => a
mempty
                         PtHeaderConfig
forall a. Monoid a => a
mempty
                         PtHeaderConfig
forall a. Monoid a => a
mempty
                         PtHeaderConfig
forall a. Monoid a => a
mempty
                         PtHeaderConfig
forall a. Monoid a => a
mempty


---------------------------------  Error Types  --------------------------------

-- | Represents single key in the configuration.
data ConfigurationKey
  = CkFileExtensions !FileType
  -- ^ no configuration for @file-extensions@
  | CkHeaderSyntax !FileType
  -- ^ no configuration for header syntax
  | CkMarginAfter !FileType
  -- ^ no configuration for @margin-after@
  | CkMarginBefore !FileType
  -- ^ no configuration for @margin-before@
  | CkPutAfter !FileType
  -- ^ no configuration for @put-after@
  | CkPutBefore !FileType
  -- ^ no configuration for @put-before@
  | CkRunMode
  -- ^ no configuration for @run-mode@
  | CkSourcePaths
  -- ^ no configuration for @source-paths@
  | CkExcludedPaths
  -- ^ no configuration for @excluded-paths@
  | CkTemplateSource
  -- ^ no configuration for template source
  | CkVariables
  -- ^ no configuration for @variables@
  | CkEnabled
  -- ^ no configuration for @enabled@
  deriving (ConfigurationKey -> ConfigurationKey -> Bool
(ConfigurationKey -> ConfigurationKey -> Bool)
-> (ConfigurationKey -> ConfigurationKey -> Bool)
-> Eq ConfigurationKey
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ConfigurationKey -> ConfigurationKey -> Bool
$c/= :: ConfigurationKey -> ConfigurationKey -> Bool
== :: ConfigurationKey -> ConfigurationKey -> Bool
$c== :: ConfigurationKey -> ConfigurationKey -> Bool
Eq, Int -> ConfigurationKey -> ShowS
[ConfigurationKey] -> ShowS
ConfigurationKey -> String
(Int -> ConfigurationKey -> ShowS)
-> (ConfigurationKey -> String)
-> ([ConfigurationKey] -> ShowS)
-> Show ConfigurationKey
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ConfigurationKey] -> ShowS
$cshowList :: [ConfigurationKey] -> ShowS
show :: ConfigurationKey -> String
$cshow :: ConfigurationKey -> String
showsPrec :: Int -> ConfigurationKey -> ShowS
$cshowsPrec :: Int -> ConfigurationKey -> ShowS
Show)


-- | Exception specific to the "Headroom.Configuration" module.
data ConfigurationError
  = MissingConfiguration !ConfigurationKey
  -- ^ some of the required configuration keys has not been specified
  | MixedHeaderSyntax
  -- ^ illegal configuration for 'HeaderSyntax'
  deriving (ConfigurationError -> ConfigurationError -> Bool
(ConfigurationError -> ConfigurationError -> Bool)
-> (ConfigurationError -> ConfigurationError -> Bool)
-> Eq ConfigurationError
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ConfigurationError -> ConfigurationError -> Bool
$c/= :: ConfigurationError -> ConfigurationError -> Bool
== :: ConfigurationError -> ConfigurationError -> Bool
$c== :: ConfigurationError -> ConfigurationError -> Bool
Eq, Int -> ConfigurationError -> ShowS
[ConfigurationError] -> ShowS
ConfigurationError -> String
(Int -> ConfigurationError -> ShowS)
-> (ConfigurationError -> String)
-> ([ConfigurationError] -> ShowS)
-> Show ConfigurationError
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ConfigurationError] -> ShowS
$cshowList :: [ConfigurationError] -> ShowS
show :: ConfigurationError -> String
$cshow :: ConfigurationError -> String
showsPrec :: Int -> ConfigurationError -> ShowS
$cshowsPrec :: Int -> ConfigurationError -> ShowS
Show, Typeable)

instance Exception ConfigurationError where
  displayException :: ConfigurationError -> String
displayException = ConfigurationError -> String
displayException'
  toException :: ConfigurationError -> SomeException
toException      = ConfigurationError -> SomeException
forall e. Exception e => e -> SomeException
toHeadroomError
  fromException :: SomeException -> Maybe ConfigurationError
fromException    = SomeException -> Maybe ConfigurationError
forall e. Exception e => SomeException -> Maybe e
fromHeadroomError

displayException' :: ConfigurationError -> String
displayException' :: ConfigurationError -> String
displayException' = Text -> String
T.unpack (Text -> String)
-> (ConfigurationError -> Text) -> ConfigurationError -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. \case
  MissingConfiguration ConfigurationKey
key -> case ConfigurationKey
key of
    CkFileExtensions FileType
fileType -> Text -> Maybe Text -> Maybe Text -> Text
missingConfig
      (Text -> FileType -> Text
forall a. Show a => Text -> a -> Text
withFT Text
"file-extensions" FileType
fileType)
      (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"file-extensions")
      Maybe Text
forall a. Maybe a
Nothing
    CkHeaderSyntax FileType
fileType -> Text -> Maybe Text -> Maybe Text -> Text
missingConfig
      (Text -> FileType -> Text
forall a. Show a => Text -> a -> Text
withFT Text
"comment-syntax" FileType
fileType)
      (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"block-comment|line-comment")
      Maybe Text
forall a. Maybe a
Nothing
    CkMarginAfter FileType
fileType -> Text -> Maybe Text -> Maybe Text -> Text
missingConfig (Text -> FileType -> Text
forall a. Show a => Text -> a -> Text
withFT Text
"margin-after" FileType
fileType)
                                            (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"margin-after")
                                            Maybe Text
forall a. Maybe a
Nothing
    CkMarginBefore FileType
fileType -> Text -> Maybe Text -> Maybe Text -> Text
missingConfig
      (Text -> FileType -> Text
forall a. Show a => Text -> a -> Text
withFT Text
"margin-before" FileType
fileType)
      (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"margin-before")
      Maybe Text
forall a. Maybe a
Nothing
    CkPutAfter FileType
fileType ->
      Text -> Maybe Text -> Maybe Text -> Text
missingConfig (Text -> FileType -> Text
forall a. Show a => Text -> a -> Text
withFT Text
"put-after" FileType
fileType) (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"put-after") Maybe Text
forall a. Maybe a
Nothing
    CkPutBefore FileType
fileType ->
      Text -> Maybe Text -> Maybe Text -> Text
missingConfig (Text -> FileType -> Text
forall a. Show a => Text -> a -> Text
withFT Text
"put-before" FileType
fileType) (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"put-before") Maybe Text
forall a. Maybe a
Nothing
    ConfigurationKey
CkRunMode -> Text -> Maybe Text -> Maybe Text -> Text
missingConfig
      Text
"mode of the run command"
      (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"run-mode")
      (Text -> Maybe Text
forall a. a -> Maybe a
Just
        Text
"(-a|--add-headers)|(-c|--check-header)|(-d|--drop-header)|(-r|--replace-headers)"
      )
    ConfigurationKey
CkSourcePaths -> Text -> Maybe Text -> Maybe Text -> Text
missingConfig Text
"paths to source code files"
                                   (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"source-paths")
                                   (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"-s|--source-path")
    ConfigurationKey
CkExcludedPaths -> Text -> Maybe Text -> Maybe Text -> Text
missingConfig Text
"excluded paths"
                                     (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"excluded-paths")
                                     (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"-e|--excluded-path")
    ConfigurationKey
CkTemplateSource -> Text -> Maybe Text -> Maybe Text -> Text
missingConfig
      Text
"template files source"
      (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"template-paths")
      (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"(-t|--template-path)|--builtin-templates")
    ConfigurationKey
CkVariables -> Text -> Maybe Text -> Maybe Text -> Text
missingConfig Text
"template variables"
                                 (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"variables")
                                 (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"-v|--variable")
    ConfigurationKey
CkEnabled -> Text -> Maybe Text -> Maybe Text -> Text
missingConfig Text
"enabled" (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"enabled") Maybe Text
forall a. Maybe a
Nothing
  ConfigurationError
MixedHeaderSyntax -> Text
mixedHeaderSyntax
 where
  withFT :: Text -> a -> Text
withFT Text
msg a
fileType = Text
msg Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" (" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> String -> Text
T.pack (a -> String
forall a. Show a => a -> String
show a
fileType) Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
")"
  mixedHeaderSyntax :: Text
mixedHeaderSyntax = [Text] -> Text
forall a. Monoid a => [a] -> a
mconcat
    [ Text
"Invalid configuration, combining 'block-comment' with 'line-comment' "
    , Text
"is not allowed. Either use 'block-comment' to define multi-line "
    , Text
"comment header, or 'line-comment' to define header composed of "
    , Text
"multiple single-line comments."
    ]


missingConfig :: Text -> Maybe Text -> Maybe Text -> Text
missingConfig :: Text -> Maybe Text -> Maybe Text -> Text
missingConfig Text
desc Maybe Text
yaml Maybe Text
cli = [Text] -> Text
forall a. Monoid a => [a] -> a
mconcat
  [ Text
"Missing configuration for '"
  , Text
desc
  , Text
"' ("
  , Text
options
  , Text
"). See official documentation for more details."
  ]
 where
  cliText :: Maybe Text
cliText  = (Text -> Text) -> Maybe Text -> Maybe Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\Text
c -> Text
"command line option '" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
c Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"'") Maybe Text
cli
  yamlText :: Maybe Text
yamlText = (Text -> Text) -> Maybe Text -> Maybe Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\Text
y -> Text
"YAML option '" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
y Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"'") Maybe Text
yaml
  options :: Text
options  = Text -> [Text] -> Text
T.intercalate Text
" or " ([Text] -> Text)
-> ([Maybe Text] -> [Text]) -> [Maybe Text] -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Maybe Text] -> [Text]
forall a. [Maybe a] -> [a]
catMaybes ([Maybe Text] -> Text) -> [Maybe Text] -> Text
forall a b. (a -> b) -> a -> b
$ [Maybe Text
cliText, Maybe Text
yamlText]


-----------------------------------  LENSES  -----------------------------------

suffixLenses ''Configuration
suffixLenses ''UpdateCopyrightConfig
suffixLenses ''HeaderFnConfig
suffixLenses ''HeaderFnConfigs