module Stackctl.Spec.Generate
( Generate (..)
, GenerateSpec (..)
, GenerateTemplate (..)
, generate
, TemplateFormat (..)
) where
import Stackctl.Prelude
import Stackctl.AWS
import Stackctl.AWS.Scope
import Stackctl.Action
import Stackctl.Config (HasConfig)
import Stackctl.DirectoryOption
import Stackctl.Spec.Discover (buildSpecPath)
import Stackctl.StackSpec
import Stackctl.StackSpecPath
import Stackctl.StackSpecYaml
data Generate = Generate
{ Generate -> Maybe StackDescription
gDescription :: Maybe StackDescription
, Generate -> Maybe [StackName]
gDepends :: Maybe [StackName]
, Generate -> Maybe [Action]
gActions :: Maybe [Action]
, Generate -> Maybe [Parameter]
gParameters :: Maybe [Parameter]
, Generate -> Maybe [Capability]
gCapabilities :: Maybe [Capability]
, Generate -> Maybe [Tag]
gTags :: Maybe [Tag]
, Generate -> GenerateSpec
gSpec :: GenerateSpec
, Generate -> GenerateTemplate
gTemplate :: GenerateTemplate
, Generate -> Bool
gOverwrite :: Bool
}
data GenerateSpec
=
GenerateSpec StackName
|
GenerateSpecTo StackName FilePath
data GenerateTemplate
=
GenerateTemplate TemplateBody TemplateFormat
|
GenerateTemplateTo TemplateBody FilePath
|
UseExistingTemplate FilePath
data TemplateFormat
= TemplateFormatYaml
| TemplateFormatJson
generate
:: ( MonadMask m
, MonadUnliftIO m
, MonadLogger m
, MonadReader env m
, HasConfig env
, HasAwsScope env
, HasDirectoryOption env
)
=> Generate
-> m FilePath
generate :: forall (m :: * -> *) env.
(MonadMask m, MonadUnliftIO m, MonadLogger m, MonadReader env m,
HasConfig env, HasAwsScope env, HasDirectoryOption env) =>
Generate -> m FilePath
generate Generate {Bool
Maybe [Tag]
Maybe [Parameter]
Maybe [Capability]
Maybe [StackName]
Maybe [Action]
Maybe StackDescription
GenerateTemplate
GenerateSpec
gOverwrite :: Bool
gTemplate :: GenerateTemplate
gSpec :: GenerateSpec
gTags :: Maybe [Tag]
gCapabilities :: Maybe [Capability]
gParameters :: Maybe [Parameter]
gActions :: Maybe [Action]
gDepends :: Maybe [StackName]
gDescription :: Maybe StackDescription
gOverwrite :: Generate -> Bool
gTemplate :: Generate -> GenerateTemplate
gSpec :: Generate -> GenerateSpec
gTags :: Generate -> Maybe [Tag]
gCapabilities :: Generate -> Maybe [Capability]
gParameters :: Generate -> Maybe [Parameter]
gActions :: Generate -> Maybe [Action]
gDepends :: Generate -> Maybe [StackName]
gDescription :: Generate -> Maybe StackDescription
..} = do
let
(StackName
stackName, FilePath
stackPath) = case GenerateSpec
gSpec of
GenerateSpec StackName
name -> (StackName
name, Text -> FilePath
unpack (StackName -> Text
unStackName StackName
name) forall a. Semigroup a => a -> a -> a
<> FilePath
".yaml")
GenerateSpecTo StackName
name FilePath
path -> (StackName
name, FilePath
path)
(Maybe TemplateBody
mTemplateBody, FilePath
templatePath) = case GenerateTemplate
gTemplate of
GenerateTemplate TemplateBody
body TemplateFormat
format ->
( forall a. a -> Maybe a
Just TemplateBody
body
, case TemplateFormat
format of
TemplateFormat
TemplateFormatYaml -> Text -> FilePath
unpack (StackName -> Text
unStackName StackName
stackName) forall a. Semigroup a => a -> a -> a
<> FilePath
".yaml"
TemplateFormat
TemplateFormatJson -> Text -> FilePath
unpack (StackName -> Text
unStackName StackName
stackName) forall a. Semigroup a => a -> a -> a
<> FilePath
".json"
)
GenerateTemplateTo TemplateBody
body FilePath
path -> (forall a. a -> Maybe a
Just TemplateBody
body, FilePath
path)
UseExistingTemplate FilePath
path -> (forall a. Maybe a
Nothing, FilePath
path)
specYaml :: StackSpecYaml
specYaml =
StackSpecYaml
{ ssyDescription :: Maybe StackDescription
ssyDescription = Maybe StackDescription
gDescription
, ssyTemplate :: FilePath
ssyTemplate = FilePath
templatePath
, ssyDepends :: Maybe [StackName]
ssyDepends = Maybe [StackName]
gDepends
, ssyActions :: Maybe [Action]
ssyActions = Maybe [Action]
gActions
, ssyParameters :: Maybe ParametersYaml
ssyParameters = [ParameterYaml] -> ParametersYaml
parametersYaml forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe Parameter -> Maybe ParameterYaml
parameterYaml forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe [Parameter]
gParameters
, ssyCapabilities :: Maybe [Capability]
ssyCapabilities = Maybe [Capability]
gCapabilities
, ssyTags :: Maybe TagsYaml
ssyTags = [TagYaml] -> TagsYaml
tagsYaml forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map Tag -> TagYaml
TagYaml forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe [Tag]
gTags
}
FilePath
dir <- forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view forall a b. (a -> b) -> a -> b
$ forall env. HasDirectoryOption env => Lens' env DirectoryOption
directoryOptionL forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall s a. (s -> a) -> SimpleGetter s a
to DirectoryOption -> FilePath
unDirectoryOption
StackSpecPath
specPath <- forall env (m :: * -> *).
(MonadReader env m, HasAwsScope env) =>
StackName -> FilePath -> m StackSpecPath
buildSpecPath StackName
stackName FilePath
stackPath
StackSpec
stackSpec <- forall env (m :: * -> *).
(MonadReader env m, HasConfig env) =>
FilePath -> StackSpecPath -> StackSpecYaml -> m StackSpec
buildStackSpec FilePath
dir StackSpecPath
specPath StackSpecYaml
specYaml
forall (m :: * -> *) a.
(MonadIO m, MonadMask m) =>
[Pair] -> m a -> m a
withThreadContext [Key
"stackName" forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= StackSpec -> StackName
stackSpecStackName StackSpec
stackSpec] forall a b. (a -> b) -> a -> b
$ do
forall (m :: * -> *).
(MonadUnliftIO m, MonadLogger m) =>
Bool -> StackSpec -> Maybe TemplateBody -> m ()
writeStackSpec Bool
gOverwrite StackSpec
stackSpec Maybe TemplateBody
mTemplateBody
forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ StackSpecPath -> FilePath
stackSpecPathFilePath StackSpecPath
specPath