mirror of
https://github.com/opentffoundation/opentf.git
synced 2025-12-19 17:59:05 -05:00
Experiment with -json-into command output option
Signed-off-by: Christian Mesh <christianmesh1@gmail.com>
This commit is contained in:
@@ -35,6 +35,8 @@ type Plan struct {
|
||||
// ViewType specifies which output format to use
|
||||
ViewType ViewType
|
||||
|
||||
JsonInto string
|
||||
|
||||
// ShowSensitive is used to display the value of variables marked as sensitive.
|
||||
ShowSensitive bool
|
||||
}
|
||||
@@ -59,6 +61,7 @@ func ParsePlan(args []string) (*Plan, tfdiags.Diagnostics) {
|
||||
|
||||
var json bool
|
||||
cmdFlags.BoolVar(&json, "json", false, "json")
|
||||
cmdFlags.StringVar(&plan.JsonInto, "json-into", "", "json-into")
|
||||
|
||||
if err := cmdFlags.Parse(args); err != nil {
|
||||
diags = diags.Append(tfdiags.Sourceless(
|
||||
@@ -86,7 +89,7 @@ func ParsePlan(args []string) (*Plan, tfdiags.Diagnostics) {
|
||||
}
|
||||
|
||||
switch {
|
||||
case json:
|
||||
case json || plan.JsonInto != "":
|
||||
plan.ViewType = ViewJSON
|
||||
default:
|
||||
plan.ViewType = ViewHuman
|
||||
|
||||
@@ -8,6 +8,7 @@ package command
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/opentofu/opentofu/internal/command/views"
|
||||
@@ -30,6 +31,7 @@ func (c *GetCommand) Run(args []string) int {
|
||||
cmdFlags.BoolVar(&update, "update", false, "update")
|
||||
cmdFlags.StringVar(&testsDirectory, "test-directory", "tests", "test-directory")
|
||||
cmdFlags.BoolVar(&c.outputInJSON, "json", false, "json")
|
||||
cmdFlags.StringVar(&c.outputJSONInto, "json-into", "", "json-into")
|
||||
cmdFlags.Usage = func() { c.Ui.Error(c.Help()) }
|
||||
if err := cmdFlags.Parse(args); err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error parsing command-line flags: %s\n", err.Error()))
|
||||
@@ -40,9 +42,22 @@ func (c *GetCommand) Run(args []string) int {
|
||||
c.Meta.Color = false
|
||||
c.oldUi = c.Ui
|
||||
c.Ui = &WrappedUi{
|
||||
cliUi: c.oldUi,
|
||||
jsonView: views.NewJSONView(c.View),
|
||||
outputInJSON: true,
|
||||
cliUi: c.oldUi,
|
||||
jsonView: views.NewJSONView(c.View, nil),
|
||||
onlyOutputInJSON: true,
|
||||
}
|
||||
}
|
||||
|
||||
if c.outputJSONInto != "" {
|
||||
out, err := os.OpenFile(c.outputJSONInto, os.O_RDWR|os.O_CREATE, 0600)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
c.oldUi = c.Ui
|
||||
c.Ui = &WrappedUi{
|
||||
cliUi: c.oldUi,
|
||||
jsonView: views.NewJSONView(c.View, out),
|
||||
onlyOutputInJSON: false,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strings"
|
||||
@@ -73,6 +74,7 @@ func (c *InitCommand) Run(args []string) int {
|
||||
cmdFlags.BoolVar(&c.Meta.ignoreRemoteVersion, "ignore-remote-version", false, "continue even if remote and local OpenTofu versions are incompatible")
|
||||
cmdFlags.StringVar(&testsDirectory, "test-directory", "tests", "test-directory")
|
||||
cmdFlags.BoolVar(&c.outputInJSON, "json", false, "json")
|
||||
cmdFlags.StringVar(&c.outputJSONInto, "json-into", "", "json-into")
|
||||
cmdFlags.Usage = func() { c.Ui.Error(c.Help()) }
|
||||
if err := cmdFlags.Parse(args); err != nil {
|
||||
return 1
|
||||
@@ -83,9 +85,22 @@ func (c *InitCommand) Run(args []string) int {
|
||||
c.Meta.Color = false
|
||||
c.oldUi = c.Ui
|
||||
c.Ui = &WrappedUi{
|
||||
cliUi: c.oldUi,
|
||||
jsonView: views.NewJSONView(c.View),
|
||||
outputInJSON: true,
|
||||
cliUi: c.oldUi,
|
||||
jsonView: views.NewJSONView(c.View, nil),
|
||||
onlyOutputInJSON: true,
|
||||
}
|
||||
}
|
||||
|
||||
if c.outputJSONInto != "" {
|
||||
out, err := os.OpenFile(c.outputJSONInto, os.O_RDWR|os.O_CREATE, 0600)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
c.oldUi = c.Ui
|
||||
c.Ui = &WrappedUi{
|
||||
cliUi: c.oldUi,
|
||||
jsonView: views.NewJSONView(c.View, out),
|
||||
onlyOutputInJSON: false,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -299,7 +299,8 @@ type Meta struct {
|
||||
// state even if the remote and local OpenTofu versions don't match.
|
||||
ignoreRemoteVersion bool
|
||||
|
||||
outputInJSON bool
|
||||
outputInJSON bool
|
||||
outputJSONInto string
|
||||
|
||||
// Used to cache the root module rootModuleCallCache and known variables.
|
||||
// This helps prevent duplicate errors/warnings.
|
||||
@@ -760,8 +761,17 @@ func (m *Meta) showDiagnostics(vals ...interface{}) {
|
||||
return
|
||||
}
|
||||
|
||||
if m.outputJSONInto != "" {
|
||||
out, err := os.OpenFile(m.outputJSONInto, os.O_RDWR|os.O_CREATE, 0600)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
jsonView := views.NewJSONView(m.View, out)
|
||||
jsonView.Diagnostics(diags)
|
||||
return
|
||||
}
|
||||
if m.outputInJSON {
|
||||
jsonView := views.NewJSONView(m.View)
|
||||
jsonView := views.NewJSONView(m.View, nil)
|
||||
jsonView.Diagnostics(diags)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -19,9 +19,9 @@ import (
|
||||
// implement cli.Ui interface, so that we can make all command support json
|
||||
// output in a short time.
|
||||
type WrappedUi struct {
|
||||
cliUi cli.Ui
|
||||
jsonView *views.JSONView
|
||||
outputInJSON bool
|
||||
cliUi cli.Ui
|
||||
jsonView *views.JSONView
|
||||
onlyOutputInJSON bool
|
||||
}
|
||||
|
||||
func (m *WrappedUi) Ask(s string) (string, error) {
|
||||
@@ -33,32 +33,32 @@ func (m *WrappedUi) AskSecret(s string) (string, error) {
|
||||
}
|
||||
|
||||
func (m *WrappedUi) Output(s string) {
|
||||
if m.outputInJSON {
|
||||
m.jsonView.Output(s)
|
||||
m.jsonView.Output(s)
|
||||
if m.onlyOutputInJSON {
|
||||
return
|
||||
}
|
||||
m.cliUi.Output(s)
|
||||
}
|
||||
|
||||
func (m *WrappedUi) Info(s string) {
|
||||
if m.outputInJSON {
|
||||
m.jsonView.Info(s)
|
||||
m.jsonView.Info(s)
|
||||
if m.onlyOutputInJSON {
|
||||
return
|
||||
}
|
||||
m.cliUi.Info(s)
|
||||
}
|
||||
|
||||
func (m *WrappedUi) Error(s string) {
|
||||
if m.outputInJSON {
|
||||
m.jsonView.Error(s)
|
||||
m.jsonView.Error(s)
|
||||
if m.onlyOutputInJSON {
|
||||
return
|
||||
}
|
||||
m.cliUi.Error(s)
|
||||
}
|
||||
|
||||
func (m *WrappedUi) Warn(s string) {
|
||||
if m.outputInJSON {
|
||||
m.jsonView.Warn(s)
|
||||
m.jsonView.Warn(s)
|
||||
if m.onlyOutputInJSON {
|
||||
return
|
||||
}
|
||||
m.cliUi.Warn(s)
|
||||
|
||||
@@ -43,7 +43,7 @@ func (c *PlanCommand) Run(rawArgs []string) int {
|
||||
|
||||
// Instantiate the view, even if there are flag errors, so that we render
|
||||
// diagnostics according to the desired view
|
||||
view := views.NewPlan(args.ViewType, c.View)
|
||||
view := views.NewPlan(args, c.View)
|
||||
|
||||
if diags.HasErrors() {
|
||||
view.Diagnostics(diags)
|
||||
|
||||
@@ -33,7 +33,7 @@ func NewApply(vt arguments.ViewType, destroy bool, view *View) Apply {
|
||||
switch vt {
|
||||
case arguments.ViewJSON:
|
||||
return &ApplyJSON{
|
||||
view: NewJSONView(view),
|
||||
view: NewJSONView(view, nil),
|
||||
destroy: destroy,
|
||||
countHook: &countHook{},
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ import (
|
||||
// Test a sequence of hooks associated with creating a resource
|
||||
func TestJSONHook_create(t *testing.T) {
|
||||
streams, done := terminal.StreamsForTesting(t)
|
||||
hook := newJSONHook(NewJSONView(NewView(streams)))
|
||||
hook := newJSONHook(NewJSONView(NewView(streams), nil))
|
||||
|
||||
var nowMu sync.Mutex
|
||||
now := time.Now()
|
||||
@@ -195,7 +195,7 @@ func TestJSONHook_create(t *testing.T) {
|
||||
|
||||
func TestJSONHook_errors(t *testing.T) {
|
||||
streams, done := terminal.StreamsForTesting(t)
|
||||
hook := newJSONHook(NewJSONView(NewView(streams)))
|
||||
hook := newJSONHook(NewJSONView(NewView(streams), nil))
|
||||
|
||||
addr := addrs.Resource{
|
||||
Mode: addrs.ManagedResourceMode,
|
||||
@@ -282,7 +282,7 @@ func TestJSONHook_errors(t *testing.T) {
|
||||
|
||||
func TestJSONHook_refresh(t *testing.T) {
|
||||
streams, done := terminal.StreamsForTesting(t)
|
||||
hook := newJSONHook(NewJSONView(NewView(streams)))
|
||||
hook := newJSONHook(NewJSONView(NewView(streams), nil))
|
||||
|
||||
addr := addrs.Resource{
|
||||
Mode: addrs.DataResourceMode,
|
||||
@@ -497,7 +497,7 @@ func TestJSONHook_ephemeral(t *testing.T) {
|
||||
for _, tt := range cases {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
streams, done := terminal.StreamsForTesting(t)
|
||||
h := newJSONHook(NewJSONView(NewView(streams)))
|
||||
h := newJSONHook(NewJSONView(NewView(streams), nil))
|
||||
|
||||
action, err := tt.preF(h)
|
||||
if err != nil {
|
||||
|
||||
@@ -8,6 +8,7 @@ package views
|
||||
import (
|
||||
encJson "encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/hashicorp/go-hclog"
|
||||
|
||||
@@ -22,10 +23,13 @@ import (
|
||||
// command/views/json package.
|
||||
const JSON_UI_VERSION = "1.2"
|
||||
|
||||
func NewJSONView(view *View) *JSONView {
|
||||
func NewJSONView(view *View, out *os.File) *JSONView {
|
||||
if out == nil {
|
||||
out = view.streams.Stdout.File
|
||||
}
|
||||
log := hclog.New(&hclog.LoggerOptions{
|
||||
Name: "tofu.ui",
|
||||
Output: view.streams.Stdout.File,
|
||||
Output: out,
|
||||
JSONFormat: true,
|
||||
JSONEscapeDisabled: true,
|
||||
})
|
||||
|
||||
@@ -27,7 +27,7 @@ import (
|
||||
// convenient way to test that NewJSONView works.
|
||||
func TestNewJSONView(t *testing.T) {
|
||||
streams, done := terminal.StreamsForTesting(t)
|
||||
NewJSONView(NewView(streams))
|
||||
NewJSONView(NewView(streams), nil)
|
||||
|
||||
version := tfversion.String()
|
||||
want := []map[string]interface{}{
|
||||
@@ -78,7 +78,7 @@ func TestJSONView_Log(t *testing.T) {
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.caseName, func(t *testing.T) {
|
||||
streams, done := terminal.StreamsForTesting(t)
|
||||
jv := NewJSONView(NewView(streams))
|
||||
jv := NewJSONView(NewView(streams), nil)
|
||||
jv.Log(tc.input)
|
||||
testJSONViewOutputEquals(t, done(t).Stdout(), tc.want)
|
||||
})
|
||||
@@ -89,7 +89,7 @@ func TestJSONView_Log(t *testing.T) {
|
||||
// complex diagnostics are tested elsewhere.
|
||||
func TestJSONView_Diagnostics(t *testing.T) {
|
||||
streams, done := terminal.StreamsForTesting(t)
|
||||
jv := NewJSONView(NewView(streams))
|
||||
jv := NewJSONView(NewView(streams), nil)
|
||||
|
||||
var diags tfdiags.Diagnostics
|
||||
diags = diags.Append(tfdiags.Sourceless(
|
||||
@@ -134,7 +134,7 @@ func TestJSONView_Diagnostics(t *testing.T) {
|
||||
|
||||
func TestJSONView_DiagnosticsWithMetadata(t *testing.T) {
|
||||
streams, done := terminal.StreamsForTesting(t)
|
||||
jv := NewJSONView(NewView(streams))
|
||||
jv := NewJSONView(NewView(streams), nil)
|
||||
|
||||
var diags tfdiags.Diagnostics
|
||||
diags = diags.Append(tfdiags.Sourceless(
|
||||
@@ -181,7 +181,7 @@ func TestJSONView_DiagnosticsWithMetadata(t *testing.T) {
|
||||
|
||||
func TestJSONView_PlannedChange(t *testing.T) {
|
||||
streams, done := terminal.StreamsForTesting(t)
|
||||
jv := NewJSONView(NewView(streams))
|
||||
jv := NewJSONView(NewView(streams), nil)
|
||||
|
||||
foo, diags := addrs.ParseModuleInstanceStr("module.foo")
|
||||
if len(diags) > 0 {
|
||||
@@ -222,7 +222,7 @@ func TestJSONView_PlannedChange(t *testing.T) {
|
||||
|
||||
func TestJSONView_ResourceDrift(t *testing.T) {
|
||||
streams, done := terminal.StreamsForTesting(t)
|
||||
jv := NewJSONView(NewView(streams))
|
||||
jv := NewJSONView(NewView(streams), nil)
|
||||
|
||||
foo, diags := addrs.ParseModuleInstanceStr("module.foo")
|
||||
if len(diags) > 0 {
|
||||
@@ -263,7 +263,7 @@ func TestJSONView_ResourceDrift(t *testing.T) {
|
||||
|
||||
func TestJSONView_ChangeSummary(t *testing.T) {
|
||||
streams, done := terminal.StreamsForTesting(t)
|
||||
jv := NewJSONView(NewView(streams))
|
||||
jv := NewJSONView(NewView(streams), nil)
|
||||
|
||||
jv.ChangeSummary(&viewsjson.ChangeSummary{
|
||||
Add: 1,
|
||||
@@ -293,7 +293,7 @@ func TestJSONView_ChangeSummary(t *testing.T) {
|
||||
|
||||
func TestJSONView_ChangeSummaryWithImport(t *testing.T) {
|
||||
streams, done := terminal.StreamsForTesting(t)
|
||||
jv := NewJSONView(NewView(streams))
|
||||
jv := NewJSONView(NewView(streams), nil)
|
||||
|
||||
jv.ChangeSummary(&viewsjson.ChangeSummary{
|
||||
Add: 1,
|
||||
@@ -324,7 +324,7 @@ func TestJSONView_ChangeSummaryWithImport(t *testing.T) {
|
||||
|
||||
func TestJSONView_ChangeSummaryWithForget(t *testing.T) {
|
||||
streams, done := terminal.StreamsForTesting(t)
|
||||
jv := NewJSONView(NewView(streams))
|
||||
jv := NewJSONView(NewView(streams), nil)
|
||||
|
||||
jv.ChangeSummary(&viewsjson.ChangeSummary{
|
||||
Add: 1,
|
||||
@@ -355,7 +355,7 @@ func TestJSONView_ChangeSummaryWithForget(t *testing.T) {
|
||||
|
||||
func TestJSONView_Hook(t *testing.T) {
|
||||
streams, done := terminal.StreamsForTesting(t)
|
||||
jv := NewJSONView(NewView(streams))
|
||||
jv := NewJSONView(NewView(streams), nil)
|
||||
|
||||
foo, diags := addrs.ParseModuleInstanceStr("module.foo")
|
||||
if len(diags) > 0 {
|
||||
@@ -395,7 +395,7 @@ func TestJSONView_Hook(t *testing.T) {
|
||||
|
||||
func TestJSONView_Outputs(t *testing.T) {
|
||||
streams, done := terminal.StreamsForTesting(t)
|
||||
jv := NewJSONView(NewView(streams))
|
||||
jv := NewJSONView(NewView(streams), nil)
|
||||
|
||||
jv.Outputs(jsonentities.Outputs{
|
||||
"boop_count": {
|
||||
|
||||
@@ -7,6 +7,7 @@ package views
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
@@ -49,6 +50,66 @@ func NewOperation(vt arguments.ViewType, inAutomation bool, view *View) Operatio
|
||||
}
|
||||
}
|
||||
|
||||
type OperationMulti []Operation
|
||||
|
||||
var _ Operation = (OperationMulti)(nil)
|
||||
|
||||
func (o OperationMulti) Interrupted() {
|
||||
for _, operation := range o {
|
||||
operation.Interrupted()
|
||||
}
|
||||
}
|
||||
|
||||
func (o OperationMulti) FatalInterrupt() {
|
||||
for _, operation := range o {
|
||||
operation.FatalInterrupt()
|
||||
}
|
||||
}
|
||||
|
||||
func (o OperationMulti) Stopping() {
|
||||
for _, operation := range o {
|
||||
operation.Stopping()
|
||||
}
|
||||
}
|
||||
|
||||
func (o OperationMulti) Cancelled(planMode plans.Mode) {
|
||||
for _, operation := range o {
|
||||
operation.Cancelled(planMode)
|
||||
}
|
||||
}
|
||||
|
||||
func (o OperationMulti) EmergencyDumpState(stateFile *statefile.File, enc encryption.StateEncryption) error {
|
||||
var errs []error
|
||||
for _, operation := range o {
|
||||
errs = append(errs, operation.EmergencyDumpState(stateFile, enc))
|
||||
}
|
||||
return errors.Join(errs...)
|
||||
}
|
||||
|
||||
func (o OperationMulti) PlannedChange(change *plans.ResourceInstanceChangeSrc) {
|
||||
for _, operation := range o {
|
||||
operation.PlannedChange(change)
|
||||
}
|
||||
}
|
||||
|
||||
func (o OperationMulti) Plan(plan *plans.Plan, schemas *tofu.Schemas) {
|
||||
for _, operation := range o {
|
||||
operation.Plan(plan, schemas)
|
||||
}
|
||||
}
|
||||
|
||||
func (o OperationMulti) PlanNextStep(planPath string, genConfigPath string) {
|
||||
for _, operation := range o {
|
||||
operation.PlanNextStep(planPath, genConfigPath)
|
||||
}
|
||||
}
|
||||
|
||||
func (o OperationMulti) Diagnostics(diags tfdiags.Diagnostics) {
|
||||
for _, operation := range o {
|
||||
operation.Diagnostics(diags)
|
||||
}
|
||||
}
|
||||
|
||||
type OperationHuman struct {
|
||||
view *View
|
||||
|
||||
|
||||
@@ -508,7 +508,7 @@ func TestOperation_planNextStepInAutomation(t *testing.T) {
|
||||
// This test is not a realistic stream of messages.
|
||||
func TestOperationJSON_logs(t *testing.T) {
|
||||
streams, done := terminal.StreamsForTesting(t)
|
||||
v := &OperationJSON{view: NewJSONView(NewView(streams))}
|
||||
v := &OperationJSON{view: NewJSONView(NewView(streams), nil)}
|
||||
|
||||
// Added an ephemeral resource change to double-check that it's not
|
||||
// shown.
|
||||
@@ -567,7 +567,7 @@ func TestOperationJSON_logs(t *testing.T) {
|
||||
// we upgrade state format in the future.
|
||||
func TestOperationJSON_emergencyDumpState(t *testing.T) {
|
||||
streams, done := terminal.StreamsForTesting(t)
|
||||
v := &OperationJSON{view: NewJSONView(NewView(streams))}
|
||||
v := &OperationJSON{view: NewJSONView(NewView(streams), nil)}
|
||||
|
||||
stateFile := statefile.New(nil, "foo", 1)
|
||||
stateBuf := new(bytes.Buffer)
|
||||
@@ -601,7 +601,7 @@ func TestOperationJSON_emergencyDumpState(t *testing.T) {
|
||||
|
||||
func TestOperationJSON_planNoChanges(t *testing.T) {
|
||||
streams, done := terminal.StreamsForTesting(t)
|
||||
v := &OperationJSON{view: NewJSONView(NewView(streams))}
|
||||
v := &OperationJSON{view: NewJSONView(NewView(streams), nil)}
|
||||
|
||||
plan := &plans.Plan{
|
||||
Changes: plans.NewChanges(),
|
||||
@@ -630,7 +630,7 @@ func TestOperationJSON_planNoChanges(t *testing.T) {
|
||||
|
||||
func TestOperationJSON_plan(t *testing.T) {
|
||||
streams, done := terminal.StreamsForTesting(t)
|
||||
v := &OperationJSON{view: NewJSONView(NewView(streams))}
|
||||
v := &OperationJSON{view: NewJSONView(NewView(streams), nil)}
|
||||
|
||||
root := addrs.RootModuleInstance
|
||||
vpc, diags := addrs.ParseModuleInstanceStr("module.vpc")
|
||||
@@ -799,7 +799,7 @@ func TestOperationJSON_plan(t *testing.T) {
|
||||
|
||||
func TestOperationJSON_planWithImport(t *testing.T) {
|
||||
streams, done := terminal.StreamsForTesting(t)
|
||||
v := &OperationJSON{view: NewJSONView(NewView(streams))}
|
||||
v := &OperationJSON{view: NewJSONView(NewView(streams), nil)}
|
||||
|
||||
root := addrs.RootModuleInstance
|
||||
vpc, diags := addrs.ParseModuleInstanceStr("module.vpc")
|
||||
@@ -947,7 +947,7 @@ func TestOperationJSON_planWithImport(t *testing.T) {
|
||||
|
||||
func TestOperationJSON_planDriftWithMove(t *testing.T) {
|
||||
streams, done := terminal.StreamsForTesting(t)
|
||||
v := &OperationJSON{view: NewJSONView(NewView(streams))}
|
||||
v := &OperationJSON{view: NewJSONView(NewView(streams), nil)}
|
||||
|
||||
root := addrs.RootModuleInstance
|
||||
boop := addrs.Resource{Mode: addrs.ManagedResourceMode, Type: "test_resource", Name: "boop"}
|
||||
@@ -1085,7 +1085,7 @@ func TestOperationJSON_planDriftWithMove(t *testing.T) {
|
||||
|
||||
func TestOperationJSON_planDriftWithMoveRefreshOnly(t *testing.T) {
|
||||
streams, done := terminal.StreamsForTesting(t)
|
||||
v := &OperationJSON{view: NewJSONView(NewView(streams))}
|
||||
v := &OperationJSON{view: NewJSONView(NewView(streams), nil)}
|
||||
|
||||
root := addrs.RootModuleInstance
|
||||
boop := addrs.Resource{Mode: addrs.ManagedResourceMode, Type: "test_resource", Name: "boop"}
|
||||
@@ -1217,7 +1217,7 @@ func TestOperationJSON_planDriftWithMoveRefreshOnly(t *testing.T) {
|
||||
|
||||
func TestOperationJSON_planOutputChanges(t *testing.T) {
|
||||
streams, done := terminal.StreamsForTesting(t)
|
||||
v := &OperationJSON{view: NewJSONView(NewView(streams))}
|
||||
v := &OperationJSON{view: NewJSONView(NewView(streams), nil)}
|
||||
|
||||
root := addrs.RootModuleInstance
|
||||
|
||||
@@ -1303,7 +1303,7 @@ func TestOperationJSON_planOutputChanges(t *testing.T) {
|
||||
|
||||
func TestOperationJSON_plannedChange(t *testing.T) {
|
||||
streams, done := terminal.StreamsForTesting(t)
|
||||
v := &OperationJSON{view: NewJSONView(NewView(streams))}
|
||||
v := &OperationJSON{view: NewJSONView(NewView(streams), nil)}
|
||||
|
||||
root := addrs.RootModuleInstance
|
||||
boop := addrs.Resource{Mode: addrs.ManagedResourceMode, Type: "test_instance", Name: "boop"}
|
||||
|
||||
@@ -7,6 +7,7 @@ package views
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/opentofu/opentofu/internal/command/arguments"
|
||||
"github.com/opentofu/opentofu/internal/tfdiags"
|
||||
@@ -23,19 +24,62 @@ type Plan interface {
|
||||
}
|
||||
|
||||
// NewPlan returns an initialized Plan implementation for the given ViewType.
|
||||
func NewPlan(vt arguments.ViewType, view *View) Plan {
|
||||
switch vt {
|
||||
func NewPlan(args *arguments.Plan, view *View) Plan {
|
||||
human := &PlanHuman{
|
||||
view: view,
|
||||
inAutomation: view.RunningInAutomation(),
|
||||
}
|
||||
|
||||
switch args.ViewType {
|
||||
case arguments.ViewJSON:
|
||||
if args.JsonInto != "" {
|
||||
out, err := os.OpenFile(args.JsonInto, os.O_RDWR|os.O_CREATE, 0600)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return PlanMulti{human, &PlanJSON{
|
||||
view: NewJSONView(view, out),
|
||||
}}
|
||||
}
|
||||
return &PlanJSON{
|
||||
view: NewJSONView(view),
|
||||
view: NewJSONView(view, nil),
|
||||
}
|
||||
case arguments.ViewHuman:
|
||||
return &PlanHuman{
|
||||
view: view,
|
||||
inAutomation: view.RunningInAutomation(),
|
||||
}
|
||||
return human
|
||||
default:
|
||||
panic(fmt.Sprintf("unknown view type %v", vt))
|
||||
panic(fmt.Sprintf("unknown view type %v", args.ViewType))
|
||||
}
|
||||
}
|
||||
|
||||
type PlanMulti []Plan
|
||||
|
||||
var _ Plan = (PlanMulti)(nil)
|
||||
|
||||
func (p PlanMulti) Operation() Operation {
|
||||
var operation OperationMulti
|
||||
for _, plan := range p {
|
||||
operation = append(operation, plan.Operation())
|
||||
}
|
||||
return operation
|
||||
}
|
||||
|
||||
func (p PlanMulti) Hooks() []tofu.Hook {
|
||||
var hooks []tofu.Hook
|
||||
for _, plan := range p {
|
||||
hooks = append(hooks, plan.Hooks()...)
|
||||
}
|
||||
return hooks
|
||||
}
|
||||
|
||||
func (p PlanMulti) Diagnostics(diags tfdiags.Diagnostics) {
|
||||
for _, plan := range p {
|
||||
plan.Diagnostics(diags)
|
||||
}
|
||||
}
|
||||
|
||||
func (p PlanMulti) HelpPrompt() {
|
||||
for _, plan := range p {
|
||||
plan.HelpPrompt()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ import (
|
||||
func TestPlanHuman_operation(t *testing.T) {
|
||||
streams, done := terminal.StreamsForTesting(t)
|
||||
defer done(t)
|
||||
v := NewPlan(arguments.ViewHuman, NewView(streams).SetRunningInAutomation(true)).Operation()
|
||||
v := NewPlan(&arguments.Plan{ViewType: arguments.ViewHuman}, NewView(streams).SetRunningInAutomation(true)).Operation()
|
||||
if hv, ok := v.(*OperationHuman); !ok {
|
||||
t.Fatalf("unexpected return type %t", v)
|
||||
} else if hv.inAutomation != true {
|
||||
@@ -36,7 +36,7 @@ func TestPlanHuman_operation(t *testing.T) {
|
||||
func TestPlanHuman_hooks(t *testing.T) {
|
||||
streams, done := terminal.StreamsForTesting(t)
|
||||
defer done(t)
|
||||
v := NewPlan(arguments.ViewHuman, NewView(streams).SetRunningInAutomation((true)))
|
||||
v := NewPlan(&arguments.Plan{ViewType: arguments.ViewHuman}, NewView(streams).SetRunningInAutomation((true)))
|
||||
hooks := v.Hooks()
|
||||
|
||||
var uiHook *UiHook
|
||||
|
||||
@@ -31,7 +31,7 @@ func NewRefresh(vt arguments.ViewType, view *View) Refresh {
|
||||
switch vt {
|
||||
case arguments.ViewJSON:
|
||||
return &RefreshJSON{
|
||||
view: NewJSONView(view),
|
||||
view: NewJSONView(view, nil),
|
||||
}
|
||||
case arguments.ViewHuman:
|
||||
return &RefreshHuman{
|
||||
|
||||
@@ -78,7 +78,7 @@ func NewTest(vt arguments.ViewType, view *View) Test {
|
||||
switch vt {
|
||||
case arguments.ViewJSON:
|
||||
return &TestJSON{
|
||||
view: NewJSONView(view),
|
||||
view: NewJSONView(view, nil),
|
||||
}
|
||||
case arguments.ViewHuman:
|
||||
return &TestHuman{
|
||||
|
||||
Reference in New Issue
Block a user