mirror of
https://github.com/terraform-docs/terraform-docs.git
synced 2026-03-27 04:48:33 +07:00
Generate submodules documents with '--resurcive' flag
Considering the file strucutre below of main module and its submodules, now it is possible to generate documentation for them main and all its submodules in one execution, with `--recursive` flag. Note that generating documentation recursively is allowed only with `--output-file` set. Path to find submodules can be configured with `--recursive-path` (defaults to `modules`). Each submodule can also have their own `.terraform-docs.yml` confi file, to override configuration from root module. ``` . ├── README.md ├── main.tf ├── modules │ └── my-sub-module │ ├── README.md │ ├── main.tf │ ├── variables.tf │ └── versions.tf ├── outputs.tf ├── variables.tf └── versions.tf ``` Signed-off-by: Khosrow Moossavi <khos2ow@gmail.com>
This commit is contained in:
@@ -19,15 +19,15 @@ import (
|
||||
)
|
||||
|
||||
// NewCommand returns a new cobra.Command for 'asciidoc' formatter
|
||||
func NewCommand(config *cli.Config) *cobra.Command {
|
||||
func NewCommand(runtime *cli.Runtime, config *cli.Config) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Args: cobra.ExactArgs(1),
|
||||
Use: "asciidoc [PATH]",
|
||||
Aliases: []string{"adoc"},
|
||||
Short: "Generate AsciiDoc of inputs and outputs",
|
||||
Annotations: cli.Annotations("asciidoc"),
|
||||
PreRunE: cli.PreRunEFunc(config),
|
||||
RunE: cli.RunEFunc(config),
|
||||
PreRunE: runtime.PreRunEFunc,
|
||||
RunE: runtime.RunEFunc,
|
||||
}
|
||||
|
||||
// flags
|
||||
@@ -39,8 +39,8 @@ func NewCommand(config *cli.Config) *cobra.Command {
|
||||
cmd.PersistentFlags().BoolVar(&config.Settings.Type, "type", true, "show Type column or section")
|
||||
|
||||
// subcommands
|
||||
cmd.AddCommand(document.NewCommand(config))
|
||||
cmd.AddCommand(table.NewCommand(config))
|
||||
cmd.AddCommand(document.NewCommand(runtime, config))
|
||||
cmd.AddCommand(table.NewCommand(runtime, config))
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -17,15 +17,15 @@ import (
|
||||
)
|
||||
|
||||
// NewCommand returns a new cobra.Command for 'asciidoc document' formatter
|
||||
func NewCommand(config *cli.Config) *cobra.Command {
|
||||
func NewCommand(runtime *cli.Runtime, config *cli.Config) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Args: cobra.ExactArgs(1),
|
||||
Use: "document [PATH]",
|
||||
Aliases: []string{"doc"},
|
||||
Short: "Generate AsciiDoc document of inputs and outputs",
|
||||
Annotations: cli.Annotations("asciidoc document"),
|
||||
PreRunE: cli.PreRunEFunc(config),
|
||||
RunE: cli.RunEFunc(config),
|
||||
PreRunE: runtime.PreRunEFunc,
|
||||
RunE: runtime.RunEFunc,
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -17,15 +17,15 @@ import (
|
||||
)
|
||||
|
||||
// NewCommand returns a new cobra.Command for 'asciidoc table' formatter
|
||||
func NewCommand(config *cli.Config) *cobra.Command {
|
||||
func NewCommand(runtime *cli.Runtime, config *cli.Config) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Args: cobra.ExactArgs(1),
|
||||
Use: "table [PATH]",
|
||||
Aliases: []string{"tbl"},
|
||||
Short: "Generate AsciiDoc tables of inputs and outputs",
|
||||
Annotations: cli.Annotations("asciidoc table"),
|
||||
PreRunE: cli.PreRunEFunc(config),
|
||||
RunE: cli.RunEFunc(config),
|
||||
PreRunE: runtime.PreRunEFunc,
|
||||
RunE: runtime.RunEFunc,
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -17,14 +17,14 @@ import (
|
||||
)
|
||||
|
||||
// NewCommand returns a new cobra.Command for 'json' formatter
|
||||
func NewCommand(config *cli.Config) *cobra.Command {
|
||||
func NewCommand(runtime *cli.Runtime, config *cli.Config) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Args: cobra.ExactArgs(1),
|
||||
Use: "json [PATH]",
|
||||
Short: "Generate JSON of inputs and outputs",
|
||||
Annotations: cli.Annotations("json"),
|
||||
PreRunE: cli.PreRunEFunc(config),
|
||||
RunE: cli.RunEFunc(config),
|
||||
PreRunE: runtime.PreRunEFunc,
|
||||
RunE: runtime.RunEFunc,
|
||||
}
|
||||
|
||||
// flags
|
||||
|
||||
@@ -17,15 +17,15 @@ import (
|
||||
)
|
||||
|
||||
// NewCommand returns a new cobra.Command for 'markdown document' formatter
|
||||
func NewCommand(config *cli.Config) *cobra.Command {
|
||||
func NewCommand(runtime *cli.Runtime, config *cli.Config) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Args: cobra.ExactArgs(1),
|
||||
Use: "document [PATH]",
|
||||
Aliases: []string{"doc"},
|
||||
Short: "Generate Markdown document of inputs and outputs",
|
||||
Annotations: cli.Annotations("markdown document"),
|
||||
PreRunE: cli.PreRunEFunc(config),
|
||||
RunE: cli.RunEFunc(config),
|
||||
PreRunE: runtime.PreRunEFunc,
|
||||
RunE: runtime.RunEFunc,
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -19,15 +19,15 @@ import (
|
||||
)
|
||||
|
||||
// NewCommand returns a new cobra.Command for 'markdown' formatter
|
||||
func NewCommand(config *cli.Config) *cobra.Command {
|
||||
func NewCommand(runtime *cli.Runtime, config *cli.Config) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Args: cobra.ExactArgs(1),
|
||||
Use: "markdown [PATH]",
|
||||
Aliases: []string{"md"},
|
||||
Short: "Generate Markdown of inputs and outputs",
|
||||
Annotations: cli.Annotations("markdown"),
|
||||
PreRunE: cli.PreRunEFunc(config),
|
||||
RunE: cli.RunEFunc(config),
|
||||
PreRunE: runtime.PreRunEFunc,
|
||||
RunE: runtime.RunEFunc,
|
||||
}
|
||||
|
||||
// flags
|
||||
@@ -41,8 +41,8 @@ func NewCommand(config *cli.Config) *cobra.Command {
|
||||
cmd.PersistentFlags().BoolVar(&config.Settings.Type, "type", true, "show Type column or section")
|
||||
|
||||
// subcommands
|
||||
cmd.AddCommand(document.NewCommand(config))
|
||||
cmd.AddCommand(table.NewCommand(config))
|
||||
cmd.AddCommand(document.NewCommand(runtime, config))
|
||||
cmd.AddCommand(table.NewCommand(runtime, config))
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -17,15 +17,15 @@ import (
|
||||
)
|
||||
|
||||
// NewCommand returns a new cobra.Command for 'markdown table' formatter
|
||||
func NewCommand(config *cli.Config) *cobra.Command {
|
||||
func NewCommand(runtime *cli.Runtime, config *cli.Config) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Args: cobra.ExactArgs(1),
|
||||
Use: "table [PATH]",
|
||||
Aliases: []string{"tbl"},
|
||||
Short: "Generate Markdown tables of inputs and outputs",
|
||||
Annotations: cli.Annotations("markdown table"),
|
||||
PreRunE: cli.PreRunEFunc(config),
|
||||
RunE: cli.RunEFunc(config),
|
||||
PreRunE: runtime.PreRunEFunc,
|
||||
RunE: runtime.RunEFunc,
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -17,14 +17,14 @@ import (
|
||||
)
|
||||
|
||||
// NewCommand returns a new cobra.Command for pretty formatter
|
||||
func NewCommand(config *cli.Config) *cobra.Command {
|
||||
func NewCommand(runtime *cli.Runtime, config *cli.Config) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Args: cobra.ExactArgs(1),
|
||||
Use: "pretty [PATH]",
|
||||
Short: "Generate colorized pretty of inputs and outputs",
|
||||
Annotations: cli.Annotations("pretty"),
|
||||
PreRunE: cli.PreRunEFunc(config),
|
||||
RunE: cli.RunEFunc(config),
|
||||
PreRunE: runtime.PreRunEFunc,
|
||||
RunE: runtime.RunEFunc,
|
||||
}
|
||||
|
||||
// flags
|
||||
|
||||
23
cmd/root.go
23
cmd/root.go
@@ -43,6 +43,7 @@ func Execute() error {
|
||||
// NewCommand returns a new cobra.Command for 'root' command
|
||||
func NewCommand() *cobra.Command {
|
||||
config := cli.DefaultConfig()
|
||||
runtime := cli.NewRuntime(config)
|
||||
cmd := &cobra.Command{
|
||||
Args: cobra.MaximumNArgs(1),
|
||||
Use: "terraform-docs [PATH]",
|
||||
@@ -52,12 +53,14 @@ func NewCommand() *cobra.Command {
|
||||
SilenceUsage: true,
|
||||
SilenceErrors: true,
|
||||
Annotations: cli.Annotations("root"),
|
||||
PreRunE: cli.PreRunEFunc(config),
|
||||
RunE: cli.RunEFunc(config),
|
||||
PreRunE: runtime.PreRunEFunc,
|
||||
RunE: runtime.RunEFunc,
|
||||
}
|
||||
|
||||
// flags
|
||||
cmd.PersistentFlags().StringVarP(&config.File, "config", "c", ".terraform-docs.yml", "config file name")
|
||||
cmd.PersistentFlags().BoolVar(&config.Recursive, "recursive", false, "update submodules recursively (default false)")
|
||||
cmd.PersistentFlags().StringVar(&config.RecursivePath, "recursive-path", "modules", "submodules path to recursively update")
|
||||
|
||||
cmd.PersistentFlags().StringSliceVar(&config.Sections.Show, "show", []string{}, "show section ["+cli.AllSections+"]")
|
||||
cmd.PersistentFlags().StringSliceVar(&config.Sections.Hide, "hide", []string{}, "hide section ["+cli.AllSections+"]")
|
||||
@@ -79,14 +82,14 @@ func NewCommand() *cobra.Command {
|
||||
cmd.PersistentFlags().StringVar(&config.OutputValues.From, "output-values-from", "", "inject output values from file into outputs (default \"\")")
|
||||
|
||||
// formatter subcommands
|
||||
cmd.AddCommand(asciidoc.NewCommand(config))
|
||||
cmd.AddCommand(json.NewCommand(config))
|
||||
cmd.AddCommand(markdown.NewCommand(config))
|
||||
cmd.AddCommand(pretty.NewCommand(config))
|
||||
cmd.AddCommand(tfvars.NewCommand(config))
|
||||
cmd.AddCommand(toml.NewCommand(config))
|
||||
cmd.AddCommand(xml.NewCommand(config))
|
||||
cmd.AddCommand(yaml.NewCommand(config))
|
||||
cmd.AddCommand(asciidoc.NewCommand(runtime, config))
|
||||
cmd.AddCommand(json.NewCommand(runtime, config))
|
||||
cmd.AddCommand(markdown.NewCommand(runtime, config))
|
||||
cmd.AddCommand(pretty.NewCommand(runtime, config))
|
||||
cmd.AddCommand(tfvars.NewCommand(runtime, config))
|
||||
cmd.AddCommand(toml.NewCommand(runtime, config))
|
||||
cmd.AddCommand(xml.NewCommand(runtime, config))
|
||||
cmd.AddCommand(yaml.NewCommand(runtime, config))
|
||||
|
||||
// other subcommands
|
||||
cmd.AddCommand(completion.NewCommand())
|
||||
|
||||
@@ -17,14 +17,14 @@ import (
|
||||
)
|
||||
|
||||
// NewCommand returns a new cobra.Command for 'tfvars hcl' formatter
|
||||
func NewCommand(config *cli.Config) *cobra.Command {
|
||||
func NewCommand(runtime *cli.Runtime, config *cli.Config) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Args: cobra.ExactArgs(1),
|
||||
Use: "hcl [PATH]",
|
||||
Short: "Generate HCL format of terraform.tfvars of inputs",
|
||||
Annotations: cli.Annotations("tfvars hcl"),
|
||||
PreRunE: cli.PreRunEFunc(config),
|
||||
RunE: cli.RunEFunc(config),
|
||||
PreRunE: runtime.PreRunEFunc,
|
||||
RunE: runtime.RunEFunc,
|
||||
}
|
||||
cmd.PersistentFlags().BoolVar(&config.Settings.Description, "description", false, "show Descriptions on variables")
|
||||
return cmd
|
||||
|
||||
@@ -17,14 +17,14 @@ import (
|
||||
)
|
||||
|
||||
// NewCommand returns a new cobra.Command for 'tfvars json' formatter
|
||||
func NewCommand(config *cli.Config) *cobra.Command {
|
||||
func NewCommand(runtime *cli.Runtime, config *cli.Config) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Args: cobra.ExactArgs(1),
|
||||
Use: "json [PATH]",
|
||||
Short: "Generate JSON format of terraform.tfvars of inputs",
|
||||
Annotations: cli.Annotations("tfvars json"),
|
||||
PreRunE: cli.PreRunEFunc(config),
|
||||
RunE: cli.RunEFunc(config),
|
||||
PreRunE: runtime.PreRunEFunc,
|
||||
RunE: runtime.RunEFunc,
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ import (
|
||||
)
|
||||
|
||||
// NewCommand returns a new cobra.Command for 'tfvars' formatter
|
||||
func NewCommand(config *cli.Config) *cobra.Command {
|
||||
func NewCommand(runtime *cli.Runtime, config *cli.Config) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Args: cobra.ExactArgs(1),
|
||||
Use: "tfvars [PATH]",
|
||||
@@ -28,8 +28,8 @@ func NewCommand(config *cli.Config) *cobra.Command {
|
||||
}
|
||||
|
||||
// subcommands
|
||||
cmd.AddCommand(hcl.NewCommand(config))
|
||||
cmd.AddCommand(json.NewCommand(config))
|
||||
cmd.AddCommand(hcl.NewCommand(runtime, config))
|
||||
cmd.AddCommand(json.NewCommand(runtime, config))
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -17,14 +17,14 @@ import (
|
||||
)
|
||||
|
||||
// NewCommand returns a new cobra.Command for 'toml' formatter
|
||||
func NewCommand(config *cli.Config) *cobra.Command {
|
||||
func NewCommand(runtime *cli.Runtime, config *cli.Config) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Args: cobra.ExactArgs(1),
|
||||
Use: "toml [PATH]",
|
||||
Short: "Generate TOML of inputs and outputs",
|
||||
Annotations: cli.Annotations("toml"),
|
||||
PreRunE: cli.PreRunEFunc(config),
|
||||
RunE: cli.RunEFunc(config),
|
||||
PreRunE: runtime.PreRunEFunc,
|
||||
RunE: runtime.RunEFunc,
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -17,14 +17,14 @@ import (
|
||||
)
|
||||
|
||||
// NewCommand returns a new cobra.Command for 'xml' formatter
|
||||
func NewCommand(config *cli.Config) *cobra.Command {
|
||||
func NewCommand(runtime *cli.Runtime, config *cli.Config) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Args: cobra.ExactArgs(1),
|
||||
Use: "xml [PATH]",
|
||||
Short: "Generate XML of inputs and outputs",
|
||||
Annotations: cli.Annotations("xml"),
|
||||
PreRunE: cli.PreRunEFunc(config),
|
||||
RunE: cli.RunEFunc(config),
|
||||
PreRunE: runtime.PreRunEFunc,
|
||||
RunE: runtime.RunEFunc,
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -17,14 +17,14 @@ import (
|
||||
)
|
||||
|
||||
// NewCommand returns a new cobra.Command for 'yaml' formatter
|
||||
func NewCommand(config *cli.Config) *cobra.Command {
|
||||
func NewCommand(runtime *cli.Runtime, config *cli.Config) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Args: cobra.ExactArgs(1),
|
||||
Use: "yaml [PATH]",
|
||||
Short: "Generate YAML of inputs and outputs",
|
||||
Annotations: cli.Annotations("yaml"),
|
||||
PreRunE: cli.PreRunEFunc(config),
|
||||
RunE: cli.RunEFunc(config),
|
||||
PreRunE: runtime.PreRunEFunc,
|
||||
RunE: runtime.RunEFunc,
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -39,6 +39,8 @@ terraform-docs asciidoc document [PATH] [flags]
|
||||
--output-template string output template (default "<!-- BEGIN_TF_DOCS -->\n{{ .Content }}\n<!-- END_TF_DOCS -->")
|
||||
--output-values inject output values into outputs (default false)
|
||||
--output-values-from string inject output values from file into outputs (default "")
|
||||
--recursive update submodules recursively (default false)
|
||||
--recursive-path string submodules path to recursively update (default "modules")
|
||||
--required show Required column or section (default true)
|
||||
--sensitive show Sensitive column or section (default true)
|
||||
--show strings show section [all, data-sources, footer, header, inputs, modules, outputs, providers, requirements, resources]
|
||||
|
||||
@@ -39,6 +39,8 @@ terraform-docs asciidoc table [PATH] [flags]
|
||||
--output-template string output template (default "<!-- BEGIN_TF_DOCS -->\n{{ .Content }}\n<!-- END_TF_DOCS -->")
|
||||
--output-values inject output values into outputs (default false)
|
||||
--output-values-from string inject output values from file into outputs (default "")
|
||||
--recursive update submodules recursively (default false)
|
||||
--recursive-path string submodules path to recursively update (default "modules")
|
||||
--required show Required column or section (default true)
|
||||
--sensitive show Sensitive column or section (default true)
|
||||
--show strings show section [all, data-sources, footer, header, inputs, modules, outputs, providers, requirements, resources]
|
||||
|
||||
@@ -42,6 +42,8 @@ terraform-docs asciidoc [PATH] [flags]
|
||||
--output-template string output template (default "<!-- BEGIN_TF_DOCS -->\n{{ .Content }}\n<!-- END_TF_DOCS -->")
|
||||
--output-values inject output values into outputs (default false)
|
||||
--output-values-from string inject output values from file into outputs (default "")
|
||||
--recursive update submodules recursively (default false)
|
||||
--recursive-path string submodules path to recursively update (default "modules")
|
||||
--show strings show section [all, data-sources, footer, header, inputs, modules, outputs, providers, requirements, resources]
|
||||
--sort sort items (default true)
|
||||
--sort-by string sort items by criteria [name, required, type] (default "name")
|
||||
|
||||
@@ -37,6 +37,8 @@ terraform-docs json [PATH] [flags]
|
||||
--output-template string output template (default "<!-- BEGIN_TF_DOCS -->\n{{ .Content }}\n<!-- END_TF_DOCS -->")
|
||||
--output-values inject output values into outputs (default false)
|
||||
--output-values-from string inject output values from file into outputs (default "")
|
||||
--recursive update submodules recursively (default false)
|
||||
--recursive-path string submodules path to recursively update (default "modules")
|
||||
--show strings show section [all, data-sources, footer, header, inputs, modules, outputs, providers, requirements, resources]
|
||||
--sort sort items (default true)
|
||||
--sort-by string sort items by criteria [name, required, type] (default "name")
|
||||
|
||||
@@ -41,6 +41,8 @@ terraform-docs markdown document [PATH] [flags]
|
||||
--output-template string output template (default "<!-- BEGIN_TF_DOCS -->\n{{ .Content }}\n<!-- END_TF_DOCS -->")
|
||||
--output-values inject output values into outputs (default false)
|
||||
--output-values-from string inject output values from file into outputs (default "")
|
||||
--recursive update submodules recursively (default false)
|
||||
--recursive-path string submodules path to recursively update (default "modules")
|
||||
--required show Required column or section (default true)
|
||||
--sensitive show Sensitive column or section (default true)
|
||||
--show strings show section [all, data-sources, footer, header, inputs, modules, outputs, providers, requirements, resources]
|
||||
|
||||
@@ -41,6 +41,8 @@ terraform-docs markdown table [PATH] [flags]
|
||||
--output-template string output template (default "<!-- BEGIN_TF_DOCS -->\n{{ .Content }}\n<!-- END_TF_DOCS -->")
|
||||
--output-values inject output values into outputs (default false)
|
||||
--output-values-from string inject output values from file into outputs (default "")
|
||||
--recursive update submodules recursively (default false)
|
||||
--recursive-path string submodules path to recursively update (default "modules")
|
||||
--required show Required column or section (default true)
|
||||
--sensitive show Sensitive column or section (default true)
|
||||
--show strings show section [all, data-sources, footer, header, inputs, modules, outputs, providers, requirements, resources]
|
||||
|
||||
@@ -44,6 +44,8 @@ terraform-docs markdown [PATH] [flags]
|
||||
--output-template string output template (default "<!-- BEGIN_TF_DOCS -->\n{{ .Content }}\n<!-- END_TF_DOCS -->")
|
||||
--output-values inject output values into outputs (default false)
|
||||
--output-values-from string inject output values from file into outputs (default "")
|
||||
--recursive update submodules recursively (default false)
|
||||
--recursive-path string submodules path to recursively update (default "modules")
|
||||
--show strings show section [all, data-sources, footer, header, inputs, modules, outputs, providers, requirements, resources]
|
||||
--sort sort items (default true)
|
||||
--sort-by string sort items by criteria [name, required, type] (default "name")
|
||||
|
||||
@@ -37,6 +37,8 @@ terraform-docs pretty [PATH] [flags]
|
||||
--output-template string output template (default "<!-- BEGIN_TF_DOCS -->\n{{ .Content }}\n<!-- END_TF_DOCS -->")
|
||||
--output-values inject output values into outputs (default false)
|
||||
--output-values-from string inject output values from file into outputs (default "")
|
||||
--recursive update submodules recursively (default false)
|
||||
--recursive-path string submodules path to recursively update (default "modules")
|
||||
--show strings show section [all, data-sources, footer, header, inputs, modules, outputs, providers, requirements, resources]
|
||||
--sort sort items (default true)
|
||||
--sort-by string sort items by criteria [name, required, type] (default "name")
|
||||
|
||||
@@ -31,6 +31,8 @@ terraform-docs [PATH] [flags]
|
||||
--output-template string output template (default "<!-- BEGIN_TF_DOCS -->\n{{ .Content }}\n<!-- END_TF_DOCS -->")
|
||||
--output-values inject output values into outputs (default false)
|
||||
--output-values-from string inject output values from file into outputs (default "")
|
||||
--recursive update submodules recursively (default false)
|
||||
--recursive-path string submodules path to recursively update (default "modules")
|
||||
--show strings show section [all, data-sources, footer, header, inputs, modules, outputs, providers, requirements, resources]
|
||||
--sort sort items (default true)
|
||||
--sort-by string sort items by criteria [name, required, type] (default "name")
|
||||
|
||||
@@ -37,6 +37,8 @@ terraform-docs tfvars hcl [PATH] [flags]
|
||||
--output-template string output template (default "<!-- BEGIN_TF_DOCS -->\n{{ .Content }}\n<!-- END_TF_DOCS -->")
|
||||
--output-values inject output values into outputs (default false)
|
||||
--output-values-from string inject output values from file into outputs (default "")
|
||||
--recursive update submodules recursively (default false)
|
||||
--recursive-path string submodules path to recursively update (default "modules")
|
||||
--show strings show section [all, data-sources, footer, header, inputs, modules, outputs, providers, requirements, resources]
|
||||
--sort sort items (default true)
|
||||
--sort-by string sort items by criteria [name, required, type] (default "name")
|
||||
|
||||
@@ -36,6 +36,8 @@ terraform-docs tfvars json [PATH] [flags]
|
||||
--output-template string output template (default "<!-- BEGIN_TF_DOCS -->\n{{ .Content }}\n<!-- END_TF_DOCS -->")
|
||||
--output-values inject output values into outputs (default false)
|
||||
--output-values-from string inject output values from file into outputs (default "")
|
||||
--recursive update submodules recursively (default false)
|
||||
--recursive-path string submodules path to recursively update (default "modules")
|
||||
--show strings show section [all, data-sources, footer, header, inputs, modules, outputs, providers, requirements, resources]
|
||||
--sort sort items (default true)
|
||||
--sort-by string sort items by criteria [name, required, type] (default "name")
|
||||
|
||||
@@ -32,6 +32,8 @@ Generate terraform.tfvars of inputs.
|
||||
--output-template string output template (default "<!-- BEGIN_TF_DOCS -->\n{{ .Content }}\n<!-- END_TF_DOCS -->")
|
||||
--output-values inject output values into outputs (default false)
|
||||
--output-values-from string inject output values from file into outputs (default "")
|
||||
--recursive update submodules recursively (default false)
|
||||
--recursive-path string submodules path to recursively update (default "modules")
|
||||
--show strings show section [all, data-sources, footer, header, inputs, modules, outputs, providers, requirements, resources]
|
||||
--sort sort items (default true)
|
||||
--sort-by string sort items by criteria [name, required, type] (default "name")
|
||||
|
||||
@@ -36,6 +36,8 @@ terraform-docs toml [PATH] [flags]
|
||||
--output-template string output template (default "<!-- BEGIN_TF_DOCS -->\n{{ .Content }}\n<!-- END_TF_DOCS -->")
|
||||
--output-values inject output values into outputs (default false)
|
||||
--output-values-from string inject output values from file into outputs (default "")
|
||||
--recursive update submodules recursively (default false)
|
||||
--recursive-path string submodules path to recursively update (default "modules")
|
||||
--show strings show section [all, data-sources, footer, header, inputs, modules, outputs, providers, requirements, resources]
|
||||
--sort sort items (default true)
|
||||
--sort-by string sort items by criteria [name, required, type] (default "name")
|
||||
|
||||
@@ -36,6 +36,8 @@ terraform-docs xml [PATH] [flags]
|
||||
--output-template string output template (default "<!-- BEGIN_TF_DOCS -->\n{{ .Content }}\n<!-- END_TF_DOCS -->")
|
||||
--output-values inject output values into outputs (default false)
|
||||
--output-values-from string inject output values from file into outputs (default "")
|
||||
--recursive update submodules recursively (default false)
|
||||
--recursive-path string submodules path to recursively update (default "modules")
|
||||
--show strings show section [all, data-sources, footer, header, inputs, modules, outputs, providers, requirements, resources]
|
||||
--sort sort items (default true)
|
||||
--sort-by string sort items by criteria [name, required, type] (default "name")
|
||||
|
||||
@@ -36,6 +36,8 @@ terraform-docs yaml [PATH] [flags]
|
||||
--output-template string output template (default "<!-- BEGIN_TF_DOCS -->\n{{ .Content }}\n<!-- END_TF_DOCS -->")
|
||||
--output-values inject output values into outputs (default false)
|
||||
--output-values-from string inject output values from file into outputs (default "")
|
||||
--recursive update submodules recursively (default false)
|
||||
--recursive-path string submodules path to recursively update (default "modules")
|
||||
--show strings show section [all, data-sources, footer, header, inputs, modules, outputs, providers, requirements, resources]
|
||||
--sort sort items (default true)
|
||||
--sort-by string sort items by criteria [name, required, type] (default "name")
|
||||
|
||||
@@ -223,6 +223,42 @@ $ terraform-docs markdown table --output-file ./docs/README.md .
|
||||
$ terraform-docs markdown table --output-file /path/to/module/docs/README.md .
|
||||
```
|
||||
|
||||
## Recursive Submodules
|
||||
|
||||
Since `v0.15.0`
|
||||
|
||||
Considering the file strucutre below of main module and its submodules, it is
|
||||
possible to generate documentation for them main and all its submodules in one
|
||||
execution, with `--recursive` flag.
|
||||
|
||||
Note that generating documentation recursively is allowed only with `--output-file`
|
||||
set.
|
||||
|
||||
Path to find submodules can be configured with `--recursive-path` (defaults to
|
||||
`modules`).
|
||||
|
||||
Each submodule can also have their own `.terraform-docs.yml` confi file, to
|
||||
override configuration from root module.
|
||||
|
||||
```bash
|
||||
$ pwd
|
||||
/path/to/module
|
||||
|
||||
$ tree .
|
||||
.
|
||||
├── README.md
|
||||
├── main.tf
|
||||
├── modules
|
||||
│ └── my-sub-module
|
||||
│ ├── README.md
|
||||
│ ├── main.tf
|
||||
│ ├── variables.tf
|
||||
│ └── versions.tf
|
||||
├── outputs.tf
|
||||
├── variables.tf
|
||||
└── versions.tf
|
||||
```
|
||||
|
||||
## Generate terraform.tfvars
|
||||
|
||||
Since `v0.9.0`
|
||||
|
||||
@@ -51,17 +51,19 @@ var flagMappings = map[string]string{
|
||||
|
||||
// Config represents all the available config options that can be accessed and passed through CLI
|
||||
type Config struct {
|
||||
File string `mapstructure:"-"`
|
||||
Formatter string `mapstructure:"formatter"`
|
||||
Version string `mapstructure:"version"`
|
||||
HeaderFrom string `mapstructure:"header-from"`
|
||||
FooterFrom string `mapstructure:"footer-from"`
|
||||
Content string `mapstructure:"content"`
|
||||
Sections sections `mapstructure:"sections"`
|
||||
Output output `mapstructure:"output"`
|
||||
OutputValues outputvalues `mapstructure:"output-values"`
|
||||
Sort sort `mapstructure:"sort"`
|
||||
Settings settings `mapstructure:"settings"`
|
||||
File string `mapstructure:"-"`
|
||||
Recursive bool `mapstructure:"-"`
|
||||
RecursivePath string `mapstructure:"-"`
|
||||
Formatter string `mapstructure:"formatter"`
|
||||
Version string `mapstructure:"version"`
|
||||
HeaderFrom string `mapstructure:"header-from"`
|
||||
FooterFrom string `mapstructure:"footer-from"`
|
||||
Content string `mapstructure:"content"`
|
||||
Sections sections `mapstructure:"sections"`
|
||||
Output output `mapstructure:"output"`
|
||||
OutputValues outputvalues `mapstructure:"output-values"`
|
||||
Sort sort `mapstructure:"sort"`
|
||||
Settings settings `mapstructure:"settings"`
|
||||
|
||||
moduleRoot string
|
||||
isFlagChanged func(string) bool
|
||||
@@ -70,17 +72,19 @@ type Config struct {
|
||||
// DefaultConfig returns new instance of Config with default values set
|
||||
func DefaultConfig() *Config {
|
||||
return &Config{
|
||||
File: "",
|
||||
Formatter: "",
|
||||
Version: "",
|
||||
HeaderFrom: "main.tf",
|
||||
FooterFrom: "",
|
||||
Content: "",
|
||||
Sections: defaultSections(),
|
||||
Output: defaultOutput(),
|
||||
OutputValues: defaultOutputValues(),
|
||||
Sort: defaultSort(),
|
||||
Settings: defaultSettings(),
|
||||
File: "",
|
||||
Recursive: false,
|
||||
RecursivePath: "modules",
|
||||
Formatter: "",
|
||||
Version: "",
|
||||
HeaderFrom: "main.tf",
|
||||
FooterFrom: "",
|
||||
Content: "",
|
||||
Sections: defaultSections(),
|
||||
Output: defaultOutput(),
|
||||
OutputValues: defaultOutputValues(),
|
||||
Sort: defaultSort(),
|
||||
Settings: defaultSettings(),
|
||||
|
||||
moduleRoot: "",
|
||||
isFlagChanged: func(name string) bool { return false },
|
||||
@@ -414,6 +418,11 @@ func (c *Config) process() error { //nolint:gocyclo
|
||||
return fmt.Errorf("value of 'formatter' can't be empty")
|
||||
}
|
||||
|
||||
// recursive
|
||||
if c.Recursive && c.RecursivePath == "" {
|
||||
return fmt.Errorf("value of '--recursive-path' can't be empty")
|
||||
}
|
||||
|
||||
// sections
|
||||
c.Sections.dataSources = c.Sections.visibility("data-sources")
|
||||
c.Sections.header = c.Sections.visibility("header")
|
||||
|
||||
@@ -547,9 +547,7 @@ func TestConfigProcess(t *testing.T) {
|
||||
errMsg string
|
||||
}{
|
||||
"OK": {
|
||||
config: func(c *Config) {
|
||||
c.Formatter = "foo"
|
||||
},
|
||||
config: func(c *Config) {},
|
||||
wantErr: false,
|
||||
errMsg: "",
|
||||
},
|
||||
@@ -560,9 +558,16 @@ func TestConfigProcess(t *testing.T) {
|
||||
wantErr: true,
|
||||
errMsg: "value of 'formatter' can't be empty",
|
||||
},
|
||||
"RecursivePathEmpty": {
|
||||
config: func(c *Config) {
|
||||
c.Recursive = true
|
||||
c.RecursivePath = ""
|
||||
},
|
||||
wantErr: true,
|
||||
errMsg: "value of '--recursive-path' can't be empty",
|
||||
},
|
||||
"HeaderFromEmpty": {
|
||||
config: func(c *Config) {
|
||||
c.Formatter = "foo"
|
||||
c.HeaderFrom = ""
|
||||
},
|
||||
wantErr: true,
|
||||
@@ -570,7 +575,6 @@ func TestConfigProcess(t *testing.T) {
|
||||
},
|
||||
"FooterFrom": {
|
||||
config: func(c *Config) {
|
||||
c.Formatter = "foo"
|
||||
c.FooterFrom = ""
|
||||
c.Sections.footer = true
|
||||
c.isFlagChanged = func(s string) bool { return true }
|
||||
@@ -593,6 +597,7 @@ func TestConfigProcess(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
config := DefaultConfig()
|
||||
config.Formatter = "foo"
|
||||
tt.config(config)
|
||||
err := config.process()
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
goversion "github.com/hashicorp/go-version"
|
||||
"github.com/spf13/cobra"
|
||||
@@ -28,144 +29,170 @@ import (
|
||||
"github.com/terraform-docs/terraform-docs/internal/version"
|
||||
)
|
||||
|
||||
// PreRunEFunc returns actual 'cobra.Command#PreRunE' function for 'formatter'
|
||||
// commands. This functions reads and normalizes flags and arguments passed
|
||||
// Runtime represents the execution runtime for CLI.
|
||||
type Runtime struct {
|
||||
rootDir string
|
||||
|
||||
formatter string
|
||||
config *Config
|
||||
|
||||
cmd *cobra.Command
|
||||
}
|
||||
|
||||
// NewRuntime retruns new instance of Runtime. If `config` is not provided
|
||||
// default config will be used.
|
||||
func NewRuntime(config *Config) *Runtime {
|
||||
if config == nil {
|
||||
config = DefaultConfig()
|
||||
}
|
||||
return &Runtime{config: config}
|
||||
}
|
||||
|
||||
// PreRunEFunc is the 'cobra.Command#PreRunE' function for 'formatter'
|
||||
// commands. This function reads and normalizes flags and arguments passed
|
||||
// through CLI execution.
|
||||
func PreRunEFunc(config *Config) func(*cobra.Command, []string) error { //nolint:gocyclo
|
||||
// NOTE(khos2ow): this function is over our cyclomatic complexity goal.
|
||||
// Be wary when adding branches, and look for functionality that could
|
||||
// be reasonably moved into an injected dependency.
|
||||
func (r *Runtime) PreRunEFunc(cmd *cobra.Command, args []string) error {
|
||||
r.formatter = cmd.Annotations["command"]
|
||||
|
||||
return func(cmd *cobra.Command, args []string) error {
|
||||
config.isFlagChanged = cmd.Flags().Changed
|
||||
// root command must have an argument, otherwise we're going to show help
|
||||
if r.formatter == "root" && len(args) == 0 {
|
||||
cmd.Help() //nolint:errcheck,gosec
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
formatter := cmd.Annotations["command"]
|
||||
r.config.isFlagChanged = cmd.Flags().Changed
|
||||
r.rootDir = args[0]
|
||||
r.cmd = cmd
|
||||
|
||||
// root command must have an argument, otherwise we're going to show help
|
||||
if formatter == "root" && len(args) == 0 {
|
||||
cmd.Help() //nolint:errcheck,gosec
|
||||
os.Exit(0)
|
||||
}
|
||||
// this can only happen in one way: terraform-docs -c "" /path/to/module
|
||||
if r.config.File == "" {
|
||||
return fmt.Errorf("value of '--config' can't be empty")
|
||||
}
|
||||
|
||||
// this can only happen in one way: terraform-docs -c "" /path/to/module
|
||||
if config.File == "" {
|
||||
return errors.New("value of '--config' can't be empty")
|
||||
}
|
||||
// attempt to read config file and override them with corresponding flags
|
||||
if err := r.readConfig(r.config, ""); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
v := viper.New()
|
||||
return checkConstraint(r.config.Version, version.Core())
|
||||
}
|
||||
|
||||
if config.isFlagChanged("config") {
|
||||
v.SetConfigFile(config.File)
|
||||
} else {
|
||||
v.SetConfigName(".terraform-docs")
|
||||
v.SetConfigType("yml")
|
||||
}
|
||||
type module struct {
|
||||
rootDir string
|
||||
config *Config
|
||||
}
|
||||
|
||||
v.AddConfigPath(args[0]) // first look at module root
|
||||
v.AddConfigPath(args[0] + "/.config") // then .config/ folder at module root
|
||||
v.AddConfigPath(".") // then current directory
|
||||
v.AddConfigPath(".config") // then .config/ folder at current directory
|
||||
v.AddConfigPath("$HOME/.tfdocs.d") // and finally $HOME/.tfdocs.d/
|
||||
// RunEFunc is the 'cobra.Command#RunE' function for 'formatter' commands. It attempts
|
||||
// to discover submodules, on `--recursive` flag, and generates the content for them
|
||||
// as well as the root module.
|
||||
func (r *Runtime) RunEFunc(cmd *cobra.Command, args []string) error {
|
||||
modules := []module{
|
||||
{rootDir: r.rootDir, config: r.config},
|
||||
}
|
||||
|
||||
if err := v.ReadInConfig(); err != nil {
|
||||
var perr *os.PathError
|
||||
if errors.As(err, &perr) {
|
||||
return fmt.Errorf("config file %s not found", config.File)
|
||||
}
|
||||
|
||||
var cerr viper.ConfigFileNotFoundError
|
||||
if !errors.As(err, &cerr) {
|
||||
return err
|
||||
}
|
||||
|
||||
// config is not provided, only show error for root command
|
||||
if formatter == "root" {
|
||||
cmd.Help() //nolint:errcheck,gosec
|
||||
os.Exit(0)
|
||||
}
|
||||
}
|
||||
|
||||
// bind flags to viper
|
||||
bindFlags(cmd, v)
|
||||
|
||||
if err := v.Unmarshal(config); err != nil {
|
||||
return fmt.Errorf("unable to decode config, %w", err)
|
||||
}
|
||||
|
||||
if err := checkConstraint(config.Version, version.Core()); err != nil {
|
||||
// Generating content recursively is only allowed when `config.Output.File`
|
||||
// is set. Otherwise it would be impossible to distinguish where output of
|
||||
// one module ends and the other begin, if content is outpput to stdout.
|
||||
if r.config.Recursive && r.config.RecursivePath != "" {
|
||||
items, err := r.findSubmodules()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// explicitly setting formatter to Config for non-root commands this
|
||||
// will effectively override formattter properties from config file
|
||||
// if 1) config file exists and 2) formatter is set and 3) explicitly
|
||||
// a subcommand was executed in the terminal
|
||||
if formatter != "root" {
|
||||
config.Formatter = formatter
|
||||
modules = append(modules, items...)
|
||||
}
|
||||
|
||||
for _, module := range modules {
|
||||
cfg := r.config
|
||||
|
||||
// If submodules contains its own configuration file, use that instead
|
||||
if module.config != nil {
|
||||
cfg = module.config
|
||||
}
|
||||
|
||||
// set the module root directory
|
||||
config.moduleRoot = args[0]
|
||||
cfg.moduleRoot = module.rootDir
|
||||
|
||||
// process and validate configuration
|
||||
return config.process()
|
||||
if err := cfg.process(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if r.config.Recursive && cfg.Output.File == "" {
|
||||
return fmt.Errorf("value of '--output-file' cannot be empty with '--recursive'")
|
||||
}
|
||||
|
||||
if err := generateContent(cfg); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// RunEFunc returns actual 'cobra.Command#RunE' function for 'formatter' commands.
|
||||
// This functions extract print.Settings and terraform.Options from generated and
|
||||
// normalized Config and initializes required print.Format instance and executes it.
|
||||
func RunEFunc(config *Config) func(*cobra.Command, []string) error {
|
||||
return func(cmd *cobra.Command, _ []string) error {
|
||||
settings, options := config.extract()
|
||||
options.Path = config.moduleRoot
|
||||
// readConfig attempts to read config file, either default `.terraform-docs.yml`
|
||||
// or provided file with `-c, --config` flag. It will then attempt to override
|
||||
// them with corresponding flags (if set).
|
||||
func (r *Runtime) readConfig(config *Config, submoduleDir string) error {
|
||||
v := viper.New()
|
||||
|
||||
module, err := terraform.LoadWithOptions(options)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
formatter, err := format.Factory(config.Formatter, settings)
|
||||
if err != nil {
|
||||
plugins, perr := plugin.Discover()
|
||||
if perr != nil {
|
||||
return fmt.Errorf("formatter '%s' not found", config.Formatter)
|
||||
}
|
||||
|
||||
client, found := plugins.Get(config.Formatter)
|
||||
if !found {
|
||||
return fmt.Errorf("formatter '%s' not found", config.Formatter)
|
||||
}
|
||||
|
||||
content, cerr := client.Execute(pluginsdk.ExecuteArgs{
|
||||
Module: module.Convert(),
|
||||
Settings: settings.Convert(),
|
||||
})
|
||||
if cerr != nil {
|
||||
return cerr
|
||||
}
|
||||
return writeContent(config, content)
|
||||
}
|
||||
|
||||
generator, err := formatter.Generate(module)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
generator.Path(config.moduleRoot)
|
||||
|
||||
content, err := generator.ExecuteTemplate(config.Content)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return writeContent(config, content)
|
||||
if config.isFlagChanged("config") {
|
||||
v.SetConfigFile(config.File)
|
||||
} else {
|
||||
v.SetConfigName(".terraform-docs")
|
||||
v.SetConfigType("yml")
|
||||
}
|
||||
|
||||
if submoduleDir != "" {
|
||||
v.AddConfigPath(submoduleDir) // first look at submodule root
|
||||
v.AddConfigPath(submoduleDir + "/.config") // then .config/ folder at submodule root
|
||||
}
|
||||
|
||||
v.AddConfigPath(r.rootDir) // first look at module root
|
||||
v.AddConfigPath(r.rootDir + "/.config") // then .config/ folder at module root
|
||||
v.AddConfigPath(".") // then current directory
|
||||
v.AddConfigPath(".config") // then .config/ folder at current directory
|
||||
v.AddConfigPath("$HOME/.tfdocs.d") // and finally $HOME/.tfdocs.d/
|
||||
|
||||
if err := v.ReadInConfig(); err != nil {
|
||||
var perr *os.PathError
|
||||
if errors.As(err, &perr) {
|
||||
return fmt.Errorf("config file %s not found", config.File)
|
||||
}
|
||||
|
||||
var cerr viper.ConfigFileNotFoundError
|
||||
if !errors.As(err, &cerr) {
|
||||
return err
|
||||
}
|
||||
|
||||
// config is not provided, only show error for root command
|
||||
if r.formatter == "root" {
|
||||
r.cmd.Help() //nolint:errcheck,gosec
|
||||
os.Exit(0)
|
||||
}
|
||||
}
|
||||
|
||||
r.bindFlags(v)
|
||||
|
||||
if err := v.Unmarshal(config); err != nil {
|
||||
return fmt.Errorf("unable to decode config, %w", err)
|
||||
}
|
||||
|
||||
// explicitly setting formatter to Config for non-root commands this
|
||||
// will effectively override formattter properties from config file
|
||||
// if 1) config file exists and 2) formatter is set and 3) explicitly
|
||||
// a subcommand was executed in the terminal
|
||||
if r.formatter != "root" {
|
||||
config.Formatter = r.formatter
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// bindFlags binds current command's changed flags to viper
|
||||
func bindFlags(cmd *cobra.Command, v *viper.Viper) {
|
||||
// bindFlags binds current command's changed flags to viper.
|
||||
func (r *Runtime) bindFlags(v *viper.Viper) {
|
||||
sectionsCleared := false
|
||||
fs := cmd.Flags()
|
||||
fs := r.cmd.Flags()
|
||||
fs.VisitAll(func(f *pflag.Flag) {
|
||||
if !f.Changed {
|
||||
return
|
||||
@@ -197,6 +224,47 @@ func bindFlags(cmd *cobra.Command, v *viper.Viper) {
|
||||
})
|
||||
}
|
||||
|
||||
// findSubmodules generates list of submodules in `rootDir/RecursivePath` if
|
||||
// `--recursive` flag is set. This keeps track of `.terraform-docs.yml` in any
|
||||
// of the submodules (if exists) to override the root configuration.
|
||||
func (r *Runtime) findSubmodules() ([]module, error) {
|
||||
dir := filepath.Join(r.rootDir, r.config.RecursivePath)
|
||||
|
||||
if _, err := os.Stat(dir); os.IsNotExist(err) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info, err := os.ReadDir(dir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
modules := []module{}
|
||||
|
||||
for _, file := range info {
|
||||
if !file.IsDir() {
|
||||
continue
|
||||
}
|
||||
|
||||
var cfg *Config
|
||||
|
||||
path := filepath.Join(dir, file.Name())
|
||||
cfgfile := filepath.Join(path, r.config.File)
|
||||
|
||||
if _, err := os.Stat(cfgfile); !os.IsNotExist(err) {
|
||||
cfg = DefaultConfig()
|
||||
|
||||
if err := r.readConfig(cfg, path); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
modules = append(modules, module{rootDir: path, config: cfg})
|
||||
}
|
||||
|
||||
return modules, nil
|
||||
}
|
||||
|
||||
// checkConstraint validates if current version of terraform-docs being executed
|
||||
// is valid against 'version' string provided in config file, and fail if the
|
||||
// constraints is violated.
|
||||
@@ -218,6 +286,59 @@ func checkConstraint(versionRange string, currentVersion string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// generateContent extracts print.Settings and terraform.Options from normalized
|
||||
// Config and generates the output content for the module (and submodules if avialble)
|
||||
// and write the result to the output (either stdout or a file).
|
||||
func generateContent(config *Config) error {
|
||||
settings, options := config.extract()
|
||||
options.Path = config.moduleRoot
|
||||
|
||||
module, err := terraform.LoadWithOptions(options)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
formatter, err := format.Factory(config.Formatter, settings)
|
||||
|
||||
// formatter is unkowns, this might mean that the intended formatter is
|
||||
// coming from a plugin. We are going to attempt to find a plugin with
|
||||
// that name and generate the content with it or error out if not found.
|
||||
if err != nil {
|
||||
plugins, perr := plugin.Discover()
|
||||
if perr != nil {
|
||||
return fmt.Errorf("formatter '%s' not found", config.Formatter)
|
||||
}
|
||||
|
||||
client, found := plugins.Get(config.Formatter)
|
||||
if !found {
|
||||
return fmt.Errorf("formatter '%s' not found", config.Formatter)
|
||||
}
|
||||
|
||||
content, cerr := client.Execute(pluginsdk.ExecuteArgs{
|
||||
Module: module.Convert(),
|
||||
Settings: settings.Convert(),
|
||||
})
|
||||
if cerr != nil {
|
||||
return cerr
|
||||
}
|
||||
|
||||
return writeContent(config, content)
|
||||
}
|
||||
|
||||
generator, err := formatter.Generate(module)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
generator.Path(options.Path)
|
||||
|
||||
content, err := generator.ExecuteTemplate(config.Content)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return writeContent(config, content)
|
||||
}
|
||||
|
||||
// writeContent to a Writer. This can either be os.Stdout or specific
|
||||
// file (e.g. README.md) if '--output-file' is provided.
|
||||
func writeContent(config *Config, content string) error {
|
||||
|
||||
@@ -154,7 +154,7 @@ func (fw *fileWriter) inject(filename string, content string, generated string)
|
||||
return fw.write(filename, []byte(generated))
|
||||
}
|
||||
|
||||
// wrtie the content to io.Writer. If no io.Writer is available,
|
||||
// write the content to io.Writer. If no io.Writer is available,
|
||||
// it will be written to 'filename'.
|
||||
func (fw *fileWriter) write(filename string, p []byte) (int, error) {
|
||||
// if run in check mode return exit 1
|
||||
|
||||
Reference in New Issue
Block a user