mirror of
https://github.com/terraform-docs/terraform-docs.git
synced 2026-03-27 04:48:33 +07:00
refactor: Introduce Format interface and expose to public pkg (#195)
* Introduce format interface and expose to public pkg * fix issues after merge * don't panic * Rename TFString back to String
This commit is contained in:
14
Makefile
14
Makefile
@@ -24,9 +24,9 @@ GOPKGS ?= $(shell $(GOCMD) list $(MODVENDOR) ./... | grep -v /vendor)
|
||||
MODVENDOR := -mod=vendor
|
||||
|
||||
GOLDFLAGS :="
|
||||
GOLDFLAGS += -X $(PACKAGE)/internal/pkg/version.version=$(VERSION)
|
||||
GOLDFLAGS += -X $(PACKAGE)/internal/pkg/version.commitHash=$(COMMIT_HASH)
|
||||
GOLDFLAGS += -X $(PACKAGE)/internal/pkg/version.buildDate=$(BUILD_DATE)
|
||||
GOLDFLAGS += -X $(PACKAGE)/internal/version.version=$(VERSION)
|
||||
GOLDFLAGS += -X $(PACKAGE)/internal/version.commitHash=$(COMMIT_HASH)
|
||||
GOLDFLAGS += -X $(PACKAGE)/internal/version.buildDate=$(BUILD_DATE)
|
||||
GOLDFLAGS +="
|
||||
|
||||
GOBUILD ?= CGO_ENABLED=0 $(GOCMD) build $(MODVENDOR) -ldflags $(GOLDFLAGS)
|
||||
@@ -147,19 +147,27 @@ changelog: ## Generate Changelog
|
||||
|
||||
.PHONY: git-chglog
|
||||
git-chglog:
|
||||
ifeq (, $(shell which git-chglog))
|
||||
curl -sfL https://github.com/git-chglog/git-chglog/releases/download/$(GITCHGLOG_VERSION)/git-chglog_$(shell go env GOOS)_$(shell go env GOARCH) -o $(shell go env GOPATH)/bin/git-chglog && chmod +x $(shell go env GOPATH)/bin/git-chglog
|
||||
endif
|
||||
|
||||
.PHONY: goimports
|
||||
goimports:
|
||||
ifeq (, $(shell which goimports))
|
||||
GO111MODULE=off go get -u golang.org/x/tools/cmd/goimports
|
||||
endif
|
||||
|
||||
.PHONY: golangci
|
||||
golangci:
|
||||
ifeq (, $(shell which golangci-lint))
|
||||
curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(shell go env GOPATH)/bin $(GOLANGCI_VERSION)
|
||||
endif
|
||||
|
||||
.PHONY: gox
|
||||
gox:
|
||||
ifeq (, $(shell which gox))
|
||||
GO111MODULE=off go get -u github.com/mitchellh/gox
|
||||
endif
|
||||
|
||||
.PHONY: tools
|
||||
tools: ## Install required tools
|
||||
|
||||
11
cmd/json.go
11
cmd/json.go
@@ -1,8 +1,7 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"github.com/segmentio/terraform-docs/internal/pkg/print/json"
|
||||
"github.com/segmentio/terraform-docs/internal/pkg/tfconf"
|
||||
"github.com/segmentio/terraform-docs/internal/format"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
@@ -10,13 +9,13 @@ var jsonCmd = &cobra.Command{
|
||||
Args: cobra.ExactArgs(1),
|
||||
Use: "json [PATH]",
|
||||
Short: "Generate JSON of inputs and outputs",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
doPrint(args[0], func(module *tfconf.Module) (string, error) {
|
||||
return json.Print(module, settings)
|
||||
})
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
return doPrint(args[0], format.NewJSON(settings))
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
jsonCmd.PersistentFlags().BoolVar(new(bool), "no-escape", false, "do not escape special characters")
|
||||
|
||||
rootCmd.AddCommand(jsonCmd)
|
||||
}
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"github.com/segmentio/terraform-docs/internal/pkg/print/markdown/document"
|
||||
"github.com/segmentio/terraform-docs/internal/pkg/print/markdown/table"
|
||||
"github.com/segmentio/terraform-docs/internal/pkg/tfconf"
|
||||
"github.com/segmentio/terraform-docs/internal/format"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
@@ -12,10 +10,8 @@ var markdownCmd = &cobra.Command{
|
||||
Use: "markdown [PATH]",
|
||||
Aliases: []string{"md"},
|
||||
Short: "Generate Markdown of inputs and outputs",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
doPrint(args[0], func(module *tfconf.Module) (string, error) {
|
||||
return table.Print(module, settings)
|
||||
})
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
return doPrint(args[0], format.NewTable(settings))
|
||||
},
|
||||
}
|
||||
|
||||
@@ -24,10 +20,8 @@ var mdTableCmd = &cobra.Command{
|
||||
Use: "table [PATH]",
|
||||
Aliases: []string{"tbl"},
|
||||
Short: "Generate Markdown tables of inputs and outputs",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
doPrint(args[0], func(module *tfconf.Module) (string, error) {
|
||||
return table.Print(module, settings)
|
||||
})
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
return doPrint(args[0], format.NewTable(settings))
|
||||
},
|
||||
}
|
||||
|
||||
@@ -36,14 +30,16 @@ var mdDocumentCmd = &cobra.Command{
|
||||
Use: "document [PATH]",
|
||||
Aliases: []string{"doc"},
|
||||
Short: "Generate Markdown document of inputs and outputs",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
doPrint(args[0], func(module *tfconf.Module) (string, error) {
|
||||
return document.Print(module, settings)
|
||||
})
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
return doPrint(args[0], format.NewDocument(settings))
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
markdownCmd.PersistentFlags().BoolVar(new(bool), "no-required", false, "do not show \"Required\" column or section")
|
||||
markdownCmd.PersistentFlags().BoolVar(new(bool), "no-escape", false, "do not escape special characters")
|
||||
markdownCmd.PersistentFlags().IntVar(&settings.MarkdownIndent, "indent", 2, "indention level of Markdown sections [1, 2, 3, 4, 5]")
|
||||
|
||||
markdownCmd.AddCommand(mdTableCmd)
|
||||
markdownCmd.AddCommand(mdDocumentCmd)
|
||||
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"github.com/segmentio/terraform-docs/internal/pkg/print/pretty"
|
||||
"github.com/segmentio/terraform-docs/internal/pkg/tfconf"
|
||||
"github.com/segmentio/terraform-docs/internal/format"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
@@ -10,13 +9,13 @@ var prettyCmd = &cobra.Command{
|
||||
Args: cobra.ExactArgs(1),
|
||||
Use: "pretty [PATH]",
|
||||
Short: "Generate colorized pretty of inputs and outputs",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
doPrint(args[0], func(module *tfconf.Module) (string, error) {
|
||||
return pretty.Print(module, settings)
|
||||
})
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
return doPrint(args[0], format.NewPretty(settings))
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
prettyCmd.PersistentFlags().BoolVar(new(bool), "no-color", false, "do not colorize printed result")
|
||||
|
||||
rootCmd.AddCommand(prettyCmd)
|
||||
}
|
||||
|
||||
71
cmd/root.go
71
cmd/root.go
@@ -2,16 +2,15 @@ package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/segmentio/terraform-docs/internal/pkg/print"
|
||||
"github.com/segmentio/terraform-docs/internal/pkg/tfconf"
|
||||
"github.com/segmentio/terraform-docs/internal/pkg/version"
|
||||
"github.com/segmentio/terraform-docs/internal/module"
|
||||
"github.com/segmentio/terraform-docs/internal/version"
|
||||
"github.com/segmentio/terraform-docs/pkg/print"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var settings = print.NewSettings()
|
||||
var options = tfconf.Options{}
|
||||
var options = module.NewOptions()
|
||||
|
||||
// rootCmd represents the base command when called without any subcommands
|
||||
var rootCmd = &cobra.Command{
|
||||
@@ -21,27 +20,19 @@ var rootCmd = &cobra.Command{
|
||||
Long: "A utility to generate documentation from Terraform modules in various output formats",
|
||||
Version: version.Version(),
|
||||
PersistentPreRun: func(cmd *cobra.Command, args []string) {
|
||||
noheader, _ := cmd.Flags().GetBool("no-header")
|
||||
noproviders, _ := cmd.Flags().GetBool("no-providers")
|
||||
noinputs, _ := cmd.Flags().GetBool("no-inputs")
|
||||
nooutputs, _ := cmd.Flags().GetBool("no-outputs")
|
||||
oppositeBool := func(name string) bool {
|
||||
val, _ := cmd.Flags().GetBool(name)
|
||||
return !val
|
||||
}
|
||||
settings.ShowHeader = oppositeBool("no-header")
|
||||
settings.ShowProviders = oppositeBool("no-providers")
|
||||
settings.ShowInputs = oppositeBool("no-inputs")
|
||||
settings.ShowOutputs = oppositeBool("no-outputs")
|
||||
|
||||
nocolor, _ := cmd.Flags().GetBool("no-color")
|
||||
nosort, _ := cmd.Flags().GetBool("no-sort")
|
||||
norequired, _ := cmd.Flags().GetBool("no-required")
|
||||
noescape, _ := cmd.Flags().GetBool("no-escape")
|
||||
|
||||
settings.ShowHeader = !noheader
|
||||
settings.ShowProviders = !noproviders
|
||||
settings.ShowInputs = !noinputs
|
||||
settings.ShowOutputs = !nooutputs
|
||||
|
||||
settings.OutputValues = options.OutputValues
|
||||
|
||||
settings.ShowColor = !nocolor
|
||||
settings.SortByName = !nosort
|
||||
settings.ShowRequired = !norequired
|
||||
settings.EscapeCharacters = !noescape
|
||||
settings.ShowColor = oppositeBool("no-color")
|
||||
settings.SortByName = oppositeBool("no-sort")
|
||||
settings.ShowRequired = oppositeBool("no-required")
|
||||
settings.EscapeCharacters = oppositeBool("no-escape")
|
||||
},
|
||||
}
|
||||
|
||||
@@ -63,14 +54,6 @@ func init() {
|
||||
rootCmd.PersistentFlags().BoolVar(&settings.SortByRequired, "sort-inputs-by-required", false, "[deprecated] use '--sort-by-required' instead")
|
||||
rootCmd.PersistentFlags().BoolVar(new(bool), "with-aggregate-type-defaults", false, "[deprecated] print default values of aggregate types")
|
||||
//-----------------------------
|
||||
|
||||
markdownCmd.PersistentFlags().BoolVar(new(bool), "no-required", false, "do not show \"Required\" column or section")
|
||||
markdownCmd.PersistentFlags().BoolVar(new(bool), "no-escape", false, "do not escape special characters")
|
||||
markdownCmd.PersistentFlags().IntVar(&settings.MarkdownIndent, "indent", 2, "indention level of Markdown sections [1, 2, 3, 4, 5]")
|
||||
|
||||
prettyCmd.PersistentFlags().BoolVar(new(bool), "no-color", false, "do not colorize printed result")
|
||||
|
||||
jsonCmd.PersistentFlags().BoolVar(new(bool), "no-escape", false, "do not escape special characters")
|
||||
}
|
||||
|
||||
// Execute adds all child commands to the root command and sets flags appropriately.
|
||||
@@ -92,18 +75,22 @@ func FormatterCmds() []*cobra.Command {
|
||||
}
|
||||
}
|
||||
|
||||
func doPrint(path string, fn func(*tfconf.Module) (string, error)) {
|
||||
options.Path = path
|
||||
module, err := tfconf.CreateModule(&options)
|
||||
func doPrint(path string, printer print.Format) error {
|
||||
options.With(&module.Options{
|
||||
Path: path,
|
||||
SortBy: &module.SortBy{
|
||||
Name: settings.SortByName,
|
||||
Required: settings.SortByRequired,
|
||||
},
|
||||
})
|
||||
tfmodule, err := module.LoadWithOptions(options)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
return err
|
||||
}
|
||||
|
||||
output, err := fn(module)
|
||||
|
||||
output, err := printer.Print(tfmodule, settings)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println(output)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ package cmd
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/segmentio/terraform-docs/internal/pkg/version"
|
||||
"github.com/segmentio/terraform-docs/internal/version"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"github.com/segmentio/terraform-docs/internal/pkg/print/yaml"
|
||||
"github.com/segmentio/terraform-docs/internal/pkg/tfconf"
|
||||
"github.com/segmentio/terraform-docs/internal/format"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
@@ -10,10 +9,8 @@ var yamlCmd = &cobra.Command{
|
||||
Args: cobra.ExactArgs(1),
|
||||
Use: "yaml [PATH]",
|
||||
Short: "Generate YAML of inputs and outputs",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
doPrint(args[0], func(module *tfconf.Module) (string, error) {
|
||||
return yaml.Print(module, settings)
|
||||
})
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
return doPrint(args[0], format.NewYAML(settings))
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
package document
|
||||
package format
|
||||
|
||||
import (
|
||||
"text/template"
|
||||
|
||||
"github.com/segmentio/terraform-docs/internal/pkg/print"
|
||||
"github.com/segmentio/terraform-docs/internal/pkg/print/markdown"
|
||||
"github.com/segmentio/terraform-docs/internal/pkg/tfconf"
|
||||
"github.com/segmentio/terraform-docs/internal/pkg/tmpl"
|
||||
"github.com/segmentio/terraform-docs/pkg/print"
|
||||
"github.com/segmentio/terraform-docs/pkg/tfconf"
|
||||
"github.com/segmentio/terraform-docs/pkg/tmpl"
|
||||
)
|
||||
|
||||
const (
|
||||
headerTpl = `
|
||||
documentHeaderTpl = `
|
||||
{{- if .Settings.ShowHeader -}}
|
||||
{{- with .Module.Header -}}
|
||||
{{ sanitizeHeader . }}
|
||||
@@ -19,7 +18,7 @@ const (
|
||||
{{ end -}}
|
||||
`
|
||||
|
||||
providersTpl = `
|
||||
documentProvidersTpl = `
|
||||
{{- if .Settings.ShowProviders -}}
|
||||
{{ indent 0 }} Providers
|
||||
{{ if not .Module.Providers }}
|
||||
@@ -34,7 +33,7 @@ const (
|
||||
{{ end -}}
|
||||
`
|
||||
|
||||
inputsTpl = `
|
||||
documentInputsTpl = `
|
||||
{{- if .Settings.ShowInputs -}}
|
||||
{{- if .Settings.ShowRequired -}}
|
||||
{{ indent 0 }} Required Inputs
|
||||
@@ -69,7 +68,7 @@ const (
|
||||
{{ end -}}
|
||||
`
|
||||
|
||||
inputTpl = `
|
||||
documentInputTpl = `
|
||||
{{ printf "\n" }}
|
||||
{{ indent 1 }} {{ name .Name }}
|
||||
|
||||
@@ -82,7 +81,7 @@ const (
|
||||
{{- end }}
|
||||
`
|
||||
|
||||
outputsTpl = `
|
||||
documentOutputsTpl = `
|
||||
{{- if .Settings.ShowOutputs -}}
|
||||
{{ indent 0 }} Outputs
|
||||
{{ if not .Module.Outputs }}
|
||||
@@ -110,33 +109,36 @@ const (
|
||||
`
|
||||
)
|
||||
|
||||
// Print prints a document as Markdown document.
|
||||
func Print(module *tfconf.Module, settings *print.Settings) (string, error) {
|
||||
module.Sort(settings)
|
||||
// Document represents Markdown Document format.
|
||||
type Document struct {
|
||||
template *tmpl.Template
|
||||
}
|
||||
|
||||
t := tmpl.NewTemplate(&tmpl.Item{
|
||||
// NewDocument returns new instance of Document.
|
||||
func NewDocument(settings *print.Settings) *Document {
|
||||
tt := tmpl.NewTemplate(&tmpl.Item{
|
||||
Name: "document",
|
||||
Text: documentTpl,
|
||||
}, &tmpl.Item{
|
||||
Name: "header",
|
||||
Text: headerTpl,
|
||||
Text: documentHeaderTpl,
|
||||
}, &tmpl.Item{
|
||||
Name: "providers",
|
||||
Text: providersTpl,
|
||||
Text: documentProvidersTpl,
|
||||
}, &tmpl.Item{
|
||||
Name: "inputs",
|
||||
Text: inputsTpl,
|
||||
Text: documentInputsTpl,
|
||||
}, &tmpl.Item{
|
||||
Name: "input",
|
||||
Text: inputTpl,
|
||||
Text: documentInputTpl,
|
||||
}, &tmpl.Item{
|
||||
Name: "outputs",
|
||||
Text: outputsTpl,
|
||||
Text: documentOutputsTpl,
|
||||
})
|
||||
t.Settings(settings)
|
||||
t.CustomFunc(template.FuncMap{
|
||||
tt.Settings(settings)
|
||||
tt.CustomFunc(template.FuncMap{
|
||||
"type": func(t string) string {
|
||||
result, extraline := markdown.PrintFencedCodeBlock(t, "hcl")
|
||||
result, extraline := printFencedCodeBlock(t, "hcl")
|
||||
if !extraline {
|
||||
result += "\n"
|
||||
}
|
||||
@@ -146,7 +148,7 @@ func Print(module *tfconf.Module, settings *print.Settings) (string, error) {
|
||||
if v == "n/a" {
|
||||
return v
|
||||
}
|
||||
result, extraline := markdown.PrintFencedCodeBlock(v, "json")
|
||||
result, extraline := printFencedCodeBlock(v, "json")
|
||||
if !extraline {
|
||||
result += "\n"
|
||||
}
|
||||
@@ -156,10 +158,16 @@ func Print(module *tfconf.Module, settings *print.Settings) (string, error) {
|
||||
return settings.ShowRequired
|
||||
},
|
||||
})
|
||||
rendered, err := t.Render(module)
|
||||
return &Document{
|
||||
template: tt,
|
||||
}
|
||||
}
|
||||
|
||||
// Print prints a Terraform module as Markdown document.
|
||||
func (d *Document) Print(module *tfconf.Module, settings *print.Settings) (string, error) {
|
||||
rendered, err := d.template.Render(module)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return markdown.Sanitize(rendered), nil
|
||||
return sanitize(rendered), nil
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
package document
|
||||
package format
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/segmentio/terraform-docs/internal/pkg/print"
|
||||
"github.com/segmentio/terraform-docs/internal/pkg/testutil"
|
||||
"github.com/segmentio/terraform-docs/internal/pkg/tfconf"
|
||||
"github.com/segmentio/terraform-docs/internal/module"
|
||||
"github.com/segmentio/terraform-docs/internal/testutil"
|
||||
"github.com/segmentio/terraform-docs/pkg/print"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
@@ -13,13 +13,15 @@ func TestDocument(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
settings := testutil.Settings().WithSections().Build()
|
||||
|
||||
expected, err := testutil.GetExpected("document")
|
||||
expected, err := testutil.GetExpected("document", "document")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions()
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewDocument(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -31,13 +33,15 @@ func TestDocumentWithRequired(t *testing.T) {
|
||||
ShowRequired: true,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("document-WithRequired")
|
||||
expected, err := testutil.GetExpected("document", "document-WithRequired")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions()
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewDocument(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -49,13 +53,19 @@ func TestDocumentSortByName(t *testing.T) {
|
||||
SortByName: true,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("document-SortByName")
|
||||
expected, err := testutil.GetExpected("document", "document-SortByName")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions().With(&module.Options{
|
||||
SortBy: &module.SortBy{
|
||||
Name: true,
|
||||
},
|
||||
})
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewDocument(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -68,13 +78,20 @@ func TestDocumentSortByRequired(t *testing.T) {
|
||||
SortByRequired: true,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("document-SortByRequired")
|
||||
expected, err := testutil.GetExpected("document", "document-SortByRequired")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions().With(&module.Options{
|
||||
SortBy: &module.SortBy{
|
||||
Name: true,
|
||||
Required: true,
|
||||
},
|
||||
})
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewDocument(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -89,13 +106,15 @@ func TestDocumentNoHeader(t *testing.T) {
|
||||
ShowOutputs: true,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("document-NoHeader")
|
||||
expected, err := testutil.GetExpected("document", "document-NoHeader")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions()
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewDocument(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -110,13 +129,15 @@ func TestDocumentNoProviders(t *testing.T) {
|
||||
ShowOutputs: true,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("document-NoProviders")
|
||||
expected, err := testutil.GetExpected("document", "document-NoProviders")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions()
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewDocument(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -131,13 +152,15 @@ func TestDocumentNoInputs(t *testing.T) {
|
||||
ShowOutputs: true,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("document-NoInputs")
|
||||
expected, err := testutil.GetExpected("document", "document-NoInputs")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions()
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewDocument(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -152,13 +175,15 @@ func TestDocumentNoOutputs(t *testing.T) {
|
||||
ShowOutputs: false,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("document-NoOutputs")
|
||||
expected, err := testutil.GetExpected("document", "document-NoOutputs")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions()
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewDocument(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -173,13 +198,15 @@ func TestDocumentOnlyHeader(t *testing.T) {
|
||||
ShowOutputs: false,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("document-OnlyHeader")
|
||||
expected, err := testutil.GetExpected("document", "document-OnlyHeader")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions()
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewDocument(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -194,13 +221,15 @@ func TestDocumentOnlyProviders(t *testing.T) {
|
||||
ShowOutputs: false,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("document-OnlyProviders")
|
||||
expected, err := testutil.GetExpected("document", "document-OnlyProviders")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions()
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewDocument(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -215,13 +244,15 @@ func TestDocumentOnlyInputs(t *testing.T) {
|
||||
ShowOutputs: false,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("document-OnlyInputs")
|
||||
expected, err := testutil.GetExpected("document", "document-OnlyInputs")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions()
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewDocument(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -236,13 +267,15 @@ func TestDocumentOnlyOutputs(t *testing.T) {
|
||||
ShowOutputs: true,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("document-OnlyOutputs")
|
||||
expected, err := testutil.GetExpected("document", "document-OnlyOutputs")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions()
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewDocument(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -254,13 +287,15 @@ func TestDocumentEscapeCharacters(t *testing.T) {
|
||||
EscapeCharacters: true,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("document-EscapeCharacters")
|
||||
expected, err := testutil.GetExpected("document", "document-EscapeCharacters")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions()
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewDocument(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -272,13 +307,15 @@ func TestDocumentIndentationBelowAllowed(t *testing.T) {
|
||||
MarkdownIndent: 0,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("document-IndentationBelowAllowed")
|
||||
expected, err := testutil.GetExpected("document", "document-IndentationBelowAllowed")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions()
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewDocument(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -290,13 +327,15 @@ func TestDocumentIndentationAboveAllowed(t *testing.T) {
|
||||
MarkdownIndent: 10,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("document-IndentationAboveAllowed")
|
||||
expected, err := testutil.GetExpected("document", "document-IndentationAboveAllowed")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions()
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewDocument(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -308,13 +347,15 @@ func TestDocumentIndentationOfFour(t *testing.T) {
|
||||
MarkdownIndent: 4,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("document-IndentationOfFour")
|
||||
expected, err := testutil.GetExpected("document", "document-IndentationOfFour")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions()
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewDocument(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -326,17 +367,18 @@ func TestDocumentOutputValues(t *testing.T) {
|
||||
OutputValues: true,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("document-OutputValues")
|
||||
expected, err := testutil.GetExpected("document", "document-OutputValues")
|
||||
assert.Nil(err)
|
||||
|
||||
options := &tfconf.Options{
|
||||
options := module.NewOptions().With(&module.Options{
|
||||
OutputValues: true,
|
||||
OutputValuesPath: "output_values.json",
|
||||
}
|
||||
})
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewDocument(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -1,18 +1,24 @@
|
||||
package json
|
||||
package format
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"strings"
|
||||
|
||||
"github.com/segmentio/terraform-docs/internal/pkg/print"
|
||||
"github.com/segmentio/terraform-docs/internal/pkg/tfconf"
|
||||
"github.com/segmentio/terraform-docs/pkg/print"
|
||||
"github.com/segmentio/terraform-docs/pkg/tfconf"
|
||||
)
|
||||
|
||||
// Print prints a document as json.
|
||||
func Print(module *tfconf.Module, settings *print.Settings) (string, error) {
|
||||
module.Sort(settings)
|
||||
// JSON represents JSON format.
|
||||
type JSON struct{}
|
||||
|
||||
// NewJSON returns new instance of JSON.
|
||||
func NewJSON(settings *print.Settings) *JSON {
|
||||
return &JSON{}
|
||||
}
|
||||
|
||||
// Print prints a Terraform module as json.
|
||||
func (j *JSON) Print(module *tfconf.Module, settings *print.Settings) (string, error) {
|
||||
copy := &tfconf.Module{
|
||||
Header: "",
|
||||
Providers: make([]*tfconf.Provider, 0),
|
||||
@@ -1,11 +1,11 @@
|
||||
package json
|
||||
package format
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/segmentio/terraform-docs/internal/pkg/print"
|
||||
"github.com/segmentio/terraform-docs/internal/pkg/testutil"
|
||||
"github.com/segmentio/terraform-docs/internal/pkg/tfconf"
|
||||
"github.com/segmentio/terraform-docs/internal/module"
|
||||
"github.com/segmentio/terraform-docs/internal/testutil"
|
||||
"github.com/segmentio/terraform-docs/pkg/print"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
@@ -13,13 +13,15 @@ func TestJson(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
settings := testutil.Settings().WithSections().Build()
|
||||
|
||||
expected, err := testutil.GetExpected("json")
|
||||
expected, err := testutil.GetExpected("json", "json")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions()
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewJSON(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -31,13 +33,19 @@ func TestJsonSortByName(t *testing.T) {
|
||||
SortByName: true,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("json-SortByName")
|
||||
expected, err := testutil.GetExpected("json", "json-SortByName")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions().With(&module.Options{
|
||||
SortBy: &module.SortBy{
|
||||
Name: true,
|
||||
},
|
||||
})
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewJSON(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -50,13 +58,20 @@ func TestJsonSortByRequired(t *testing.T) {
|
||||
SortByRequired: true,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("json-SortByRequired")
|
||||
expected, err := testutil.GetExpected("json", "json-SortByRequired")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions().With(&module.Options{
|
||||
SortBy: &module.SortBy{
|
||||
Name: true,
|
||||
Required: true,
|
||||
},
|
||||
})
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewJSON(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -71,13 +86,15 @@ func TestJsonNoHeader(t *testing.T) {
|
||||
ShowOutputs: true,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("json-NoHeader")
|
||||
expected, err := testutil.GetExpected("json", "json-NoHeader")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions()
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewJSON(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -92,13 +109,15 @@ func TestJsonNoProviders(t *testing.T) {
|
||||
ShowOutputs: true,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("json-NoProviders")
|
||||
expected, err := testutil.GetExpected("json", "json-NoProviders")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions()
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewJSON(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -113,13 +132,15 @@ func TestJsonNoInputs(t *testing.T) {
|
||||
ShowOutputs: true,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("json-NoInputs")
|
||||
expected, err := testutil.GetExpected("json", "json-NoInputs")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions()
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewJSON(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -134,13 +155,15 @@ func TestJsonNoOutputs(t *testing.T) {
|
||||
ShowOutputs: false,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("json-NoOutputs")
|
||||
expected, err := testutil.GetExpected("json", "json-NoOutputs")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions()
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewJSON(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -155,13 +178,15 @@ func TestJsonOnlyHeader(t *testing.T) {
|
||||
ShowOutputs: false,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("json-OnlyHeader")
|
||||
expected, err := testutil.GetExpected("json", "json-OnlyHeader")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions()
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewJSON(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -176,13 +201,15 @@ func TestJsonOnlyProviders(t *testing.T) {
|
||||
ShowOutputs: false,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("json-OnlyProviders")
|
||||
expected, err := testutil.GetExpected("json", "json-OnlyProviders")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions()
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewJSON(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -197,13 +224,15 @@ func TestJsonOnlyInputs(t *testing.T) {
|
||||
ShowOutputs: false,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("json-OnlyInputs")
|
||||
expected, err := testutil.GetExpected("json", "json-OnlyInputs")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions()
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewJSON(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -218,13 +247,15 @@ func TestJsonOnlyOutputs(t *testing.T) {
|
||||
ShowOutputs: true,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("json-OnlyOutputs")
|
||||
expected, err := testutil.GetExpected("json", "json-OnlyOutputs")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions()
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewJSON(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -236,13 +267,15 @@ func TestJsonEscapeCharacters(t *testing.T) {
|
||||
EscapeCharacters: true,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("json-EscapeCharacters")
|
||||
expected, err := testutil.GetExpected("json", "json-EscapeCharacters")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions()
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewJSON(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -253,17 +286,18 @@ func TestJsonOutputValues(t *testing.T) {
|
||||
OutputValues: true,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("json-OutputValues")
|
||||
expected, err := testutil.GetExpected("json", "json-OutputValues")
|
||||
assert.Nil(err)
|
||||
|
||||
options := &tfconf.Options{
|
||||
options := module.NewOptions().With(&module.Options{
|
||||
OutputValues: true,
|
||||
OutputValuesPath: "output_values.json",
|
||||
}
|
||||
})
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewJSON(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -1,16 +1,16 @@
|
||||
package pretty
|
||||
package format
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"text/template"
|
||||
|
||||
"github.com/segmentio/terraform-docs/internal/pkg/print"
|
||||
"github.com/segmentio/terraform-docs/internal/pkg/tfconf"
|
||||
"github.com/segmentio/terraform-docs/internal/pkg/tmpl"
|
||||
"github.com/segmentio/terraform-docs/pkg/print"
|
||||
"github.com/segmentio/terraform-docs/pkg/tfconf"
|
||||
"github.com/segmentio/terraform-docs/pkg/tmpl"
|
||||
)
|
||||
|
||||
const (
|
||||
headerTpl = `
|
||||
prettyHeaderTpl = `
|
||||
{{- if .Settings.ShowHeader -}}
|
||||
{{- with .Module.Header }}
|
||||
{{- printf "\n" }}
|
||||
@@ -20,7 +20,7 @@ const (
|
||||
{{ end -}}
|
||||
`
|
||||
|
||||
providersTpl = `
|
||||
prettyProvidersTpl = `
|
||||
{{- if .Settings.ShowProviders -}}
|
||||
{{- with .Module.Providers }}
|
||||
{{- printf "\n" -}}
|
||||
@@ -33,7 +33,7 @@ const (
|
||||
{{ end -}}
|
||||
`
|
||||
|
||||
inputsTpl = `
|
||||
prettyInputsTpl = `
|
||||
{{- if .Settings.ShowInputs -}}
|
||||
{{- with .Module.Inputs }}
|
||||
{{- printf "\n" -}}
|
||||
@@ -46,7 +46,7 @@ const (
|
||||
{{ end -}}
|
||||
`
|
||||
|
||||
outputsTpl = `
|
||||
prettyOutputsTpl = `
|
||||
{{- if .Settings.ShowOutputs -}}
|
||||
{{- with .Module.Outputs }}
|
||||
{{- printf "\n" -}}
|
||||
@@ -70,28 +70,31 @@ const (
|
||||
`
|
||||
)
|
||||
|
||||
// Print prints a pretty document.
|
||||
func Print(module *tfconf.Module, settings *print.Settings) (string, error) {
|
||||
module.Sort(settings)
|
||||
// Pretty represents colorized pretty format.
|
||||
type Pretty struct {
|
||||
template *tmpl.Template
|
||||
}
|
||||
|
||||
t := tmpl.NewTemplate(&tmpl.Item{
|
||||
// NewPretty returns new instance of Pretty.
|
||||
func NewPretty(settings *print.Settings) *Pretty {
|
||||
tt := tmpl.NewTemplate(&tmpl.Item{
|
||||
Name: "pretty",
|
||||
Text: prettyTpl,
|
||||
}, &tmpl.Item{
|
||||
Name: "header",
|
||||
Text: headerTpl,
|
||||
Text: prettyHeaderTpl,
|
||||
}, &tmpl.Item{
|
||||
Name: "providers",
|
||||
Text: providersTpl,
|
||||
Text: prettyProvidersTpl,
|
||||
}, &tmpl.Item{
|
||||
Name: "inputs",
|
||||
Text: inputsTpl,
|
||||
Text: prettyInputsTpl,
|
||||
}, &tmpl.Item{
|
||||
Name: "outputs",
|
||||
Text: outputsTpl,
|
||||
Text: prettyOutputsTpl,
|
||||
})
|
||||
t.Settings(settings)
|
||||
t.CustomFunc(template.FuncMap{
|
||||
tt.Settings(settings)
|
||||
tt.CustomFunc(template.FuncMap{
|
||||
"colorize": func(c string, s string) string {
|
||||
r := "\033[0m"
|
||||
if !settings.ShowColor {
|
||||
@@ -101,10 +104,16 @@ func Print(module *tfconf.Module, settings *print.Settings) (string, error) {
|
||||
return fmt.Sprintf("%s%s%s", c, s, r)
|
||||
},
|
||||
})
|
||||
rendered, err := t.Render(module)
|
||||
return &Pretty{
|
||||
template: tt,
|
||||
}
|
||||
}
|
||||
|
||||
// Print prints a Terraform module document.
|
||||
func (p *Pretty) Print(module *tfconf.Module, settings *print.Settings) (string, error) {
|
||||
rendered, err := p.template.Render(module)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return rendered, nil
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
package pretty
|
||||
package format
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/segmentio/terraform-docs/internal/pkg/print"
|
||||
"github.com/segmentio/terraform-docs/internal/pkg/testutil"
|
||||
"github.com/segmentio/terraform-docs/internal/pkg/tfconf"
|
||||
"github.com/segmentio/terraform-docs/internal/module"
|
||||
"github.com/segmentio/terraform-docs/internal/testutil"
|
||||
"github.com/segmentio/terraform-docs/pkg/print"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
@@ -13,13 +13,15 @@ func TestPretty(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
settings := testutil.Settings().WithSections().WithColor().Build()
|
||||
|
||||
expected, err := testutil.GetExpected("pretty")
|
||||
expected, err := testutil.GetExpected("pretty", "pretty")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions()
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewPretty(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -31,13 +33,19 @@ func TestPrettySortByName(t *testing.T) {
|
||||
SortByName: true,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("pretty-SortByName")
|
||||
expected, err := testutil.GetExpected("pretty", "pretty-SortByName")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions().With(&module.Options{
|
||||
SortBy: &module.SortBy{
|
||||
Name: true,
|
||||
},
|
||||
})
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewPretty(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -50,13 +58,20 @@ func TestPrettySortByRequired(t *testing.T) {
|
||||
SortByRequired: true,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("pretty-SortByRequired")
|
||||
expected, err := testutil.GetExpected("pretty", "pretty-SortByRequired")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions().With(&module.Options{
|
||||
SortBy: &module.SortBy{
|
||||
Name: true,
|
||||
Required: true,
|
||||
},
|
||||
})
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewPretty(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -71,13 +86,15 @@ func TestPrettyNoHeader(t *testing.T) {
|
||||
ShowOutputs: true,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("pretty-NoHeader")
|
||||
expected, err := testutil.GetExpected("pretty", "pretty-NoHeader")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions()
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewPretty(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -92,13 +109,15 @@ func TestPrettyNoProviders(t *testing.T) {
|
||||
ShowOutputs: true,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("pretty-NoProviders")
|
||||
expected, err := testutil.GetExpected("pretty", "pretty-NoProviders")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions()
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewPretty(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -113,13 +132,15 @@ func TestPrettyNoInputs(t *testing.T) {
|
||||
ShowOutputs: true,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("pretty-NoInputs")
|
||||
expected, err := testutil.GetExpected("pretty", "pretty-NoInputs")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions()
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewPretty(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -134,13 +155,15 @@ func TestPrettyNoOutputs(t *testing.T) {
|
||||
ShowOutputs: false,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("pretty-NoOutputs")
|
||||
expected, err := testutil.GetExpected("pretty", "pretty-NoOutputs")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions()
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewPretty(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -155,13 +178,15 @@ func TestPrettyOnlyHeader(t *testing.T) {
|
||||
ShowOutputs: false,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("pretty-OnlyHeader")
|
||||
expected, err := testutil.GetExpected("pretty", "pretty-OnlyHeader")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions()
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewPretty(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -176,13 +201,15 @@ func TestPrettyOnlyProviders(t *testing.T) {
|
||||
ShowOutputs: false,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("pretty-OnlyProviders")
|
||||
expected, err := testutil.GetExpected("pretty", "pretty-OnlyProviders")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions()
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewPretty(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -197,13 +224,15 @@ func TestPrettyOnlyInputs(t *testing.T) {
|
||||
ShowOutputs: false,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("pretty-OnlyInputs")
|
||||
expected, err := testutil.GetExpected("pretty", "pretty-OnlyInputs")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions()
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewPretty(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -218,13 +247,15 @@ func TestPrettyOnlyOutputs(t *testing.T) {
|
||||
ShowOutputs: true,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("pretty-OnlyOutputs")
|
||||
expected, err := testutil.GetExpected("pretty", "pretty-OnlyOutputs")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions()
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewPretty(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -236,13 +267,15 @@ func TestPrettyNoColor(t *testing.T) {
|
||||
ShowColor: false,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("pretty-NoColor")
|
||||
expected, err := testutil.GetExpected("pretty", "pretty-NoColor")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions()
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewPretty(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -254,17 +287,18 @@ func TestPrettyOutputValues(t *testing.T) {
|
||||
OutputValues: true,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("pretty-OutputValues")
|
||||
expected, err := testutil.GetExpected("pretty", "pretty-OutputValues")
|
||||
assert.Nil(err)
|
||||
|
||||
options := &tfconf.Options{
|
||||
options := module.NewOptions().With(&module.Options{
|
||||
OutputValues: true,
|
||||
OutputValuesPath: "output_values.json",
|
||||
}
|
||||
})
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewPretty(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -1,16 +1,15 @@
|
||||
package table
|
||||
package format
|
||||
|
||||
import (
|
||||
"text/template"
|
||||
|
||||
"github.com/segmentio/terraform-docs/internal/pkg/print"
|
||||
"github.com/segmentio/terraform-docs/internal/pkg/print/markdown"
|
||||
"github.com/segmentio/terraform-docs/internal/pkg/tfconf"
|
||||
"github.com/segmentio/terraform-docs/internal/pkg/tmpl"
|
||||
"github.com/segmentio/terraform-docs/pkg/print"
|
||||
"github.com/segmentio/terraform-docs/pkg/tfconf"
|
||||
"github.com/segmentio/terraform-docs/pkg/tmpl"
|
||||
)
|
||||
|
||||
const (
|
||||
headerTpl = `
|
||||
tableHeaderTpl = `
|
||||
{{- if .Settings.ShowHeader -}}
|
||||
{{- with .Module.Header -}}
|
||||
{{ sanitizeHeader . }}
|
||||
@@ -19,7 +18,7 @@ const (
|
||||
{{ end -}}
|
||||
`
|
||||
|
||||
providersTpl = `
|
||||
tableProvidersTpl = `
|
||||
{{- if .Settings.ShowProviders -}}
|
||||
{{ indent 0 }} Providers
|
||||
{{ if not .Module.Providers }}
|
||||
@@ -34,7 +33,7 @@ const (
|
||||
{{ end -}}
|
||||
`
|
||||
|
||||
inputsTpl = `
|
||||
tableInputsTpl = `
|
||||
{{- if .Settings.ShowInputs -}}
|
||||
{{ indent 0 }} Inputs
|
||||
{{ if not .Module.Inputs }}
|
||||
@@ -58,7 +57,7 @@ const (
|
||||
{{ end -}}
|
||||
`
|
||||
|
||||
outputsTpl = `
|
||||
tableOutputsTpl = `
|
||||
{{- if .Settings.ShowOutputs -}}
|
||||
{{ indent 0 }} Outputs
|
||||
{{ if not .Module.Outputs }}
|
||||
@@ -81,44 +80,53 @@ const (
|
||||
`
|
||||
)
|
||||
|
||||
// Print prints a document as Markdown tables.
|
||||
func Print(module *tfconf.Module, settings *print.Settings) (string, error) {
|
||||
module.Sort(settings)
|
||||
// Table represents Markdown Table format.
|
||||
type Table struct {
|
||||
template *tmpl.Template
|
||||
}
|
||||
|
||||
t := tmpl.NewTemplate(&tmpl.Item{
|
||||
// NewTable returns new instance of Table.
|
||||
func NewTable(settings *print.Settings) *Table {
|
||||
tt := tmpl.NewTemplate(&tmpl.Item{
|
||||
Name: "table",
|
||||
Text: tableTpl,
|
||||
}, &tmpl.Item{
|
||||
Name: "header",
|
||||
Text: headerTpl,
|
||||
Text: tableHeaderTpl,
|
||||
}, &tmpl.Item{
|
||||
Name: "providers",
|
||||
Text: providersTpl,
|
||||
Text: tableProvidersTpl,
|
||||
}, &tmpl.Item{
|
||||
Name: "inputs",
|
||||
Text: inputsTpl,
|
||||
Text: tableInputsTpl,
|
||||
}, &tmpl.Item{
|
||||
Name: "outputs",
|
||||
Text: outputsTpl,
|
||||
Text: tableOutputsTpl,
|
||||
})
|
||||
t.Settings(settings)
|
||||
t.CustomFunc(template.FuncMap{
|
||||
tt.Settings(settings)
|
||||
tt.CustomFunc(template.FuncMap{
|
||||
"type": func(t string) string {
|
||||
inputType, _ := markdown.PrintFencedCodeBlock(t, "")
|
||||
inputType, _ := printFencedCodeBlock(t, "")
|
||||
return inputType
|
||||
},
|
||||
"value": func(v string) string {
|
||||
var result = "n/a"
|
||||
if v != "" {
|
||||
result, _ = markdown.PrintFencedCodeBlock(v, "")
|
||||
result, _ = printFencedCodeBlock(v, "")
|
||||
}
|
||||
return result
|
||||
},
|
||||
})
|
||||
rendered, err := t.Render(module)
|
||||
return &Table{
|
||||
template: tt,
|
||||
}
|
||||
}
|
||||
|
||||
// Print prints a Terraform module as Markdown tables.
|
||||
func (t *Table) Print(module *tfconf.Module, settings *print.Settings) (string, error) {
|
||||
rendered, err := t.template.Render(module)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return markdown.Sanitize(rendered), nil
|
||||
return sanitize(rendered), nil
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
package table
|
||||
package format
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/segmentio/terraform-docs/internal/pkg/print"
|
||||
"github.com/segmentio/terraform-docs/internal/pkg/testutil"
|
||||
"github.com/segmentio/terraform-docs/internal/pkg/tfconf"
|
||||
"github.com/segmentio/terraform-docs/internal/module"
|
||||
"github.com/segmentio/terraform-docs/internal/testutil"
|
||||
"github.com/segmentio/terraform-docs/pkg/print"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
@@ -13,13 +13,15 @@ func TestTable(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
settings := testutil.Settings().WithSections().Build()
|
||||
|
||||
expected, err := testutil.GetExpected("table")
|
||||
expected, err := testutil.GetExpected("table", "table")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions()
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewTable(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -31,13 +33,15 @@ func TestTableWithRequired(t *testing.T) {
|
||||
ShowRequired: true,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("table-WithRequired")
|
||||
expected, err := testutil.GetExpected("table", "table-WithRequired")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions()
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewTable(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -49,13 +53,19 @@ func TestTableSortByName(t *testing.T) {
|
||||
SortByName: true,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("table-SortByName")
|
||||
expected, err := testutil.GetExpected("table", "table-SortByName")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions().With(&module.Options{
|
||||
SortBy: &module.SortBy{
|
||||
Name: true,
|
||||
},
|
||||
})
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewTable(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -68,13 +78,20 @@ func TestTableSortByRequired(t *testing.T) {
|
||||
SortByRequired: true,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("table-SortByRequired")
|
||||
expected, err := testutil.GetExpected("table", "table-SortByRequired")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions().With(&module.Options{
|
||||
SortBy: &module.SortBy{
|
||||
Name: true,
|
||||
Required: true,
|
||||
},
|
||||
})
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewTable(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -89,13 +106,15 @@ func TestTableNoHeader(t *testing.T) {
|
||||
ShowOutputs: true,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("table-NoHeader")
|
||||
expected, err := testutil.GetExpected("table", "table-NoHeader")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions()
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewTable(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -110,13 +129,15 @@ func TestTableNoProviders(t *testing.T) {
|
||||
ShowOutputs: true,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("table-NoProviders")
|
||||
expected, err := testutil.GetExpected("table", "table-NoProviders")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions()
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewTable(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -131,13 +152,15 @@ func TestTableNoInputs(t *testing.T) {
|
||||
ShowOutputs: true,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("table-NoInputs")
|
||||
expected, err := testutil.GetExpected("table", "table-NoInputs")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions()
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewTable(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -152,13 +175,15 @@ func TestTableNoOutputs(t *testing.T) {
|
||||
ShowOutputs: false,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("table-NoOutputs")
|
||||
expected, err := testutil.GetExpected("table", "table-NoOutputs")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions()
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewTable(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -173,13 +198,15 @@ func TestTableOnlyHeader(t *testing.T) {
|
||||
ShowOutputs: false,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("table-OnlyHeader")
|
||||
expected, err := testutil.GetExpected("table", "table-OnlyHeader")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions()
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewTable(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -194,13 +221,15 @@ func TestTableOnlyProviders(t *testing.T) {
|
||||
ShowOutputs: false,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("table-OnlyProviders")
|
||||
expected, err := testutil.GetExpected("table", "table-OnlyProviders")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions()
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewTable(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -215,13 +244,15 @@ func TestTableOnlyInputs(t *testing.T) {
|
||||
ShowOutputs: false,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("table-OnlyInputs")
|
||||
expected, err := testutil.GetExpected("table", "table-OnlyInputs")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions()
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewTable(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -236,13 +267,15 @@ func TestTableOnlyOutputs(t *testing.T) {
|
||||
ShowOutputs: true,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("table-OnlyOutputs")
|
||||
expected, err := testutil.GetExpected("table", "table-OnlyOutputs")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions()
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewTable(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -254,31 +287,35 @@ func TestTableEscapeCharacters(t *testing.T) {
|
||||
EscapeCharacters: true,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("table-EscapeCharacters")
|
||||
expected, err := testutil.GetExpected("table", "table-EscapeCharacters")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions()
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewTable(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
}
|
||||
|
||||
func TestTableIndentationBellowAllowed(t *testing.T) {
|
||||
func TestTableIndentationBelowAllowed(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
settings := testutil.Settings().WithSections().With(&print.Settings{
|
||||
MarkdownIndent: 0,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("table-IndentationBellowAllowed")
|
||||
expected, err := testutil.GetExpected("table", "table-IndentationBelowAllowed")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions()
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewTable(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -290,13 +327,15 @@ func TestTableIndentationAboveAllowed(t *testing.T) {
|
||||
MarkdownIndent: 10,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("table-IndentationAboveAllowed")
|
||||
expected, err := testutil.GetExpected("table", "table-IndentationAboveAllowed")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions()
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewTable(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -308,13 +347,15 @@ func TestTableIndentationOfFour(t *testing.T) {
|
||||
MarkdownIndent: 4,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("table-IndentationOfFour")
|
||||
expected, err := testutil.GetExpected("table", "table-IndentationOfFour")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions()
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewTable(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -326,17 +367,18 @@ func TestTableOutputValues(t *testing.T) {
|
||||
OutputValues: true,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("table-OutputValues")
|
||||
expected, err := testutil.GetExpected("table", "table-OutputValues")
|
||||
assert.Nil(err)
|
||||
|
||||
options := &tfconf.Options{
|
||||
options := module.NewOptions().With(&module.Options{
|
||||
OutputValues: true,
|
||||
OutputValuesPath: "output_values.json",
|
||||
}
|
||||
})
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewTable(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
43
internal/format/util.go
Normal file
43
internal/format/util.go
Normal file
@@ -0,0 +1,43 @@
|
||||
package format
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// sanitize cleans a Markdown document to soothe linters.
|
||||
func sanitize(markdown string) string {
|
||||
result := markdown
|
||||
|
||||
// Preserve double spaces at the end of the line
|
||||
result = regexp.MustCompile(` {2}(\r?\n)`).ReplaceAllString(result, "‡‡$1")
|
||||
|
||||
// Remove trailing spaces from the end of lines
|
||||
result = regexp.MustCompile(` +(\r?\n)`).ReplaceAllString(result, "$1")
|
||||
result = regexp.MustCompile(` +$`).ReplaceAllLiteralString(result, "")
|
||||
|
||||
// Preserve double spaces at the end of the line
|
||||
result = regexp.MustCompile(`‡‡(\r?\n)`).ReplaceAllString(result, " $1")
|
||||
|
||||
// Remove blank line with only double spaces in it
|
||||
result = regexp.MustCompile(`(\r?\n) (\r?\n)`).ReplaceAllString(result, "$1")
|
||||
|
||||
// Remove multiple consecutive blank lines
|
||||
result = regexp.MustCompile(`(\r?\n){3,}`).ReplaceAllString(result, "$1$1")
|
||||
result = regexp.MustCompile(`(\r?\n){2,}$`).ReplaceAllString(result, "$1")
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// printFencedCodeBlock prints codes in fences, it automatically detects if
|
||||
// the input 'code' contains '\n' it will use multi line fence, otherwise it
|
||||
// wraps the 'code' inside single-tick block.
|
||||
// If the fenced is multi-line it also appens an extra '\n` at the end and
|
||||
// returns true accordingly, otherwise returns false for non-carriage return.
|
||||
func printFencedCodeBlock(code string, language string) (string, bool) {
|
||||
if strings.Contains(code, "\n") {
|
||||
return fmt.Sprintf("\n\n```%s\n%s\n```\n", language, code), true
|
||||
}
|
||||
return fmt.Sprintf("`%s`", code), false
|
||||
}
|
||||
@@ -1,17 +1,23 @@
|
||||
package yaml
|
||||
package format
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/segmentio/terraform-docs/internal/pkg/print"
|
||||
"github.com/segmentio/terraform-docs/internal/pkg/tfconf"
|
||||
"github.com/segmentio/terraform-docs/pkg/print"
|
||||
"github.com/segmentio/terraform-docs/pkg/tfconf"
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
// Print prints a document as yaml.
|
||||
func Print(module *tfconf.Module, settings *print.Settings) (string, error) {
|
||||
module.Sort(settings)
|
||||
// YAML represents YAML format.
|
||||
type YAML struct{}
|
||||
|
||||
// NewYAML returns new instance of YAML.
|
||||
func NewYAML(settings *print.Settings) *YAML {
|
||||
return &YAML{}
|
||||
}
|
||||
|
||||
// Print prints a Terraform module as yaml.
|
||||
func (y *YAML) Print(module *tfconf.Module, settings *print.Settings) (string, error) {
|
||||
copy := &tfconf.Module{
|
||||
Header: "",
|
||||
Providers: make([]*tfconf.Provider, 0),
|
||||
@@ -1,11 +1,11 @@
|
||||
package yaml
|
||||
package format
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/segmentio/terraform-docs/internal/pkg/print"
|
||||
"github.com/segmentio/terraform-docs/internal/pkg/testutil"
|
||||
"github.com/segmentio/terraform-docs/internal/pkg/tfconf"
|
||||
"github.com/segmentio/terraform-docs/internal/module"
|
||||
"github.com/segmentio/terraform-docs/internal/testutil"
|
||||
"github.com/segmentio/terraform-docs/pkg/print"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
@@ -13,13 +13,15 @@ func TestYaml(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
settings := testutil.Settings().WithSections().Build()
|
||||
|
||||
expected, err := testutil.GetExpected("yaml")
|
||||
expected, err := testutil.GetExpected("yaml", "yaml")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions()
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewYAML(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -31,13 +33,19 @@ func TestYamlSortByName(t *testing.T) {
|
||||
SortByName: true,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("yaml-SortByName")
|
||||
expected, err := testutil.GetExpected("yaml", "yaml-SortByName")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions().With(&module.Options{
|
||||
SortBy: &module.SortBy{
|
||||
Name: true,
|
||||
},
|
||||
})
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewYAML(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -50,13 +58,20 @@ func TestYamlSortByRequired(t *testing.T) {
|
||||
SortByRequired: true,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("yaml-SortByRequired")
|
||||
expected, err := testutil.GetExpected("yaml", "yaml-SortByRequired")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions().With(&module.Options{
|
||||
SortBy: &module.SortBy{
|
||||
Name: true,
|
||||
Required: true,
|
||||
},
|
||||
})
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewYAML(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -71,13 +86,15 @@ func TestYamlNoHeader(t *testing.T) {
|
||||
ShowOutputs: true,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("yaml-NoHeader")
|
||||
expected, err := testutil.GetExpected("yaml", "yaml-NoHeader")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions()
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewYAML(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -92,13 +109,15 @@ func TestYamlNoProviders(t *testing.T) {
|
||||
ShowOutputs: true,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("yaml-NoProviders")
|
||||
expected, err := testutil.GetExpected("yaml", "yaml-NoProviders")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions()
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewYAML(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -113,13 +132,15 @@ func TestYamlNoInputs(t *testing.T) {
|
||||
ShowOutputs: true,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("yaml-NoInputs")
|
||||
expected, err := testutil.GetExpected("yaml", "yaml-NoInputs")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions()
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewYAML(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -134,13 +155,15 @@ func TestYamlNoOutputs(t *testing.T) {
|
||||
ShowOutputs: false,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("yaml-NoOutputs")
|
||||
expected, err := testutil.GetExpected("yaml", "yaml-NoOutputs")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions()
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewYAML(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -155,13 +178,15 @@ func TestYamlOnlyHeader(t *testing.T) {
|
||||
ShowOutputs: false,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("yaml-OnlyHeader")
|
||||
expected, err := testutil.GetExpected("yaml", "yaml-OnlyHeader")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions()
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewYAML(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -176,13 +201,15 @@ func TestYamlOnlyProviders(t *testing.T) {
|
||||
ShowOutputs: false,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("yaml-OnlyProviders")
|
||||
expected, err := testutil.GetExpected("yaml", "yaml-OnlyProviders")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions()
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewYAML(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -197,13 +224,15 @@ func TestYamlOnlyInputs(t *testing.T) {
|
||||
ShowOutputs: false,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("yaml-OnlyInputs")
|
||||
expected, err := testutil.GetExpected("yaml", "yaml-OnlyInputs")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions()
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewYAML(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -218,13 +247,15 @@ func TestYamlOnlyOutputs(t *testing.T) {
|
||||
ShowOutputs: true,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("yaml-OnlyOutputs")
|
||||
expected, err := testutil.GetExpected("yaml", "yaml-OnlyOutputs")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
options := module.NewOptions()
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewYAML(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
@@ -236,17 +267,18 @@ func TestYamlOutputValues(t *testing.T) {
|
||||
OutputValues: true,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("yaml-OutputValues")
|
||||
expected, err := testutil.GetExpected("yaml", "yaml-OutputValues")
|
||||
assert.Nil(err)
|
||||
|
||||
options := &tfconf.Options{
|
||||
options := module.NewOptions().With(&module.Options{
|
||||
OutputValues: true,
|
||||
OutputValuesPath: "output_values.json",
|
||||
}
|
||||
})
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
printer := NewYAML(settings)
|
||||
actual, err := printer.Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
39
internal/module/input.go
Normal file
39
internal/module/input.go
Normal file
@@ -0,0 +1,39 @@
|
||||
package module
|
||||
|
||||
import (
|
||||
"github.com/segmentio/terraform-docs/pkg/tfconf"
|
||||
)
|
||||
|
||||
type inputsSortedByName []*tfconf.Input
|
||||
|
||||
func (a inputsSortedByName) Len() int { return len(a) }
|
||||
func (a inputsSortedByName) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
||||
func (a inputsSortedByName) Less(i, j int) bool {
|
||||
return a[i].Name < a[j].Name
|
||||
}
|
||||
|
||||
type inputsSortedByRequired []*tfconf.Input
|
||||
|
||||
func (a inputsSortedByRequired) Len() int { return len(a) }
|
||||
func (a inputsSortedByRequired) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
||||
func (a inputsSortedByRequired) Less(i, j int) bool {
|
||||
switch {
|
||||
// i required, j not: i gets priority
|
||||
case !a[i].HasDefault() && a[j].HasDefault():
|
||||
return true
|
||||
// j required, i not: i does not get priority
|
||||
case a[i].HasDefault() && !a[j].HasDefault():
|
||||
return false
|
||||
// Otherwise, sort by name
|
||||
default:
|
||||
return a[i].Name < a[j].Name
|
||||
}
|
||||
}
|
||||
|
||||
type inputsSortedByPosition []*tfconf.Input
|
||||
|
||||
func (a inputsSortedByPosition) Len() int { return len(a) }
|
||||
func (a inputsSortedByPosition) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
||||
func (a inputsSortedByPosition) Less(i, j int) bool {
|
||||
return a[i].Position.Filename < a[j].Position.Filename || a[i].Position.Line < a[j].Position.Line
|
||||
}
|
||||
264
internal/module/module.go
Normal file
264
internal/module/module.go
Normal file
@@ -0,0 +1,264 @@
|
||||
package module
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/terraform-config-inspect/tfconfig"
|
||||
"github.com/segmentio/terraform-docs/internal/reader"
|
||||
"github.com/segmentio/terraform-docs/internal/types"
|
||||
"github.com/segmentio/terraform-docs/pkg/tfconf"
|
||||
)
|
||||
|
||||
// LoadWithOptions returns new instance of Module with all the inputs and
|
||||
// outputs discovered from provided 'path' containing Terraform config
|
||||
func LoadWithOptions(options *Options) (*tfconf.Module, error) {
|
||||
tfmodule := loadModule(options.Path)
|
||||
|
||||
header := loadHeader(options.Path)
|
||||
inputs, required, optional := loadInputs(tfmodule)
|
||||
outputs := loadOutputs(tfmodule, options)
|
||||
providers := loadProviders(tfmodule)
|
||||
|
||||
module := &tfconf.Module{
|
||||
Header: header,
|
||||
Inputs: inputs,
|
||||
Outputs: outputs,
|
||||
Providers: providers,
|
||||
|
||||
RequiredInputs: required,
|
||||
OptionalInputs: optional,
|
||||
}
|
||||
sortItems(module, options.SortBy)
|
||||
return module, nil
|
||||
}
|
||||
|
||||
func loadModule(path string) *tfconfig.Module {
|
||||
module, diag := tfconfig.LoadModule(path)
|
||||
if diag != nil && diag.HasErrors() {
|
||||
log.Fatal(diag)
|
||||
}
|
||||
return module
|
||||
}
|
||||
|
||||
func loadHeader(path string) string {
|
||||
filename := filepath.Join(path, "main.tf")
|
||||
_, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
return "" // absorb the error, we don't need to bubble it up or break the execution
|
||||
}
|
||||
lines := reader.Lines{
|
||||
FileName: filename,
|
||||
LineNum: -1,
|
||||
Condition: func(line string) bool {
|
||||
line = strings.TrimSpace(line)
|
||||
return strings.HasPrefix(line, "/*") || strings.HasPrefix(line, "*") || strings.HasPrefix(line, "*/")
|
||||
},
|
||||
Parser: func(line string) (string, bool) {
|
||||
line = strings.TrimSpace(line)
|
||||
if strings.HasPrefix(line, "/*") || strings.HasPrefix(line, "*/") {
|
||||
return "", false
|
||||
}
|
||||
if line == "*" {
|
||||
return "", true
|
||||
}
|
||||
line = strings.TrimPrefix(line, "* ")
|
||||
return line, true
|
||||
},
|
||||
}
|
||||
header, err := lines.Extract()
|
||||
if err != nil {
|
||||
return "" // absorb the error, we don't need to bubble it up or break the execution
|
||||
}
|
||||
return strings.Join(header, "\n")
|
||||
}
|
||||
|
||||
func loadInputs(tfmodule *tfconfig.Module) ([]*tfconf.Input, []*tfconf.Input, []*tfconf.Input) {
|
||||
var inputs = make([]*tfconf.Input, 0, len(tfmodule.Variables))
|
||||
var required = make([]*tfconf.Input, 0, len(tfmodule.Variables))
|
||||
var optional = make([]*tfconf.Input, 0, len(tfmodule.Variables))
|
||||
|
||||
for _, input := range tfmodule.Variables {
|
||||
inputType := input.Type
|
||||
if input.Type == "" {
|
||||
inputType = "any"
|
||||
if input.Default != nil {
|
||||
switch xType := fmt.Sprintf("%T", input.Default); xType {
|
||||
case "string":
|
||||
inputType = "string"
|
||||
case "int", "int8", "int16", "int32", "int64", "float32", "float64":
|
||||
inputType = "number"
|
||||
case "bool":
|
||||
inputType = "bool"
|
||||
case "[]interface {}":
|
||||
inputType = "list"
|
||||
case "map[string]interface {}":
|
||||
inputType = "map"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inputDescription := input.Description
|
||||
if inputDescription == "" {
|
||||
inputDescription = loadComments(input.Pos.Filename, input.Pos.Line-1)
|
||||
}
|
||||
|
||||
i := &tfconf.Input{
|
||||
Name: input.Name,
|
||||
Type: types.String(inputType),
|
||||
Description: types.String(inputDescription),
|
||||
Default: input.Default,
|
||||
Position: tfconf.Position{
|
||||
Filename: input.Pos.Filename,
|
||||
Line: input.Pos.Line,
|
||||
},
|
||||
}
|
||||
|
||||
inputs = append(inputs, i)
|
||||
if i.HasDefault() {
|
||||
optional = append(optional, i)
|
||||
} else {
|
||||
required = append(required, i)
|
||||
}
|
||||
}
|
||||
return inputs, required, optional
|
||||
}
|
||||
|
||||
func loadOutputs(tfmodule *tfconfig.Module, options *Options) []*tfconf.Output {
|
||||
outputs := make([]*tfconf.Output, 0, len(tfmodule.Outputs))
|
||||
for _, o := range tfmodule.Outputs {
|
||||
description := o.Description
|
||||
if description == "" {
|
||||
description = loadComments(o.Pos.Filename, o.Pos.Line-1)
|
||||
}
|
||||
output := &tfconf.Output{
|
||||
Name: o.Name,
|
||||
Description: types.String(description),
|
||||
Position: tfconf.Position{
|
||||
Filename: o.Pos.Filename,
|
||||
Line: o.Pos.Line,
|
||||
},
|
||||
}
|
||||
if options.OutputValues {
|
||||
terraformOutputs, err := loadOutputValues(options)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
if terraformOutputs[output.Name].Sensitive {
|
||||
output.Value = "<sensitive>"
|
||||
} else {
|
||||
output.Value = terraformOutputs[output.Name].Value
|
||||
}
|
||||
}
|
||||
outputs = append(outputs, output)
|
||||
}
|
||||
return outputs
|
||||
}
|
||||
|
||||
func loadOutputValues(options *Options) (map[string]*TerraformOutput, error) {
|
||||
var out []byte
|
||||
var err error
|
||||
if options.OutputValuesPath == "" {
|
||||
cmd := exec.Command("terraform", "output", "-json")
|
||||
cmd.Dir = options.Path
|
||||
if out, err = cmd.Output(); err != nil {
|
||||
return nil, fmt.Errorf("caught error while reading the terraform outputs: %v", err)
|
||||
}
|
||||
} else {
|
||||
if out, err = ioutil.ReadFile(options.OutputValuesPath); err != nil {
|
||||
return nil, fmt.Errorf("caught error while reading the terraform outputs file at %s: %v", options.OutputValuesPath, err)
|
||||
}
|
||||
}
|
||||
var terraformOutputs map[string]*TerraformOutput
|
||||
err = json.Unmarshal(out, &terraformOutputs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return terraformOutputs, err
|
||||
}
|
||||
|
||||
func loadProviders(tfmodule *tfconfig.Module) []*tfconf.Provider {
|
||||
resources := []map[string]*tfconfig.Resource{tfmodule.ManagedResources, tfmodule.DataResources}
|
||||
discovered := make(map[string]*tfconf.Provider)
|
||||
for _, resource := range resources {
|
||||
for _, r := range resource {
|
||||
var version = ""
|
||||
if rv, ok := tfmodule.RequiredProviders[r.Provider.Name]; ok && len(rv.VersionConstraints) > 0 {
|
||||
version = strings.Join(rv.VersionConstraints, " ")
|
||||
}
|
||||
key := fmt.Sprintf("%s.%s", r.Provider.Name, r.Provider.Alias)
|
||||
discovered[key] = &tfconf.Provider{
|
||||
Name: r.Provider.Name,
|
||||
Alias: types.String(r.Provider.Alias),
|
||||
Version: types.String(version),
|
||||
Position: tfconf.Position{
|
||||
Filename: r.Pos.Filename,
|
||||
Line: r.Pos.Line,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
providers := make([]*tfconf.Provider, 0, len(discovered))
|
||||
for _, provider := range discovered {
|
||||
providers = append(providers, provider)
|
||||
}
|
||||
return providers
|
||||
}
|
||||
|
||||
func loadComments(filename string, lineNum int) string {
|
||||
lines := reader.Lines{
|
||||
FileName: filename,
|
||||
LineNum: lineNum,
|
||||
Condition: func(line string) bool {
|
||||
return strings.HasPrefix(line, "#") || strings.HasPrefix(line, "//")
|
||||
},
|
||||
Parser: func(line string) (string, bool) {
|
||||
line = strings.TrimSpace(line)
|
||||
line = strings.TrimPrefix(line, "#")
|
||||
line = strings.TrimPrefix(line, "//")
|
||||
line = strings.TrimSpace(line)
|
||||
return line, true
|
||||
},
|
||||
}
|
||||
comment, err := lines.Extract()
|
||||
if err != nil {
|
||||
return "" // absorb the error, we don't need to bubble it up or break the execution
|
||||
}
|
||||
return strings.Join(comment, " ")
|
||||
}
|
||||
|
||||
func sortItems(tfmodule *tfconf.Module, sortby *SortBy) {
|
||||
if sortby.Name {
|
||||
sort.Sort(providersSortedByName(tfmodule.Providers))
|
||||
} else {
|
||||
sort.Sort(providersSortedByPosition(tfmodule.Providers))
|
||||
}
|
||||
|
||||
if sortby.Name {
|
||||
if sortby.Required {
|
||||
sort.Sort(inputsSortedByRequired(tfmodule.Inputs))
|
||||
sort.Sort(inputsSortedByRequired(tfmodule.RequiredInputs))
|
||||
sort.Sort(inputsSortedByRequired(tfmodule.OptionalInputs))
|
||||
} else {
|
||||
sort.Sort(inputsSortedByName(tfmodule.Inputs))
|
||||
sort.Sort(inputsSortedByName(tfmodule.RequiredInputs))
|
||||
sort.Sort(inputsSortedByName(tfmodule.OptionalInputs))
|
||||
}
|
||||
} else {
|
||||
sort.Sort(inputsSortedByPosition(tfmodule.Inputs))
|
||||
sort.Sort(inputsSortedByPosition(tfmodule.RequiredInputs))
|
||||
sort.Sort(inputsSortedByPosition(tfmodule.OptionalInputs))
|
||||
}
|
||||
|
||||
if sortby.Name {
|
||||
sort.Sort(outputsSortedByName(tfmodule.Outputs))
|
||||
} else {
|
||||
sort.Sort(outputsSortedByPosition(tfmodule.Outputs))
|
||||
}
|
||||
}
|
||||
40
internal/module/options.go
Normal file
40
internal/module/options.go
Normal file
@@ -0,0 +1,40 @@
|
||||
package module
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/imdario/mergo"
|
||||
)
|
||||
|
||||
// SortBy contains different sort criteria corresponding
|
||||
// to available flags (e.g. name, required, etc)
|
||||
type SortBy struct {
|
||||
Name bool
|
||||
Required bool
|
||||
}
|
||||
|
||||
// Options contains required options to load a Module from path
|
||||
type Options struct {
|
||||
Path string
|
||||
SortBy *SortBy
|
||||
OutputValues bool
|
||||
OutputValuesPath string
|
||||
}
|
||||
|
||||
// NewOptions returns new instance of Options
|
||||
func NewOptions() *Options {
|
||||
return &Options{
|
||||
Path: "",
|
||||
SortBy: &SortBy{Name: false, Required: false},
|
||||
OutputValues: false,
|
||||
OutputValuesPath: "",
|
||||
}
|
||||
}
|
||||
|
||||
// With override options with existing Options
|
||||
func (o *Options) With(override *Options) *Options {
|
||||
if err := mergo.Merge(o, override); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
return o
|
||||
}
|
||||
28
internal/module/output.go
Normal file
28
internal/module/output.go
Normal file
@@ -0,0 +1,28 @@
|
||||
package module
|
||||
|
||||
import (
|
||||
"github.com/segmentio/terraform-docs/pkg/tfconf"
|
||||
)
|
||||
|
||||
// TerraformOutput is used for unmarshalling `terraform outputs --json` into
|
||||
type TerraformOutput struct {
|
||||
Sensitive bool `json:"sensitive"`
|
||||
Type interface{} `json:"type"`
|
||||
Value interface{} `json:"value"`
|
||||
}
|
||||
|
||||
type outputsSortedByName []*tfconf.Output
|
||||
|
||||
func (a outputsSortedByName) Len() int { return len(a) }
|
||||
func (a outputsSortedByName) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
||||
func (a outputsSortedByName) Less(i, j int) bool {
|
||||
return a[i].Name < a[j].Name
|
||||
}
|
||||
|
||||
type outputsSortedByPosition []*tfconf.Output
|
||||
|
||||
func (a outputsSortedByPosition) Len() int { return len(a) }
|
||||
func (a outputsSortedByPosition) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
||||
func (a outputsSortedByPosition) Less(i, j int) bool {
|
||||
return a[i].Position.Filename < a[j].Position.Filename || a[i].Position.Line < a[j].Position.Line
|
||||
}
|
||||
21
internal/module/provider.go
Normal file
21
internal/module/provider.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package module
|
||||
|
||||
import (
|
||||
"github.com/segmentio/terraform-docs/pkg/tfconf"
|
||||
)
|
||||
|
||||
type providersSortedByName []*tfconf.Provider
|
||||
|
||||
func (a providersSortedByName) Len() int { return len(a) }
|
||||
func (a providersSortedByName) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
||||
func (a providersSortedByName) Less(i, j int) bool {
|
||||
return a[i].Name < a[j].Name || (a[i].Name == a[j].Name && a[i].Alias < a[j].Alias)
|
||||
}
|
||||
|
||||
type providersSortedByPosition []*tfconf.Provider
|
||||
|
||||
func (a providersSortedByPosition) Len() int { return len(a) }
|
||||
func (a providersSortedByPosition) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
||||
func (a providersSortedByPosition) Less(i, j int) bool {
|
||||
return a[i].Position.Filename < a[j].Position.Filename || a[i].Position.Line < a[j].Position.Line
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
package print
|
||||
@@ -1,29 +0,0 @@
|
||||
package tfconf
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/segmentio/terraform-docs/internal/pkg/reader"
|
||||
)
|
||||
|
||||
func readComment(filename string, lineNum int) string {
|
||||
lines := reader.Lines{
|
||||
FileName: filename,
|
||||
LineNum: lineNum,
|
||||
Condition: func(line string) bool {
|
||||
return strings.HasPrefix(line, "#") || strings.HasPrefix(line, "//")
|
||||
},
|
||||
Parser: func(line string) (string, bool) {
|
||||
line = strings.TrimSpace(line)
|
||||
line = strings.TrimPrefix(line, "#")
|
||||
line = strings.TrimPrefix(line, "//")
|
||||
line = strings.TrimSpace(line)
|
||||
return line, true
|
||||
},
|
||||
}
|
||||
comment, err := lines.Extract()
|
||||
if err != nil {
|
||||
return "" // absorb the error, we don't need to bubble it up or break the execution
|
||||
}
|
||||
return strings.Join(comment, " ")
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
package tfconf
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/segmentio/terraform-docs/internal/pkg/reader"
|
||||
)
|
||||
|
||||
func readHeader(path string) string {
|
||||
filename := filepath.Join(path, "main.tf")
|
||||
_, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
return "" // absorb the error, we don't need to bubble it up or break the execution
|
||||
}
|
||||
lines := reader.Lines{
|
||||
FileName: filename,
|
||||
LineNum: -1,
|
||||
Condition: func(line string) bool {
|
||||
line = strings.TrimSpace(line)
|
||||
return strings.HasPrefix(line, "/*") || strings.HasPrefix(line, "*") || strings.HasPrefix(line, "*/")
|
||||
},
|
||||
Parser: func(line string) (string, bool) {
|
||||
line = strings.TrimSpace(line)
|
||||
if strings.HasPrefix(line, "/*") || strings.HasPrefix(line, "*/") {
|
||||
return "", false
|
||||
}
|
||||
if line == "*" {
|
||||
return "", true
|
||||
}
|
||||
line = strings.TrimPrefix(line, "* ")
|
||||
return line, true
|
||||
},
|
||||
}
|
||||
header, err := lines.Extract()
|
||||
if err != nil {
|
||||
return "" // absorb the error, we don't need to bubble it up or break the execution
|
||||
}
|
||||
return strings.Join(header, "\n")
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
package tfconf
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
)
|
||||
|
||||
// Input represents a Terraform input.
|
||||
type Input struct {
|
||||
Name string `json:"name" yaml:"name"`
|
||||
Type String `json:"type" yaml:"type"`
|
||||
Description String `json:"description" yaml:"description"`
|
||||
Default interface{} `json:"default" yaml:"default"`
|
||||
Position Position `json:"-" yaml:"-"`
|
||||
}
|
||||
|
||||
// Value returns JSON representation of the 'Default' value, which is an 'interface'.
|
||||
// If 'Default' is a primitive type, the primitive value of 'Default' will be returned
|
||||
// and not the JSON formatted of it.
|
||||
func (i *Input) Value() string {
|
||||
marshaled, err := json.MarshalIndent(i.Default, "", " ")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if value := string(marshaled); value != "null" {
|
||||
return value
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// HasDefault indicates if a Terraform variable has a default value set.
|
||||
func (i *Input) HasDefault() bool {
|
||||
return i.Default != nil
|
||||
}
|
||||
|
||||
type inputsSortedByName []*Input
|
||||
|
||||
func (a inputsSortedByName) Len() int {
|
||||
return len(a)
|
||||
}
|
||||
|
||||
func (a inputsSortedByName) Swap(i, j int) {
|
||||
a[i], a[j] = a[j], a[i]
|
||||
}
|
||||
|
||||
func (a inputsSortedByName) Less(i, j int) bool {
|
||||
return a[i].Name < a[j].Name
|
||||
}
|
||||
|
||||
type inputsSortedByRequired []*Input
|
||||
|
||||
func (a inputsSortedByRequired) Len() int {
|
||||
return len(a)
|
||||
}
|
||||
|
||||
func (a inputsSortedByRequired) Swap(i, j int) {
|
||||
a[i], a[j] = a[j], a[i]
|
||||
}
|
||||
|
||||
func (a inputsSortedByRequired) Less(i, j int) bool {
|
||||
switch {
|
||||
// i required, j not: i gets priority
|
||||
case !a[i].HasDefault() && a[j].HasDefault():
|
||||
return true
|
||||
// j required, i not: i does not get priority
|
||||
case a[i].HasDefault() && !a[j].HasDefault():
|
||||
return false
|
||||
// Otherwise, sort by name
|
||||
default:
|
||||
return a[i].Name < a[j].Name
|
||||
}
|
||||
}
|
||||
|
||||
type inputsSortedByPosition []*Input
|
||||
|
||||
func (a inputsSortedByPosition) Len() int {
|
||||
return len(a)
|
||||
}
|
||||
|
||||
func (a inputsSortedByPosition) Swap(i, j int) {
|
||||
a[i], a[j] = a[j], a[i]
|
||||
}
|
||||
|
||||
func (a inputsSortedByPosition) Less(i, j int) bool {
|
||||
return a[i].Position.Filename < a[j].Position.Filename || a[i].Position.Line < a[j].Position.Line
|
||||
}
|
||||
@@ -1,226 +0,0 @@
|
||||
package tfconf
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os/exec"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/terraform-config-inspect/tfconfig"
|
||||
"github.com/segmentio/terraform-docs/internal/pkg/print"
|
||||
)
|
||||
|
||||
// Module represents a Terraform mod. It consists of
|
||||
// - Header ('header' json key): Module header found in shape of multi line comments at the beginning of 'main.tf'
|
||||
// - Inputs ('inputs' json key): List of input 'variables' extracted from the Terraform module .tf files
|
||||
// - Outputs ('outputs' json key): List of 'outputs' extracted from Terraform module .tf files
|
||||
// - Providers ('providers' json key): List of 'providers' extracted from resources used in Terraform module
|
||||
type Module struct {
|
||||
Header string `json:"header" yaml:"header"`
|
||||
Inputs []*Input `json:"inputs" yaml:"inputs"`
|
||||
Outputs []*Output `json:"outputs" yaml:"outputs"`
|
||||
Providers []*Provider `json:"providers" yaml:"providers"`
|
||||
RequiredInputs []*Input `json:"-" yaml:"-"`
|
||||
OptionalInputs []*Input `json:"-" yaml:"-"`
|
||||
}
|
||||
|
||||
// HasInputs indicates if the document has inputs.
|
||||
func (m *Module) HasInputs() bool {
|
||||
return len(m.Inputs) > 0
|
||||
}
|
||||
|
||||
// HasOutputs indicates if the document has outputs.
|
||||
func (m *Module) HasOutputs() bool {
|
||||
return len(m.Outputs) > 0
|
||||
}
|
||||
|
||||
// Sort sorts list of inputs and outputs based on provided flags (name, required, etc)
|
||||
func (m *Module) Sort(settings *print.Settings) {
|
||||
if settings.SortByName {
|
||||
sort.Sort(providersSortedByName(m.Providers))
|
||||
} else {
|
||||
sort.Sort(providersSortedByPosition(m.Providers))
|
||||
}
|
||||
|
||||
if settings.SortByName {
|
||||
if settings.SortByRequired {
|
||||
sort.Sort(inputsSortedByRequired(m.Inputs))
|
||||
sort.Sort(inputsSortedByRequired(m.RequiredInputs))
|
||||
sort.Sort(inputsSortedByRequired(m.OptionalInputs))
|
||||
} else {
|
||||
sort.Sort(inputsSortedByName(m.Inputs))
|
||||
sort.Sort(inputsSortedByName(m.RequiredInputs))
|
||||
sort.Sort(inputsSortedByName(m.OptionalInputs))
|
||||
}
|
||||
} else {
|
||||
sort.Sort(inputsSortedByPosition(m.Inputs))
|
||||
sort.Sort(inputsSortedByPosition(m.RequiredInputs))
|
||||
sort.Sort(inputsSortedByPosition(m.OptionalInputs))
|
||||
}
|
||||
|
||||
if settings.SortByName {
|
||||
sort.Sort(outputsSortedByName(m.Outputs))
|
||||
} else {
|
||||
sort.Sort(outputsSortedByPosition(m.Outputs))
|
||||
}
|
||||
}
|
||||
|
||||
// CreateModule returns new instance of Module with all the inputs and
|
||||
// outputs discovered from provided 'path' containing Terraform config
|
||||
func CreateModule(options *Options) (*Module, error) {
|
||||
mod := loadModule(options.Path)
|
||||
|
||||
header := readHeader(options.Path)
|
||||
|
||||
var inputs = make([]*Input, 0, len(mod.Variables))
|
||||
var requiredInputs = make([]*Input, 0, len(mod.Variables))
|
||||
var optionalInputs = make([]*Input, 0, len(mod.Variables))
|
||||
|
||||
for _, input := range mod.Variables {
|
||||
inputType := input.Type
|
||||
if input.Type == "" {
|
||||
inputType = "any"
|
||||
if input.Default != nil {
|
||||
switch xType := fmt.Sprintf("%T", input.Default); xType {
|
||||
case "string":
|
||||
inputType = "string"
|
||||
case "int", "int8", "int16", "int32", "int64", "float32", "float64":
|
||||
inputType = "number"
|
||||
case "bool":
|
||||
inputType = "bool"
|
||||
case "[]interface {}":
|
||||
inputType = "list"
|
||||
case "map[string]interface {}":
|
||||
inputType = "map"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inputDescription := input.Description
|
||||
if inputDescription == "" {
|
||||
inputDescription = readComment(input.Pos.Filename, input.Pos.Line-1)
|
||||
}
|
||||
|
||||
i := &Input{
|
||||
Name: input.Name,
|
||||
Type: String(inputType),
|
||||
Description: String(inputDescription),
|
||||
Default: input.Default,
|
||||
Position: Position{
|
||||
Filename: input.Pos.Filename,
|
||||
Line: input.Pos.Line,
|
||||
},
|
||||
}
|
||||
|
||||
inputs = append(inputs, i)
|
||||
if i.HasDefault() {
|
||||
optionalInputs = append(optionalInputs, i)
|
||||
} else {
|
||||
requiredInputs = append(requiredInputs, i)
|
||||
}
|
||||
}
|
||||
|
||||
// output module
|
||||
var outputs = make([]*Output, 0, len(mod.Outputs))
|
||||
for _, o := range mod.Outputs {
|
||||
outputDescription := o.Description
|
||||
if outputDescription == "" {
|
||||
outputDescription = readComment(o.Pos.Filename, o.Pos.Line-1)
|
||||
}
|
||||
output := &Output{
|
||||
Name: o.Name,
|
||||
Description: String(outputDescription),
|
||||
Position: Position{
|
||||
Filename: o.Pos.Filename,
|
||||
Line: o.Pos.Line,
|
||||
},
|
||||
}
|
||||
if options.OutputValues {
|
||||
terraformOutputs, err := loadOutputValues(options)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if terraformOutputs[output.Name].Sensitive {
|
||||
output.Value = "<sensitive>"
|
||||
} else {
|
||||
output.Value = terraformOutputs[output.Name].Value
|
||||
}
|
||||
}
|
||||
outputs = append(outputs, output)
|
||||
}
|
||||
|
||||
var providerSet = loadProviders(mod.RequiredProviders, mod.ManagedResources, mod.DataResources)
|
||||
var providers = make([]*Provider, 0, len(providerSet))
|
||||
for _, provider := range providerSet {
|
||||
providers = append(providers, provider)
|
||||
}
|
||||
|
||||
module := &Module{
|
||||
Header: header,
|
||||
Inputs: inputs,
|
||||
Outputs: outputs,
|
||||
Providers: providers,
|
||||
RequiredInputs: requiredInputs,
|
||||
OptionalInputs: optionalInputs,
|
||||
}
|
||||
return module, nil
|
||||
}
|
||||
|
||||
func loadModule(path string) *tfconfig.Module {
|
||||
module, diag := tfconfig.LoadModule(path)
|
||||
if diag != nil && diag.HasErrors() {
|
||||
log.Fatal(diag)
|
||||
}
|
||||
return module
|
||||
}
|
||||
|
||||
func loadProviders(requiredProviders map[string]*tfconfig.ProviderRequirement, resources ...map[string]*tfconfig.Resource) map[string]*Provider {
|
||||
var providers = make(map[string]*Provider)
|
||||
for _, resource := range resources {
|
||||
for _, r := range resource {
|
||||
var version = ""
|
||||
if requiredVersion, ok := requiredProviders[r.Provider.Name]; ok && len(requiredVersion.VersionConstraints) > 0 {
|
||||
version = strings.Join(requiredVersion.VersionConstraints, " ")
|
||||
}
|
||||
key := fmt.Sprintf("%s.%s", r.Provider.Name, r.Provider.Alias)
|
||||
providers[key] = &Provider{
|
||||
Name: r.Provider.Name,
|
||||
Alias: String(r.Provider.Alias),
|
||||
Version: String(version),
|
||||
Position: Position{
|
||||
Filename: r.Pos.Filename,
|
||||
Line: r.Pos.Line,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
return providers
|
||||
}
|
||||
|
||||
func loadOutputValues(options *Options) (map[string]*TerraformOutput, error) {
|
||||
var out []byte
|
||||
var err error
|
||||
|
||||
if options.OutputValuesPath == "" {
|
||||
cmd := exec.Command("terraform", "output", "-json")
|
||||
cmd.Dir = options.Path
|
||||
if out, err = cmd.Output(); err != nil {
|
||||
return nil, fmt.Errorf("caught error while reading the terraform outputs: %v", err)
|
||||
}
|
||||
} else {
|
||||
if out, err = ioutil.ReadFile(options.OutputValuesPath); err != nil {
|
||||
return nil, fmt.Errorf("caught error while reading the terraform outputs file at %s: %v", options.OutputValuesPath, err)
|
||||
}
|
||||
}
|
||||
|
||||
var terraformOutputs map[string]*TerraformOutput
|
||||
err = json.Unmarshal(out, &terraformOutputs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return terraformOutputs, err
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user