Skip to content

Commit

Permalink
JSON view: Plan summary for applying a plan file
Browse files Browse the repository at this point in the history
  • Loading branch information
magodo committed Dec 25, 2024
1 parent 572d12b commit e7c642a
Show file tree
Hide file tree
Showing 3 changed files with 4 additions and 94 deletions.
8 changes: 4 additions & 4 deletions internal/backend/local/backend_apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -224,10 +224,10 @@ func (b *Local) opApply(
op.ReportResult(runningOp, diags)
return
}
for _, change := range plan.Changes.Resources {
if change.Action != plans.NoOp {
op.View.PlannedChange(change)
}
if _, ok := op.View.(*views.OperationJSON); ok {
// We don't display the plan for OperationHuman because the output of
// Plan already includes the change details for all resource instances.
op.View.Plan(plan, schemas)
}
}

Expand Down
16 changes: 0 additions & 16 deletions internal/command/views/operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ type Operation interface {

EmergencyDumpState(stateFile *statefile.File) error

PlannedChange(change *plans.ResourceInstanceChangeSrc)
Plan(plan *plans.Plan, schemas *terraform.Schemas)
PlanNextStep(planPath string, genConfigPath string)

Expand Down Expand Up @@ -130,13 +129,6 @@ func (v *OperationHuman) Plan(plan *plans.Plan, schemas *terraform.Schemas) {
renderer.RenderHumanPlan(jplan, plan.UIMode, opts...)
}

func (v *OperationHuman) PlannedChange(change *plans.ResourceInstanceChangeSrc) {
// PlannedChange is primarily for machine-readable output in order to
// get a per-resource-instance change description. We don't use it
// with OperationHuman because the output of Plan already includes the
// change details for all resource instances.
}

// PlanNextStep gives the user some next-steps, unless we're running in an
// automation tool which is presumed to provide its own UI for further actions.
func (v *OperationHuman) PlanNextStep(planPath string, genConfigPath string) {
Expand Down Expand Up @@ -268,14 +260,6 @@ func (v *OperationJSON) Plan(plan *plans.Plan, schemas *terraform.Schemas) {
}
}

func (v *OperationJSON) PlannedChange(change *plans.ResourceInstanceChangeSrc) {
if change.Action == plans.Delete && change.Addr.Resource.Resource.Mode == addrs.DataResourceMode {
// Avoid rendering data sources on deletion
return
}
v.view.PlannedChange(json.NewResourceInstanceChange(change))
}

// PlanNextStep does nothing for the JSON view as it is a hook for user-facing
// output only applicable to human-readable UI.
func (v *OperationJSON) PlanNextStep(planPath string, genConfigPath string) {
Expand Down
74 changes: 0 additions & 74 deletions internal/command/views/operation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1253,77 +1253,3 @@ func TestOperationJSON_planOutputChanges(t *testing.T) {

testJSONViewOutputEquals(t, done(t).Stdout(), want)
}

func TestOperationJSON_plannedChange(t *testing.T) {
streams, done := terminal.StreamsForTesting(t)
v := &OperationJSON{view: NewJSONView(NewView(streams))}

root := addrs.RootModuleInstance
boop := addrs.Resource{Mode: addrs.ManagedResourceMode, Type: "test_instance", Name: "boop"}
derp := addrs.Resource{Mode: addrs.DataResourceMode, Type: "test_source", Name: "derp"}

// Replace requested by user
v.PlannedChange(&plans.ResourceInstanceChangeSrc{
Addr: boop.Instance(addrs.IntKey(0)).Absolute(root),
PrevRunAddr: boop.Instance(addrs.IntKey(0)).Absolute(root),
ChangeSrc: plans.ChangeSrc{Action: plans.DeleteThenCreate},
ActionReason: plans.ResourceInstanceReplaceByRequest,
})

// Simple create
v.PlannedChange(&plans.ResourceInstanceChangeSrc{
Addr: boop.Instance(addrs.IntKey(1)).Absolute(root),
PrevRunAddr: boop.Instance(addrs.IntKey(1)).Absolute(root),
ChangeSrc: plans.ChangeSrc{Action: plans.Create},
})

// Data source deletion
v.PlannedChange(&plans.ResourceInstanceChangeSrc{
Addr: derp.Instance(addrs.NoKey).Absolute(root),
PrevRunAddr: derp.Instance(addrs.NoKey).Absolute(root),
ChangeSrc: plans.ChangeSrc{Action: plans.Delete},
})

// Expect only two messages, as the data source deletion should be a no-op
want := []map[string]interface{}{
{
"@level": "info",
"@message": "test_instance.boop[0]: Plan to replace",
"@module": "terraform.ui",
"type": "planned_change",
"change": map[string]interface{}{
"action": "replace",
"reason": "requested",
"resource": map[string]interface{}{
"addr": `test_instance.boop[0]`,
"implied_provider": "test",
"module": "",
"resource": `test_instance.boop[0]`,
"resource_key": float64(0),
"resource_name": "boop",
"resource_type": "test_instance",
},
},
},
{
"@level": "info",
"@message": "test_instance.boop[1]: Plan to create",
"@module": "terraform.ui",
"type": "planned_change",
"change": map[string]interface{}{
"action": "create",
"resource": map[string]interface{}{
"addr": `test_instance.boop[1]`,
"implied_provider": "test",
"module": "",
"resource": `test_instance.boop[1]`,
"resource_key": float64(1),
"resource_name": "boop",
"resource_type": "test_instance",
},
},
},
}

testJSONViewOutputEquals(t, done(t).Stdout(), want)
}

0 comments on commit e7c642a

Please sign in to comment.