Skip to content

Commit 70df13e

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 f3008ac commit 70df13e

File tree

4 files changed

+39
-10
lines changed

4 files changed

+39
-10
lines changed

README.md

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

terraform/parser.go

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ type Parser interface {
1414
// ParseResult represents the result of parsed terraform execution
1515
type ParseResult struct {
1616
Result string
17+
Action string
1718
ExitCode int
1819
Error error
1920
}
@@ -30,8 +31,9 @@ type FmtParser struct {
3031

3132
// PlanParser is a parser for terraform plan
3233
type PlanParser struct {
33-
Pass *regexp.Regexp
34-
Fail *regexp.Regexp
34+
Pass *regexp.Regexp
35+
Action *regexp.Regexp
36+
Fail *regexp.Regexp
3537
}
3638

3739
// ApplyParser is a parser for terraform apply
@@ -55,8 +57,9 @@ func NewFmtParser() *FmtParser {
5557
// NewPlanParser is PlanParser initialized with its Regexp
5658
func NewPlanParser() *PlanParser {
5759
return &PlanParser{
58-
Pass: regexp.MustCompile(`(?m)^(Plan: \d|No changes.)`),
59-
Fail: regexp.MustCompile(`(?m)^(Error: )`),
60+
Pass: regexp.MustCompile(`(?m)^(Plan: \d|No changes.)`),
61+
Action: regexp.MustCompile(`(?m)^(An execution plan has been generated)`),
62+
Fail: regexp.MustCompile(`(?m)^(Error: )`),
6063
}
6164
}
6265

@@ -103,21 +106,30 @@ func (p *PlanParser) Parse(body string) ParseResult {
103106
}
104107
}
105108
lines := strings.Split(body, "\n")
106-
var i int
107-
var result, line string
109+
var i, actionStartIdx int
110+
var result, action, line string
108111
for i, line = range lines {
112+
if p.Action.MatchString(line) {
113+
// action starts with the line: An execution plan...
114+
actionStartIdx = i
115+
}
109116
if p.Pass.MatchString(line) || p.Fail.MatchString(line) {
110117
break
111118
}
112119
}
113120
switch {
114121
case p.Pass.MatchString(line):
115122
result = lines[i]
123+
if actionStartIdx != 0 {
124+
// action ends with the line above summary
125+
action = strings.Join(trimLastNewline(lines[actionStartIdx:i]), "\n")
126+
}
116127
case p.Fail.MatchString(line):
117128
result = strings.Join(trimLastNewline(lines[i:]), "\n")
118129
}
119130
return ParseResult{
120131
Result: result,
132+
Action: action,
121133
ExitCode: exitCode,
122134
Error: nil,
123135
}

terraform/parser_test.go

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,21 @@ func TestPlanParserParse(t *testing.T) {
251251
name: "plan ok pattern",
252252
body: planSuccessResult,
253253
result: ParseResult{
254-
Result: "Plan: 1 to add, 0 to change, 0 to destroy.",
254+
Result: "Plan: 1 to add, 0 to change, 0 to destroy.",
255+
Action: `An execution plan has been generated and is shown below.
256+
Resource actions are indicated with the following symbols:
257+
+ create
258+
259+
Terraform will perform the following actions:
260+
261+
+ google_compute_global_address.my_another_project
262+
id: <computed>
263+
address: <computed>
264+
ip_version: "IPV4"
265+
name: "my-another-project"
266+
project: "my-project"
267+
self_link: <computed>
268+
`,
255269
ExitCode: 0,
256270
Error: nil,
257271
},

terraform/template.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ type FmtTemplate struct {
111111
// PlanTemplate is a default template for terraform plan
112112
type PlanTemplate struct {
113113
Template string
114+
Action string
114115

115116
CommonTemplate
116117
}
@@ -182,7 +183,7 @@ func (t *DefaultTemplate) Execute() (resp string, err error) {
182183
return resp, err
183184
}
184185

185-
// Execute binds the execution result of terraform fmt into tepmlate
186+
// Execute binds the execution result of terraform fmt into template
186187
func (t *FmtTemplate) Execute() (resp string, err error) {
187188
tpl, err := template.New("fmt").Parse(t.Template)
188189
if err != nil {
@@ -202,7 +203,7 @@ func (t *FmtTemplate) Execute() (resp string, err error) {
202203
return resp, err
203204
}
204205

205-
// Execute binds the execution result of terraform plan into tepmlate
206+
// Execute binds the execution result of terraform plan into template
206207
func (t *PlanTemplate) Execute() (resp string, err error) {
207208
tpl, err := template.New("plan").Parse(t.Template)
208209
if err != nil {
@@ -212,6 +213,7 @@ func (t *PlanTemplate) Execute() (resp string, err error) {
212213
if err := tpl.Execute(&b, map[string]interface{}{
213214
"Title": t.Title,
214215
"Message": t.Message,
216+
"Action": t.Action,
215217
"Result": t.Result,
216218
"Body": t.Body,
217219
"Link": t.Link,
@@ -222,7 +224,7 @@ func (t *PlanTemplate) Execute() (resp string, err error) {
222224
return resp, err
223225
}
224226

225-
// Execute binds the execution result of terraform apply into tepmlate
227+
// Execute binds the execution result of terraform apply into template
226228
func (t *ApplyTemplate) Execute() (resp string, err error) {
227229
tpl, err := template.New("apply").Parse(t.Template)
228230
if err != nil {

0 commit comments

Comments
 (0)