Add option --no-sort to omit sorted rendering of inputs and outputs. (#61)

This commit is contained in:
Martin Etmajer
2018-09-23 00:14:45 +02:00
committed by GitHub
parent 853dd8fd63
commit 5584170a2c
21 changed files with 420 additions and 173 deletions

View File

@@ -49,6 +49,7 @@ This project is no longer maintained by Segment. Instead, [Martin Etmajer](https
Options:
-h, --help show help information
--no-required omit "Required" column when generating markdown
--no-sort omit sorted rendering of inputs and ouputs
--version print version
```

View File

@@ -6,7 +6,6 @@ import (
"log"
"path"
"path/filepath"
"sort"
"strconv"
"strings"
@@ -43,18 +42,6 @@ func (d *Doc) HasOutputs() bool {
return len(d.Outputs) > 0
}
type inputsByName []Input
func (a inputsByName) Len() int { return len(a) }
func (a inputsByName) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a inputsByName) Less(i, j int) bool { return a[i].Name < a[j].Name }
type outputsByName []Output
func (a outputsByName) Len() int { return len(a) }
func (a outputsByName) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a outputsByName) Less(i, j int) bool { return a[i].Name < a[j].Name }
// CreateFromPaths creates a new document from a list of file or directory paths.
func CreateFromPaths(paths []string) (*Doc, error) {
names := make([]string, 0)
@@ -110,8 +97,6 @@ func Create(files map[string]*ast.File) *Doc {
}
}
sort.Sort(inputsByName(doc.Inputs))
sort.Sort(outputsByName(doc.Outputs))
return doc
}

View File

@@ -78,34 +78,10 @@ func TestInputs(t *testing.T) {
expected := []doc.Input{
doc.Input{
Name: "list-1",
Description: "It's list number one.",
Default: &doc.Value{
Type: "list",
Literal: "",
},
Type: "list",
},
doc.Input{
Name: "list-2",
Description: "It's list number two.",
Name: "string-2",
Description: "It's string number two.",
Default: nil,
Type: "list",
},
doc.Input{
Name: "map-1",
Description: "It's map number one.",
Default: &doc.Value{
Type: "map",
Literal: "",
},
Type: "map",
},
doc.Input{
Name: "map-2",
Description: "It's map number two.",
Default: nil,
Type: "map",
Type: "string",
},
doc.Input{
Name: "string-1",
@@ -117,10 +93,34 @@ func TestInputs(t *testing.T) {
Type: "string",
},
doc.Input{
Name: "string-2",
Description: "It's string number two.",
Name: "map-2",
Description: "It's map number two.",
Default: nil,
Type: "string",
Type: "map",
},
doc.Input{
Name: "map-1",
Description: "It's map number one.",
Default: &doc.Value{
Type: "map",
Literal: "",
},
Type: "map",
},
doc.Input{
Name: "list-2",
Description: "It's list number two.",
Default: nil,
Type: "list",
},
doc.Input{
Name: "list-1",
Description: "It's list number one.",
Default: &doc.Value{
Type: "list",
Literal: "",
},
Type: "list",
},
}
@@ -142,34 +142,10 @@ func TestInputsFromVariablesTf(t *testing.T) {
expected := []doc.Input{
doc.Input{
Name: "list-1",
Description: "It's list number one.",
Default: &doc.Value{
Type: "list",
Literal: "",
},
Type: "list",
},
doc.Input{
Name: "list-2",
Description: "It's list number two.",
Name: "string-2",
Description: "It's string number two.",
Default: nil,
Type: "list",
},
doc.Input{
Name: "map-1",
Description: "It's map number one.",
Default: &doc.Value{
Type: "map",
Literal: "",
},
Type: "map",
},
doc.Input{
Name: "map-2",
Description: "It's map number two.",
Default: nil,
Type: "map",
Type: "string",
},
doc.Input{
Name: "string-1",
@@ -181,10 +157,34 @@ func TestInputsFromVariablesTf(t *testing.T) {
Type: "string",
},
doc.Input{
Name: "string-2",
Description: "It's string number two.",
Name: "map-2",
Description: "It's map number two.",
Default: nil,
Type: "string",
Type: "map",
},
doc.Input{
Name: "map-1",
Description: "It's map number one.",
Default: &doc.Value{
Type: "map",
Literal: "",
},
Type: "map",
},
doc.Input{
Name: "list-2",
Description: "It's list number two.",
Default: nil,
Type: "list",
},
doc.Input{
Name: "list-1",
Description: "It's list number one.",
Default: &doc.Value{
Type: "list",
Literal: "",
},
Type: "list",
},
}
@@ -195,14 +195,14 @@ func TestOutputs(t *testing.T) {
actual := doc.TestDoc(t, ".").Outputs
expected := []doc.Output{
doc.Output{
Name: "output-1",
Description: "It's output number one.",
},
doc.Output{
Name: "output-2",
Description: "It's output number two.",
},
doc.Output{
Name: "output-1",
Description: "It's output number one.",
},
}
assert.Equal(t, expected, actual)
@@ -217,14 +217,14 @@ func TestOutputsFromOutputsTf(t *testing.T) {
actual := doc.TestDocFromFile(t, ".", "outputs.tf").Outputs
expected := []doc.Output{
doc.Output{
Name: "output-1",
Description: "It's output number one.",
},
doc.Output{
Name: "output-2",
Description: "It's output number two.",
},
doc.Output{
Name: "output-1",
Description: "It's output number one.",
},
}
assert.Equal(t, expected, actual)

View File

@@ -1,6 +1,8 @@
package doc
// Input represents a Terraform input variable.
import "sort"
// Input represents a Terraform input.
type Input struct {
Name string
Description string
@@ -22,3 +24,22 @@ func (i *Input) IsOptional() bool {
func (i *Input) IsRequired() 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
}
// SortInputsByName sorts a list of inputs by name.
func SortInputsByName(inputs []Input) {
sort.Sort(inputsSortedByName(inputs))
}

View File

@@ -1,5 +1,7 @@
package doc
import "sort"
// Output represents a Terraform output.
type Output struct {
Name string
@@ -10,3 +12,22 @@ type Output struct {
func (o *Output) HasDescription() bool {
return o.Description != ""
}
type outputsSortedByName []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
}
// SortOutputsByName sorts a list of outputs by name.
func SortOutputsByName(outputs []Output) {
sort.Sort(outputsSortedByName(outputs))
}

View File

@@ -1,9 +1,9 @@
// It's output number one.
output "output-1" {
value = "1"
}
output "output-2" {
description = "It's output number two."
value = "2"
}
// It's output number one.
output "output-1" {
value = "1"
}

View File

@@ -1,12 +1,16 @@
// It's list number one.
variable "list-1" {
default = ["a", "b", "c"]
type = "list"
variable "string-2" {
description = "It's string number two."
type = "string"
}
variable "list-2" {
description = "It's list number two."
type = "list"
// It's string number one.
variable "string-1" {
default = "bar"
}
variable "map-2" {
description = "It's map number two."
type = "map"
}
// It's map number one.
@@ -19,17 +23,13 @@ variable "map-1" {
type = "map"
}
variable "map-2" {
description = "It's map number two."
type = "map"
variable "list-2" {
description = "It's list number two."
type = "list"
}
// It's string number one.
variable "string-1" {
default = "bar"
}
variable "string-2" {
description = "It's string number two."
type = "string"
// It's list number one.
variable "list-1" {
default = ["a", "b", "c"]
type = "list"
}

View File

@@ -4,6 +4,7 @@ import (
"encoding/json"
"github.com/segmentio/terraform-docs/internal/pkg/doc"
"github.com/segmentio/terraform-docs/internal/pkg/print"
"github.com/segmentio/terraform-docs/internal/pkg/settings"
)
@@ -14,6 +15,18 @@ const (
// Print prints a document as json.
func Print(document *doc.Doc, settings settings.Settings) (string, error) {
if document.HasInputs() {
if settings.Has(print.WithSorting) {
doc.SortInputsByName(document.Inputs)
}
}
if document.HasOutputs() {
if settings.Has(print.WithSorting) {
doc.SortOutputsByName(document.Outputs)
}
}
buffer, err := json.MarshalIndent(document, prefix, indent)
if err != nil {
return "", err

View File

@@ -12,6 +12,7 @@ import (
func TestPrint(t *testing.T) {
doc := doc.TestDoc(t, "..")
var settings settings.Settings
actual, err := json.Print(doc, settings)
@@ -26,3 +27,22 @@ func TestPrint(t *testing.T) {
assert.Equal(t, expected, actual)
}
func TestPrintWithSorting(t *testing.T) {
doc := doc.TestDoc(t, "..")
var settings settings.Settings
settings.Add(print.WithSorting)
actual, err := json.Print(doc, settings)
if err != nil {
t.Fatal(err)
}
expected, err := print.ReadGoldenFile("json-WithSorting")
if err != nil {
t.Fatal(err)
}
assert.Equal(t, expected, actual)
}

View File

@@ -0,0 +1,60 @@
{
"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\n",
"Inputs": [
{
"Name": "list-1",
"Description": "It's list number one.",
"Default": {
"Type": "list",
"Literal": ""
},
"Type": "list"
},
{
"Name": "list-2",
"Description": "It's list number two.",
"Default": null,
"Type": "list"
},
{
"Name": "map-1",
"Description": "It's map number one.",
"Default": {
"Type": "map",
"Literal": ""
},
"Type": "map"
},
{
"Name": "map-2",
"Description": "It's map number two.",
"Default": null,
"Type": "map"
},
{
"Name": "string-1",
"Description": "It's string number one.",
"Default": {
"Type": "string",
"Literal": "bar"
},
"Type": "string"
},
{
"Name": "string-2",
"Description": "It's string number two.",
"Default": null,
"Type": "string"
}
],
"Outputs": [
{
"Name": "output-1",
"Description": "It's output number one."
},
{
"Name": "output-2",
"Description": "It's output number two."
}
]
}

View File

@@ -2,34 +2,10 @@
"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\n",
"Inputs": [
{
"Name": "list-1",
"Description": "It's list number one.",
"Default": {
"Type": "list",
"Literal": ""
},
"Type": "list"
},
{
"Name": "list-2",
"Description": "It's list number two.",
"Name": "string-2",
"Description": "It's string number two.",
"Default": null,
"Type": "list"
},
{
"Name": "map-1",
"Description": "It's map number one.",
"Default": {
"Type": "map",
"Literal": ""
},
"Type": "map"
},
{
"Name": "map-2",
"Description": "It's map number two.",
"Default": null,
"Type": "map"
"Type": "string"
},
{
"Name": "string-1",
@@ -41,20 +17,44 @@
"Type": "string"
},
{
"Name": "string-2",
"Description": "It's string number two.",
"Name": "map-2",
"Description": "It's map number two.",
"Default": null,
"Type": "string"
"Type": "map"
},
{
"Name": "map-1",
"Description": "It's map number one.",
"Default": {
"Type": "map",
"Literal": ""
},
"Type": "map"
},
{
"Name": "list-2",
"Description": "It's list number two.",
"Default": null,
"Type": "list"
},
{
"Name": "list-1",
"Description": "It's list number one.",
"Default": {
"Type": "list",
"Literal": ""
},
"Type": "list"
}
],
"Outputs": [
{
"Name": "output-1",
"Description": "It's output number one."
},
{
"Name": "output-2",
"Description": "It's output number two."
},
{
"Name": "output-1",
"Description": "It's output number one."
}
]
}

View File

@@ -19,10 +19,18 @@ func Print(document *doc.Doc, settings settings.Settings) (string, error) {
}
if document.HasInputs() {
if settings.Has(print.WithSorting) {
doc.SortInputsByName(document.Inputs)
}
printInputs(&buffer, document.Inputs, settings)
}
if document.HasOutputs() {
if settings.Has(print.WithSorting) {
doc.SortOutputsByName(document.Outputs)
}
printOutputs(&buffer, document.Outputs, settings)
}

View File

@@ -45,3 +45,22 @@ func TestPrintWithRequired(t *testing.T) {
assert.Equal(t, expected, actual)
}
func TestPrintWithSorting(t *testing.T) {
doc := doc.TestDoc(t, "..")
var settings settings.Settings
settings.Add(print.WithSorting)
actual, err := markdown.Print(doc, settings)
if err != nil {
t.Fatal(err)
}
expected, err := print.ReadGoldenFile("markdown-WithSorting")
if err != nil {
t.Fatal(err)
}
assert.Equal(t, expected, actual)
}

View File

@@ -21,16 +21,16 @@ module "foo" {
| Name | Description | Type | Default | Required |
|------|-------------|:----:|:-----:|:-----:|
| list-1 | It's list number one. | list | `<list>` | no |
| list-2 | It's list number two. | list | - | yes |
| map-1 | It's map number one. | map | `<map>` | no |
| map-2 | It's map number two. | map | - | yes |
| string-1 | It's string number one. | string | `bar` | no |
| string-2 | It's string number two. | string | - | yes |
| string-1 | It's string number one. | string | `bar` | no |
| map-2 | It's map number two. | map | - | yes |
| map-1 | It's map number one. | map | `<map>` | no |
| list-2 | It's list number two. | list | - | yes |
| list-1 | It's list number one. | list | `<list>` | no |
## Outputs
| Name | Description |
|------|-------------|
| output-1 | It's output number one. |
| output-2 | It's output number two. |
| output-1 | It's output number one. |

View File

@@ -0,0 +1,36 @@
Usage:
module "foo" {
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"
}
}
## Inputs
| Name | Description | Type | Default |
|------|-------------|:----:|:-----:|
| list-1 | It's list number one. | list | `<list>` |
| list-2 | It's list number two. | list | - |
| map-1 | It's map number one. | map | `<map>` |
| map-2 | It's map number two. | map | - |
| string-1 | It's string number one. | string | `bar` |
| string-2 | It's string number two. | string | - |
## Outputs
| Name | Description |
|------|-------------|
| output-1 | It's output number one. |
| output-2 | It's output number two. |

View File

@@ -21,16 +21,16 @@ module "foo" {
| Name | Description | Type | Default |
|------|-------------|:----:|:-----:|
| list-1 | It's list number one. | list | `<list>` |
| list-2 | It's list number two. | list | - |
| map-1 | It's map number one. | map | `<map>` |
| map-2 | It's map number two. | map | - |
| string-1 | It's string number one. | string | `bar` |
| string-2 | It's string number two. | string | - |
| string-1 | It's string number one. | string | `bar` |
| map-2 | It's map number two. | map | - |
| map-1 | It's map number one. | map | `<map>` |
| list-2 | It's list number two. | list | - |
| list-1 | It's list number one. | list | `<list>` |
## Outputs
| Name | Description |
|------|-------------|
| output-1 | It's output number one. |
| output-2 | It's output number two. |
| output-1 | It's output number one. |

View File

@@ -5,6 +5,7 @@ import (
"fmt"
"github.com/segmentio/terraform-docs/internal/pkg/doc"
"github.com/segmentio/terraform-docs/internal/pkg/print"
"github.com/segmentio/terraform-docs/internal/pkg/settings"
)
@@ -17,10 +18,18 @@ func Print(document *doc.Doc, settings settings.Settings) (string, error) {
}
if document.HasInputs() {
if settings.Has(print.WithSorting) {
doc.SortInputsByName(document.Inputs)
}
printInputs(&buffer, document.Inputs, settings)
}
if document.HasOutputs() {
if settings.Has(print.WithSorting) {
doc.SortOutputsByName(document.Outputs)
}
printOutputs(&buffer, document.Outputs, settings)
}

View File

@@ -4,6 +4,7 @@ import (
"testing"
"github.com/segmentio/terraform-docs/internal/pkg/doc"
"github.com/segmentio/terraform-docs/internal/pkg/print"
"github.com/segmentio/terraform-docs/internal/pkg/print/pretty"
"github.com/segmentio/terraform-docs/internal/pkg/settings"
"github.com/stretchr/testify/assert"
@@ -22,6 +23,72 @@ func TestPretty(t *testing.T) {
sgr_color_2 := "\x1b[90m"
sgr_reset := "\x1b[0m"
expected :=
"\nUsage:\n" +
"\n" +
"module \"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" +
"\n" +
"\n" +
"\n" +
" " + sgr_color_1 + "var.string-2" + sgr_reset + " (required)\n" +
" " + sgr_color_2 + "It's string number two." + sgr_reset + "\n" +
"\n" +
" " + sgr_color_1 + "var.string-1" + sgr_reset + " (bar)\n" +
" " + sgr_color_2 + "It's string number one." + sgr_reset + "\n" +
"\n" +
" " + sgr_color_1 + "var.map-2" + sgr_reset + " (required)\n" +
" " + sgr_color_2 + "It's map number two." + sgr_reset + "\n" +
"\n" +
" " + sgr_color_1 + "var.map-1" + sgr_reset + " (<map>)\n" +
" " + sgr_color_2 + "It's map number one." + sgr_reset + "\n" +
"\n" +
" " + sgr_color_1 + "var.list-2" + sgr_reset + " (required)\n" +
" " + sgr_color_2 + "It's list number two." + sgr_reset + "\n" +
"\n" +
" " + sgr_color_1 + "var.list-1" + sgr_reset + " (<list>)\n" +
" " + sgr_color_2 + "It's list number one." + sgr_reset + "\n" +
"\n" +
"\n" +
"\n" +
" " + sgr_color_1 + "output.output-2" + sgr_reset + "\n" +
" " + sgr_color_2 + "It's output number two." + sgr_reset + "\n" +
"\n" +
" " + sgr_color_1 + "output.output-1" + sgr_reset + "\n" +
" " + sgr_color_2 + "It's output number one." + sgr_reset + "\n" +
"\n" +
"\n"
assert.Equal(t, expected, actual)
}
func TestPrettyWithSorting(t *testing.T) {
doc := doc.TestDoc(t, "..")
var settings settings.Settings
settings.Add(print.WithSorting)
actual, err := pretty.Print(doc, settings)
if err != nil {
t.Fatal(err)
}
sgr_color_1 := "\x1b[36m"
sgr_color_2 := "\x1b[90m"
sgr_reset := "\x1b[0m"
expected :=
"\nUsage:\n" +
"\n" +

View File

@@ -8,4 +8,6 @@ const (
_ settings.Setting = iota
// WithRequired prints if inputs are required
WithRequired
// WithSorting prints sorted inputs and outputs
WithSorting
)

View File

@@ -15,23 +15,3 @@ func (s *Settings) Add(setting Setting) {
func (s *Settings) Has(setting Setting) bool {
return *s&Settings(1<<setting) != 0
}
/*
package settings
// Setting represents a setting
type Setting uint
// Settings represents all settings
type Settings struct {
s uint
}
func (s *Settings) add(setting Setting) {
s.s |= 1 << setting
}
func (s *Settings) has(setting Setting) bool {
return s.s&(1<<setting) != 0
}
*/

View File

@@ -43,6 +43,7 @@ const usage = `
Options:
-h, --help show help information
--no-required omit "Required" column when generating markdown
--no-sort omit sorted rendering of inputs and ouputs
--version print version
`
@@ -65,6 +66,10 @@ func main() {
printSettings.Add(print.WithRequired)
}
if !args["--no-sort"].(bool) {
printSettings.Add(print.WithSorting)
}
var out string
switch {