From 26b907387d2eee17640f10ea39eb401ec644fede Mon Sep 17 00:00:00 2001 From: Lyle Franklin Date: Wed, 20 Jun 2018 08:58:07 -0700 Subject: [PATCH] cli: Remove error on empty outputs when `-json` is set (#11721) - Fixes #11696 - This changes makes `terraform output -json` return '{}' instead of throwing an error about "no outputs defined" - If `-json` is not set, the user will receive an error as before - This UX helps new users to understand how outputs are used - Allows for easier automation of TF CLI as an empty set of outputs is usually acceptable, but any other error from `output` would be re-raised to the user. --- command/output.go | 2 +- command/output_test.go | 63 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/command/output.go b/command/output.go index 8677858da..4b8d57d07 100644 --- a/command/output.go +++ b/command/output.go @@ -85,7 +85,7 @@ func (c *OutputCommand) Run(args []string) int { return 1 } - if state.Empty() || len(mod.Outputs) == 0 { + if !jsonOutput && (state.Empty() || len(mod.Outputs) == 0) { c.Ui.Error( "The state file either has no outputs defined, or all the defined\n" + "outputs are empty. Please define an output in your configuration\n" + diff --git a/command/output_test.go b/command/output_test.go index e4b536448..5b6304e16 100644 --- a/command/output_test.go +++ b/command/output_test.go @@ -235,6 +235,69 @@ func TestOutput_json(t *testing.T) { } } +func TestOutput_emptyOutputsErr(t *testing.T) { + originalState := &terraform.State{ + Modules: []*terraform.ModuleState{ + { + Path: []string{"root"}, + Outputs: map[string]*terraform.OutputState{}, + }, + }, + } + + statePath := testStateFile(t, originalState) + + ui := new(cli.MockUi) + c := &OutputCommand{ + Meta: Meta{ + ContextOpts: testCtxConfig(testProvider()), + Ui: ui, + }, + } + + args := []string{ + "-state", statePath, + } + if code := c.Run(args); code != 1 { + t.Fatalf("bad: \n%s", ui.ErrorWriter.String()) + } +} + +func TestOutput_jsonEmptyOutputs(t *testing.T) { + originalState := &terraform.State{ + Modules: []*terraform.ModuleState{ + { + Path: []string{"root"}, + Outputs: map[string]*terraform.OutputState{}, + }, + }, + } + + statePath := testStateFile(t, originalState) + + ui := new(cli.MockUi) + c := &OutputCommand{ + Meta: Meta{ + ContextOpts: testCtxConfig(testProvider()), + Ui: ui, + }, + } + + args := []string{ + "-state", statePath, + "-json", + } + if code := c.Run(args); code != 0 { + t.Fatalf("bad: \n%s", ui.ErrorWriter.String()) + } + + actual := strings.TrimSpace(ui.OutputWriter.String()) + expected := "{}" + if actual != expected { + t.Fatalf("bad:\n%#v\n%#v", expected, actual) + } +} + func TestMissingModuleOutput(t *testing.T) { originalState := &terraform.State{ Modules: []*terraform.ModuleState{