Skip to content

Commit 9d42044

Browse files
author
Han Zhou
committed
feat(tf,plan): extract action part from terraform plan output.
**Why** Sometimes we found the part about `Refreshing Terraform state in-memory prior to plan` has too many lines that we do not need to care about in the code review. So make this change can help us to focus on the action part that terraform plan is.
1 parent 7a2ba7c commit 9d42044

File tree

5 files changed

+59
-10
lines changed

5 files changed

+59
-10
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ Placeholder | Usage
7272
---|---
7373
`{{ .Title }}` | Like `## Plan result`
7474
`{{ .Message }}` | A string that can be set from CLI with `--message` option
75+
`{{ .Action }}` | Using in terraform plan, and matched leading message by parsing like `Terraform will perform the following actions:`
7576
`{{ .Result }}` | Matched result by parsing like `Plan: 1 to add` or `No changes`
7677
`{{ .Body }}` | The entire of Terraform execution result
7778
`{{ .Link }}` | The link of the build page on CI

terraform/parser.go

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ type Parser interface {
1515
type ParseResult struct {
1616
Result string
1717
HasDestroy bool
18+
Action string
1819
ExitCode int
1920
Error error
2021
}
@@ -32,6 +33,7 @@ type FmtParser struct {
3233
// PlanParser is a parser for terraform plan
3334
type PlanParser struct {
3435
Pass *regexp.Regexp
36+
Action *regexp.Regexp
3537
Fail *regexp.Regexp
3638
HasDestroy *regexp.Regexp
3739
}
@@ -57,8 +59,9 @@ func NewFmtParser() *FmtParser {
5759
// NewPlanParser is PlanParser initialized with its Regexp
5860
func NewPlanParser() *PlanParser {
5961
return &PlanParser{
60-
Pass: regexp.MustCompile(`(?m)^(Plan: \d|No changes.)`),
61-
Fail: regexp.MustCompile(`(?m)^(Error: )`),
62+
Pass: regexp.MustCompile(`(?m)^(Plan: \d|No changes.)`),
63+
Action: regexp.MustCompile(`(?m)^(An execution plan has been generated)`),
64+
Fail: regexp.MustCompile(`(?m)^(Error: )`),
6265
// "0 to destroy" should be treated as "no destroy"
6366
HasDestroy: regexp.MustCompile(`(?m)([1-9][0-9]* to destroy.)`),
6467
}
@@ -107,16 +110,24 @@ func (p *PlanParser) Parse(body string) ParseResult {
107110
}
108111
}
109112
lines := strings.Split(body, "\n")
110-
var i int
111-
var result, line string
113+
var i, actionStartIdx int
114+
var result, action, line string
112115
for i, line = range lines {
116+
if p.Action.MatchString(line) {
117+
// action starts with the line: An execution plan...
118+
actionStartIdx = i
119+
}
113120
if p.Pass.MatchString(line) || p.Fail.MatchString(line) {
114121
break
115122
}
116123
}
117124
switch {
118125
case p.Pass.MatchString(line):
119126
result = lines[i]
127+
if actionStartIdx != 0 {
128+
// action ends with the line above summary
129+
action = strings.Join(trimLastNewline(lines[actionStartIdx:i]), "\n")
130+
}
120131
case p.Fail.MatchString(line):
121132
result = strings.Join(trimLastNewline(lines[i:]), "\n")
122133
}
@@ -126,6 +137,7 @@ func (p *PlanParser) Parse(body string) ParseResult {
126137
return ParseResult{
127138
Result: result,
128139
HasDestroy: hasDestroy,
140+
Action: action,
129141
ExitCode: exitCode,
130142
Error: nil,
131143
}

terraform/parser_test.go

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ versions.tf
3535
--- old/versions.tf
3636
+++ new/versions.tf
3737
@@ -1,4 +1,4 @@
38-
38+
3939
terraform {
4040
- required_version = ">= 0.12"
4141
+ required_version = ">= 0.12"
@@ -309,8 +309,22 @@ func TestPlanParserParse(t *testing.T) {
309309
result: ParseResult{
310310
Result: "Plan: 1 to add, 0 to change, 0 to destroy.",
311311
HasDestroy: false,
312-
ExitCode: 0,
313-
Error: nil,
312+
Action: `An execution plan has been generated and is shown below.
313+
Resource actions are indicated with the following symbols:
314+
+ create
315+
316+
Terraform will perform the following actions:
317+
318+
+ google_compute_global_address.my_another_project
319+
id: <computed>
320+
address: <computed>
321+
ip_version: "IPV4"
322+
name: "my-another-project"
323+
project: "my-project"
324+
self_link: <computed>
325+
`,
326+
ExitCode: 0,
327+
Error: nil,
314328
},
315329
},
316330
{
@@ -353,15 +367,23 @@ func TestPlanParserParse(t *testing.T) {
353367
result: ParseResult{
354368
Result: "Plan: 0 to add, 0 to change, 1 to destroy.",
355369
HasDestroy: true,
356-
ExitCode: 0,
357-
Error: nil,
370+
Action: `An execution plan has been generated and is shown below.
371+
Resource actions are indicated with the following symbols:
372+
- destroy
373+
374+
Terraform will perform the following actions:
375+
376+
- google_project_iam_member.team_platform[2]
377+
`,
378+
ExitCode: 0,
379+
Error: nil,
358380
},
359381
},
360382
}
361383
for _, testCase := range testCases {
362384
result := NewPlanParser().Parse(testCase.body)
363385
if !reflect.DeepEqual(result, testCase.result) {
364-
t.Errorf("got %v but want %v", result, testCase.result)
386+
t.Errorf("<%s>: got %v but want %v", testCase.name, result, testCase.result)
365387
}
366388
}
367389
}

terraform/template.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ type Template interface {
104104
type CommonTemplate struct {
105105
Title string
106106
Message string
107+
Action string
107108
Result string
108109
Body string
109110
Link string
@@ -261,6 +262,7 @@ func (t *PlanTemplate) Execute() (string, error) {
261262
"Title": t.Title,
262263
"Message": t.Message,
263264
"Result": t.Result,
265+
"Action": t.Action,
264266
"Body": t.Body,
265267
"Link": t.Link,
266268
}
@@ -279,6 +281,7 @@ func (t *DestroyWarningTemplate) Execute() (string, error) {
279281
"Title": t.Title,
280282
"Message": t.Message,
281283
"Result": t.Result,
284+
"Action": t.Action,
282285
"Body": t.Body,
283286
"Link": t.Link,
284287
}

terraform/template_test.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,17 @@ message
450450
},
451451
resp: `a-b-c-d`,
452452
},
453+
{
454+
template: `{{ .Title }}-{{ .Message }}-{{ .Action }}-{{ .Result }}-{{ .Body }}`,
455+
value: CommonTemplate{
456+
Title: "a",
457+
Message: "b",
458+
Action: "action",
459+
Result: "c",
460+
Body: "d",
461+
},
462+
resp: `a-b-action-c-d`,
463+
},
453464
}
454465
for _, testCase := range testCases {
455466
template := NewPlanTemplate(testCase.template)

0 commit comments

Comments
 (0)