add output-check option for outputs

adding option to compare outputted file with generated
terraform-doc and fail if different

Signed-off-by: Ricardo Herrera <rickhl@outlook.com>
Signed-off-by: Khosrow Moossavi <khos2ow@gmail.com>
This commit is contained in:
Ricardo Herrera
2021-03-30 15:19:55 -04:00
committed by Khosrow Moossavi
parent f694e50633
commit 21eaab4fc7
20 changed files with 70 additions and 0 deletions

View File

@@ -65,6 +65,7 @@ func NewCommand() *cobra.Command {
cmd.PersistentFlags().StringVar(&config.Output.File, "output-file", "", "file path to insert output into (default \"\")")
cmd.PersistentFlags().StringVar(&config.Output.Mode, "output-mode", "inject", "output to file method ["+cli.OutputModes+"]")
cmd.PersistentFlags().StringVar(&config.Output.Template, "output-template", cli.OutputTemplate, "output template")
cmd.PersistentFlags().BoolVar(&config.Output.Check, "output-check", false, "check if content of output file is up to date (default false)")
cmd.PersistentFlags().BoolVar(&config.Sort.Enabled, "sort", true, "sort items")
cmd.PersistentFlags().StringVar(&config.Sort.By, "sort-by", "name", "sort items by criteria ["+cli.SortTypes+"]")

View File

@@ -32,6 +32,7 @@ terraform-docs asciidoc document [PATH] [flags]
--header-from string relative path of a file to read header from (default "main.tf")
--hide strings hide section [all, data-sources, footer, header, inputs, modules, outputs, providers, requirements, resources]
--indent int indention level of AsciiDoc sections [1, 2, 3, 4, 5] (default 2)
--output-check check if content of output file is up to date (default false)
--output-file string file path to insert output into (default "")
--output-mode string output to file method [inject, replace] (default "inject")
--output-template string output template (default "<!-- BEGIN_TF_DOCS -->\n{{ .Content }}\n<!-- END_TF_DOCS -->")

View File

@@ -32,6 +32,7 @@ terraform-docs asciidoc table [PATH] [flags]
--header-from string relative path of a file to read header from (default "main.tf")
--hide strings hide section [all, data-sources, footer, header, inputs, modules, outputs, providers, requirements, resources]
--indent int indention level of AsciiDoc sections [1, 2, 3, 4, 5] (default 2)
--output-check check if content of output file is up to date (default false)
--output-file string file path to insert output into (default "")
--output-mode string output to file method [inject, replace] (default "inject")
--output-template string output template (default "<!-- BEGIN_TF_DOCS -->\n{{ .Content }}\n<!-- END_TF_DOCS -->")

View File

@@ -35,6 +35,7 @@ terraform-docs asciidoc [PATH] [flags]
--footer-from string relative path of a file to read footer from (default "")
--header-from string relative path of a file to read header from (default "main.tf")
--hide strings hide section [all, data-sources, footer, header, inputs, modules, outputs, providers, requirements, resources]
--output-check check if content of output file is up to date (default false)
--output-file string file path to insert output into (default "")
--output-mode string output to file method [inject, replace] (default "inject")
--output-template string output template (default "<!-- BEGIN_TF_DOCS -->\n{{ .Content }}\n<!-- END_TF_DOCS -->")

View File

@@ -30,6 +30,7 @@ terraform-docs json [PATH] [flags]
--footer-from string relative path of a file to read footer from (default "")
--header-from string relative path of a file to read header from (default "main.tf")
--hide strings hide section [all, data-sources, footer, header, inputs, modules, outputs, providers, requirements, resources]
--output-check check if content of output file is up to date (default false)
--output-file string file path to insert output into (default "")
--output-mode string output to file method [inject, replace] (default "inject")
--output-template string output template (default "<!-- BEGIN_TF_DOCS -->\n{{ .Content }}\n<!-- END_TF_DOCS -->")

View File

@@ -34,6 +34,7 @@ terraform-docs markdown document [PATH] [flags]
--hide strings hide section [all, data-sources, footer, header, inputs, modules, outputs, providers, requirements, resources]
--html use HTML tags in genereted output (default true)
--indent int indention level of Markdown sections [1, 2, 3, 4, 5] (default 2)
--output-check check if content of output file is up to date (default false)
--output-file string file path to insert output into (default "")
--output-mode string output to file method [inject, replace] (default "inject")
--output-template string output template (default "<!-- BEGIN_TF_DOCS -->\n{{ .Content }}\n<!-- END_TF_DOCS -->")

View File

@@ -34,6 +34,7 @@ terraform-docs markdown table [PATH] [flags]
--hide strings hide section [all, data-sources, footer, header, inputs, modules, outputs, providers, requirements, resources]
--html use HTML tags in genereted output (default true)
--indent int indention level of Markdown sections [1, 2, 3, 4, 5] (default 2)
--output-check check if content of output file is up to date (default false)
--output-file string file path to insert output into (default "")
--output-mode string output to file method [inject, replace] (default "inject")
--output-template string output template (default "<!-- BEGIN_TF_DOCS -->\n{{ .Content }}\n<!-- END_TF_DOCS -->")

View File

@@ -37,6 +37,7 @@ terraform-docs markdown [PATH] [flags]
--footer-from string relative path of a file to read footer from (default "")
--header-from string relative path of a file to read header from (default "main.tf")
--hide strings hide section [all, data-sources, footer, header, inputs, modules, outputs, providers, requirements, resources]
--output-check check if content of output file is up to date (default false)
--output-file string file path to insert output into (default "")
--output-mode string output to file method [inject, replace] (default "inject")
--output-template string output template (default "<!-- BEGIN_TF_DOCS -->\n{{ .Content }}\n<!-- END_TF_DOCS -->")

View File

@@ -30,6 +30,7 @@ terraform-docs pretty [PATH] [flags]
--footer-from string relative path of a file to read footer from (default "")
--header-from string relative path of a file to read header from (default "main.tf")
--hide strings hide section [all, data-sources, footer, header, inputs, modules, outputs, providers, requirements, resources]
--output-check check if content of output file is up to date (default false)
--output-file string file path to insert output into (default "")
--output-mode string output to file method [inject, replace] (default "inject")
--output-template string output template (default "<!-- BEGIN_TF_DOCS -->\n{{ .Content }}\n<!-- END_TF_DOCS -->")

View File

@@ -24,6 +24,7 @@ terraform-docs [PATH] [flags]
--header-from string relative path of a file to read header from (default "main.tf")
-h, --help help for terraform-docs
--hide strings hide section [all, data-sources, footer, header, inputs, modules, outputs, providers, requirements, resources]
--output-check check if content of output file is up to date (default false)
--output-file string file path to insert output into (default "")
--output-mode string output to file method [inject, replace] (default "inject")
--output-template string output template (default "<!-- BEGIN_TF_DOCS -->\n{{ .Content }}\n<!-- END_TF_DOCS -->")

View File

@@ -30,6 +30,7 @@ terraform-docs tfvars hcl [PATH] [flags]
--footer-from string relative path of a file to read footer from (default "")
--header-from string relative path of a file to read header from (default "main.tf")
--hide strings hide section [all, data-sources, footer, header, inputs, modules, outputs, providers, requirements, resources]
--output-check check if content of output file is up to date (default false)
--output-file string file path to insert output into (default "")
--output-mode string output to file method [inject, replace] (default "inject")
--output-template string output template (default "<!-- BEGIN_TF_DOCS -->\n{{ .Content }}\n<!-- END_TF_DOCS -->")

View File

@@ -29,6 +29,7 @@ terraform-docs tfvars json [PATH] [flags]
--footer-from string relative path of a file to read footer from (default "")
--header-from string relative path of a file to read header from (default "main.tf")
--hide strings hide section [all, data-sources, footer, header, inputs, modules, outputs, providers, requirements, resources]
--output-check check if content of output file is up to date (default false)
--output-file string file path to insert output into (default "")
--output-mode string output to file method [inject, replace] (default "inject")
--output-template string output template (default "<!-- BEGIN_TF_DOCS -->\n{{ .Content }}\n<!-- END_TF_DOCS -->")

View File

@@ -25,6 +25,7 @@ Generate terraform.tfvars of inputs.
--footer-from string relative path of a file to read footer from (default "")
--header-from string relative path of a file to read header from (default "main.tf")
--hide strings hide section [all, data-sources, footer, header, inputs, modules, outputs, providers, requirements, resources]
--output-check check if content of output file is up to date (default false)
--output-file string file path to insert output into (default "")
--output-mode string output to file method [inject, replace] (default "inject")
--output-template string output template (default "<!-- BEGIN_TF_DOCS -->\n{{ .Content }}\n<!-- END_TF_DOCS -->")

View File

@@ -29,6 +29,7 @@ terraform-docs toml [PATH] [flags]
--footer-from string relative path of a file to read footer from (default "")
--header-from string relative path of a file to read header from (default "main.tf")
--hide strings hide section [all, data-sources, footer, header, inputs, modules, outputs, providers, requirements, resources]
--output-check check if content of output file is up to date (default false)
--output-file string file path to insert output into (default "")
--output-mode string output to file method [inject, replace] (default "inject")
--output-template string output template (default "<!-- BEGIN_TF_DOCS -->\n{{ .Content }}\n<!-- END_TF_DOCS -->")

View File

@@ -29,6 +29,7 @@ terraform-docs xml [PATH] [flags]
--footer-from string relative path of a file to read footer from (default "")
--header-from string relative path of a file to read header from (default "main.tf")
--hide strings hide section [all, data-sources, footer, header, inputs, modules, outputs, providers, requirements, resources]
--output-check check if content of output file is up to date (default false)
--output-file string file path to insert output into (default "")
--output-mode string output to file method [inject, replace] (default "inject")
--output-template string output template (default "<!-- BEGIN_TF_DOCS -->\n{{ .Content }}\n<!-- END_TF_DOCS -->")

View File

@@ -29,6 +29,7 @@ terraform-docs yaml [PATH] [flags]
--footer-from string relative path of a file to read footer from (default "")
--header-from string relative path of a file to read header from (default "main.tf")
--hide strings hide section [all, data-sources, footer, header, inputs, modules, outputs, providers, requirements, resources]
--output-check check if content of output file is up to date (default false)
--output-file string file path to insert output into (default "")
--output-mode string output to file method [inject, replace] (default "inject")
--output-template string output template (default "<!-- BEGIN_TF_DOCS -->\n{{ .Content }}\n<!-- END_TF_DOCS -->")

View File

@@ -203,6 +203,7 @@ type output struct {
File string `mapstructure:"file"`
Mode string `mapstructure:"mode"`
Template string `mapstructure:"template"`
Check bool
beginComment string
endComment string
@@ -213,6 +214,7 @@ func defaultOutput() output {
File: "",
Mode: outputModeInject,
Template: OutputTemplate,
Check: false,
beginComment: outputBeginComment,
endComment: outputEndComment,

View File

@@ -229,6 +229,8 @@ func writeContent(config *Config, content string) error {
mode: config.Output.Mode,
check: config.Output.Check,
template: config.Output.Template,
begin: config.Output.beginComment,
end: config.Output.endComment,

View File

@@ -13,6 +13,7 @@ package cli
import (
"bytes"
"errors"
"fmt"
"io"
"os"
"path/filepath"
@@ -46,6 +47,8 @@ type fileWriter struct {
mode string
check bool
template string
begin string
end string
@@ -154,8 +157,26 @@ func (fw *fileWriter) inject(filename string, content string, generated string)
// wrtie the content to io.Writer. If no io.Writer is available,
// it will be written to 'filename'.
func (fw *fileWriter) write(filename string, p []byte) (int, error) {
// if run in check mode return exit 1
if fw.check {
f, err := os.ReadFile(filename)
if err != nil {
return 0, err
}
// check for changes and print changed file
if !bytes.Equal(f, p) {
return 0, fmt.Errorf("%s is out of date", filename)
}
fmt.Printf("%s is up to date\n", filename)
return 0, nil
}
if fw.writer != nil {
return fw.writer.Write(p)
}
fmt.Printf("%s updated successfully\n", filename)
return len(p), os.WriteFile(filename, p, 0644)
}

View File

@@ -58,6 +58,7 @@ func TestFileWriter(t *testing.T) {
tests := map[string]struct {
file string
mode string
check bool
template string
begin string
end string
@@ -71,6 +72,7 @@ func TestFileWriter(t *testing.T) {
"ModeInject": {
file: "mode-inject.md",
mode: "inject",
check: false,
template: OutputTemplate,
begin: outputBeginComment,
end: outputEndComment,
@@ -83,6 +85,7 @@ func TestFileWriter(t *testing.T) {
"ModeInjectEmptyFile": {
file: "empty-file.md",
mode: "inject",
check: false,
template: OutputTemplate,
begin: outputBeginComment,
end: outputEndComment,
@@ -95,6 +98,7 @@ func TestFileWriter(t *testing.T) {
"ModeInjectNoCommentAppend": {
file: "mode-inject-no-comment.md",
mode: "inject",
check: false,
template: OutputTemplate,
begin: outputBeginComment,
end: outputEndComment,
@@ -107,6 +111,7 @@ func TestFileWriter(t *testing.T) {
"ModeInjectFileMissing": {
file: "file-missing.md",
mode: "inject",
check: false,
template: OutputTemplate,
begin: outputBeginComment,
end: outputEndComment,
@@ -119,6 +124,7 @@ func TestFileWriter(t *testing.T) {
"ModeReplaceWithComment": {
file: "mode-replace.md",
mode: "replace",
check: false,
template: OutputTemplate,
begin: outputBeginComment,
end: outputEndComment,
@@ -131,6 +137,7 @@ func TestFileWriter(t *testing.T) {
"ModeReplaceWithCommentEmptyFile": {
file: "mode-replace.md",
mode: "replace",
check: false,
template: OutputTemplate,
begin: outputBeginComment,
end: outputEndComment,
@@ -143,6 +150,7 @@ func TestFileWriter(t *testing.T) {
"ModeReplaceWithCommentFileMissing": {
file: "file-missing.md",
mode: "replace",
check: false,
template: OutputTemplate,
begin: outputBeginComment,
end: outputEndComment,
@@ -155,6 +163,7 @@ func TestFileWriter(t *testing.T) {
"ModeReplaceWithoutComment": {
file: "mode-replace.md",
mode: "replace",
check: false,
template: outputContent,
begin: "",
end: "",
@@ -167,6 +176,7 @@ func TestFileWriter(t *testing.T) {
"ModeReplaceWithoutTemplate": {
file: "mode-replace.md",
mode: "replace",
check: false,
template: "",
begin: "",
end: "",
@@ -181,6 +191,7 @@ func TestFileWriter(t *testing.T) {
"EmptyTemplate": {
file: "not-applicable.md",
mode: "inject",
check: false,
template: "",
begin: outputBeginComment,
end: outputEndComment,
@@ -193,6 +204,7 @@ func TestFileWriter(t *testing.T) {
"BeginCommentMissing": {
file: "begin-comment-missing.md",
mode: "inject",
check: false,
template: OutputTemplate,
begin: outputBeginComment,
end: outputEndComment,
@@ -205,6 +217,7 @@ func TestFileWriter(t *testing.T) {
"EndCommentMissing": {
file: "end-comment-missing.md",
mode: "inject",
check: false,
template: OutputTemplate,
begin: outputBeginComment,
end: outputEndComment,
@@ -217,6 +230,7 @@ func TestFileWriter(t *testing.T) {
"EndCommentBeforeBegin": {
file: "end-comment-before-begin.md",
mode: "inject",
check: false,
template: OutputTemplate,
begin: outputBeginComment,
end: outputEndComment,
@@ -226,6 +240,19 @@ func TestFileWriter(t *testing.T) {
wantErr: true,
errMsg: "end comment is before begin comment",
},
"ModeReplaceOutOfDate": {
file: "mode-replace.md",
mode: "replace",
check: true,
template: OutputTemplate,
begin: outputBeginComment,
end: outputEndComment,
writer: nil,
expected: "",
wantErr: true,
errMsg: "testdata/writer/mode-replace.md is out of date",
},
}
for name, tt := range tests {
t.Run(name, func(t *testing.T) {
@@ -237,6 +264,8 @@ func TestFileWriter(t *testing.T) {
mode: tt.mode,
check: tt.check,
template: tt.template,
begin: tt.begin,
end: tt.end,