From 46a29b13eda654d1652393fcde63159bb0f2e7a2 Mon Sep 17 00:00:00 2001 From: Alisdair McDiarmid Date: Tue, 16 Mar 2021 09:46:36 -0400 Subject: [PATCH] cli: Add format version to validate -json output In line with the other complex JSON output formats for plan and provider schema, here we add an explicit `format_version` field to the JSON output of terraform validate. --- .../incorrectmodulename/output.json | 1 + .../validate-invalid/interpolation/output.json | 1 + .../missing_defined_var/output.json | 1 + .../validate-invalid/missing_quote/output.json | 1 + .../validate-invalid/missing_var/output.json | 1 + .../validate-invalid/multiple_modules/output.json | 1 + .../validate-invalid/multiple_providers/output.json | 1 + .../validate-invalid/multiple_resources/output.json | 1 + command/testdata/validate-invalid/output.json | 1 + .../testdata/validate-invalid/outputs/output.json | 1 + command/testdata/validate-valid/output.json | 1 + command/validate.go | 13 +++++++++++-- website/docs/cli/commands/validate.html.md | 6 ++++++ 13 files changed, 28 insertions(+), 2 deletions(-) diff --git a/command/testdata/validate-invalid/incorrectmodulename/output.json b/command/testdata/validate-invalid/incorrectmodulename/output.json index f3b681755..4dfa754b6 100644 --- a/command/testdata/validate-invalid/incorrectmodulename/output.json +++ b/command/testdata/validate-invalid/incorrectmodulename/output.json @@ -1,4 +1,5 @@ { + "format_version": "0.1", "valid": false, "error_count": 6, "warning_count": 0, diff --git a/command/testdata/validate-invalid/interpolation/output.json b/command/testdata/validate-invalid/interpolation/output.json index dc0e5f4d7..7845ec0f4 100644 --- a/command/testdata/validate-invalid/interpolation/output.json +++ b/command/testdata/validate-invalid/interpolation/output.json @@ -1,4 +1,5 @@ { + "format_version": "0.1", "valid": false, "error_count": 2, "warning_count": 0, diff --git a/command/testdata/validate-invalid/missing_defined_var/output.json b/command/testdata/validate-invalid/missing_defined_var/output.json index ac2d30361..c2a57c5e6 100644 --- a/command/testdata/validate-invalid/missing_defined_var/output.json +++ b/command/testdata/validate-invalid/missing_defined_var/output.json @@ -1,4 +1,5 @@ { + "format_version": "0.1", "valid": true, "error_count": 0, "warning_count": 0, diff --git a/command/testdata/validate-invalid/missing_quote/output.json b/command/testdata/validate-invalid/missing_quote/output.json index 1ccb37a4d..cdf99d8b2 100644 --- a/command/testdata/validate-invalid/missing_quote/output.json +++ b/command/testdata/validate-invalid/missing_quote/output.json @@ -1,4 +1,5 @@ { + "format_version": "0.1", "valid": false, "error_count": 1, "warning_count": 0, diff --git a/command/testdata/validate-invalid/missing_var/output.json b/command/testdata/validate-invalid/missing_var/output.json index 389c3ba59..2a4e0be71 100644 --- a/command/testdata/validate-invalid/missing_var/output.json +++ b/command/testdata/validate-invalid/missing_var/output.json @@ -1,4 +1,5 @@ { + "format_version": "0.1", "valid": false, "error_count": 1, "warning_count": 0, diff --git a/command/testdata/validate-invalid/multiple_modules/output.json b/command/testdata/validate-invalid/multiple_modules/output.json index f0106b367..a18c6bc78 100644 --- a/command/testdata/validate-invalid/multiple_modules/output.json +++ b/command/testdata/validate-invalid/multiple_modules/output.json @@ -1,4 +1,5 @@ { + "format_version": "0.1", "valid": false, "error_count": 2, "warning_count": 0, diff --git a/command/testdata/validate-invalid/multiple_providers/output.json b/command/testdata/validate-invalid/multiple_providers/output.json index 4b9a8c929..63eb2d193 100644 --- a/command/testdata/validate-invalid/multiple_providers/output.json +++ b/command/testdata/validate-invalid/multiple_providers/output.json @@ -1,4 +1,5 @@ { + "format_version": "0.1", "valid": false, "error_count": 1, "warning_count": 0, diff --git a/command/testdata/validate-invalid/multiple_resources/output.json b/command/testdata/validate-invalid/multiple_resources/output.json index 7c15e58a8..33d505228 100644 --- a/command/testdata/validate-invalid/multiple_resources/output.json +++ b/command/testdata/validate-invalid/multiple_resources/output.json @@ -1,4 +1,5 @@ { + "format_version": "0.1", "valid": false, "error_count": 1, "warning_count": 0, diff --git a/command/testdata/validate-invalid/output.json b/command/testdata/validate-invalid/output.json index 9043bbe4d..663fe0153 100644 --- a/command/testdata/validate-invalid/output.json +++ b/command/testdata/validate-invalid/output.json @@ -1,4 +1,5 @@ { + "format_version": "0.1", "valid": false, "error_count": 1, "warning_count": 0, diff --git a/command/testdata/validate-invalid/outputs/output.json b/command/testdata/validate-invalid/outputs/output.json index 8ea40437b..d05ed4b77 100644 --- a/command/testdata/validate-invalid/outputs/output.json +++ b/command/testdata/validate-invalid/outputs/output.json @@ -1,4 +1,5 @@ { + "format_version": "0.1", "valid": false, "error_count": 2, "warning_count": 0, diff --git a/command/testdata/validate-valid/output.json b/command/testdata/validate-valid/output.json index ac2d30361..c2a57c5e6 100644 --- a/command/testdata/validate-valid/output.json +++ b/command/testdata/validate-valid/output.json @@ -1,4 +1,5 @@ { + "format_version": "0.1", "valid": true, "error_count": 0, "warning_count": 0, diff --git a/command/validate.go b/command/validate.go index d9f8e40a8..ea163cbdf 100644 --- a/command/validate.go +++ b/command/validate.go @@ -119,7 +119,14 @@ func (c *ValidateCommand) validate(dir string) tfdiags.Diagnostics { func (c *ValidateCommand) showResults(diags tfdiags.Diagnostics, jsonOutput bool) int { switch { case jsonOutput: + // FormatVersion represents the version of the json format and will be + // incremented for any change to this format that requires changes to a + // consuming parser. + const FormatVersion = "0.1" + type Output struct { + FormatVersion string `json:"format_version"` + // We include some summary information that is actually redundant // with the detailed diagnostics, but avoids the need for callers // to re-implement our logic for deciding these. @@ -129,8 +136,10 @@ func (c *ValidateCommand) showResults(diags tfdiags.Diagnostics, jsonOutput bool Diagnostics []*viewsjson.Diagnostic `json:"diagnostics"` } - var output Output - output.Valid = true // until proven otherwise + output := Output{ + FormatVersion: FormatVersion, + Valid: true, // until proven otherwise + } configSources := c.configSources() for _, diag := range diags { output.Diagnostics = append(output.Diagnostics, viewsjson.NewDiagnostic(diag, configSources)) diff --git a/website/docs/cli/commands/validate.html.md b/website/docs/cli/commands/validate.html.md index 687e83789..c6436c6af 100644 --- a/website/docs/cli/commands/validate.html.md +++ b/website/docs/cli/commands/validate.html.md @@ -57,6 +57,12 @@ to the JSON output setting. For that reason, external software consuming Terraform's output should be prepared to find data on stdout that _isn't_ valid JSON, which it should then treat as a generic error case. +**Note:** The output includes a `format_version` key, which currently has major +version zero to indicate that the format is experimental and subject to change. +A future version will assign a non-zero major version and make stronger +promises about compatibility. We do not anticipate any significant breaking +changes to the format before its first major version, however. + In the normal case, Terraform will print a JSON object to the standard output stream. The top-level JSON object will have the following properties: