diff --git a/examples/variables.tf b/examples/variables.tf index 37bf358..dd84249 100644 --- a/examples/variables.tf +++ b/examples/variables.tf @@ -51,3 +51,9 @@ variable "list-1" { // A variable with underscores. variable "input_with_underscores" {} + +// A variable with pipe in the description +variable "input-with-pipe" { + description = "It includes v1 | v2 | v3" + default = "v1" +} diff --git a/internal/pkg/doc/doc_test.go b/internal/pkg/doc/doc_test.go index 0ca7255..e7c21d7 100644 --- a/internal/pkg/doc/doc_test.go +++ b/internal/pkg/doc/doc_test.go @@ -110,6 +110,16 @@ var inputWithUnderscores = doc.Input{ Default: nil, } +var inputWithPipe = doc.Input{ + Name: "input-with-pipe", + Description: "It includes v1 | v2 | v3", + Default: &doc.Value{ + Type: "string", + Value: "v1", + }, + Type: "string", +} + var output1 = doc.Output{ Name: "output-1", Description: "It's output number one.", @@ -204,6 +214,7 @@ func TestInputs(t *testing.T) { inputList2, inputList1, inputWithUnderscores, + inputWithPipe, } assert.Equal(t, expected, actual) @@ -234,6 +245,7 @@ func TestInputsFromVariablesTf(t *testing.T) { inputList2, inputList1, inputWithUnderscores, + inputWithPipe, } assert.Equal(t, expected, actual) @@ -245,6 +257,7 @@ func TestInputsSortedByName(t *testing.T) { doc.SortInputsByName(actual) expected := []doc.Input{ + inputWithPipe, inputWithUnderscores, inputList1, inputList2, @@ -272,6 +285,7 @@ func TestInputsSortedByRequired(t *testing.T) { inputMap2, inputString2, inputUnquoted, + inputWithPipe, inputList1, inputList3, inputMap1, diff --git a/internal/pkg/print/json/testdata/json-WithSortByName.golden b/internal/pkg/print/json/testdata/json-WithSortByName.golden index 5dc7898..9015d1f 100644 --- a/internal/pkg/print/json/testdata/json-WithSortByName.golden +++ b/internal/pkg/print/json/testdata/json-WithSortByName.golden @@ -1,6 +1,15 @@ { "Comment": "Usage:\n\nmodule \"foo\" {\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", "Inputs": [ + { + "Name": "input-with-pipe", + "Description": "It includes v1 | v2 | v3", + "Default": { + "Type": "string", + "Value": "v1" + }, + "Type": "string" + }, { "Name": "input_with_underscores", "Description": "A variable with underscores.", diff --git a/internal/pkg/print/json/testdata/json-WithSortInputsByRequired.golden b/internal/pkg/print/json/testdata/json-WithSortInputsByRequired.golden index 79ad2e5..018e8bc 100644 --- a/internal/pkg/print/json/testdata/json-WithSortInputsByRequired.golden +++ b/internal/pkg/print/json/testdata/json-WithSortInputsByRequired.golden @@ -31,6 +31,15 @@ "Default": null, "Type": "string" }, + { + "Name": "input-with-pipe", + "Description": "It includes v1 | v2 | v3", + "Default": { + "Type": "string", + "Value": "v1" + }, + "Type": "string" + }, { "Name": "list-1", "Description": "It's list number one.", diff --git a/internal/pkg/print/json/testdata/json.golden b/internal/pkg/print/json/testdata/json.golden index fb320b5..c477e2e 100644 --- a/internal/pkg/print/json/testdata/json.golden +++ b/internal/pkg/print/json/testdata/json.golden @@ -92,6 +92,15 @@ "Description": "A variable with underscores.", "Default": null, "Type": "string" + }, + { + "Name": "input-with-pipe", + "Description": "It includes v1 | v2 | v3", + "Default": { + "Type": "string", + "Value": "v1" + }, + "Type": "string" } ], "Outputs": [ diff --git a/internal/pkg/print/markdown/document/document.go b/internal/pkg/print/markdown/document/document.go index cc1b528..e7a1c21 100644 --- a/internal/pkg/print/markdown/document/document.go +++ b/internal/pkg/print/markdown/document/document.go @@ -77,7 +77,7 @@ func printFencedCodeBlock(code string) string { func printInput(buffer *bytes.Buffer, input doc.Input, settings settings.Settings) { buffer.WriteString("\n") buffer.WriteString(fmt.Sprintf("### %s\n\n", strings.Replace(input.Name, "_", "\\_", -1))) - buffer.WriteString(fmt.Sprintf("Description: %s\n\n", markdown.ConvertMultiLineText(input.Description))) + buffer.WriteString(fmt.Sprintf("Description: %s\n\n", markdown.SanitizeDescription(input.Description))) buffer.WriteString(fmt.Sprintf("Type: `%s`\n", input.Type)) // Don't print defaults for required inputs when we're already explicit about it being required @@ -123,6 +123,6 @@ func printOutputs(buffer *bytes.Buffer, outputs []doc.Output, settings settings. for _, output := range outputs { buffer.WriteString("\n") buffer.WriteString(fmt.Sprintf("### %s\n\n", strings.Replace(output.Name, "_", "\\_", -1))) - buffer.WriteString(fmt.Sprintf("Description: %s\n", markdown.ConvertMultiLineText(output.Description))) + buffer.WriteString(fmt.Sprintf("Description: %s\n", markdown.SanitizeDescription(output.Description))) } } diff --git a/internal/pkg/print/markdown/document/testdata/document-WithAggregateTypeDefaults.golden b/internal/pkg/print/markdown/document/testdata/document-WithAggregateTypeDefaults.golden index 820faf5..f28ba35 100644 --- a/internal/pkg/print/markdown/document/testdata/document-WithAggregateTypeDefaults.golden +++ b/internal/pkg/print/markdown/document/testdata/document-WithAggregateTypeDefaults.golden @@ -131,6 +131,14 @@ Type: `string` Default: n/a +### input-with-pipe + +Description: It includes v1 \| v2 \| v3 + +Type: `string` + +Default: `"v1"` + ## Outputs The following outputs are exported: diff --git a/internal/pkg/print/markdown/document/testdata/document-WithRequired.golden b/internal/pkg/print/markdown/document/testdata/document-WithRequired.golden index 9c3b2a2..8fd8b83 100644 --- a/internal/pkg/print/markdown/document/testdata/document-WithRequired.golden +++ b/internal/pkg/print/markdown/document/testdata/document-WithRequired.golden @@ -101,6 +101,14 @@ Type: `list` Default: `` +### input-with-pipe + +Description: It includes v1 \| v2 \| v3 + +Type: `string` + +Default: `"v1"` + ## Outputs The following outputs are exported: diff --git a/internal/pkg/print/markdown/document/testdata/document-WithSortByName.golden b/internal/pkg/print/markdown/document/testdata/document-WithSortByName.golden index a684fd6..c9f2009 100644 --- a/internal/pkg/print/markdown/document/testdata/document-WithSortByName.golden +++ b/internal/pkg/print/markdown/document/testdata/document-WithSortByName.golden @@ -19,6 +19,14 @@ module "foo" { The following input variables are supported: +### input-with-pipe + +Description: It includes v1 \| v2 \| v3 + +Type: `string` + +Default: `"v1"` + ### input\_with\_underscores Description: A variable with underscores. diff --git a/internal/pkg/print/markdown/document/testdata/document-WithSortInputsByRequired.golden b/internal/pkg/print/markdown/document/testdata/document-WithSortInputsByRequired.golden index e672ef7..3d6eae7 100644 --- a/internal/pkg/print/markdown/document/testdata/document-WithSortInputsByRequired.golden +++ b/internal/pkg/print/markdown/document/testdata/document-WithSortInputsByRequired.golden @@ -59,6 +59,14 @@ Type: `string` Default: n/a +### input-with-pipe + +Description: It includes v1 \| v2 \| v3 + +Type: `string` + +Default: `"v1"` + ### list-1 Description: It's list number one. diff --git a/internal/pkg/print/markdown/document/testdata/document.golden b/internal/pkg/print/markdown/document/testdata/document.golden index a21f386..d1d4ddd 100644 --- a/internal/pkg/print/markdown/document/testdata/document.golden +++ b/internal/pkg/print/markdown/document/testdata/document.golden @@ -107,6 +107,14 @@ Type: `string` Default: n/a +### input-with-pipe + +Description: It includes v1 \| v2 \| v3 + +Type: `string` + +Default: `"v1"` + ## Outputs The following outputs are exported: diff --git a/internal/pkg/print/markdown/markdown.go b/internal/pkg/print/markdown/markdown.go index 856e8c1..b4a4d3b 100644 --- a/internal/pkg/print/markdown/markdown.go +++ b/internal/pkg/print/markdown/markdown.go @@ -5,6 +5,14 @@ import ( "strings" ) +// SanitizeDescription converts description to suitable Markdown representation. (including mline-break, illegal characters, etc) +func SanitizeDescription(s string) string { + s = ConvertMultiLineText(s) + s = EscapeIllegalCharacters(s) + + return s +} + // ConvertMultiLineText converts a multi-line text into a suitable Markdown representation. func ConvertMultiLineText(s string) string { // Convert double newlines to

. @@ -18,6 +26,17 @@ func ConvertMultiLineText(s string) string { return strings.Replace(s, "\n", " ", -1) } +// EscapeIllegalCharacters escapes characters which have special meaning in Markdown into their corresponding literal. +func EscapeIllegalCharacters(s string) string { + // Escape pipe + s = strings.Replace(s, "|", "\\|", -1) + + // Escape underscore + s = strings.Replace(s, "_", "\\_", -1) + + return s +} + // Sanitize cleans a Markdown document to soothe linters. func Sanitize(markdown string) string { result := markdown diff --git a/internal/pkg/print/markdown/table/table.go b/internal/pkg/print/markdown/table/table.go index a73cfa6..c16f5a3 100644 --- a/internal/pkg/print/markdown/table/table.go +++ b/internal/pkg/print/markdown/table/table.go @@ -82,7 +82,7 @@ func printInputs(buffer *bytes.Buffer, inputs []doc.Input, settings settings.Set buffer.WriteString( fmt.Sprintf("| %s | %s | %s | %s |", strings.Replace(input.Name, "_", "\\_", -1), - markdown.ConvertMultiLineText(input.Description), + markdown.SanitizeDescription(input.Description), input.Type, getInputDefaultValue(&input, settings))) @@ -111,6 +111,6 @@ func printOutputs(buffer *bytes.Buffer, outputs []doc.Output, settings settings. buffer.WriteString( fmt.Sprintf("| %s | %s |\n", strings.Replace(output.Name, "_", "\\_", -1), - markdown.ConvertMultiLineText(output.Description))) + markdown.SanitizeDescription(output.Description))) } } diff --git a/internal/pkg/print/markdown/table/testdata/table-WithAggregateTypeDefaults.golden b/internal/pkg/print/markdown/table/testdata/table-WithAggregateTypeDefaults.golden index 7b297bb..d00b754 100644 --- a/internal/pkg/print/markdown/table/testdata/table-WithAggregateTypeDefaults.golden +++ b/internal/pkg/print/markdown/table/testdata/table-WithAggregateTypeDefaults.golden @@ -30,6 +30,7 @@ module "foo" { | list-2 | It's list number two. | list | n/a | | list-1 | It's list number one. | list | `[ "a", "b", "c" ]` | | input\_with\_underscores | A variable with underscores. | string | n/a | +| input-with-pipe | It includes v1 \| v2 \| v3 | string | `"v1"` | ## Outputs diff --git a/internal/pkg/print/markdown/table/testdata/table-WithRequired.golden b/internal/pkg/print/markdown/table/testdata/table-WithRequired.golden index fbee235..3832eb2 100644 --- a/internal/pkg/print/markdown/table/testdata/table-WithRequired.golden +++ b/internal/pkg/print/markdown/table/testdata/table-WithRequired.golden @@ -30,6 +30,7 @@ module "foo" { | list-2 | It's list number two. | list | n/a | yes | | list-1 | It's list number one. | list | `` | no | | input\_with\_underscores | A variable with underscores. | string | n/a | yes | +| input-with-pipe | It includes v1 \| v2 \| v3 | string | `"v1"` | no | ## Outputs diff --git a/internal/pkg/print/markdown/table/testdata/table-WithSortByName.golden b/internal/pkg/print/markdown/table/testdata/table-WithSortByName.golden index ecb72b7..4a38dc3 100644 --- a/internal/pkg/print/markdown/table/testdata/table-WithSortByName.golden +++ b/internal/pkg/print/markdown/table/testdata/table-WithSortByName.golden @@ -19,6 +19,7 @@ module "foo" { | Name | Description | Type | Default | |------|-------------|:----:|:-----:| +| input-with-pipe | It includes v1 \| v2 \| v3 | string | `"v1"` | | input\_with\_underscores | A variable with underscores. | string | n/a | | list-1 | It's list number one. | list | `` | | list-2 | It's list number two. | list | n/a | diff --git a/internal/pkg/print/markdown/table/testdata/table-WithSortInputsByRequired.golden b/internal/pkg/print/markdown/table/testdata/table-WithSortInputsByRequired.golden index fbc4e9b..bb5f7f3 100644 --- a/internal/pkg/print/markdown/table/testdata/table-WithSortInputsByRequired.golden +++ b/internal/pkg/print/markdown/table/testdata/table-WithSortInputsByRequired.golden @@ -24,6 +24,7 @@ module "foo" { | map-2 | It's map number two. | map | n/a | | string-2 | It's string number two. | string | n/a | | unquoted | | string | n/a | +| input-with-pipe | It includes v1 \| v2 \| v3 | string | `"v1"` | | list-1 | It's list number one. | list | `` | | list-3 | | list | `` | | map-1 | It's map number one. | map | `` | diff --git a/internal/pkg/print/markdown/table/testdata/table.golden b/internal/pkg/print/markdown/table/testdata/table.golden index 32a79b3..9d73f09 100644 --- a/internal/pkg/print/markdown/table/testdata/table.golden +++ b/internal/pkg/print/markdown/table/testdata/table.golden @@ -30,6 +30,7 @@ module "foo" { | list-2 | It's list number two. | list | n/a | | list-1 | It's list number one. | list | `` | | input\_with\_underscores | A variable with underscores. | string | n/a | +| input-with-pipe | It includes v1 \| v2 \| v3 | string | `"v1"` | ## Outputs diff --git a/internal/pkg/print/pretty/pretty_test.go b/internal/pkg/print/pretty/pretty_test.go index 4134936..e163d6c 100644 --- a/internal/pkg/print/pretty/pretty_test.go +++ b/internal/pkg/print/pretty/pretty_test.go @@ -75,6 +75,9 @@ func TestPretty(t *testing.T) { " " + sgr_color_1 + "var.input_with_underscores" + sgr_reset + " (required)\n" + " " + sgr_color_2 + "A variable with underscores." + sgr_reset + "\n" + "\n" + + " " + sgr_color_1 + "var.input-with-pipe" + sgr_reset + " (\"v1\")\n" + + " " + sgr_color_2 + "It includes v1 | v2 | v3" + sgr_reset + "\n" + + "\n" + "\n" + "\n" + " " + sgr_color_1 + "output.unquoted" + sgr_reset + "\n" + @@ -158,6 +161,9 @@ func TestPrettyWithWithAggregateTypeDefaults(t *testing.T) { " " + sgr_color_1 + "var.input_with_underscores" + sgr_reset + " (required)\n" + " " + sgr_color_2 + "A variable with underscores." + sgr_reset + "\n" + "\n" + + " " + sgr_color_1 + "var.input-with-pipe" + sgr_reset + " (\"v1\")\n" + + " " + sgr_color_2 + "It includes v1 | v2 | v3" + sgr_reset + "\n" + + "\n" + "\n" + "\n" + " " + sgr_color_1 + "output.unquoted" + sgr_reset + "\n" + @@ -208,6 +214,9 @@ func TestPrettyWithSortByName(t *testing.T) { "}\n" + "\n" + "\n" + + " " + sgr_color_1 + "var.input-with-pipe" + sgr_reset + " (\"v1\")\n" + + " " + sgr_color_2 + "It includes v1 | v2 | v3" + sgr_reset + "\n" + + "\n" + " " + sgr_color_1 + "var.input_with_underscores" + sgr_reset + " (required)\n" + " " + sgr_color_2 + "A variable with underscores." + sgr_reset + "\n" + "\n" + @@ -307,6 +316,9 @@ func TestPrettyWithSortInputsByRequired(t *testing.T) { " " + sgr_color_1 + "var.unquoted" + sgr_reset + " (required)\n" + " " + sgr_color_2 + "" + sgr_reset + "\n" + "\n" + + " " + sgr_color_1 + "var.input-with-pipe" + sgr_reset + " (\"v1\")\n" + + " " + sgr_color_2 + "It includes v1 | v2 | v3" + sgr_reset + "\n" + + "\n" + " " + sgr_color_1 + "var.list-1" + sgr_reset + " ()\n" + " " + sgr_color_2 + "It's list number one." + sgr_reset + "\n" + "\n" +