stackctl-1.4.2.2: src/Stackctl/Spec/Generate.hs
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
{ gDescription :: Maybe StackDescription
, gDepends :: Maybe [StackName]
, gActions :: Maybe [Action]
, gParameters :: Maybe [Parameter]
, gCapabilities :: Maybe [Capability]
, gTags :: Maybe [Tag]
, gSpec :: GenerateSpec
, gTemplate :: GenerateTemplate
, gOverwrite :: Bool
}
data GenerateSpec
= -- | Generate at an inferred name
GenerateSpec StackName
| -- | Generate to a given path
GenerateSpecTo StackName FilePath
data GenerateTemplate
= -- | Generate at an inferred name
GenerateTemplate TemplateBody TemplateFormat
| -- | Generate to the given path
GenerateTemplateTo TemplateBody FilePath
| -- | Assume template exists
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 Generate {..} = do
let
(stackName, stackPath) = case gSpec of
GenerateSpec name -> (name, unpack (unStackName name) <> ".yaml")
GenerateSpecTo name path -> (name, path)
(mTemplateBody, templatePath) = case gTemplate of
GenerateTemplate body format ->
( Just body
, case format of
TemplateFormatYaml -> unpack (unStackName stackName) <> ".yaml"
TemplateFormatJson -> unpack (unStackName stackName) <> ".json"
)
GenerateTemplateTo body path -> (Just body, path)
UseExistingTemplate path -> (Nothing, path)
specYaml =
StackSpecYaml
{ ssyDescription = gDescription
, ssyTemplate = templatePath
, ssyDepends = gDepends
, ssyActions = gActions
, ssyParameters = parametersYaml . mapMaybe parameterYaml <$> gParameters
, ssyCapabilities = gCapabilities
, ssyTags = tagsYaml . map TagYaml <$> gTags
}
dir <- view $ directoryOptionL . to unDirectoryOption
specPath <- buildSpecPath stackName stackPath
stackSpec <- buildStackSpec dir specPath specYaml
withThreadContext ["stackName" .= stackSpecStackName stackSpec] $ do
writeStackSpec gOverwrite stackSpec mTemplateBody
pure $ stackSpecPathFilePath specPath