Skip to content

Commit ecfbdaf

Browse files
add number of action invocations to change summary
1 parent eee744c commit ecfbdaf

File tree

8 files changed

+165
-64
lines changed

8 files changed

+165
-64
lines changed
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
{"@level":"info","@message":"Terraform 0.15.0-dev","@module":"terraform.ui","terraform":"0.15.0-dev","type":"version","ui":"0.1.0"}
22
{"@level":"warn","@message":"Warning: Deprecated flag: -state","@module":"terraform.ui","diagnostic":{"detail":"Use the \"path\" attribute within the \"local\" backend to specify a file for state storage","severity":"warning","summary":"Deprecated flag: -state"},"type":"diagnostic"}
33
{"@level":"info","@message":"test_instance.foo: Plan to create","@module":"terraform.ui","change":{"resource":{"addr":"test_instance.foo","module":"","resource":"test_instance.foo","implied_provider":"test","resource_type":"test_instance","resource_name":"foo","resource_key":null},"action":"create"},"type":"planned_change"}
4-
{"@level":"info","@message":"Plan: 1 to add, 0 to change, 0 to destroy.","@module":"terraform.ui","changes":{"add":1,"import":0,"change":0,"remove":0,"operation":"plan"},"type":"change_summary"}
4+
{"@level":"info","@message":"Plan: 1 to add, 0 to change, 0 to destroy.","@module":"terraform.ui","changes":{"action_invocation":0,"add":1,"import":0,"change":0,"remove":0,"operation":"plan"},"type":"change_summary"}
55
{"@level":"info","@message":"test_instance.foo: Creating...","@module":"terraform.ui","hook":{"resource":{"addr":"test_instance.foo","module":"","resource":"test_instance.foo","implied_provider":"test","resource_type":"test_instance","resource_name":"foo","resource_key":null},"action":"create"},"type":"apply_start"}
66
{"@level":"info","@message":"test_instance.foo: Creation complete after 0s","@module":"terraform.ui","hook":{"resource":{"addr":"test_instance.foo","module":"","resource":"test_instance.foo","implied_provider":"test","resource_type":"test_instance","resource_name":"foo","resource_key":null},"action":"create","elapsed_seconds":0},"type":"apply_complete"}
7-
{"@level":"info","@message":"Apply complete! Resources: 1 added, 0 changed, 0 destroyed.","@module":"terraform.ui","changes":{"add":1,"import":0,"change":0,"remove":0,"operation":"apply"},"type":"change_summary"}
7+
{"@level":"info","@message":"Apply complete! Resources: 1 added, 0 changed, 0 destroyed.","@module":"terraform.ui","changes":{"action_invocation":0,"add":1,"import":0,"change":0,"remove":0,"operation":"apply"},"type":"change_summary"}
88
{"@level":"info","@message":"Outputs: 0","@module":"terraform.ui","outputs":{},"type":"outputs"}

internal/command/testdata/plan/output.jsonlog

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
{"@level":"info","@message":"data.test_data_source.a: Refreshing...","@module":"terraform.ui","hook":{"resource":{"addr":"data.test_data_source.a","module":"","resource":"data.test_data_source.a","implied_provider":"test","resource_type":"test_data_source","resource_name":"a","resource_key":null},"action":"read"},"type":"apply_start"}
33
{"@level":"info","@message":"data.test_data_source.a: Refresh complete after 0s [id=zzzzz]","@module":"terraform.ui","hook":{"resource":{"addr":"data.test_data_source.a","module":"","resource":"data.test_data_source.a","implied_provider":"test","resource_type":"test_data_source","resource_name":"a","resource_key":null},"action":"read","id_key":"id","id_value":"zzzzz","elapsed_seconds":0},"type":"apply_complete"}
44
{"@level":"info","@message":"test_instance.foo: Plan to create","@module":"terraform.ui","change":{"resource":{"addr":"test_instance.foo","module":"","resource":"test_instance.foo","implied_provider":"test","resource_type":"test_instance","resource_name":"foo","resource_key":null},"action":"create"},"type":"planned_change"}
5-
{"@level":"info","@message":"Plan: 1 to add, 0 to change, 0 to destroy.","@module":"terraform.ui","changes":{"add":1,"import":0,"change":0,"remove":0,"operation":"plan"},"type":"change_summary"}
5+
{"@level":"info","@message":"Plan: 1 to add, 0 to change, 0 to destroy.","@module":"terraform.ui","changes":{"action_invocation":0,"add":1,"import":0,"change":0,"remove":0,"operation":"plan"},"type":"change_summary"}

internal/command/views/apply.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -138,11 +138,12 @@ func (v *ApplyJSON) ResourceCount(stateOutPath string) {
138138
operation = json.OperationDestroyed
139139
}
140140
v.view.ChangeSummary(&json.ChangeSummary{
141-
Add: v.countHook.Added,
142-
Change: v.countHook.Changed,
143-
Remove: v.countHook.Removed,
144-
Import: v.countHook.Imported,
145-
Operation: operation,
141+
Add: v.countHook.Added,
142+
Change: v.countHook.Changed,
143+
Remove: v.countHook.Removed,
144+
Import: v.countHook.Imported,
145+
ActionInvocation: v.countHook.ActionInvocation,
146+
Operation: operation,
146147
})
147148
}
148149

internal/command/views/hook_count.go

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,11 @@ import (
1616
// countHook is a hook that counts the number of resources
1717
// added, removed, changed during the course of an apply.
1818
type countHook struct {
19-
Added int
20-
Changed int
21-
Removed int
22-
Imported int
19+
Added int
20+
Changed int
21+
Removed int
22+
Imported int
23+
ActionInvocation int
2324

2425
ToAdd int
2526
ToChange int
@@ -43,6 +44,7 @@ func (h *countHook) Reset() {
4344
h.Changed = 0
4445
h.Removed = 0
4546
h.Imported = 0
47+
h.ActionInvocation = 0
4648
}
4749

4850
func (h *countHook) PreApply(id terraform.HookResourceIdentity, dk addrs.DeposedKey, action plans.Action, priorState, plannedNewState cty.Value) (terraform.HookAction, error) {
@@ -116,3 +118,11 @@ func (h *countHook) PostApplyImport(id terraform.HookResourceIdentity, importing
116118
h.Imported++
117119
return terraform.HookActionContinue, nil
118120
}
121+
122+
func (h *countHook) CompleteAction(id terraform.HookActionIdentity, err error) (terraform.HookAction, error) {
123+
h.Lock()
124+
defer h.Unlock()
125+
126+
h.ActionInvocation++
127+
return terraform.HookActionContinue, nil
128+
}

internal/command/views/json/change_summary.go

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@
33

44
package json
55

6-
import "fmt"
6+
import (
7+
"fmt"
8+
"strings"
9+
)
710

811
type Operation string
912

@@ -14,31 +17,46 @@ const (
1417
)
1518

1619
type ChangeSummary struct {
17-
Add int `json:"add"`
18-
Change int `json:"change"`
19-
Import int `json:"import"`
20-
Remove int `json:"remove"`
21-
Operation Operation `json:"operation"`
20+
Add int `json:"add"`
21+
Change int `json:"change"`
22+
Import int `json:"import"`
23+
Remove int `json:"remove"`
24+
ActionInvocation int `json:"action_invocation"`
25+
Operation Operation `json:"operation"`
2226
}
2327

2428
// The summary strings for apply and plan are accidentally a public interface
2529
// used by HCP Terraform and Terraform Enterprise, so the exact formats of
2630
// these strings are important.
2731
func (cs *ChangeSummary) String() string {
32+
var buf strings.Builder
2833
switch cs.Operation {
2934
case OperationApplied:
35+
buf.WriteString("Apply complete! Resources: ")
3036
if cs.Import > 0 {
31-
return fmt.Sprintf("Apply complete! Resources: %d imported, %d added, %d changed, %d destroyed.", cs.Import, cs.Add, cs.Change, cs.Remove)
37+
buf.WriteString(fmt.Sprintf("%d imported, ", cs.Import))
38+
}
39+
buf.WriteString(fmt.Sprintf("%d added, %d changed, %d destroyed.", cs.Add, cs.Change, cs.Remove))
40+
if cs.ActionInvocation > 0 {
41+
buf.WriteString(fmt.Sprintf(" %d actions invoked.", cs.ActionInvocation))
3242
}
33-
return fmt.Sprintf("Apply complete! Resources: %d added, %d changed, %d destroyed.", cs.Add, cs.Change, cs.Remove)
3443
case OperationDestroyed:
35-
return fmt.Sprintf("Destroy complete! Resources: %d destroyed.", cs.Remove)
44+
buf.WriteString(fmt.Sprintf("Destroy complete! Resources: %d destroyed.", cs.Remove))
45+
if cs.ActionInvocation > 0 {
46+
buf.WriteString(fmt.Sprintf(" %d actions invoked.", cs.ActionInvocation))
47+
}
3648
case OperationPlanned:
49+
buf.WriteString("Plan: ")
3750
if cs.Import > 0 {
38-
return fmt.Sprintf("Plan: %d to import, %d to add, %d to change, %d to destroy.", cs.Import, cs.Add, cs.Change, cs.Remove)
51+
buf.WriteString(fmt.Sprintf("%d to import, ", cs.Import))
52+
}
53+
buf.WriteString(fmt.Sprintf("%d to add, %d to change, %d to destroy.", cs.Add, cs.Change, cs.Remove))
54+
if cs.ActionInvocation > 0 {
55+
buf.WriteString(fmt.Sprintf(" %d actions to be invoked.", cs.ActionInvocation))
3956
}
40-
return fmt.Sprintf("Plan: %d to add, %d to change, %d to destroy.", cs.Add, cs.Change, cs.Remove)
4157
default:
42-
return fmt.Sprintf("%s: %d add, %d change, %d destroy", cs.Operation, cs.Add, cs.Change, cs.Remove)
58+
buf.WriteString(fmt.Sprintf("%s: %d add, %d change, %d destroy", cs.Operation, cs.Add, cs.Change, cs.Remove))
4359
}
60+
61+
return buf.String()
4462
}

internal/command/views/json_view_test.go

Lines changed: 75 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -252,11 +252,12 @@ func TestJSONView_ChangeSummary(t *testing.T) {
252252
"@module": "terraform.ui",
253253
"type": "change_summary",
254254
"changes": map[string]interface{}{
255-
"add": float64(1),
256-
"import": float64(0),
257-
"change": float64(2),
258-
"remove": float64(3),
259-
"operation": "apply",
255+
"action_invocation": float64(0),
256+
"add": float64(1),
257+
"import": float64(0),
258+
"change": float64(2),
259+
"remove": float64(3),
260+
"operation": "apply",
260261
},
261262
},
262263
}
@@ -282,11 +283,75 @@ func TestJSONView_ChangeSummaryWithImport(t *testing.T) {
282283
"@module": "terraform.ui",
283284
"type": "change_summary",
284285
"changes": map[string]interface{}{
285-
"add": float64(1),
286-
"change": float64(2),
287-
"remove": float64(3),
288-
"import": float64(1),
289-
"operation": "apply",
286+
"action_invocation": float64(0),
287+
"add": float64(1),
288+
"change": float64(2),
289+
"remove": float64(3),
290+
"import": float64(1),
291+
"operation": "apply",
292+
},
293+
},
294+
}
295+
testJSONViewOutputEquals(t, done(t).Stdout(), want)
296+
}
297+
298+
func TestJSONView_ChangeSummaryWithActionInvocations(t *testing.T) {
299+
streams, done := terminal.StreamsForTesting(t)
300+
jv := NewJSONView(NewView(streams))
301+
302+
jv.ChangeSummary(&viewsjson.ChangeSummary{
303+
Add: 1,
304+
Change: 2,
305+
Remove: 3,
306+
ActionInvocation: 23,
307+
Operation: viewsjson.OperationApplied,
308+
})
309+
310+
want := []map[string]interface{}{
311+
{
312+
"@level": "info",
313+
"@message": "Apply complete! Resources: 1 added, 2 changed, 3 destroyed. 23 actions invoked.",
314+
"@module": "terraform.ui",
315+
"type": "change_summary",
316+
"changes": map[string]interface{}{
317+
"action_invocation": float64(23),
318+
"add": float64(1),
319+
"change": float64(2),
320+
"remove": float64(3),
321+
"import": float64(0),
322+
"operation": "apply",
323+
},
324+
},
325+
}
326+
testJSONViewOutputEquals(t, done(t).Stdout(), want)
327+
}
328+
329+
func TestJSONView_ChangeSummaryWithActionInvocationsAndImports(t *testing.T) {
330+
streams, done := terminal.StreamsForTesting(t)
331+
jv := NewJSONView(NewView(streams))
332+
333+
jv.ChangeSummary(&viewsjson.ChangeSummary{
334+
Add: 1,
335+
Change: 2,
336+
Remove: 3,
337+
Import: 2,
338+
ActionInvocation: 23,
339+
Operation: viewsjson.OperationApplied,
340+
})
341+
342+
want := []map[string]interface{}{
343+
{
344+
"@level": "info",
345+
"@message": "Apply complete! Resources: 2 imported, 1 added, 2 changed, 3 destroyed. 23 actions invoked.",
346+
"@module": "terraform.ui",
347+
"type": "change_summary",
348+
"changes": map[string]interface{}{
349+
"action_invocation": float64(23),
350+
"add": float64(1),
351+
"change": float64(2),
352+
"remove": float64(3),
353+
"import": float64(2),
354+
"operation": "apply",
290355
},
291356
},
292357
}

internal/command/views/operation.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@ func (v *OperationJSON) Plan(plan *plans.Plan, schemas *terraform.Schemas) {
254254
v.view.PlannedChange(json.NewResourceInstanceChange(change))
255255
}
256256
}
257+
cs.ActionInvocation = len(plan.Changes.ActionInvocations)
257258

258259
v.view.ChangeSummary(cs)
259260

internal/command/views/operation_test.go

Lines changed: 36 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -573,11 +573,12 @@ func TestOperationJSON_planNoChanges(t *testing.T) {
573573
"@module": "terraform.ui",
574574
"type": "change_summary",
575575
"changes": map[string]interface{}{
576-
"operation": "plan",
577-
"add": float64(0),
578-
"import": float64(0),
579-
"change": float64(0),
580-
"remove": float64(0),
576+
"operation": "plan",
577+
"action_invocation": float64(0),
578+
"add": float64(0),
579+
"import": float64(0),
580+
"change": float64(0),
581+
"remove": float64(0),
581582
},
582583
},
583584
}
@@ -741,11 +742,12 @@ func TestOperationJSON_plan(t *testing.T) {
741742
"@module": "terraform.ui",
742743
"type": "change_summary",
743744
"changes": map[string]interface{}{
744-
"operation": "plan",
745-
"add": float64(3),
746-
"import": float64(0),
747-
"change": float64(1),
748-
"remove": float64(3),
745+
"operation": "plan",
746+
"action_invocation": float64(0),
747+
"add": float64(3),
748+
"import": float64(0),
749+
"change": float64(1),
750+
"remove": float64(3),
749751
},
750752
},
751753
}
@@ -888,11 +890,12 @@ func TestOperationJSON_planWithImport(t *testing.T) {
888890
"@module": "terraform.ui",
889891
"type": "change_summary",
890892
"changes": map[string]interface{}{
891-
"operation": "plan",
892-
"add": float64(1),
893-
"import": float64(4),
894-
"change": float64(1),
895-
"remove": float64(2),
893+
"operation": "plan",
894+
"action_invocation": float64(0),
895+
"add": float64(1),
896+
"import": float64(4),
897+
"change": float64(1),
898+
"remove": float64(2),
896899
},
897900
},
898901
}
@@ -1025,11 +1028,12 @@ func TestOperationJSON_planDriftWithMove(t *testing.T) {
10251028
"@module": "terraform.ui",
10261029
"type": "change_summary",
10271030
"changes": map[string]interface{}{
1028-
"operation": "plan",
1029-
"add": float64(0),
1030-
"import": float64(0),
1031-
"change": float64(0),
1032-
"remove": float64(0),
1031+
"operation": "plan",
1032+
"action_invocation": float64(0),
1033+
"add": float64(0),
1034+
"import": float64(0),
1035+
"change": float64(0),
1036+
"remove": float64(0),
10331037
},
10341038
},
10351039
}
@@ -1156,11 +1160,12 @@ func TestOperationJSON_planDriftWithMoveRefreshOnly(t *testing.T) {
11561160
"@module": "terraform.ui",
11571161
"type": "change_summary",
11581162
"changes": map[string]interface{}{
1159-
"operation": "plan",
1160-
"add": float64(0),
1161-
"import": float64(0),
1162-
"change": float64(0),
1163-
"remove": float64(0),
1163+
"operation": "plan",
1164+
"action_invocation": float64(0),
1165+
"add": float64(0),
1166+
"import": float64(0),
1167+
"change": float64(0),
1168+
"remove": float64(0),
11641169
},
11651170
},
11661171
}
@@ -1216,11 +1221,12 @@ func TestOperationJSON_planOutputChanges(t *testing.T) {
12161221
"@module": "terraform.ui",
12171222
"type": "change_summary",
12181223
"changes": map[string]interface{}{
1219-
"operation": "plan",
1220-
"add": float64(0),
1221-
"import": float64(0),
1222-
"change": float64(0),
1223-
"remove": float64(0),
1224+
"operation": "plan",
1225+
"action_invocation": float64(0),
1226+
"add": float64(0),
1227+
"import": float64(0),
1228+
"change": float64(0),
1229+
"remove": float64(0),
12241230
},
12251231
},
12261232
// Output changes

0 commit comments

Comments
 (0)