Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 64 additions & 0 deletions server/events/command/project_result_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -225,3 +225,67 @@ func TestPlanSuccess_Summary(t *testing.T) {
})
}
}

var Summary string

func BenchmarkPlanSuccess_Summary(b *testing.B) {
var s string

fixtures := map[string]string{
"changes": `
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
- destroy

Terraform will perform the following actions:

- null_resource.hi[1]


Plan: 0 to add, 0 to change, 1 to destroy.`,
"no changes": `
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:

No changes. Infrastructure is up-to-date.`,
"changes outside Terraform": `
Note: Objects have changed outside of Terraform

Terraform detected the following changes made outside of Terraform since the
last "terraform apply":

No changes. Your infrastructure matches the configuration.`,
"changes and changes outside": `
Note: Objects have changed outside of Terraform

Terraform detected the following changes made outside of Terraform since the
last "terraform apply":

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
- destroy

Terraform will perform the following actions:

- null_resource.hi[1]


Plan: 0 to add, 0 to change, 1 to destroy.`,
"empty summary, no matches": `No match, expect empty`,
}

for name, output := range fixtures {
p := &models.PlanSuccess{
TerraformOutput: output,
}

b.Run(name, func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
s = p.Summary()
}

Summary = s
})
}
}
87 changes: 61 additions & 26 deletions server/events/markdown_renderer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2214,8 +2214,7 @@ $$$
}
}

func TestRenderProjectResultsWithEnableDiffMarkdownFormat(t *testing.T) {
tfOutput := `An execution plan has been generated and is shown below.
const tfOutput = `An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
~ update in-place
-/+ destroy and then create replacement
Expand Down Expand Up @@ -2398,30 +2397,31 @@ Terraform will perform the following actions:

Plan: 1 to add, 2 to change, 1 to destroy.
`
cases := []struct {
Description string
Command command.Name
ProjectResults []command.ProjectResult
VCSHost models.VCSHostType
Expected string
}{
{
"single successful plan with diff markdown formatted",
command.Plan,
[]command.ProjectResult{
{
PlanSuccess: &models.PlanSuccess{
TerraformOutput: tfOutput,
LockURL: "lock-url",
RePlanCmd: "atlantis plan -d path -w workspace",
ApplyCmd: "atlantis apply -d path -w workspace",
},
Workspace: "workspace",
RepoRelDir: "path",

var cases = []struct {
Description string
Command command.Name
ProjectResults []command.ProjectResult
VCSHost models.VCSHostType
Expected string
}{
{
"single successful plan with diff markdown formatted",
command.Plan,
[]command.ProjectResult{
{
PlanSuccess: &models.PlanSuccess{
TerraformOutput: tfOutput,
LockURL: "lock-url",
RePlanCmd: "atlantis plan -d path -w workspace",
ApplyCmd: "atlantis apply -d path -w workspace",
},
Workspace: "workspace",
RepoRelDir: "path",
},
models.Github,
`Ran Plan for dir: $path$ workspace: $workspace$
},
models.Github,
`Ran Plan for dir: $path$ workspace: $workspace$

<details><summary>Show Output</summary>

Expand Down Expand Up @@ -2619,8 +2619,10 @@ Plan: 1 to add, 2 to change, 1 to destroy.


`,
},
}
},
}

func TestRenderProjectResultsWithEnableDiffMarkdownFormat(t *testing.T) {
r := events.GetMarkdownRenderer(
false, // GitlabSupportsCommonMark
true, // DisableApplyAll
Expand Down Expand Up @@ -2650,3 +2652,36 @@ Plan: 1 to add, 2 to change, 1 to destroy.
})
}
}

var Render string

func BenchmarkRenderProjectResultsWithEnableDiffMarkdownFormat(b *testing.B) {
var render string

r := events.GetMarkdownRenderer(
false, // GitlabSupportsCommonMark
true, // DisableApplyAll
true, // DisableApply
false, // DisableMarkdownFolding
false, // DisableRepoLocking
true, // EnableDiffMarkdownFormat
"", // MarkdownTemplateOverridesDir
)

for _, c := range cases {
b.Run(c.Description, func(b *testing.B) {
res := command.Result{
ProjectResults: c.ProjectResults,
}
for _, verbose := range []bool{true, false} {
b.Run(fmt.Sprintf("verbose %t", verbose), func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
render = r.Render(res, c.Command, "log", verbose, c.VCSHost)
}
Render = render
})
}
})
}
}
30 changes: 18 additions & 12 deletions server/events/models/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -366,28 +366,34 @@ type PlanSuccess struct {
HasDiverged bool
}

// Summary regexes
var (
reChangesOutside = regexp.MustCompile(`Note: Objects have changed outside of Terraform`)
rePlanChanges = regexp.MustCompile(`Plan: \d+ to add, \d+ to change, \d+ to destroy.`)
reNoChanges = regexp.MustCompile(`No changes. (Infrastructure is up-to-date|Your infrastructure matches the configuration).`)
)

// Summary extracts one line summary of plan changes from TerraformOutput.
func (p *PlanSuccess) Summary() string {
note := ""
r := regexp.MustCompile(`Note: Objects have changed outside of Terraform`)
if match := r.FindString(p.TerraformOutput); match != "" {
note = fmt.Sprintf("\n**%s**\n", match)
if match := reChangesOutside.FindString(p.TerraformOutput); match != "" {
note = "\n**" + match + "**\n"
}

r = regexp.MustCompile(`Plan: \d+ to add, \d+ to change, \d+ to destroy.`)
if match := r.FindString(p.TerraformOutput); match != "" {
if match := rePlanChanges.FindString(p.TerraformOutput); match != "" {
return note + match
}
r = regexp.MustCompile(`No changes. (Infrastructure is up-to-date|Your infrastructure matches the configuration).`)
return note + r.FindString(p.TerraformOutput)
return note + reNoChanges.FindString(p.TerraformOutput)
}

// Diff Markdown regexes
var (
diffKeywordRegex = regexp.MustCompile(`(?m)^( +)([-+~]\s)(.*)(\s=\s|\s->\s|<<|\{|\(known after apply\)| {2,}[^ ]+:.*)(.*)`)
diffListRegex = regexp.MustCompile(`(?m)^( +)([-+~]\s)(".*",)`)
diffTildeRegex = regexp.MustCompile(`(?m)^~`)
)

// DiffMarkdownFormattedTerraformOutput formats the Terraform output to match diff markdown format
func (p PlanSuccess) DiffMarkdownFormattedTerraformOutput() string {
diffKeywordRegex := regexp.MustCompile(`(?m)^( +)([-+~]\s)(.*)(\s=\s|\s->\s|<<|\{|\(known after apply\)| {2,}[^ ]+:.*)(.*)`)
diffListRegex := regexp.MustCompile(`(?m)^( +)([-+~]\s)(".*",)`)
diffTildeRegex := regexp.MustCompile(`(?m)^~`)

formattedTerraformOutput := diffKeywordRegex.ReplaceAllString(p.TerraformOutput, "$2$1$3$4$5")
formattedTerraformOutput = diffListRegex.ReplaceAllString(formattedTerraformOutput, "$2$1$3")
formattedTerraformOutput = diffTildeRegex.ReplaceAllString(formattedTerraformOutput, "!")
Expand Down