refactor: Refactor cli implemention and configuration (#266)

* Refactor cli implemention and configuration

* cleanup
This commit is contained in:
Khosrow Moossavi
2020-05-20 22:21:19 -04:00
committed by GitHub
parent 085cac0c54
commit 04a9ef49eb
54 changed files with 943 additions and 493 deletions

View File

@@ -1,48 +0,0 @@
package cmd
import (
"github.com/spf13/cobra"
)
var asciidocCmd = &cobra.Command{
Args: cobra.ExactArgs(1),
Use: "asciidoc [PATH]",
Aliases: []string{"adoc"},
Short: "Generate AsciiDoc of inputs and outputs",
Annotations: formatAnnotations("asciidoc"),
RunE: formatRunE,
}
var asciidocTableCmd = &cobra.Command{
Args: cobra.ExactArgs(1),
Use: "table [PATH]",
Aliases: []string{"tbl"},
Short: "Generate AsciiDoc tables of inputs and outputs",
Annotations: formatAnnotations("asciidoc table"),
RunE: formatRunE,
}
var asciidocDocumentCmd = &cobra.Command{
Args: cobra.ExactArgs(1),
Use: "document [PATH]",
Aliases: []string{"doc"},
Short: "Generate AsciiDoc document of inputs and outputs",
Annotations: formatAnnotations("asciidoc document"),
RunE: formatRunE,
}
func init() {
asciidocCmd.PersistentFlags().BoolVar(new(bool), "no-required", false, "do not show \"Required\" column or section")
asciidocCmd.PersistentFlags().BoolVar(new(bool), "no-sensitive", false, "do not show \"Sensitive\" column or section")
asciidocCmd.PersistentFlags().MarkDeprecated("no-required", "use '--required=false' instead") //nolint:errcheck
asciidocCmd.PersistentFlags().MarkDeprecated("no-sensitive", "use '--sensitive=false' instead") //nolint:errcheck
asciidocCmd.PersistentFlags().BoolVar(&settings.ShowRequired, "required", true, "show \"Required\" column or section")
asciidocCmd.PersistentFlags().BoolVar(&settings.ShowSensitivity, "sensitive", true, "show \"Sensitive\" column or section")
asciidocCmd.PersistentFlags().IntVar(&settings.IndentLevel, "indent", 2, "indention level of AsciiDoc sections [1, 2, 3, 4, 5]")
asciidocCmd.AddCommand(asciidocTableCmd)
asciidocCmd.AddCommand(asciidocDocumentCmd)
rootCmd.AddCommand(asciidocCmd)
}

39
cmd/asciidoc/asciidoc.go Normal file
View File

@@ -0,0 +1,39 @@
package asciidoc
import (
"github.com/spf13/cobra"
"github.com/segmentio/terraform-docs/cmd/asciidoc/document"
"github.com/segmentio/terraform-docs/cmd/asciidoc/table"
"github.com/segmentio/terraform-docs/internal/cli"
)
// NewCommand returns a new cobra.Command for 'asciidoc' formatter
func NewCommand(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),
}
// flags
cmd.PersistentFlags().BoolVar(&config.Settings.Required, "required", true, "show \"Required\" column or section")
cmd.PersistentFlags().BoolVar(&config.Settings.Sensitive, "sensitive", true, "show \"Sensitive\" column or section")
cmd.PersistentFlags().IntVar(&config.Settings.Indent, "indent", 2, "indention level of AsciiDoc sections [1, 2, 3, 4, 5]")
// deprecation
cmd.PersistentFlags().BoolVar(new(bool), "no-required", false, "do not show \"Required\" column or section")
cmd.PersistentFlags().BoolVar(new(bool), "no-sensitive", false, "do not show \"Sensitive\" column or section")
cmd.PersistentFlags().MarkDeprecated("no-required", "use '--required=false' instead") //nolint:errcheck
cmd.PersistentFlags().MarkDeprecated("no-sensitive", "use '--sensitive=false' instead") //nolint:errcheck
// subcommands
cmd.AddCommand(document.NewCommand(config))
cmd.AddCommand(table.NewCommand(config))
return cmd
}

View File

@@ -0,0 +1,21 @@
package document
import (
"github.com/spf13/cobra"
"github.com/segmentio/terraform-docs/internal/cli"
)
// NewCommand returns a new cobra.Command for 'asciidoc document' formatter
func NewCommand(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),
}
return cmd
}

View File

@@ -0,0 +1,21 @@
package table
import (
"github.com/spf13/cobra"
"github.com/segmentio/terraform-docs/internal/cli"
)
// NewCommand returns a new cobra.Command for 'asciidoc table' formatter
func NewCommand(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),
}
return cmd
}

View File

@@ -1,40 +0,0 @@
package cmd
import (
"os"
"github.com/spf13/cobra"
)
var completionCmd = &cobra.Command{
Args: cobra.NoArgs,
Use: "completion SHELL",
Short: "Generate autocomplete for terraform-docs",
Long: "Generate autocomplete for terraform-docs",
}
var bashCompletionCmd = &cobra.Command{
Args: cobra.NoArgs,
Use: "bash",
Short: "Generate autocomplete for bash",
Long: "Generate autocomplete for bash",
Run: func(cmd *cobra.Command, args []string) {
_ = rootCmd.GenBashCompletion(os.Stdout)
},
}
var zshCompletionCmd = &cobra.Command{
Args: cobra.NoArgs,
Use: "zsh",
Short: "Generate autocomplete for zsh",
Long: "Generate autocomplete for zsh",
Run: func(cmd *cobra.Command, args []string) {
_ = rootCmd.GenZshCompletion(os.Stdout)
},
}
func init() {
completionCmd.AddCommand(bashCompletionCmd)
completionCmd.AddCommand(zshCompletionCmd)
rootCmd.AddCommand(completionCmd)
}

View File

@@ -0,0 +1,20 @@
package bash
import (
"os"
"github.com/spf13/cobra"
)
// NewCommand returns a new cobra.Command for 'completion bash' command
func NewCommand() *cobra.Command {
cmd := &cobra.Command{
Args: cobra.NoArgs,
Use: "bash",
Short: "Generate shell completion for bash",
RunE: func(cmd *cobra.Command, args []string) error {
return cmd.Parent().Parent().GenBashCompletion(os.Stdout)
},
}
return cmd
}

View File

@@ -0,0 +1,40 @@
package completion
import (
"github.com/spf13/cobra"
"github.com/segmentio/terraform-docs/cmd/completion/bash"
"github.com/segmentio/terraform-docs/cmd/completion/zsh"
)
// NewCommand returns a new cobra.Command for 'completion' command
func NewCommand() *cobra.Command {
cmd := &cobra.Command{
Args: cobra.NoArgs,
Use: "completion SHELL",
Short: "Generate shell completion code for the specified shell (bash or zsh)",
Long: longDescription,
}
// subcommands
cmd.AddCommand(bash.NewCommand())
cmd.AddCommand(zsh.NewCommand())
return cmd
}
const longDescription = `Outputs terraform-doc shell completion for the given shell (bash or zsh)
This depends on the bash-completion binary. Example installation instructions:
# for bash users
$ terraform-doc completion bash > ~/.terraform-doc-completion
$ source ~/.terraform-doc-completion
# for zsh users
% terraform-doc completion zsh > /usr/local/share/zsh/site-functions/_terraform-doc
% autoload -U compinit && compinit
# or if zsh-completion is installed via homebrew
% terraform-doc completion zsh > "${fpath[1]}/_terraform-doc"
Additionally, you may want to output the completion to a file and source in your .bashrc
Note for zsh users: [1] zsh completions are only supported in versions of zsh >= 5.2
`

20
cmd/completion/zsh/zsh.go Normal file
View File

@@ -0,0 +1,20 @@
package zsh
import (
"os"
"github.com/spf13/cobra"
)
// NewCommand returns a new cobra.Command for 'completion zsh' command
func NewCommand() *cobra.Command {
cmd := &cobra.Command{
Args: cobra.NoArgs,
Use: "zsh",
Short: "Generate shel completion for zsh",
RunE: func(cmd *cobra.Command, args []string) error {
return cmd.Parent().Parent().GenZshCompletion(os.Stdout)
},
}
return cmd
}

View File

@@ -1,22 +0,0 @@
package cmd
import (
"github.com/spf13/cobra"
)
var jsonCmd = &cobra.Command{
Args: cobra.ExactArgs(1),
Use: "json [PATH]",
Short: "Generate JSON of inputs and outputs",
Annotations: formatAnnotations("json"),
RunE: formatRunE,
}
func init() {
jsonCmd.PersistentFlags().BoolVar(new(bool), "no-escape", false, "do not escape special characters")
jsonCmd.PersistentFlags().MarkDeprecated("no-escape", "use '--escape=false' instead") //nolint:errcheck
jsonCmd.PersistentFlags().BoolVar(&settings.EscapeCharacters, "escape", true, "escape special characters")
rootCmd.AddCommand(jsonCmd)
}

28
cmd/json/json.go Normal file
View File

@@ -0,0 +1,28 @@
package json
import (
"github.com/spf13/cobra"
"github.com/segmentio/terraform-docs/internal/cli"
)
// NewCommand returns a new cobra.Command for 'json' formatter
func NewCommand(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),
}
// flags
cmd.PersistentFlags().BoolVar(&config.Settings.Escape, "escape", true, "escape special characters")
// deprecation
cmd.PersistentFlags().BoolVar(new(bool), "no-escape", false, "do not escape special characters")
cmd.PersistentFlags().MarkDeprecated("no-escape", "use '--escape=false' instead") //nolint:errcheck
return cmd
}

View File

@@ -1,51 +0,0 @@
package cmd
import (
"github.com/spf13/cobra"
)
var markdownCmd = &cobra.Command{
Args: cobra.ExactArgs(1),
Use: "markdown [PATH]",
Aliases: []string{"md"},
Short: "Generate Markdown of inputs and outputs",
Annotations: formatAnnotations("markdown"),
RunE: formatRunE,
}
var markdownTableCmd = &cobra.Command{
Args: cobra.ExactArgs(1),
Use: "table [PATH]",
Aliases: []string{"tbl"},
Short: "Generate Markdown tables of inputs and outputs",
Annotations: formatAnnotations("markdown table"),
RunE: formatRunE,
}
var markdownDocumentCmd = &cobra.Command{
Args: cobra.ExactArgs(1),
Use: "document [PATH]",
Aliases: []string{"doc"},
Short: "Generate Markdown document of inputs and outputs",
Annotations: formatAnnotations("markdown document"),
RunE: formatRunE,
}
func init() {
markdownCmd.PersistentFlags().BoolVar(new(bool), "no-required", false, "do not show \"Required\" column or section")
markdownCmd.PersistentFlags().BoolVar(new(bool), "no-sensitive", false, "do not show \"Sensitive\" column or section")
markdownCmd.PersistentFlags().BoolVar(new(bool), "no-escape", false, "do not escape special characters")
markdownCmd.PersistentFlags().MarkDeprecated("no-required", "use '--required=false' instead") //nolint:errcheck
markdownCmd.PersistentFlags().MarkDeprecated("no-sensitive", "use '--sensitive=false' instead") //nolint:errcheck
markdownCmd.PersistentFlags().MarkDeprecated("no-escape", "use '--escape=false' instead") //nolint:errcheck
markdownCmd.PersistentFlags().BoolVar(&settings.ShowRequired, "required", true, "show \"Required\" column or section")
markdownCmd.PersistentFlags().BoolVar(&settings.ShowSensitivity, "sensitive", true, "show \"Sensitive\" column or section")
markdownCmd.PersistentFlags().BoolVar(&settings.EscapeCharacters, "escape", true, "escape special characters")
markdownCmd.PersistentFlags().IntVar(&settings.IndentLevel, "indent", 2, "indention level of Markdown sections [1, 2, 3, 4, 5]")
markdownCmd.AddCommand(markdownTableCmd)
markdownCmd.AddCommand(markdownDocumentCmd)
rootCmd.AddCommand(markdownCmd)
}

View File

@@ -0,0 +1,21 @@
package document
import (
"github.com/spf13/cobra"
"github.com/segmentio/terraform-docs/internal/cli"
)
// NewCommand returns a new cobra.Command for 'markdown document' formatter
func NewCommand(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),
}
return cmd
}

42
cmd/markdown/markdown.go Normal file
View File

@@ -0,0 +1,42 @@
package markdown
import (
"github.com/spf13/cobra"
"github.com/segmentio/terraform-docs/cmd/markdown/document"
"github.com/segmentio/terraform-docs/cmd/markdown/table"
"github.com/segmentio/terraform-docs/internal/cli"
)
// NewCommand returns a new cobra.Command for 'markdown' formatter
func NewCommand(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),
}
// flags
cmd.PersistentFlags().BoolVar(&config.Settings.Required, "required", true, "show \"Required\" column or section")
cmd.PersistentFlags().BoolVar(&config.Settings.Sensitive, "sensitive", true, "show \"Sensitive\" column or section")
cmd.PersistentFlags().BoolVar(&config.Settings.Escape, "escape", true, "escape special characters")
cmd.PersistentFlags().IntVar(&config.Settings.Indent, "indent", 2, "indention level of Markdown sections [1, 2, 3, 4, 5]")
// deprecation
cmd.PersistentFlags().BoolVar(new(bool), "no-required", false, "do not show \"Required\" column or section")
cmd.PersistentFlags().BoolVar(new(bool), "no-sensitive", false, "do not show \"Sensitive\" column or section")
cmd.PersistentFlags().BoolVar(new(bool), "no-escape", false, "do not escape special characters")
cmd.PersistentFlags().MarkDeprecated("no-required", "use '--required=false' instead") //nolint:errcheck
cmd.PersistentFlags().MarkDeprecated("no-sensitive", "use '--sensitive=false' instead") //nolint:errcheck
cmd.PersistentFlags().MarkDeprecated("no-escape", "use '--escape=false' instead") //nolint:errcheck
// subcommands
cmd.AddCommand(document.NewCommand(config))
cmd.AddCommand(table.NewCommand(config))
return cmd
}

View File

@@ -0,0 +1,21 @@
package table
import (
"github.com/spf13/cobra"
"github.com/segmentio/terraform-docs/internal/cli"
)
// NewCommand returns a new cobra.Command for 'markdown table' formatter
func NewCommand(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),
}
return cmd
}

View File

@@ -1,22 +0,0 @@
package cmd
import (
"github.com/spf13/cobra"
)
var prettyCmd = &cobra.Command{
Args: cobra.ExactArgs(1),
Use: "pretty [PATH]",
Short: "Generate colorized pretty of inputs and outputs",
Annotations: formatAnnotations("pretty"),
RunE: formatRunE,
}
func init() {
prettyCmd.PersistentFlags().BoolVar(new(bool), "no-color", false, "do not colorize printed result")
prettyCmd.PersistentFlags().MarkDeprecated("no-color", "use '--color=false' instead") //nolint:errcheck
prettyCmd.PersistentFlags().BoolVar(&settings.ShowColor, "color", true, "colorize printed result")
rootCmd.AddCommand(prettyCmd)
}

28
cmd/pretty/pretty.go Normal file
View File

@@ -0,0 +1,28 @@
package pretty
import (
"github.com/spf13/cobra"
"github.com/segmentio/terraform-docs/internal/cli"
)
// NewCommand returns a new cobra.Command for pretty formatter
func NewCommand(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),
}
// flags
cmd.PersistentFlags().BoolVar(&config.Settings.Color, "color", true, "colorize printed result")
// deprecation
cmd.PersistentFlags().BoolVar(new(bool), "no-color", false, "do not colorize printed result")
cmd.PersistentFlags().MarkDeprecated("no-color", "use '--color=false' instead") //nolint:errcheck
return cmd
}

View File

@@ -2,180 +2,85 @@ package cmd
import (
"fmt"
"strings"
"github.com/spf13/cobra"
"github.com/segmentio/terraform-docs/internal/format"
"github.com/segmentio/terraform-docs/internal/module"
"github.com/segmentio/terraform-docs/internal/version"
"github.com/segmentio/terraform-docs/pkg/print"
"github.com/segmentio/terraform-docs/cmd/asciidoc"
"github.com/segmentio/terraform-docs/cmd/completion"
"github.com/segmentio/terraform-docs/cmd/json"
"github.com/segmentio/terraform-docs/cmd/markdown"
"github.com/segmentio/terraform-docs/cmd/pretty"
"github.com/segmentio/terraform-docs/cmd/tfvars"
"github.com/segmentio/terraform-docs/cmd/toml"
"github.com/segmentio/terraform-docs/cmd/version"
"github.com/segmentio/terraform-docs/cmd/xml"
"github.com/segmentio/terraform-docs/cmd/yaml"
"github.com/segmentio/terraform-docs/internal/cli"
)
var hides []string
var settings = print.NewSettings()
var options = module.NewOptions()
var rootCmd = &cobra.Command{
Args: cobra.NoArgs,
Use: "terraform-docs",
Short: "A utility to generate documentation from Terraform modules in various output formats",
Long: "A utility to generate documentation from Terraform modules in various output formats",
Version: version.Version(),
SilenceUsage: true,
SilenceErrors: true,
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
oppositeBool := func(name string) bool {
val, _ := cmd.Flags().GetBool(name)
return !val
}
for _, h := range hides {
switch h {
case "header":
case "inputs":
case "outputs":
case "providers":
case "requirements":
default:
return fmt.Errorf("'%s' is not a valid section to hide, available options [header, inputs, outputs, providers, requirements]", h)
}
}
if len(hides) > 0 && contains("header") {
settings.ShowHeader = false
} else {
settings.ShowHeader = oppositeBool("no-header")
}
options.ShowHeader = settings.ShowHeader
if len(hides) > 0 && contains("inputs") {
settings.ShowInputs = false
} else {
settings.ShowInputs = oppositeBool("no-inputs")
}
if len(hides) > 0 && contains("outputs") {
settings.ShowOutputs = false
} else {
settings.ShowOutputs = oppositeBool("no-outputs")
}
if len(hides) > 0 && contains("providers") {
settings.ShowProviders = false
} else {
settings.ShowProviders = oppositeBool("no-providers")
}
if len(hides) > 0 && contains("requirements") {
settings.ShowRequirements = false
} else {
settings.ShowRequirements = oppositeBool("no-requirements")
}
settings.OutputValues = options.OutputValues
if !cmd.Flags().Changed("color") {
settings.ShowColor = oppositeBool("no-color")
}
if !cmd.Flags().Changed("sort") {
settings.SortByName = oppositeBool("no-sort")
}
if !cmd.Flags().Changed("required") {
settings.ShowRequired = oppositeBool("no-required")
}
if !cmd.Flags().Changed("escape") {
settings.EscapeCharacters = oppositeBool("no-escape")
}
if !cmd.Flags().Changed("sensitive") {
settings.ShowSensitivity = oppositeBool("no-sensitive")
}
return nil
},
}
func init() {
rootCmd.PersistentFlags().StringSliceVar(&hides, "hide", []string{}, "hide section [header, inputs, outputs, providers, requirements]")
rootCmd.PersistentFlags().BoolVar(new(bool), "no-header", false, "do not show module header")
rootCmd.PersistentFlags().BoolVar(new(bool), "no-inputs", false, "do not show inputs")
rootCmd.PersistentFlags().BoolVar(new(bool), "no-outputs", false, "do not show outputs")
rootCmd.PersistentFlags().BoolVar(new(bool), "no-providers", false, "do not show providers")
rootCmd.PersistentFlags().BoolVar(new(bool), "no-requirements", false, "do not show module requirements")
rootCmd.PersistentFlags().BoolVar(new(bool), "no-sort", false, "do no sort items")
rootCmd.PersistentFlags().BoolVar(&settings.SortByName, "sort", true, "sort items")
rootCmd.PersistentFlags().BoolVar(&settings.SortByRequired, "sort-by-required", false, "sort items by name and print required ones first (default false)")
rootCmd.PersistentFlags().BoolVar(&settings.SortByType, "sort-by-type", false, "sort items by type of them (default false)")
rootCmd.PersistentFlags().StringVar(&options.HeaderFromFile, "header-from", "main.tf", "relative path of a file to read header from")
rootCmd.PersistentFlags().BoolVar(&options.OutputValues, "output-values", false, "inject output values into outputs (default false)")
rootCmd.PersistentFlags().StringVar(&options.OutputValuesPath, "output-values-from", "", "inject output values from file into outputs")
rootCmd.PersistentFlags().MarkDeprecated("no-header", "use '--hide header' instead") //nolint:errcheck
rootCmd.PersistentFlags().MarkDeprecated("no-inputs", "use '--hide inputs' instead") //nolint:errcheck
rootCmd.PersistentFlags().MarkDeprecated("no-outputs", "use '--hide outputs' instead") //nolint:errcheck
rootCmd.PersistentFlags().MarkDeprecated("no-providers", "use '--hide providers' instead") //nolint:errcheck
rootCmd.PersistentFlags().MarkDeprecated("no-requirements", "use '--hide requirements' instead") //nolint:errcheck
rootCmd.PersistentFlags().MarkDeprecated("no-sort", "use '--sort=false' instead") //nolint:errcheck
}
// Execute adds all child commands to the root command and sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute() error {
if err := rootCmd.Execute(); err != nil {
if err := NewCommand().Execute(); err != nil {
fmt.Printf("Error: %s\n", err.Error())
return err
}
return nil
}
// RootCmd represents the base command when called without any subcommands
func RootCmd() *cobra.Command {
return rootCmd
}
// NewCommand returns a new cobra.Command for 'root' command
func NewCommand() *cobra.Command {
config := cli.DefaultConfig()
cmd := &cobra.Command{
Args: cobra.NoArgs,
Use: "terraform-docs",
Short: "A utility to generate documentation from Terraform modules in various output formats",
Long: "A utility to generate documentation from Terraform modules in various output formats",
Version: version.Full(),
SilenceUsage: true,
SilenceErrors: true,
}
func contains(section string) bool {
for _, h := range hides {
if h == section {
return true
}
}
return false
}
// flags
cmd.PersistentFlags().StringSliceVar(&config.Sections.Hide, "hide", []string{}, "hide section [header, inputs, outputs, providers, requirements]")
var formatRunE = func(cmd *cobra.Command, args []string) error {
name := strings.Replace(cmd.CommandPath(), "terraform-docs ", "", -1)
printer, err := format.Factory(name, settings)
if err != nil {
return err
}
_, err = options.With(&module.Options{
Path: args[0],
SortBy: &module.SortBy{
Name: settings.SortByName,
Required: settings.SortByRequired,
Type: settings.SortByType,
},
})
if err != nil {
return err
}
tfmodule, err := module.LoadWithOptions(options)
if err != nil {
return err
}
output, err := printer.Print(tfmodule, settings)
if err != nil {
return err
}
fmt.Println(output)
return nil
}
cmd.PersistentFlags().BoolVar(&config.Sort.Enabled, "sort", true, "sort items")
cmd.PersistentFlags().BoolVar(&config.Sort.By.Required, "sort-by-required", false, "sort items by name and print required ones first (default false)")
cmd.PersistentFlags().BoolVar(&config.Sort.By.Type, "sort-by-type", false, "sort items by type of them (default false)")
var formatAnnotations = func(cmd string) map[string]string {
annotations := make(map[string]string)
for _, s := range strings.Split(cmd, " ") {
annotations["command"] = s
}
annotations["kind"] = "formatter"
return annotations
cmd.PersistentFlags().StringVar(&config.HeaderFrom, "header-from", "main.tf", "relative path of a file to read header from")
cmd.PersistentFlags().BoolVar(&config.OutputValues.Enabled, "output-values", false, "inject output values into outputs (default false)")
cmd.PersistentFlags().StringVar(&config.OutputValues.From, "output-values-from", "", "inject output values from file into outputs (default \"\")")
// deprecation
cmd.PersistentFlags().BoolVar(new(bool), "no-header", false, "do not show module header")
cmd.PersistentFlags().BoolVar(new(bool), "no-inputs", false, "do not show inputs")
cmd.PersistentFlags().BoolVar(new(bool), "no-outputs", false, "do not show outputs")
cmd.PersistentFlags().BoolVar(new(bool), "no-providers", false, "do not show providers")
cmd.PersistentFlags().BoolVar(new(bool), "no-requirements", false, "do not show module requirements")
cmd.PersistentFlags().BoolVar(new(bool), "no-sort", false, "do no sort items")
cmd.PersistentFlags().MarkDeprecated("no-header", "use '--hide header' instead") //nolint:errcheck
cmd.PersistentFlags().MarkDeprecated("no-inputs", "use '--hide inputs' instead") //nolint:errcheck
cmd.PersistentFlags().MarkDeprecated("no-outputs", "use '--hide outputs' instead") //nolint:errcheck
cmd.PersistentFlags().MarkDeprecated("no-providers", "use '--hide providers' instead") //nolint:errcheck
cmd.PersistentFlags().MarkDeprecated("no-requirements", "use '--hide requirements' instead") //nolint:errcheck
cmd.PersistentFlags().MarkDeprecated("no-sort", "use '--sort=false' instead") //nolint:errcheck
// 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))
// other subcommands
cmd.AddCommand(completion.NewCommand())
cmd.AddCommand(version.NewCommand())
return cmd
}

View File

@@ -1,35 +0,0 @@
package cmd
import (
"github.com/spf13/cobra"
)
var tfvarsCmd = &cobra.Command{
Args: cobra.ExactArgs(1),
Use: "tfvars [PATH]",
Short: "Generate terraform.tfvars of inputs",
Annotations: formatAnnotations("tfvars"),
}
var tfvarsHCLCmd = &cobra.Command{
Args: cobra.ExactArgs(1),
Use: "hcl [PATH]",
Short: "Generate HCL format of terraform.tfvars of inputs",
Annotations: formatAnnotations("tfvars hcl"),
RunE: formatRunE,
}
var tfvarsJSONCmd = &cobra.Command{
Args: cobra.ExactArgs(1),
Use: "json [PATH]",
Short: "Generate JSON format of terraform.tfvars of inputs",
Annotations: formatAnnotations("tfvars json"),
RunE: formatRunE,
}
func init() {
tfvarsCmd.AddCommand(tfvarsHCLCmd)
tfvarsCmd.AddCommand(tfvarsJSONCmd)
rootCmd.AddCommand(tfvarsCmd)
}

20
cmd/tfvars/hcl/hcl.go Normal file
View File

@@ -0,0 +1,20 @@
package hcl
import (
"github.com/spf13/cobra"
"github.com/segmentio/terraform-docs/internal/cli"
)
// NewCommand returns a new cobra.Command for 'tfvars hcl' formatter
func NewCommand(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),
}
return cmd
}

20
cmd/tfvars/json/json.go Normal file
View File

@@ -0,0 +1,20 @@
package json
import (
"github.com/spf13/cobra"
"github.com/segmentio/terraform-docs/internal/cli"
)
// NewCommand returns a new cobra.Command for 'tfvars json' formatter
func NewCommand(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),
}
return cmd
}

25
cmd/tfvars/tfvars.go Normal file
View File

@@ -0,0 +1,25 @@
package tfvars
import (
"github.com/spf13/cobra"
"github.com/segmentio/terraform-docs/cmd/tfvars/hcl"
"github.com/segmentio/terraform-docs/cmd/tfvars/json"
"github.com/segmentio/terraform-docs/internal/cli"
)
// NewCommand returns a new cobra.Command for 'tfvars' formatter
func NewCommand(config *cli.Config) *cobra.Command {
cmd := &cobra.Command{
Args: cobra.ExactArgs(1),
Use: "tfvars [PATH]",
Short: "Generate terraform.tfvars of inputs",
Annotations: cli.Annotations("tfvars"),
}
// subcommands
cmd.AddCommand(hcl.NewCommand(config))
cmd.AddCommand(json.NewCommand(config))
return cmd
}

View File

@@ -1,17 +0,0 @@
package cmd
import (
"github.com/spf13/cobra"
)
var tomlCmd = &cobra.Command{
Args: cobra.ExactArgs(1),
Use: "toml [PATH]",
Short: "Generate TOML of inputs and outputs",
Annotations: formatAnnotations("toml"),
RunE: formatRunE,
}
func init() {
rootCmd.AddCommand(tomlCmd)
}

20
cmd/toml/toml.go Normal file
View File

@@ -0,0 +1,20 @@
package toml
import (
"github.com/spf13/cobra"
"github.com/segmentio/terraform-docs/internal/cli"
)
// NewCommand returns a new cobra.Command for 'toml' formatter
func NewCommand(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),
}
return cmd
}

View File

@@ -1,22 +0,0 @@
package cmd
import (
"fmt"
"github.com/spf13/cobra"
"github.com/segmentio/terraform-docs/internal/version"
)
var versionCmd = &cobra.Command{
Args: cobra.NoArgs,
Use: "version",
Short: "Print the version number of terraform-docs",
Run: func(cmd *cobra.Command, args []string) {
fmt.Print(fmt.Sprintf("terraform-docs version %s\n", version.Version()))
},
}
func init() {
rootCmd.AddCommand(versionCmd)
}

27
cmd/version/version.go Normal file
View File

@@ -0,0 +1,27 @@
package version
import (
"fmt"
"github.com/spf13/cobra"
"github.com/segmentio/terraform-docs/internal/version"
)
// NewCommand returns a new cobra.Command for 'version' command
func NewCommand() *cobra.Command {
cmd := &cobra.Command{
Args: cobra.NoArgs,
Use: "version",
Short: "Print the version number of terraform-docs",
Run: func(cmd *cobra.Command, args []string) {
fmt.Printf("terraform-docs version %s\n", Full())
},
}
return cmd
}
// Full returns the full version of the binary
func Full() string {
return version.Full()
}

View File

@@ -1,17 +0,0 @@
package cmd
import (
"github.com/spf13/cobra"
)
var xmlCmd = &cobra.Command{
Args: cobra.ExactArgs(1),
Use: "xml [PATH]",
Short: "Generate XML of inputs and outputs",
Annotations: formatAnnotations("xml"),
RunE: formatRunE,
}
func init() {
rootCmd.AddCommand(xmlCmd)
}

20
cmd/xml/xml.go Normal file
View File

@@ -0,0 +1,20 @@
package xml
import (
"github.com/spf13/cobra"
"github.com/segmentio/terraform-docs/internal/cli"
)
// NewCommand returns a new cobra.Command for 'xml' formatter
func NewCommand(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),
}
return cmd
}

View File

@@ -1,17 +0,0 @@
package cmd
import (
"github.com/spf13/cobra"
)
var yamlCmd = &cobra.Command{
Args: cobra.ExactArgs(1),
Use: "yaml [PATH]",
Short: "Generate YAML of inputs and outputs",
Annotations: formatAnnotations("yaml"),
RunE: formatRunE,
}
func init() {
rootCmd.AddCommand(yamlCmd)
}

20
cmd/yaml/yaml.go Normal file
View File

@@ -0,0 +1,20 @@
package yaml
import (
"github.com/spf13/cobra"
"github.com/segmentio/terraform-docs/internal/cli"
)
// NewCommand returns a new cobra.Command for 'yaml' formatter
func NewCommand(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),
}
return cmd
}

View File

@@ -13,7 +13,7 @@ A utility to generate documentation from Terraform modules in various output for
-h, --help help for terraform-docs
--hide strings hide section [header, inputs, outputs, providers, requirements]
--output-values inject output values into outputs (default false)
--output-values-from string inject output values from file into outputs
--output-values-from string inject output values from file into outputs (default "")
--sort sort items (default true)
--sort-by-required sort items by name and print required ones first (default false)
--sort-by-type sort items by type of them (default false)
@@ -36,4 +36,4 @@ A utility to generate documentation from Terraform modules in various output for
* [terraform-docs xml](/docs/formats/xml.md) - Generate XML of inputs and outputs
* [terraform-docs yaml](/docs/formats/yaml.md) - Generate YAML of inputs and outputs
###### Auto generated by spf13/cobra on 19-May-2020
###### Auto generated by spf13/cobra on 20-May-2020

View File

@@ -23,7 +23,7 @@ terraform-docs asciidoc document [PATH] [flags]
--hide strings hide section [header, inputs, outputs, providers, requirements]
--indent int indention level of AsciiDoc sections [1, 2, 3, 4, 5] (default 2)
--output-values inject output values into outputs (default false)
--output-values-from string inject output values from file into outputs
--output-values-from string inject output values from file into outputs (default "")
--required show "Required" column or section (default true)
--sensitive show "Sensitive" column or section (default true)
--sort sort items (default true)
@@ -416,4 +416,4 @@ generates the following output:
###### Auto generated by spf13/cobra on 19-May-2020
###### Auto generated by spf13/cobra on 20-May-2020

View File

@@ -23,7 +23,7 @@ terraform-docs asciidoc table [PATH] [flags]
--hide strings hide section [header, inputs, outputs, providers, requirements]
--indent int indention level of AsciiDoc sections [1, 2, 3, 4, 5] (default 2)
--output-values inject output values into outputs (default false)
--output-values-from string inject output values from file into outputs
--output-values-from string inject output values from file into outputs (default "")
--required show "Required" column or section (default true)
--sensitive show "Sensitive" column or section (default true)
--sort sort items (default true)
@@ -372,4 +372,4 @@ generates the following output:
###### Auto generated by spf13/cobra on 19-May-2020
###### Auto generated by spf13/cobra on 20-May-2020

View File

@@ -25,7 +25,7 @@ terraform-docs asciidoc [PATH] [flags]
--header-from string relative path of a file to read header from (default "main.tf")
--hide strings hide section [header, inputs, outputs, providers, requirements]
--output-values inject output values into outputs (default false)
--output-values-from string inject output values from file into outputs
--output-values-from string inject output values from file into outputs (default "")
--sort sort items (default true)
--sort-by-required sort items by name and print required ones first (default false)
--sort-by-type sort items by type of them (default false)
@@ -36,4 +36,4 @@ terraform-docs asciidoc [PATH] [flags]
* [terraform-docs asciidoc document](/docs/formats/asciidoc-document.md) - Generate AsciiDoc document of inputs and outputs
* [terraform-docs asciidoc table](/docs/formats/asciidoc-table.md) - Generate AsciiDoc tables of inputs and outputs
###### Auto generated by spf13/cobra on 19-May-2020
###### Auto generated by spf13/cobra on 20-May-2020

View File

@@ -23,7 +23,7 @@ terraform-docs json [PATH] [flags]
--header-from string relative path of a file to read header from (default "main.tf")
--hide strings hide section [header, inputs, outputs, providers, requirements]
--output-values inject output values into outputs (default false)
--output-values-from string inject output values from file into outputs
--output-values-from string inject output values from file into outputs (default "")
--sort sort items (default true)
--sort-by-required sort items by name and print required ones first (default false)
--sort-by-type sort items by type of them (default false)
@@ -335,4 +335,4 @@ generates the following output:
}
###### Auto generated by spf13/cobra on 19-May-2020
###### Auto generated by spf13/cobra on 20-May-2020

View File

@@ -24,7 +24,7 @@ terraform-docs markdown document [PATH] [flags]
--hide strings hide section [header, inputs, outputs, providers, requirements]
--indent int indention level of Markdown sections [1, 2, 3, 4, 5] (default 2)
--output-values inject output values into outputs (default false)
--output-values-from string inject output values from file into outputs
--output-values-from string inject output values from file into outputs (default "")
--required show "Required" column or section (default true)
--sensitive show "Sensitive" column or section (default true)
--sort sort items (default true)
@@ -417,4 +417,4 @@ generates the following output:
###### Auto generated by spf13/cobra on 19-May-2020
###### Auto generated by spf13/cobra on 20-May-2020

View File

@@ -24,7 +24,7 @@ terraform-docs markdown table [PATH] [flags]
--hide strings hide section [header, inputs, outputs, providers, requirements]
--indent int indention level of Markdown sections [1, 2, 3, 4, 5] (default 2)
--output-values inject output values into outputs (default false)
--output-values-from string inject output values from file into outputs
--output-values-from string inject output values from file into outputs (default "")
--required show "Required" column or section (default true)
--sensitive show "Sensitive" column or section (default true)
--sort sort items (default true)
@@ -143,4 +143,4 @@ generates the following output:
###### Auto generated by spf13/cobra on 19-May-2020
###### Auto generated by spf13/cobra on 20-May-2020

View File

@@ -26,7 +26,7 @@ terraform-docs markdown [PATH] [flags]
--header-from string relative path of a file to read header from (default "main.tf")
--hide strings hide section [header, inputs, outputs, providers, requirements]
--output-values inject output values into outputs (default false)
--output-values-from string inject output values from file into outputs
--output-values-from string inject output values from file into outputs (default "")
--sort sort items (default true)
--sort-by-required sort items by name and print required ones first (default false)
--sort-by-type sort items by type of them (default false)
@@ -37,4 +37,4 @@ terraform-docs markdown [PATH] [flags]
* [terraform-docs markdown document](/docs/formats/markdown-document.md) - Generate Markdown document of inputs and outputs
* [terraform-docs markdown table](/docs/formats/markdown-table.md) - Generate Markdown tables of inputs and outputs
###### Auto generated by spf13/cobra on 19-May-2020
###### Auto generated by spf13/cobra on 20-May-2020

View File

@@ -23,7 +23,7 @@ terraform-docs pretty [PATH] [flags]
--header-from string relative path of a file to read header from (default "main.tf")
--hide strings hide section [header, inputs, outputs, providers, requirements]
--output-values inject output values into outputs (default false)
--output-values-from string inject output values from file into outputs
--output-values-from string inject output values from file into outputs (default "")
--sort sort items (default true)
--sort-by-required sort items by name and print required ones first (default false)
--sort-by-type sort items by type of them (default false)
@@ -239,4 +239,4 @@ generates the following output:
###### Auto generated by spf13/cobra on 19-May-2020
###### Auto generated by spf13/cobra on 20-May-2020

View File

@@ -22,7 +22,7 @@ terraform-docs tfvars hcl [PATH] [flags]
--header-from string relative path of a file to read header from (default "main.tf")
--hide strings hide section [header, inputs, outputs, providers, requirements]
--output-values inject output values into outputs (default false)
--output-values-from string inject output values from file into outputs
--output-values-from string inject output values from file into outputs (default "")
--sort sort items (default true)
--sort-by-required sort items by name and print required ones first (default false)
--sort-by-type sort items by type of them (default false)
@@ -95,4 +95,4 @@ generates the following output:
with-url = ""
###### Auto generated by spf13/cobra on 19-May-2020
###### Auto generated by spf13/cobra on 20-May-2020

View File

@@ -22,7 +22,7 @@ terraform-docs tfvars json [PATH] [flags]
--header-from string relative path of a file to read header from (default "main.tf")
--hide strings hide section [header, inputs, outputs, providers, requirements]
--output-values inject output values into outputs (default false)
--output-values-from string inject output values from file into outputs
--output-values-from string inject output values from file into outputs (default "")
--sort sort items (default true)
--sort-by-required sort items by name and print required ones first (default false)
--sort-by-type sort items by type of them (default false)
@@ -97,4 +97,4 @@ generates the following output:
}
###### Auto generated by spf13/cobra on 19-May-2020
###### Auto generated by spf13/cobra on 20-May-2020

View File

@@ -18,7 +18,7 @@ Generate terraform.tfvars of inputs
--header-from string relative path of a file to read header from (default "main.tf")
--hide strings hide section [header, inputs, outputs, providers, requirements]
--output-values inject output values into outputs (default false)
--output-values-from string inject output values from file into outputs
--output-values-from string inject output values from file into outputs (default "")
--sort sort items (default true)
--sort-by-required sort items by name and print required ones first (default false)
--sort-by-type sort items by type of them (default false)
@@ -29,4 +29,4 @@ Generate terraform.tfvars of inputs
* [terraform-docs tfvars hcl](/docs/formats/tfvars-hcl.md) - Generate HCL format of terraform.tfvars of inputs
* [terraform-docs tfvars json](/docs/formats/tfvars-json.md) - Generate JSON format of terraform.tfvars of inputs
###### Auto generated by spf13/cobra on 19-May-2020
###### Auto generated by spf13/cobra on 20-May-2020

View File

@@ -22,7 +22,7 @@ terraform-docs toml [PATH] [flags]
--header-from string relative path of a file to read header from (default "main.tf")
--hide strings hide section [header, inputs, outputs, providers, requirements]
--output-values inject output values into outputs (default false)
--output-values-from string inject output values from file into outputs
--output-values-from string inject output values from file into outputs (default "")
--sort sort items (default true)
--sort-by-required sort items by name and print required ones first (default false)
--sort-by-type sort items by type of them (default false)
@@ -312,4 +312,4 @@ generates the following output:
###### Auto generated by spf13/cobra on 19-May-2020
###### Auto generated by spf13/cobra on 20-May-2020

View File

@@ -22,7 +22,7 @@ terraform-docs xml [PATH] [flags]
--header-from string relative path of a file to read header from (default "main.tf")
--hide strings hide section [header, inputs, outputs, providers, requirements]
--output-values inject output values into outputs (default false)
--output-values-from string inject output values from file into outputs
--output-values-from string inject output values from file into outputs (default "")
--sort sort items (default true)
--sort-by-required sort items by name and print required ones first (default false)
--sort-by-type sort items by type of them (default false)
@@ -334,4 +334,4 @@ generates the following output:
</module>
###### Auto generated by spf13/cobra on 19-May-2020
###### Auto generated by spf13/cobra on 20-May-2020

View File

@@ -22,7 +22,7 @@ terraform-docs yaml [PATH] [flags]
--header-from string relative path of a file to read header from (default "main.tf")
--hide strings hide section [header, inputs, outputs, providers, requirements]
--output-values inject output values into outputs (default false)
--output-values-from string inject output values from file into outputs
--output-values-from string inject output values from file into outputs (default "")
--sort sort items (default true)
--sort-by-required sort items by name and print required ones first (default false)
--sort-by-type sort items by type of them (default false)
@@ -286,4 +286,4 @@ generates the following output:
version: '>= 2.2.0'
###### Auto generated by spf13/cobra on 19-May-2020
###### Auto generated by spf13/cobra on 20-May-2020

1
go.mod
View File

@@ -10,6 +10,7 @@ require (
github.com/iancoleman/orderedmap v0.0.0-20190318233801-ac98e3ecb4b0
github.com/imdario/mergo v0.3.9
github.com/spf13/cobra v1.0.0
github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.5.1
github.com/zclconf/go-cty v1.4.1
gopkg.in/yaml.v3 v3.0.0-20200506231410-2ff61e1afc86

4
go.sum
View File

@@ -114,6 +114,8 @@ github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb6
github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
@@ -128,8 +130,6 @@ github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6Ac
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
github.com/zclconf/go-cty v1.2.0/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8=
github.com/zclconf/go-cty v1.4.0 h1:+q+tmgyUB94HIdH/uVTIi/+kt3pt4sHwEZAcTyLoGsQ=
github.com/zclconf/go-cty v1.4.0/go.mod h1:nHzOclRkoj++EU9ZjSrZvRG0BXIWt8c7loYc0qXAFGQ=
github.com/zclconf/go-cty v1.4.1 h1:Xzr4m4utRDhHDifag1onwwUSq32HLoLBsp+w6tD0880=
github.com/zclconf/go-cty v1.4.1/go.mod h1:nHzOclRkoj++EU9ZjSrZvRG0BXIWt8c7loYc0qXAFGQ=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=

View File

@@ -0,0 +1,16 @@
package cli
import (
"strings"
)
// Annotations returns set of annotations for cobra.Commands,
// specifically the 'command' namd and command 'kind'
func Annotations(cmd string) map[string]string {
annotations := make(map[string]string)
for _, s := range strings.Split(cmd, " ") {
annotations["command"] = s
}
annotations["kind"] = "formatter"
return annotations
}

235
internal/cli/config.go Normal file
View File

@@ -0,0 +1,235 @@
package cli
import (
"fmt"
"strings"
"github.com/spf13/pflag"
"github.com/segmentio/terraform-docs/internal/module"
"github.com/segmentio/terraform-docs/pkg/print"
)
type sections struct {
Hide []string
header bool
inputs bool
outputs bool
providers bool
requirements bool
}
func (s *sections) contains(section string) bool {
for _, item := range s.Hide {
if item == section {
return true
}
}
return false
}
func (s *sections) validate(fs *pflag.FlagSet) error {
sections := []string{"header", "inputs", "outputs", "providers", "requirements"}
for _, h := range s.Hide {
switch h {
case sections[0], sections[1], sections[2], sections[3], sections[4]:
default:
return fmt.Errorf("'%s' is not a valid section", h)
}
}
for _, section := range sections {
if fs.Changed("no-"+section) && s.contains(section) {
return fmt.Errorf("'--no-%s' and '--hide %s' cannot be used together", section, section)
}
}
return nil
}
type outputvalues struct {
Enabled bool
From string
}
func (o *outputvalues) validate() error {
if o.Enabled && o.From == "" {
return fmt.Errorf("value of '--output-values-from' cannot be empty")
}
return nil
}
type sortby struct {
Required bool
Type bool
}
type sort struct {
Enabled bool
By *sortby
}
func (s *sort) validate(fs *pflag.FlagSet) error {
items := []string{"sort"}
for _, item := range items {
if fs.Changed("no-"+item) && fs.Changed(item) {
return fmt.Errorf("'--no-%s' and '--%s' cannot be used together", item, item)
}
}
if fs.Changed("sort-by-required") && fs.Changed("sort-by-type") {
return fmt.Errorf("'--sort-by-required' and '--sort-by-type' cannot be used together")
}
return nil
}
type settings struct {
Color bool
Escape bool
Indent int
Required bool
Sensitive bool
}
func (s *settings) validate(fs *pflag.FlagSet) error {
items := []string{"escape", "color", "required", "sensitive"}
for _, item := range items {
if fs.Changed("no-"+item) && fs.Changed(item) {
return fmt.Errorf("'--no-%s' and '--%s' cannot be used together", item, item)
}
}
return nil
}
// Config represents all the available config options that can be accessed and passed through CLI
type Config struct {
Formatter string
HeaderFrom string
Sections *sections
OutputValues *outputvalues
Sort *sort
Settings *settings
}
// DefaultConfig returns new instance of Config with default values set
func DefaultConfig() *Config {
return &Config{
Formatter: "",
HeaderFrom: "main.tf",
Sections: &sections{
Hide: []string{},
header: true,
inputs: true,
outputs: true,
providers: true,
requirements: true,
},
OutputValues: &outputvalues{
Enabled: false,
From: "",
},
Sort: &sort{
Enabled: true,
By: &sortby{
Required: false,
Type: false,
},
},
Settings: &settings{
Color: true,
Escape: true,
Indent: 2,
Required: false,
Sensitive: false,
},
}
}
// extract and build print.Settings and module.Options out of Config
func (c *Config) extract() (*print.Settings, *module.Options, error) {
settings := print.NewSettings()
options := module.NewOptions()
// header-from
options.HeaderFromFile = c.HeaderFrom
// sections
settings.ShowHeader = c.Sections.header
settings.ShowInputs = c.Sections.inputs
settings.ShowOutputs = c.Sections.outputs
settings.ShowProviders = c.Sections.providers
settings.ShowRequirements = c.Sections.requirements
options.ShowHeader = settings.ShowHeader
// output values
settings.OutputValues = c.OutputValues.Enabled
options.OutputValues = c.OutputValues.Enabled
options.OutputValuesPath = c.OutputValues.From
// sort
settings.SortByName = c.Sort.Enabled
settings.SortByRequired = c.Sort.Enabled && c.Sort.By.Required
settings.SortByType = c.Sort.Enabled && c.Sort.By.Type
options.SortBy.Name = settings.SortByName
options.SortBy.Required = settings.SortByRequired
options.SortBy.Type = settings.SortByType
// settings
settings.EscapeCharacters = c.Settings.Escape
settings.IndentLevel = c.Settings.Indent
settings.ShowColor = c.Settings.Color
settings.ShowRequired = c.Settings.Required
settings.ShowSensitivity = c.Settings.Sensitive
return settings, options, nil
}
// normalize provided Config and check for any misuse or misconfiguration
func normalize(command string, fs *pflag.FlagSet, config *Config) error {
config.Formatter = strings.Replace(command, "terraform-docs ", "", -1)
// header-from
if fs.Changed("header-from") && config.HeaderFrom == "" {
return fmt.Errorf("value of '--header-from' cannot be empty")
}
// sections
if err := config.Sections.validate(fs); err != nil {
return err
}
config.Sections.header = !(config.Sections.contains("header") || fs.Changed("no-header"))
config.Sections.inputs = !(config.Sections.contains("inputs") || fs.Changed("no-inputs"))
config.Sections.outputs = !(config.Sections.contains("outputs") || fs.Changed("no-outputs"))
config.Sections.providers = !(config.Sections.contains("providers") || fs.Changed("no-providers"))
config.Sections.requirements = !(config.Sections.contains("requirements") || fs.Changed("no-requirements"))
// output values
if err := config.OutputValues.validate(); err != nil {
return err
}
// sort
if err := config.Sort.validate(fs); err != nil {
return err
}
if !fs.Changed("sort") {
config.Sort.Enabled = !fs.Changed("no-sort")
}
// settings
if err := config.Settings.validate(fs); err != nil {
return err
}
if !fs.Changed("escape") {
config.Settings.Escape = !fs.Changed("no-escape")
}
if !fs.Changed("color") {
config.Settings.Color = !fs.Changed("no-color")
}
if !fs.Changed("required") {
config.Settings.Required = !fs.Changed("no-required")
}
if !fs.Changed("sensitive") {
config.Settings.Sensitive = !fs.Changed("no-sensitive")
}
return nil
}

47
internal/cli/run.go Normal file
View File

@@ -0,0 +1,47 @@
package cli
import (
"fmt"
"github.com/spf13/cobra"
"github.com/segmentio/terraform-docs/internal/format"
"github.com/segmentio/terraform-docs/internal/module"
)
// PreRunEFunc returns actual 'cobra.Command#PreRunE' function
// for 'formatter' commands. This functions reads and normalizes
// flags and arguments passed through CLI execution.
func PreRunEFunc(config *Config) func(*cobra.Command, []string) error {
return func(cmd *cobra.Command, args []string) error {
return normalize(cmd.CommandPath(), cmd.Flags(), config)
}
}
// RunEFunc returns actual 'cobra.Command#RunE' function for
// 'formatter' commands. This functions extract print.Settings
// and module.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, args []string) error {
settings, options, err := config.extract()
if err != nil {
return err
}
printer, err := format.Factory(config.Formatter, settings)
if err != nil {
return err
}
options.Path = args[0]
tfmodule, err := module.LoadWithOptions(options)
if err != nil {
return err
}
output, err := printer.Print(tfmodule, settings)
if err != nil {
return err
}
fmt.Println(output)
return nil
}
}

View File

@@ -12,19 +12,19 @@ import (
// function.
func Factory(name string, settings *print.Settings) (print.Format, error) {
switch name {
case "asciidoc":
case "asciidoc", "adoc":
return NewAsciidocTable(settings), nil
case "asciidoc document":
case "asciidoc document", "asciidoc doc", "adoc document", "adoc doc":
return NewAsciidocDocument(settings), nil
case "asciidoc table":
case "asciidoc table", "asciidoc tbl", "adoc table", "adoc tbl":
return NewAsciidocTable(settings), nil
case "json":
return NewJSON(settings), nil
case "markdown":
case "markdown", "md":
return NewTable(settings), nil
case "markdown document":
case "markdown document", "markdown doc", "md document", "md doc":
return NewDocument(settings), nil
case "markdown table":
case "markdown table", "markdown tbl", "md table", "md tbl":
return NewTable(settings), nil
case "pretty":
return NewPretty(settings), nil

View File

@@ -22,18 +22,60 @@ func TestFormatFactory(t *testing.T) {
expected: "*format.AsciidocTable",
wantErr: false,
},
{
name: "format factory from name",
format: "adoc",
expected: "*format.AsciidocTable",
wantErr: false,
},
{
name: "format factory from name",
format: "asciidoc document",
expected: "*format.AsciidocDocument",
wantErr: false,
},
{
name: "format factory from name",
format: "asciidoc doc",
expected: "*format.AsciidocDocument",
wantErr: false,
},
{
name: "format factory from name",
format: "adoc document",
expected: "*format.AsciidocDocument",
wantErr: false,
},
{
name: "format factory from name",
format: "adoc doc",
expected: "*format.AsciidocDocument",
wantErr: false,
},
{
name: "format factory from name",
format: "asciidoc table",
expected: "*format.AsciidocTable",
wantErr: false,
},
{
name: "format factory from name",
format: "asciidoc tbl",
expected: "*format.AsciidocTable",
wantErr: false,
},
{
name: "format factory from name",
format: "adoc table",
expected: "*format.AsciidocTable",
wantErr: false,
},
{
name: "format factory from name",
format: "adoc tbl",
expected: "*format.AsciidocTable",
wantErr: false,
},
{
name: "format factory from name",
format: "json",
@@ -46,18 +88,60 @@ func TestFormatFactory(t *testing.T) {
expected: "*format.Table",
wantErr: false,
},
{
name: "format factory from name",
format: "md",
expected: "*format.Table",
wantErr: false,
},
{
name: "format factory from name",
format: "markdown document",
expected: "*format.Document",
wantErr: false,
},
{
name: "format factory from name",
format: "markdown doc",
expected: "*format.Document",
wantErr: false,
},
{
name: "format factory from name",
format: "md document",
expected: "*format.Document",
wantErr: false,
},
{
name: "format factory from name",
format: "md doc",
expected: "*format.Document",
wantErr: false,
},
{
name: "format factory from name",
format: "markdown table",
expected: "*format.Table",
wantErr: false,
},
{
name: "format factory from name",
format: "markdown tbl",
expected: "*format.Table",
wantErr: false,
},
{
name: "format factory from name",
format: "md table",
expected: "*format.Table",
wantErr: false,
},
{
name: "format factory from name",
format: "md tbl",
expected: "*format.Table",
wantErr: false,
},
{
name: "format factory from name",
format: "pretty",

View File

@@ -30,8 +30,8 @@ func init() {
}
}
// Version return the full version of the binary including commit hash and build date
func Version() string {
// Full return the full version of the binary including commit hash and build date
func Full() string {
if !strings.HasSuffix(version, commitHash) {
version += " " + commitHash
}

View File

@@ -63,7 +63,7 @@ type Settings struct {
SortByType bool
}
//NewSettings returns new instance of Settings
// NewSettings returns new instance of Settings
func NewSettings() *Settings {
return &Settings{
EscapeCharacters: true,

View File

@@ -26,7 +26,7 @@ var basedir = "/docs"
var formatdir = "/formats"
func main() {
err := generate(cmd.RootCmd(), "", "FORMATS_GUIDE")
err := generate(cmd.NewCommand(), "", "FORMATS_GUIDE")
if err != nil {
log.Fatal(err)
}