mirror of
https://github.com/terraform-docs/terraform-docs.git
synced 2026-03-27 12:58:35 +07:00
feat: Extract and render output values from Terraform (#191)
* Allow users to pass '--output-values' Pass empty string to CreateModule.outputValuePath * Fix bug causing 'pretty' tests to fail * Link formats documentation in README (#181) Co-authored-by: Khosrow Moossavi <khos2ow@gmail.com> * docs: Auto generate formats document from examples (#192) * Auto generate formats document from examples * fix lint issues * refactor: Add tfconf.Options to load Module with (#193) * Update Changelog * Allow users to pass '--output-values' Read the outputValuesPath from an env variable Use an env var with a path for '--output-values' Update Changelog Use an env var with a path for '--output-values' Update Changelog properly write output values for evrythng but yaml * Fix failing json+yaml tests * Remove unneeded code block from output.go * Remove unused import statement from output.go * Fix some noob mistakes * Create two flags to use for output value injection * Fix bug vanilla commands+build test to fail * Modify all tests and add new for outputvalues * Modify to include many output types * Optimize imports to appease checkfmt * Create loadOutputValues function * Fix linter issue * Code review fixes. Hopefully the final commit! * appease linter * Not allow sensitive output values to be injected * Remove trailing slash from tests * Remove default values from `--output-values-from` Co-authored-by: Martyn Ranyard <iMartyn@users.noreply.github.com> Co-authored-by: Khosrow Moossavi <khos2ow@gmail.com>
This commit is contained in:
committed by
GitHub
parent
b86f6715f9
commit
31cdef0f67
12
cmd/root.go
12
cmd/root.go
@@ -11,6 +11,7 @@ import (
|
||||
)
|
||||
|
||||
var settings = print.NewSettings()
|
||||
var options = tfconf.Options{}
|
||||
|
||||
// rootCmd represents the base command when called without any subcommands
|
||||
var rootCmd = &cobra.Command{
|
||||
@@ -35,6 +36,8 @@ var rootCmd = &cobra.Command{
|
||||
settings.ShowInputs = !noinputs
|
||||
settings.ShowOutputs = !nooutputs
|
||||
|
||||
settings.OutputValues = options.OutputValues
|
||||
|
||||
settings.ShowColor = !nocolor
|
||||
settings.SortByName = !nosort
|
||||
settings.ShowRequired = !norequired
|
||||
@@ -51,6 +54,9 @@ func init() {
|
||||
rootCmd.PersistentFlags().BoolVar(new(bool), "no-sort", false, "do no sort items")
|
||||
rootCmd.PersistentFlags().BoolVar(&settings.SortByRequired, "sort-by-required", false, "sort items by name and print required ones first")
|
||||
|
||||
rootCmd.PersistentFlags().BoolVar(&options.OutputValues, "output-values", false, "inject output values into outputs")
|
||||
rootCmd.PersistentFlags().StringVar(&options.OutputValuesPath, "output-values-from", "", "inject output values from file into outputs")
|
||||
|
||||
//-----------------------------
|
||||
// deprecated - will be removed
|
||||
//-----------------------------
|
||||
@@ -87,10 +93,8 @@ func FormatterCmds() []*cobra.Command {
|
||||
}
|
||||
|
||||
func doPrint(path string, fn func(*tfconf.Module) (string, error)) {
|
||||
options := &tfconf.Options{
|
||||
Path: path,
|
||||
}
|
||||
module, err := tfconf.CreateModule(options)
|
||||
options.Path = path
|
||||
module, err := tfconf.CreateModule(&options)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
23
examples/output_values.json
Normal file
23
examples/output_values.json
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"output-0.12": {
|
||||
"sensitive": false,
|
||||
"type": "string",
|
||||
"value": ""
|
||||
},
|
||||
"output-1": {
|
||||
"sensitive": false,
|
||||
"type": "int",
|
||||
"value": 1
|
||||
},
|
||||
"output-2": {
|
||||
"sensitive": false,
|
||||
"type": "array",
|
||||
"value": ["jack", "lola"]
|
||||
},
|
||||
"unquoted": {
|
||||
"sensitive": false,
|
||||
"type": "map",
|
||||
"value": {"leon":"cat"}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
|
||||
"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/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
@@ -12,7 +13,10 @@ func TestJson(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
settings := testutil.Settings().WithSections().Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("json")
|
||||
expected, err := testutil.GetExpected("json")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
@@ -27,7 +31,10 @@ func TestJsonSortByName(t *testing.T) {
|
||||
SortByName: true,
|
||||
}).Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("json-SortByName")
|
||||
expected, err := testutil.GetExpected("json-SortByName")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
@@ -43,7 +50,10 @@ func TestJsonSortByRequired(t *testing.T) {
|
||||
SortByRequired: true,
|
||||
}).Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("json-SortByRequired")
|
||||
expected, err := testutil.GetExpected("json-SortByRequired")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
@@ -61,7 +71,10 @@ func TestJsonNoHeader(t *testing.T) {
|
||||
ShowOutputs: true,
|
||||
}).Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("json-NoHeader")
|
||||
expected, err := testutil.GetExpected("json-NoHeader")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
@@ -79,7 +92,10 @@ func TestJsonNoProviders(t *testing.T) {
|
||||
ShowOutputs: true,
|
||||
}).Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("json-NoProviders")
|
||||
expected, err := testutil.GetExpected("json-NoProviders")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
@@ -97,7 +113,10 @@ func TestJsonNoInputs(t *testing.T) {
|
||||
ShowOutputs: true,
|
||||
}).Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("json-NoInputs")
|
||||
expected, err := testutil.GetExpected("json-NoInputs")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
@@ -115,7 +134,10 @@ func TestJsonNoOutputs(t *testing.T) {
|
||||
ShowOutputs: false,
|
||||
}).Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("json-NoOutputs")
|
||||
expected, err := testutil.GetExpected("json-NoOutputs")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
@@ -133,7 +155,10 @@ func TestJsonOnlyHeader(t *testing.T) {
|
||||
ShowOutputs: false,
|
||||
}).Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("json-OnlyHeader")
|
||||
expected, err := testutil.GetExpected("json-OnlyHeader")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
@@ -151,7 +176,10 @@ func TestJsonOnlyProviders(t *testing.T) {
|
||||
ShowOutputs: false,
|
||||
}).Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("json-OnlyProviders")
|
||||
expected, err := testutil.GetExpected("json-OnlyProviders")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
@@ -169,7 +197,10 @@ func TestJsonOnlyInputs(t *testing.T) {
|
||||
ShowOutputs: false,
|
||||
}).Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("json-OnlyInputs")
|
||||
expected, err := testutil.GetExpected("json-OnlyInputs")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
@@ -187,7 +218,10 @@ func TestJsonOnlyOutputs(t *testing.T) {
|
||||
ShowOutputs: true,
|
||||
}).Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("json-OnlyOutputs")
|
||||
expected, err := testutil.GetExpected("json-OnlyOutputs")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
@@ -202,7 +236,31 @@ func TestJsonEscapeCharacters(t *testing.T) {
|
||||
EscapeCharacters: true,
|
||||
}).Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("json-EscapeCharacters")
|
||||
expected, err := testutil.GetExpected("json-EscapeCharacters")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
}
|
||||
func TestJsonOutputValues(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
settings := testutil.Settings().WithSections().With(&print.Settings{
|
||||
OutputValues: true,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("json-OutputValues")
|
||||
assert.Nil(err)
|
||||
|
||||
options := &tfconf.Options{
|
||||
OutputValues: true,
|
||||
OutputValuesPath: "output_values.json",
|
||||
}
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
|
||||
175
internal/pkg/print/json/testdata/json-OutputValues.golden
vendored
Normal file
175
internal/pkg/print/json/testdata/json-OutputValues.golden
vendored
Normal file
@@ -0,0 +1,175 @@
|
||||
{
|
||||
"header": "Usage:\n\nExample of 'foo_bar' module in `foo_bar.tf`.\n\n- list item 1\n- list item 2\n\nEven inline **formatting** in _here_ is possible.\nand some [link](https://domain.com/)\n\n* list item 3\n* list item 4\n\n```hcl\nmodule \"foo_bar\" {\n source = \"github.com/foo/bar\"\n\n id = \"1234567890\"\n name = \"baz\"\n\n zones = [\"us-east-1\", \"us-west-1\"]\n\n tags = {\n Name = \"baz\"\n Created-By = \"first.last@email.com\"\n Date-Created = \"20180101\"\n }\n}\n```\n\nHere is some trailing text after code block,\nfollowed by another line of text.\n\n| Name | Description |\n|------|-----------------|\n| Foo | Foo description |\n| Bar | Bar description |",
|
||||
"inputs": [
|
||||
{
|
||||
"name": "unquoted",
|
||||
"type": "any",
|
||||
"description": null,
|
||||
"default": null
|
||||
},
|
||||
{
|
||||
"name": "string-3",
|
||||
"type": "string",
|
||||
"description": null,
|
||||
"default": ""
|
||||
},
|
||||
{
|
||||
"name": "string-2",
|
||||
"type": "string",
|
||||
"description": "It's string number two.",
|
||||
"default": null
|
||||
},
|
||||
{
|
||||
"name": "string-1",
|
||||
"type": "string",
|
||||
"description": "It's string number one.",
|
||||
"default": "bar"
|
||||
},
|
||||
{
|
||||
"name": "map-3",
|
||||
"type": "map",
|
||||
"description": null,
|
||||
"default": {}
|
||||
},
|
||||
{
|
||||
"name": "map-2",
|
||||
"type": "map",
|
||||
"description": "It's map number two.",
|
||||
"default": null
|
||||
},
|
||||
{
|
||||
"name": "map-1",
|
||||
"type": "map",
|
||||
"description": "It's map number one.",
|
||||
"default": {
|
||||
"a": 1,
|
||||
"b": 2,
|
||||
"c": 3
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "list-3",
|
||||
"type": "list",
|
||||
"description": null,
|
||||
"default": []
|
||||
},
|
||||
{
|
||||
"name": "list-2",
|
||||
"type": "list",
|
||||
"description": "It's list number two.",
|
||||
"default": null
|
||||
},
|
||||
{
|
||||
"name": "list-1",
|
||||
"type": "list",
|
||||
"description": "It's list number one.",
|
||||
"default": [
|
||||
"a",
|
||||
"b",
|
||||
"c"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "input_with_underscores",
|
||||
"type": "any",
|
||||
"description": "A variable with underscores.",
|
||||
"default": null
|
||||
},
|
||||
{
|
||||
"name": "input-with-pipe",
|
||||
"type": "string",
|
||||
"description": "It includes v1 | v2 | v3",
|
||||
"default": "v1"
|
||||
},
|
||||
{
|
||||
"name": "input-with-code-block",
|
||||
"type": "list",
|
||||
"description": "This is a complicated one. We need a newline. \nAnd an example in a code block\n```\ndefault = [\n \"machine rack01:neptune\"\n]\n```\n",
|
||||
"default": [
|
||||
"name rack:location"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "long_type",
|
||||
"type": "object({\n name = string,\n foo = object({ foo = string, bar = string }),\n bar = object({ foo = string, bar = string }),\n fizz = list(string),\n buzz = list(string)\n })",
|
||||
"description": "This description is itself markdown.\n\nIt spans over multiple lines.\n",
|
||||
"default": {
|
||||
"bar": {
|
||||
"bar": "bar",
|
||||
"foo": "bar"
|
||||
},
|
||||
"buzz": [
|
||||
"fizz",
|
||||
"buzz"
|
||||
],
|
||||
"fizz": [],
|
||||
"foo": {
|
||||
"bar": "foo",
|
||||
"foo": "foo"
|
||||
},
|
||||
"name": "hello"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "no-escape-default-value",
|
||||
"type": "string",
|
||||
"description": "The description contains `something_with_underscore`. Defaults to 'VALUE_WITH_UNDERSCORE'.",
|
||||
"default": "VALUE_WITH_UNDERSCORE"
|
||||
},
|
||||
{
|
||||
"name": "with-url",
|
||||
"type": "string",
|
||||
"description": "The description contains url. https://www.domain.com/foo/bar_baz.html",
|
||||
"default": ""
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "unquoted",
|
||||
"description": "It's unquoted output.",
|
||||
"value": {
|
||||
"leon": "cat"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "output-2",
|
||||
"description": "It's output number two.",
|
||||
"value": [
|
||||
"jack",
|
||||
"lola"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "output-1",
|
||||
"description": "It's output number one.",
|
||||
"value": 1
|
||||
},
|
||||
{
|
||||
"name": "output-0.12",
|
||||
"description": "terraform 0.12 only",
|
||||
"value": ""
|
||||
}
|
||||
],
|
||||
"providers": [
|
||||
{
|
||||
"name": "tls",
|
||||
"alias": null,
|
||||
"version": null
|
||||
},
|
||||
{
|
||||
"name": "aws",
|
||||
"alias": null,
|
||||
"version": ">= 2.15.0"
|
||||
},
|
||||
{
|
||||
"name": "aws",
|
||||
"alias": "ident",
|
||||
"version": ">= 2.15.0"
|
||||
},
|
||||
{
|
||||
"name": "null",
|
||||
"alias": null,
|
||||
"version": null
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -94,7 +94,10 @@ const (
|
||||
{{ indent 1 }} {{ name .Name }}
|
||||
|
||||
Description: {{ tostring .Description | sanitizeDoc }}
|
||||
{{- end }}
|
||||
{{ if $.Settings.OutputValues }}
|
||||
Value: {{ .Value | sanitizeInterface | sanitizeDoc }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ end -}}
|
||||
`
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
|
||||
"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/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
@@ -12,7 +13,10 @@ func TestDocument(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
settings := testutil.Settings().WithSections().Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("document")
|
||||
expected, err := testutil.GetExpected("document")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
@@ -27,7 +31,10 @@ func TestDocumentWithRequired(t *testing.T) {
|
||||
ShowRequired: true,
|
||||
}).Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("document-WithRequired")
|
||||
expected, err := testutil.GetExpected("document-WithRequired")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
@@ -42,7 +49,10 @@ func TestDocumentSortByName(t *testing.T) {
|
||||
SortByName: true,
|
||||
}).Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("document-SortByName")
|
||||
expected, err := testutil.GetExpected("document-SortByName")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
@@ -58,7 +68,10 @@ func TestDocumentSortByRequired(t *testing.T) {
|
||||
SortByRequired: true,
|
||||
}).Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("document-SortByRequired")
|
||||
expected, err := testutil.GetExpected("document-SortByRequired")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
@@ -76,7 +89,10 @@ func TestDocumentNoHeader(t *testing.T) {
|
||||
ShowOutputs: true,
|
||||
}).Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("document-NoHeader")
|
||||
expected, err := testutil.GetExpected("document-NoHeader")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
@@ -94,7 +110,10 @@ func TestDocumentNoProviders(t *testing.T) {
|
||||
ShowOutputs: true,
|
||||
}).Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("document-NoProviders")
|
||||
expected, err := testutil.GetExpected("document-NoProviders")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
@@ -112,7 +131,10 @@ func TestDocumentNoInputs(t *testing.T) {
|
||||
ShowOutputs: true,
|
||||
}).Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("document-NoInputs")
|
||||
expected, err := testutil.GetExpected("document-NoInputs")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
@@ -130,7 +152,10 @@ func TestDocumentNoOutputs(t *testing.T) {
|
||||
ShowOutputs: false,
|
||||
}).Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("document-NoOutputs")
|
||||
expected, err := testutil.GetExpected("document-NoOutputs")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
@@ -148,7 +173,10 @@ func TestDocumentOnlyHeader(t *testing.T) {
|
||||
ShowOutputs: false,
|
||||
}).Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("document-OnlyHeader")
|
||||
expected, err := testutil.GetExpected("document-OnlyHeader")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
@@ -166,7 +194,10 @@ func TestDocumentOnlyProviders(t *testing.T) {
|
||||
ShowOutputs: false,
|
||||
}).Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("document-OnlyProviders")
|
||||
expected, err := testutil.GetExpected("document-OnlyProviders")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
@@ -184,7 +215,10 @@ func TestDocumentOnlyInputs(t *testing.T) {
|
||||
ShowOutputs: false,
|
||||
}).Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("document-OnlyInputs")
|
||||
expected, err := testutil.GetExpected("document-OnlyInputs")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
@@ -202,7 +236,10 @@ func TestDocumentOnlyOutputs(t *testing.T) {
|
||||
ShowOutputs: true,
|
||||
}).Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("document-OnlyOutputs")
|
||||
expected, err := testutil.GetExpected("document-OnlyOutputs")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
@@ -217,7 +254,10 @@ func TestDocumentEscapeCharacters(t *testing.T) {
|
||||
EscapeCharacters: true,
|
||||
}).Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("document-EscapeCharacters")
|
||||
expected, err := testutil.GetExpected("document-EscapeCharacters")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
@@ -226,13 +266,16 @@ func TestDocumentEscapeCharacters(t *testing.T) {
|
||||
assert.Equal(expected, actual)
|
||||
}
|
||||
|
||||
func TestDocumentIndentationBellowAllowed(t *testing.T) {
|
||||
func TestDocumentIndentationBelowAllowed(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
settings := testutil.Settings().WithSections().With(&print.Settings{
|
||||
MarkdownIndent: 0,
|
||||
}).Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("document-IndentationBellowAllowed")
|
||||
expected, err := testutil.GetExpected("document-IndentationBelowAllowed")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
@@ -247,7 +290,10 @@ func TestDocumentIndentationAboveAllowed(t *testing.T) {
|
||||
MarkdownIndent: 10,
|
||||
}).Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("document-IndentationAboveAllowed")
|
||||
expected, err := testutil.GetExpected("document-IndentationAboveAllowed")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
@@ -262,7 +308,32 @@ func TestDocumentIndentationOfFour(t *testing.T) {
|
||||
MarkdownIndent: 4,
|
||||
}).Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("document-IndentationOfFour")
|
||||
expected, err := testutil.GetExpected("document-IndentationOfFour")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
}
|
||||
|
||||
func TestDocumentOutputValues(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
settings := testutil.Settings().WithSections().With(&print.Settings{
|
||||
OutputValues: true,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("document-OutputValues")
|
||||
assert.Nil(err)
|
||||
|
||||
options := &tfconf.Options{
|
||||
OutputValues: true,
|
||||
OutputValuesPath: "output_values.json",
|
||||
}
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
|
||||
268
internal/pkg/print/markdown/document/testdata/document-OutputValues.golden
vendored
Normal file
268
internal/pkg/print/markdown/document/testdata/document-OutputValues.golden
vendored
Normal file
@@ -0,0 +1,268 @@
|
||||
Usage:
|
||||
|
||||
Example of 'foo_bar' module in `foo_bar.tf`.
|
||||
|
||||
- list item 1
|
||||
- list item 2
|
||||
|
||||
Even inline **formatting** in _here_ is possible.
|
||||
and some [link](https://domain.com/)
|
||||
|
||||
* list item 3
|
||||
* list item 4
|
||||
|
||||
```hcl
|
||||
module "foo_bar" {
|
||||
source = "github.com/foo/bar"
|
||||
|
||||
id = "1234567890"
|
||||
name = "baz"
|
||||
|
||||
zones = ["us-east-1", "us-west-1"]
|
||||
|
||||
tags = {
|
||||
Name = "baz"
|
||||
Created-By = "first.last@email.com"
|
||||
Date-Created = "20180101"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Here is some trailing text after code block,
|
||||
followed by another line of text.
|
||||
|
||||
| Name | Description |
|
||||
|------|-----------------|
|
||||
| Foo | Foo description |
|
||||
| Bar | Bar description |
|
||||
|
||||
## Providers
|
||||
|
||||
The following providers are used by this module:
|
||||
|
||||
- tls
|
||||
|
||||
- aws (>= 2.15.0)
|
||||
|
||||
- aws.ident (>= 2.15.0)
|
||||
|
||||
- null
|
||||
|
||||
## Inputs
|
||||
|
||||
The following input variables are supported:
|
||||
|
||||
### unquoted
|
||||
|
||||
Description: n/a
|
||||
|
||||
Type: `any`
|
||||
|
||||
Default: n/a
|
||||
|
||||
### string-3
|
||||
|
||||
Description: n/a
|
||||
|
||||
Type: `string`
|
||||
|
||||
Default: `""`
|
||||
|
||||
### string-2
|
||||
|
||||
Description: It's string number two.
|
||||
|
||||
Type: `string`
|
||||
|
||||
Default: n/a
|
||||
|
||||
### string-1
|
||||
|
||||
Description: It's string number one.
|
||||
|
||||
Type: `string`
|
||||
|
||||
Default: `"bar"`
|
||||
|
||||
### map-3
|
||||
|
||||
Description: n/a
|
||||
|
||||
Type: `map`
|
||||
|
||||
Default: `{}`
|
||||
|
||||
### map-2
|
||||
|
||||
Description: It's map number two.
|
||||
|
||||
Type: `map`
|
||||
|
||||
Default: n/a
|
||||
|
||||
### map-1
|
||||
|
||||
Description: It's map number one.
|
||||
|
||||
Type: `map`
|
||||
|
||||
Default:
|
||||
|
||||
```json
|
||||
{
|
||||
"a": 1,
|
||||
"b": 2,
|
||||
"c": 3
|
||||
}
|
||||
```
|
||||
|
||||
### list-3
|
||||
|
||||
Description: n/a
|
||||
|
||||
Type: `list`
|
||||
|
||||
Default: `[]`
|
||||
|
||||
### list-2
|
||||
|
||||
Description: It's list number two.
|
||||
|
||||
Type: `list`
|
||||
|
||||
Default: n/a
|
||||
|
||||
### list-1
|
||||
|
||||
Description: It's list number one.
|
||||
|
||||
Type: `list`
|
||||
|
||||
Default:
|
||||
|
||||
```json
|
||||
[
|
||||
"a",
|
||||
"b",
|
||||
"c"
|
||||
]
|
||||
```
|
||||
|
||||
### input_with_underscores
|
||||
|
||||
Description: A variable with underscores.
|
||||
|
||||
Type: `any`
|
||||
|
||||
Default: n/a
|
||||
|
||||
### input-with-pipe
|
||||
|
||||
Description: It includes v1 \| v2 \| v3
|
||||
|
||||
Type: `string`
|
||||
|
||||
Default: `"v1"`
|
||||
|
||||
### input-with-code-block
|
||||
|
||||
Description: This is a complicated one. We need a newline.
|
||||
And an example in a code block
|
||||
```
|
||||
default = [
|
||||
"machine rack01:neptune"
|
||||
]
|
||||
```
|
||||
|
||||
Type: `list`
|
||||
|
||||
Default:
|
||||
|
||||
```json
|
||||
[
|
||||
"name rack:location"
|
||||
]
|
||||
```
|
||||
|
||||
### long_type
|
||||
|
||||
Description: This description is itself markdown.
|
||||
|
||||
It spans over multiple lines.
|
||||
|
||||
Type:
|
||||
|
||||
```hcl
|
||||
object({
|
||||
name = string,
|
||||
foo = object({ foo = string, bar = string }),
|
||||
bar = object({ foo = string, bar = string }),
|
||||
fizz = list(string),
|
||||
buzz = list(string)
|
||||
})
|
||||
```
|
||||
|
||||
Default:
|
||||
|
||||
```json
|
||||
{
|
||||
"bar": {
|
||||
"bar": "bar",
|
||||
"foo": "bar"
|
||||
},
|
||||
"buzz": [
|
||||
"fizz",
|
||||
"buzz"
|
||||
],
|
||||
"fizz": [],
|
||||
"foo": {
|
||||
"bar": "foo",
|
||||
"foo": "foo"
|
||||
},
|
||||
"name": "hello"
|
||||
}
|
||||
```
|
||||
|
||||
### no-escape-default-value
|
||||
|
||||
Description: The description contains `something_with_underscore`. Defaults to 'VALUE_WITH_UNDERSCORE'.
|
||||
|
||||
Type: `string`
|
||||
|
||||
Default: `"VALUE_WITH_UNDERSCORE"`
|
||||
|
||||
### with-url
|
||||
|
||||
Description: The description contains url. https://www.domain.com/foo/bar_baz.html
|
||||
|
||||
Type: `string`
|
||||
|
||||
Default: `""`
|
||||
|
||||
## Outputs
|
||||
|
||||
The following outputs are exported:
|
||||
|
||||
### unquoted
|
||||
|
||||
Description: It's unquoted output.
|
||||
|
||||
Value: map["leon":"cat"]
|
||||
|
||||
### output-2
|
||||
|
||||
Description: It's output number two.
|
||||
|
||||
Value: ["jack" "lola"]
|
||||
|
||||
### output-1
|
||||
|
||||
Description: It's output number one.
|
||||
|
||||
Value: 1
|
||||
|
||||
### output-0.12
|
||||
|
||||
Description: terraform 0.12 only
|
||||
|
||||
Value: ""
|
||||
@@ -64,10 +64,10 @@ const (
|
||||
{{ if not .Module.Outputs }}
|
||||
No output.
|
||||
{{ else }}
|
||||
| Name | Description |
|
||||
|------|-------------|
|
||||
| Name | Description |{{ if $.Settings.OutputValues }} Value |{{ end }}
|
||||
|------|-------------|{{ if $.Settings.OutputValues }}-------|{{ end }}
|
||||
{{- range .Module.Outputs }}
|
||||
| {{ name .Name }} | {{ tostring .Description | sanitizeTbl }} |
|
||||
| {{ name .Name }} | {{ tostring .Description | sanitizeTbl }} |{{ if $.Settings.OutputValues }} {{ .Value | sanitizeInterface | sanitizeTbl }} |{{ end }}
|
||||
{{- end }}
|
||||
{{ end }}
|
||||
{{ end -}}
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
|
||||
"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/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
@@ -12,7 +13,10 @@ func TestTable(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
settings := testutil.Settings().WithSections().Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("table")
|
||||
expected, err := testutil.GetExpected("table")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
@@ -27,7 +31,10 @@ func TestTableWithRequired(t *testing.T) {
|
||||
ShowRequired: true,
|
||||
}).Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("table-WithRequired")
|
||||
expected, err := testutil.GetExpected("table-WithRequired")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
@@ -42,7 +49,10 @@ func TestTableSortByName(t *testing.T) {
|
||||
SortByName: true,
|
||||
}).Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("table-SortByName")
|
||||
expected, err := testutil.GetExpected("table-SortByName")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
@@ -58,7 +68,10 @@ func TestTableSortByRequired(t *testing.T) {
|
||||
SortByRequired: true,
|
||||
}).Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("table-SortByRequired")
|
||||
expected, err := testutil.GetExpected("table-SortByRequired")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
@@ -76,7 +89,10 @@ func TestTableNoHeader(t *testing.T) {
|
||||
ShowOutputs: true,
|
||||
}).Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("table-NoHeader")
|
||||
expected, err := testutil.GetExpected("table-NoHeader")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
@@ -94,7 +110,10 @@ func TestTableNoProviders(t *testing.T) {
|
||||
ShowOutputs: true,
|
||||
}).Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("table-NoProviders")
|
||||
expected, err := testutil.GetExpected("table-NoProviders")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
@@ -112,7 +131,10 @@ func TestTableNoInputs(t *testing.T) {
|
||||
ShowOutputs: true,
|
||||
}).Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("table-NoInputs")
|
||||
expected, err := testutil.GetExpected("table-NoInputs")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
@@ -130,7 +152,10 @@ func TestTableNoOutputs(t *testing.T) {
|
||||
ShowOutputs: false,
|
||||
}).Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("table-NoOutputs")
|
||||
expected, err := testutil.GetExpected("table-NoOutputs")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
@@ -148,7 +173,10 @@ func TestTableOnlyHeader(t *testing.T) {
|
||||
ShowOutputs: false,
|
||||
}).Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("table-OnlyHeader")
|
||||
expected, err := testutil.GetExpected("table-OnlyHeader")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
@@ -166,7 +194,10 @@ func TestTableOnlyProviders(t *testing.T) {
|
||||
ShowOutputs: false,
|
||||
}).Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("table-OnlyProviders")
|
||||
expected, err := testutil.GetExpected("table-OnlyProviders")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
@@ -184,7 +215,10 @@ func TestTableOnlyInputs(t *testing.T) {
|
||||
ShowOutputs: false,
|
||||
}).Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("table-OnlyInputs")
|
||||
expected, err := testutil.GetExpected("table-OnlyInputs")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
@@ -202,7 +236,10 @@ func TestTableOnlyOutputs(t *testing.T) {
|
||||
ShowOutputs: true,
|
||||
}).Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("table-OnlyOutputs")
|
||||
expected, err := testutil.GetExpected("table-OnlyOutputs")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
@@ -217,7 +254,10 @@ func TestTableEscapeCharacters(t *testing.T) {
|
||||
EscapeCharacters: true,
|
||||
}).Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("table-EscapeCharacters")
|
||||
expected, err := testutil.GetExpected("table-EscapeCharacters")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
@@ -232,7 +272,10 @@ func TestTableIndentationBellowAllowed(t *testing.T) {
|
||||
MarkdownIndent: 0,
|
||||
}).Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("table-IndentationBellowAllowed")
|
||||
expected, err := testutil.GetExpected("table-IndentationBellowAllowed")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
@@ -247,7 +290,10 @@ func TestTableIndentationAboveAllowed(t *testing.T) {
|
||||
MarkdownIndent: 10,
|
||||
}).Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("table-IndentationAboveAllowed")
|
||||
expected, err := testutil.GetExpected("table-IndentationAboveAllowed")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
@@ -262,7 +308,32 @@ func TestTableIndentationOfFour(t *testing.T) {
|
||||
MarkdownIndent: 4,
|
||||
}).Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("table-IndentationOfFour")
|
||||
expected, err := testutil.GetExpected("table-IndentationOfFour")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
}
|
||||
|
||||
func TestTableOutputValues(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
settings := testutil.Settings().WithSections().With(&print.Settings{
|
||||
OutputValues: true,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("table-OutputValues")
|
||||
assert.Nil(err)
|
||||
|
||||
options := &tfconf.Options{
|
||||
OutputValues: true,
|
||||
OutputValuesPath: "output_values.json",
|
||||
}
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
|
||||
76
internal/pkg/print/markdown/table/testdata/table-OutputValues.golden
vendored
Normal file
76
internal/pkg/print/markdown/table/testdata/table-OutputValues.golden
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
Usage:
|
||||
|
||||
Example of 'foo_bar' module in `foo_bar.tf`.
|
||||
|
||||
- list item 1
|
||||
- list item 2
|
||||
|
||||
Even inline **formatting** in _here_ is possible.
|
||||
and some [link](https://domain.com/)
|
||||
|
||||
* list item 3
|
||||
* list item 4
|
||||
|
||||
```hcl
|
||||
module "foo_bar" {
|
||||
source = "github.com/foo/bar"
|
||||
|
||||
id = "1234567890"
|
||||
name = "baz"
|
||||
|
||||
zones = ["us-east-1", "us-west-1"]
|
||||
|
||||
tags = {
|
||||
Name = "baz"
|
||||
Created-By = "first.last@email.com"
|
||||
Date-Created = "20180101"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Here is some trailing text after code block,
|
||||
followed by another line of text.
|
||||
|
||||
| Name | Description |
|
||||
|------|-----------------|
|
||||
| Foo | Foo description |
|
||||
| Bar | Bar description |
|
||||
|
||||
## Providers
|
||||
|
||||
| Name | Version |
|
||||
|------|---------|
|
||||
| tls | n/a |
|
||||
| aws | >= 2.15.0 |
|
||||
| aws.ident | >= 2.15.0 |
|
||||
| null | n/a |
|
||||
|
||||
## Inputs
|
||||
|
||||
| Name | Description | Type | Default |
|
||||
|------|-------------|------|---------|
|
||||
| unquoted | n/a | `any` | n/a |
|
||||
| string-3 | n/a | `string` | `""` |
|
||||
| string-2 | It's string number two. | `string` | n/a |
|
||||
| string-1 | It's string number one. | `string` | `"bar"` |
|
||||
| map-3 | n/a | `map` | `{}` |
|
||||
| map-2 | It's map number two. | `map` | n/a |
|
||||
| map-1 | It's map number one. | `map` | <pre>{<br> "a": 1,<br> "b": 2,<br> "c": 3<br>}</pre> |
|
||||
| list-3 | n/a | `list` | `[]` |
|
||||
| list-2 | It's list number two. | `list` | n/a |
|
||||
| list-1 | It's list number one. | `list` | <pre>[<br> "a",<br> "b",<br> "c"<br>]</pre> |
|
||||
| input_with_underscores | A variable with underscores. | `any` | n/a |
|
||||
| input-with-pipe | It includes v1 \| v2 \| v3 | `string` | `"v1"` |
|
||||
| input-with-code-block | This is a complicated one. We need a newline.<br>And an example in a code block<pre>default = [<br> "machine rack01:neptune"<br>]</pre> | `list` | <pre>[<br> "name rack:location"<br>]</pre> |
|
||||
| long_type | This description is itself markdown.<br><br>It spans over multiple lines. | <pre>object({<br> name = string,<br> foo = object({ foo = string, bar = string }),<br> bar = object({ foo = string, bar = string }),<br> fizz = list(string),<br> buzz = list(string)<br> })</pre> | <pre>{<br> "bar": {<br> "bar": "bar",<br> "foo": "bar"<br> },<br> "buzz": [<br> "fizz",<br> "buzz"<br> ],<br> "fizz": [],<br> "foo": {<br> "bar": "foo",<br> "foo": "foo"<br> },<br> "name": "hello"<br>}</pre> |
|
||||
| no-escape-default-value | The description contains `something_with_underscore`. Defaults to 'VALUE_WITH_UNDERSCORE'. | `string` | `"VALUE_WITH_UNDERSCORE"` |
|
||||
| with-url | The description contains url. https://www.domain.com/foo/bar_baz.html | `string` | `""` |
|
||||
|
||||
## Outputs
|
||||
|
||||
| Name | Description | Value |
|
||||
|------|-------------|-------|
|
||||
| unquoted | It's unquoted output. | map["leon":"cat"] |
|
||||
| output-2 | It's output number two. | ["jack" "lola"] |
|
||||
| output-1 | It's output number one. | 1 |
|
||||
| output-0.12 | terraform 0.12 only | "" |
|
||||
@@ -52,7 +52,11 @@ const (
|
||||
{{- printf "\n" -}}
|
||||
{{- range . }}
|
||||
{{ printf "output.%s" .Name | colorize "\033[36m" }}
|
||||
{{ tostring .Description | trimSuffix "\n" | default "n/a" | colorize "\033[90m" }}
|
||||
{{- if $.Settings.OutputValues -}}
|
||||
{{- printf " " -}}
|
||||
({{ sanitizeInterface .Value }})
|
||||
{{- end }}
|
||||
{{ tostring .Description | trimSuffix "\n" | default "n/a" | colorize "\033[90m" }}
|
||||
{{ end }}
|
||||
{{ end -}}
|
||||
{{ end -}}
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
|
||||
"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/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
@@ -12,7 +13,10 @@ func TestPretty(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
settings := testutil.Settings().WithSections().WithColor().Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("pretty")
|
||||
expected, err := testutil.GetExpected("pretty")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
@@ -27,7 +31,10 @@ func TestPrettySortByName(t *testing.T) {
|
||||
SortByName: true,
|
||||
}).Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("pretty-SortByName")
|
||||
expected, err := testutil.GetExpected("pretty-SortByName")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
@@ -43,7 +50,10 @@ func TestPrettySortByRequired(t *testing.T) {
|
||||
SortByRequired: true,
|
||||
}).Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("pretty-SortByRequired")
|
||||
expected, err := testutil.GetExpected("pretty-SortByRequired")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
@@ -61,7 +71,10 @@ func TestPrettyNoHeader(t *testing.T) {
|
||||
ShowOutputs: true,
|
||||
}).Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("pretty-NoHeader")
|
||||
expected, err := testutil.GetExpected("pretty-NoHeader")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
@@ -79,7 +92,10 @@ func TestPrettyNoProviders(t *testing.T) {
|
||||
ShowOutputs: true,
|
||||
}).Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("pretty-NoProviders")
|
||||
expected, err := testutil.GetExpected("pretty-NoProviders")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
@@ -97,7 +113,10 @@ func TestPrettyNoInputs(t *testing.T) {
|
||||
ShowOutputs: true,
|
||||
}).Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("pretty-NoInputs")
|
||||
expected, err := testutil.GetExpected("pretty-NoInputs")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
@@ -115,7 +134,10 @@ func TestPrettyNoOutputs(t *testing.T) {
|
||||
ShowOutputs: false,
|
||||
}).Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("pretty-NoOutputs")
|
||||
expected, err := testutil.GetExpected("pretty-NoOutputs")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
@@ -133,7 +155,10 @@ func TestPrettyOnlyHeader(t *testing.T) {
|
||||
ShowOutputs: false,
|
||||
}).Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("pretty-OnlyHeader")
|
||||
expected, err := testutil.GetExpected("pretty-OnlyHeader")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
@@ -151,7 +176,10 @@ func TestPrettyOnlyProviders(t *testing.T) {
|
||||
ShowOutputs: false,
|
||||
}).Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("pretty-OnlyProviders")
|
||||
expected, err := testutil.GetExpected("pretty-OnlyProviders")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
@@ -169,7 +197,10 @@ func TestPrettyOnlyInputs(t *testing.T) {
|
||||
ShowOutputs: false,
|
||||
}).Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("pretty-OnlyInputs")
|
||||
expected, err := testutil.GetExpected("pretty-OnlyInputs")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
@@ -187,7 +218,10 @@ func TestPrettyOnlyOutputs(t *testing.T) {
|
||||
ShowOutputs: true,
|
||||
}).Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("pretty-OnlyOutputs")
|
||||
expected, err := testutil.GetExpected("pretty-OnlyOutputs")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
@@ -202,7 +236,32 @@ func TestPrettyNoColor(t *testing.T) {
|
||||
ShowColor: false,
|
||||
}).Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("pretty-NoColor")
|
||||
expected, err := testutil.GetExpected("pretty-NoColor")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
}
|
||||
|
||||
func TestPrettyOutputValues(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
settings := testutil.Settings().WithSections().WithColor().With(&print.Settings{
|
||||
OutputValues: true,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("pretty-OutputValues")
|
||||
assert.Nil(err)
|
||||
|
||||
options := &tfconf.Options{
|
||||
OutputValues: true,
|
||||
OutputValuesPath: "output_values.json",
|
||||
}
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
|
||||
147
internal/pkg/print/pretty/testdata/pretty-OutputValues.golden
vendored
Normal file
147
internal/pkg/print/pretty/testdata/pretty-OutputValues.golden
vendored
Normal file
@@ -0,0 +1,147 @@
|
||||
|
||||
|
||||
[90mUsage:
|
||||
|
||||
Example of 'foo_bar' module in `foo_bar.tf`.
|
||||
|
||||
- list item 1
|
||||
- list item 2
|
||||
|
||||
Even inline **formatting** in _here_ is possible.
|
||||
and some [link](https://domain.com/)
|
||||
|
||||
* list item 3
|
||||
* list item 4
|
||||
|
||||
```hcl
|
||||
module "foo_bar" {
|
||||
source = "github.com/foo/bar"
|
||||
|
||||
id = "1234567890"
|
||||
name = "baz"
|
||||
|
||||
zones = ["us-east-1", "us-west-1"]
|
||||
|
||||
tags = {
|
||||
Name = "baz"
|
||||
Created-By = "first.last@email.com"
|
||||
Date-Created = "20180101"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Here is some trailing text after code block,
|
||||
followed by another line of text.
|
||||
|
||||
| Name | Description |
|
||||
|------|-----------------|
|
||||
| Foo | Foo description |
|
||||
| Bar | Bar description |[0m
|
||||
|
||||
|
||||
|
||||
[36mprovider.tls[0m
|
||||
|
||||
[36mprovider.aws[0m (>= 2.15.0)
|
||||
|
||||
[36mprovider.aws.ident[0m (>= 2.15.0)
|
||||
|
||||
[36mprovider.null[0m
|
||||
|
||||
|
||||
|
||||
[36minput.unquoted[0m (required)
|
||||
[90mn/a[0m
|
||||
|
||||
[36minput.string-3[0m ("")
|
||||
[90mn/a[0m
|
||||
|
||||
[36minput.string-2[0m (required)
|
||||
[90mIt's string number two.[0m
|
||||
|
||||
[36minput.string-1[0m ("bar")
|
||||
[90mIt's string number one.[0m
|
||||
|
||||
[36minput.map-3[0m ({})
|
||||
[90mn/a[0m
|
||||
|
||||
[36minput.map-2[0m (required)
|
||||
[90mIt's map number two.[0m
|
||||
|
||||
[36minput.map-1[0m ({
|
||||
"a": 1,
|
||||
"b": 2,
|
||||
"c": 3
|
||||
})
|
||||
[90mIt's map number one.[0m
|
||||
|
||||
[36minput.list-3[0m ([])
|
||||
[90mn/a[0m
|
||||
|
||||
[36minput.list-2[0m (required)
|
||||
[90mIt's list number two.[0m
|
||||
|
||||
[36minput.list-1[0m ([
|
||||
"a",
|
||||
"b",
|
||||
"c"
|
||||
])
|
||||
[90mIt's list number one.[0m
|
||||
|
||||
[36minput.input_with_underscores[0m (required)
|
||||
[90mA variable with underscores.[0m
|
||||
|
||||
[36minput.input-with-pipe[0m ("v1")
|
||||
[90mIt includes v1 | v2 | v3[0m
|
||||
|
||||
[36minput.input-with-code-block[0m ([
|
||||
"name rack:location"
|
||||
])
|
||||
[90mThis is a complicated one. We need a newline.
|
||||
And an example in a code block
|
||||
```
|
||||
default = [
|
||||
"machine rack01:neptune"
|
||||
]
|
||||
```[0m
|
||||
|
||||
[36minput.long_type[0m ({
|
||||
"bar": {
|
||||
"bar": "bar",
|
||||
"foo": "bar"
|
||||
},
|
||||
"buzz": [
|
||||
"fizz",
|
||||
"buzz"
|
||||
],
|
||||
"fizz": [],
|
||||
"foo": {
|
||||
"bar": "foo",
|
||||
"foo": "foo"
|
||||
},
|
||||
"name": "hello"
|
||||
})
|
||||
[90mThis description is itself markdown.
|
||||
|
||||
It spans over multiple lines.[0m
|
||||
|
||||
[36minput.no-escape-default-value[0m ("VALUE_WITH_UNDERSCORE")
|
||||
[90mThe description contains `something_with_underscore`. Defaults to 'VALUE_WITH_UNDERSCORE'.[0m
|
||||
|
||||
[36minput.with-url[0m ("")
|
||||
[90mThe description contains url. https://www.domain.com/foo/bar_baz.html[0m
|
||||
|
||||
|
||||
|
||||
[36moutput.unquoted[0m (map["leon":"cat"])
|
||||
[90mIt's unquoted output.[0m
|
||||
|
||||
[36moutput.output-2[0m (["jack" "lola"])
|
||||
[90mIt's output number two.[0m
|
||||
|
||||
[36moutput.output-1[0m (1)
|
||||
[90mIt's output number one.[0m
|
||||
|
||||
[36moutput.output-0.12[0m ("")
|
||||
[90mterraform 0.12 only[0m
|
||||
|
||||
@@ -14,6 +14,10 @@ type Settings struct {
|
||||
// scope: Markdown
|
||||
MarkdownIndent int
|
||||
|
||||
// OutputValues ailrghaekrgj
|
||||
// scope: Global
|
||||
OutputValues bool
|
||||
|
||||
// ShowColor print "colorized" version of result in the terminal (default: true)
|
||||
// scope: Pretty
|
||||
ShowColor bool
|
||||
@@ -53,6 +57,7 @@ func NewSettings() *Settings {
|
||||
EscapeCharacters: true,
|
||||
EscapePipe: true,
|
||||
MarkdownIndent: 2,
|
||||
OutputValues: false,
|
||||
ShowColor: true,
|
||||
ShowHeader: true,
|
||||
ShowInputs: true,
|
||||
|
||||
161
internal/pkg/print/yaml/testdata/yaml-OutputValues.golden
vendored
Normal file
161
internal/pkg/print/yaml/testdata/yaml-OutputValues.golden
vendored
Normal file
@@ -0,0 +1,161 @@
|
||||
header: |-
|
||||
Usage:
|
||||
|
||||
Example of 'foo_bar' module in `foo_bar.tf`.
|
||||
|
||||
- list item 1
|
||||
- list item 2
|
||||
|
||||
Even inline **formatting** in _here_ is possible.
|
||||
and some [link](https://domain.com/)
|
||||
|
||||
* list item 3
|
||||
* list item 4
|
||||
|
||||
```hcl
|
||||
module "foo_bar" {
|
||||
source = "github.com/foo/bar"
|
||||
|
||||
id = "1234567890"
|
||||
name = "baz"
|
||||
|
||||
zones = ["us-east-1", "us-west-1"]
|
||||
|
||||
tags = {
|
||||
Name = "baz"
|
||||
Created-By = "first.last@email.com"
|
||||
Date-Created = "20180101"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Here is some trailing text after code block,
|
||||
followed by another line of text.
|
||||
|
||||
| Name | Description |
|
||||
|------|-----------------|
|
||||
| Foo | Foo description |
|
||||
| Bar | Bar description |
|
||||
inputs:
|
||||
- name: unquoted
|
||||
type: any
|
||||
description: ""
|
||||
default: null
|
||||
- name: string-3
|
||||
type: string
|
||||
description: ""
|
||||
default: ""
|
||||
- name: string-2
|
||||
type: string
|
||||
description: It's string number two.
|
||||
default: null
|
||||
- name: string-1
|
||||
type: string
|
||||
description: It's string number one.
|
||||
default: bar
|
||||
- name: map-3
|
||||
type: map
|
||||
description: ""
|
||||
default: {}
|
||||
- name: map-2
|
||||
type: map
|
||||
description: It's map number two.
|
||||
default: null
|
||||
- name: map-1
|
||||
type: map
|
||||
description: It's map number one.
|
||||
default:
|
||||
a: 1
|
||||
b: 2
|
||||
c: 3
|
||||
- name: list-3
|
||||
type: list
|
||||
description: ""
|
||||
default: []
|
||||
- name: list-2
|
||||
type: list
|
||||
description: It's list number two.
|
||||
default: null
|
||||
- name: list-1
|
||||
type: list
|
||||
description: It's list number one.
|
||||
default:
|
||||
- a
|
||||
- b
|
||||
- c
|
||||
- name: input_with_underscores
|
||||
type: any
|
||||
description: A variable with underscores.
|
||||
default: null
|
||||
- name: input-with-pipe
|
||||
type: string
|
||||
description: It includes v1 | v2 | v3
|
||||
default: v1
|
||||
- name: input-with-code-block
|
||||
type: list
|
||||
description: "This is a complicated one. We need a newline. \nAnd an example in
|
||||
a code block\n```\ndefault = [\n \"machine rack01:neptune\"\n]\n```\n"
|
||||
default:
|
||||
- name rack:location
|
||||
- name: long_type
|
||||
type: |-
|
||||
object({
|
||||
name = string,
|
||||
foo = object({ foo = string, bar = string }),
|
||||
bar = object({ foo = string, bar = string }),
|
||||
fizz = list(string),
|
||||
buzz = list(string)
|
||||
})
|
||||
description: |
|
||||
This description is itself markdown.
|
||||
|
||||
It spans over multiple lines.
|
||||
default:
|
||||
bar:
|
||||
bar: bar
|
||||
foo: bar
|
||||
buzz:
|
||||
- fizz
|
||||
- buzz
|
||||
fizz: []
|
||||
foo:
|
||||
bar: foo
|
||||
foo: foo
|
||||
name: hello
|
||||
- name: no-escape-default-value
|
||||
type: string
|
||||
description: The description contains `something_with_underscore`. Defaults to 'VALUE_WITH_UNDERSCORE'.
|
||||
default: VALUE_WITH_UNDERSCORE
|
||||
- name: with-url
|
||||
type: string
|
||||
description: The description contains url. https://www.domain.com/foo/bar_baz.html
|
||||
default: ""
|
||||
outputs:
|
||||
- name: unquoted
|
||||
description: It's unquoted output.
|
||||
value:
|
||||
leon: cat
|
||||
- name: output-2
|
||||
description: It's output number two.
|
||||
value:
|
||||
- jack
|
||||
- lola
|
||||
- name: output-1
|
||||
description: It's output number one.
|
||||
value: 1
|
||||
- name: output-0.12
|
||||
description: terraform 0.12 only
|
||||
value: ""
|
||||
providers:
|
||||
- name: tls
|
||||
alias: ""
|
||||
version: ""
|
||||
- name: aws
|
||||
alias: ""
|
||||
version: '>= 2.15.0'
|
||||
- name: aws
|
||||
alias: ident
|
||||
version: '>= 2.15.0'
|
||||
- name: "null"
|
||||
alias: ""
|
||||
version: ""
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
|
||||
"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/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
@@ -12,7 +13,10 @@ func TestYaml(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
settings := testutil.Settings().WithSections().Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("yaml")
|
||||
expected, err := testutil.GetExpected("yaml")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
@@ -27,7 +31,10 @@ func TestYamlSortByName(t *testing.T) {
|
||||
SortByName: true,
|
||||
}).Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("yaml-SortByName")
|
||||
expected, err := testutil.GetExpected("yaml-SortByName")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
@@ -43,7 +50,10 @@ func TestYamlSortByRequired(t *testing.T) {
|
||||
SortByRequired: true,
|
||||
}).Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("yaml-SortByRequired")
|
||||
expected, err := testutil.GetExpected("yaml-SortByRequired")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
@@ -61,7 +71,10 @@ func TestYamlNoHeader(t *testing.T) {
|
||||
ShowOutputs: true,
|
||||
}).Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("yaml-NoHeader")
|
||||
expected, err := testutil.GetExpected("yaml-NoHeader")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
@@ -79,7 +92,10 @@ func TestYamlNoProviders(t *testing.T) {
|
||||
ShowOutputs: true,
|
||||
}).Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("yaml-NoProviders")
|
||||
expected, err := testutil.GetExpected("yaml-NoProviders")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
@@ -97,7 +113,10 @@ func TestYamlNoInputs(t *testing.T) {
|
||||
ShowOutputs: true,
|
||||
}).Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("yaml-NoInputs")
|
||||
expected, err := testutil.GetExpected("yaml-NoInputs")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
@@ -115,7 +134,10 @@ func TestYamlNoOutputs(t *testing.T) {
|
||||
ShowOutputs: false,
|
||||
}).Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("yaml-NoOutputs")
|
||||
expected, err := testutil.GetExpected("yaml-NoOutputs")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
@@ -133,7 +155,10 @@ func TestYamlOnlyHeader(t *testing.T) {
|
||||
ShowOutputs: false,
|
||||
}).Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("yaml-OnlyHeader")
|
||||
expected, err := testutil.GetExpected("yaml-OnlyHeader")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
@@ -151,7 +176,10 @@ func TestYamlOnlyProviders(t *testing.T) {
|
||||
ShowOutputs: false,
|
||||
}).Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("yaml-OnlyProviders")
|
||||
expected, err := testutil.GetExpected("yaml-OnlyProviders")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
@@ -169,7 +197,10 @@ func TestYamlOnlyInputs(t *testing.T) {
|
||||
ShowOutputs: false,
|
||||
}).Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("yaml-OnlyInputs")
|
||||
expected, err := testutil.GetExpected("yaml-OnlyInputs")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
@@ -187,7 +218,32 @@ func TestYamlOnlyOutputs(t *testing.T) {
|
||||
ShowOutputs: true,
|
||||
}).Build()
|
||||
|
||||
module, expected, err := testutil.GetExpected("yaml-OnlyOutputs")
|
||||
expected, err := testutil.GetExpected("yaml-OnlyOutputs")
|
||||
assert.Nil(err)
|
||||
|
||||
module, err := testutil.GetModule(new(tfconf.Options))
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
|
||||
assert.Nil(err)
|
||||
assert.Equal(expected, actual)
|
||||
}
|
||||
|
||||
func TestYamlOutputValues(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
settings := testutil.Settings().WithSections().With(&print.Settings{
|
||||
OutputValues: true,
|
||||
}).Build()
|
||||
|
||||
expected, err := testutil.GetExpected("yaml-OutputValues")
|
||||
assert.Nil(err)
|
||||
|
||||
options := &tfconf.Options{
|
||||
OutputValues: true,
|
||||
OutputValuesPath: "output_values.json",
|
||||
}
|
||||
module, err := testutil.GetModule(options)
|
||||
assert.Nil(err)
|
||||
|
||||
actual, err := Print(module, settings)
|
||||
|
||||
@@ -9,23 +9,33 @@ import (
|
||||
"github.com/segmentio/terraform-docs/internal/pkg/tfconf"
|
||||
)
|
||||
|
||||
// GetExpected returns 'example' Module and expected Golden file content
|
||||
func GetExpected(goldenFile string) (*tfconf.Module, string, error) {
|
||||
// GetModule returns what is generated by the test params
|
||||
func GetModule(options *tfconf.Options) (*tfconf.Module, error) {
|
||||
path, err := getExampleFolder()
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
return nil, err
|
||||
}
|
||||
options := &tfconf.Options{
|
||||
Path: path,
|
||||
options.Path = path
|
||||
|
||||
if options.OutputValues {
|
||||
options.OutputValuesPath = filepath.Join(path, options.OutputValuesPath)
|
||||
}
|
||||
|
||||
module, err := tfconf.CreateModule(options)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
return nil, err
|
||||
}
|
||||
return module, err
|
||||
}
|
||||
|
||||
expected, err := readGoldenFile(goldenFile)
|
||||
|
||||
return module, expected, err
|
||||
// GetExpected returns 'example' Module and expected Golden file content
|
||||
func GetExpected(name string) (string, error) {
|
||||
path := filepath.Join(testDataPath(), name+".golden")
|
||||
bytes, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(bytes), nil
|
||||
}
|
||||
|
||||
func getExampleFolder() (string, error) {
|
||||
@@ -37,15 +47,6 @@ func getExampleFolder() (string, error) {
|
||||
return path, nil
|
||||
}
|
||||
|
||||
func readGoldenFile(name string) (string, error) {
|
||||
path := filepath.Join(testDataPath(), name+".golden")
|
||||
bytes, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(bytes), nil
|
||||
}
|
||||
|
||||
func testDataPath() string {
|
||||
return filepath.Join("testdata")
|
||||
}
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
package tfconf
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os/exec"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
@@ -22,8 +25,6 @@ type Module struct {
|
||||
Providers []*Provider `json:"providers" yaml:"providers"`
|
||||
RequiredInputs []*Input `json:"-" yaml:"-"`
|
||||
OptionalInputs []*Input `json:"-" yaml:"-"`
|
||||
|
||||
options *Options
|
||||
}
|
||||
|
||||
// HasInputs indicates if the document has inputs.
|
||||
@@ -68,7 +69,7 @@ func (m *Module) Sort(settings *print.Settings) {
|
||||
}
|
||||
|
||||
// CreateModule returns new instance of Module with all the inputs and
|
||||
// outputs dircoverd from provided 'path' containing Terraform config
|
||||
// outputs discovered from provided 'path' containing Terraform config
|
||||
func CreateModule(options *Options) (*Module, error) {
|
||||
mod := loadModule(options.Path)
|
||||
|
||||
@@ -122,20 +123,34 @@ func CreateModule(options *Options) (*Module, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// output module
|
||||
var outputs = make([]*Output, 0, len(mod.Outputs))
|
||||
for _, output := range mod.Outputs {
|
||||
outputDescription := output.Description
|
||||
for _, o := range mod.Outputs {
|
||||
outputDescription := o.Description
|
||||
if outputDescription == "" {
|
||||
outputDescription = readComment(output.Pos.Filename, output.Pos.Line-1)
|
||||
outputDescription = readComment(o.Pos.Filename, o.Pos.Line-1)
|
||||
}
|
||||
outputs = append(outputs, &Output{
|
||||
Name: output.Name,
|
||||
output := &Output{
|
||||
Name: o.Name,
|
||||
Description: String(outputDescription),
|
||||
Position: Position{
|
||||
Filename: output.Pos.Filename,
|
||||
Line: output.Pos.Line,
|
||||
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)
|
||||
@@ -151,8 +166,6 @@ func CreateModule(options *Options) (*Module, error) {
|
||||
Providers: providers,
|
||||
RequiredInputs: requiredInputs,
|
||||
OptionalInputs: optionalInputs,
|
||||
|
||||
options: options,
|
||||
}
|
||||
return module, nil
|
||||
}
|
||||
@@ -187,3 +200,27 @@ func loadProviders(requiredProviders map[string]*tfconfig.ProviderRequirement, r
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
@@ -2,5 +2,7 @@ package tfconf
|
||||
|
||||
// Options contains required options to load a Module from path
|
||||
type Options struct {
|
||||
Path string
|
||||
Path string
|
||||
OutputValues bool
|
||||
OutputValuesPath string
|
||||
}
|
||||
|
||||
@@ -2,9 +2,10 @@ package tfconf
|
||||
|
||||
// Output represents a Terraform output.
|
||||
type Output struct {
|
||||
Name string `json:"name" yaml:"name"`
|
||||
Description String `json:"description" yaml:"description"`
|
||||
Position Position `json:"-" yaml:"-"`
|
||||
Name string `json:"name" yaml:"name"`
|
||||
Description String `json:"description" yaml:"description"`
|
||||
Value interface{} `json:"value,omitempty" yaml:"value,omitempty"`
|
||||
Position Position `json:"-" yaml:"-"`
|
||||
}
|
||||
|
||||
type outputsSortedByName []*Output
|
||||
@@ -34,3 +35,10 @@ func (a outputsSortedByPosition) Swap(i, j int) {
|
||||
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
|
||||
}
|
||||
|
||||
// TerraformOutput is used for unmarshalling `terraform outputs --json` into
|
||||
type TerraformOutput struct {
|
||||
Sensitive bool `json:"sensitive"`
|
||||
Type interface{} `json:"type"`
|
||||
Value interface{} `json:"value"`
|
||||
}
|
||||
|
||||
@@ -160,6 +160,24 @@ func builtinFuncs(settings *print.Settings) map[string]interface{} {
|
||||
"sanitizeTbl": func(s string) string {
|
||||
return markdown.SanitizeItemForTable(s, settings)
|
||||
},
|
||||
"sanitizeInterface": func(i interface{}) string {
|
||||
var v string
|
||||
switch x := fmt.Sprintf("%T", i); x {
|
||||
case "[]interface {}":
|
||||
v = fmt.Sprintf("%q", i)
|
||||
case "map[string]interface {}":
|
||||
v = fmt.Sprintf("%q", i)
|
||||
case "float64":
|
||||
v = fmt.Sprintf("%g", i)
|
||||
case "int":
|
||||
v = fmt.Sprintf("%d", i)
|
||||
case "string":
|
||||
v = fmt.Sprintf("%#v", i)
|
||||
case "bool":
|
||||
v = fmt.Sprintf("%t", i)
|
||||
}
|
||||
return v
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user