diff --git a/server/apply_executor.go b/server/apply_executor.go
index b1d5f5de1..c6a00230e 100644
--- a/server/apply_executor.go
+++ b/server/apply_executor.go
@@ -31,37 +31,6 @@ type ApplyExecutor struct {
workspace *Workspace
}
-/** Result Types **/
-type ApplyFailure struct {
- Command string
- Output string
- ErrorMessage string
-}
-
-func (a ApplyFailure) Template() *CompiledTemplate {
- return ApplyFailureTmpl
-}
-
-type ApplySuccess struct {
- Output string
-}
-
-func (a ApplySuccess) Template() *CompiledTemplate {
- return ApplySuccessTmpl
-}
-
-type PullNotApprovedFailure struct{}
-
-func (p PullNotApprovedFailure) Template() *CompiledTemplate {
- return PullNotApprovedFailureTmpl
-}
-
-type NoPlansFailure struct{}
-
-func (n NoPlansFailure) Template() *CompiledTemplate {
- return NoPlansFailureTmpl
-}
-
// todo: why pass githbub.client here, just use the one on the struct
func (a *ApplyExecutor) execute(ctx *CommandContext, github *github.Client) {
a.githubStatus.Update(ctx.BaseRepo, ctx.Pull, Pending, ApplyStep)
diff --git a/server/command_handler.go b/server/command_handler.go
index 75772e091..f53f4039a 100644
--- a/server/command_handler.go
+++ b/server/command_handler.go
@@ -17,6 +17,30 @@ type CommandHandler struct {
logger *logging.SimpleLogger
}
+type CommandResponse struct {
+ Error error
+ Failure string
+ ProjectResults []ProjectResult
+ Command CommandType
+}
+
+type ProjectResult struct {
+ Path string
+ Error error
+ Failure string
+ PlanSuccess *PlanSuccess
+ ApplySuccess string
+}
+func (p ProjectResult) Status() Status {
+ if p.Error != nil {
+ return Error
+ }
+ if p.Failure != "" {
+ return Failure
+ }
+ return Success
+}
+
type CommandType int
const (
diff --git a/server/github_comment_renderer.go b/server/github_comment_renderer.go
index e45486b30..e5365d43a 100644
--- a/server/github_comment_renderer.go
+++ b/server/github_comment_renderer.go
@@ -7,149 +7,45 @@ import (
"text/template"
)
+var singlePathTmpl = template.Must(template.New("").Parse("{{ range $result := .Results }}{{$result}}{{end}}\n" + logTmpl))
+var multiPathTmpl = template.Must(template.New("").Parse(
+ "Ran {{.Command}} in {{ len .Results }} directories:\n" +
+ "{{ range $path, $result := .Results }}" +
+ " * `{{$path}}`\n" +
+ "{{end}}\n" +
+ "{{ range $path, $result := .Results }}" +
+ "##{{$path}}/\n" +
+ "{{$result}}\n" +
+ "---{{end}}" +
+ logTmpl))
+var planSuccessTmpl = template.Must(template.New("").Parse(
+ "```diff\n" +
+ "{{.TerraformOutput}}\n" +
+ "```\n\n" +
+ "* To **discard** this plan click [here]({{.LockURL}})."))
+var applySuccessTmpl = template.Must(template.New("").Parse(
+ "```diff\n" +
+ "{{.Output}}\n" +
+ "```"))
+var errTmplText = "**{{.Command}} Error**\n" +
+ "```\n" +
+ "{{.Error}}\n" +
+ "```\n"
+var errTmpl = template.Must(template.New("").Parse(errTmplText))
+var errWithLogTmpl = template.Must(template.New("").Parse(errTmplText + logTmpl))
+var failureTmplText = "**{{.Command}} Failed**: {{.Failure}}\n"
+var failureTmpl = template.Must(template.New("").Parse(failureTmplText))
+var failureWithLogTmpl = template.Must(template.New("").Parse(failureTmplText + logTmpl))
+var logTmpl = "{{if .Verbose}}\nLog
\n \n\n```\n{{.Log}}```\n
{{end}}\n"
+
// GithubCommentRenderer renders responses as GitHub comments
type GithubCommentRenderer struct{}
-// CompiledTemplate represents a single template with both its source text and its compiled
-// template. We compile the templates in init()
-type CompiledTemplate struct {
- text string
- Template *template.Template
-}
-
-// PathResultRendered is used as an intermediary data container. We render the individual path results
-// into Render and then pass around this struct to be rendered into the main templates
-type PathResultRendered struct {
- ProjectResult
- Rendered string
-}
-
-// todo: once this is in its own package don't need to append Tmpl
-var (
- // If you add a template here, be sure to add it to init() so it gets compiled
- SetupFailure *CompiledTemplate = &CompiledTemplate{
- text: "**{{.Command}} Failed**:\n{{.Output}}\n" + logTmpl,
- }
- SinglePath *CompiledTemplate = &CompiledTemplate{
- // we know we'll only have one result
- text: "{{ range $result := .Results }}{{$result}}{{end}}\n" + logTmpl,
- }
- MultiPath *CompiledTemplate = &CompiledTemplate{
- text: "Ran {{.Command}} in {{ len .Results }} directories:\n" +
- "{{ range $path, $result := .Results }}" +
- " * `{{$path}}`\n" +
- "{{end}}\n" +
- "{{ range $path, $result := .Results }}" +
- "##{{$path}}/\n" +
- "{{$result}}\n" +
- "---{{end}}" +
- logTmpl,
- }
- PlanSuccessTmpl *CompiledTemplate = &CompiledTemplate{
- text: "```diff\n" +
- "{{.TerraformOutput}}\n" +
- "```\n\n" +
- "* To **discard** this plan click [here]({{.LockURL}}).",
- }
- RunLockedFailureTmpl *CompiledTemplate = &CompiledTemplate{
- text: "This plan is currently locked by #{{.LockingPullNum}}\n" +
- "The locking plan must be applied or discarded before future plans can execute.",
- }
- TerraformFailureTmpl *CompiledTemplate = &CompiledTemplate{
- text: "**Atlantis encountered an error while running...**\n" +
- "```\n" +
- "$ {{.Command}}\n" +
- "{{.Output}}\n" +
- "```",
- }
- EnvironmentFileNotFoundFailureTmpl *CompiledTemplate = &CompiledTemplate{
- text: "Environment file did not exist {{.Filename}}",
- }
- EnvironmentErrorTmpl *CompiledTemplate = &CompiledTemplate{
- text: "Please specify environment variable while running plan\n" +
- "For example: `atlantis plan {environment_name}`\n" +
- "*Environments that are available can be found under the `env/` folder of the terraform stack.*",
- }
- ApplySuccessTmpl *CompiledTemplate = &CompiledTemplate{
- text: "```diff\n" +
- "{{.Output}}\n" +
- "```",
- }
- ApplyFailureTmpl *CompiledTemplate = &CompiledTemplate{
- text: "**Apply Failed**:\n" +
- "```bash\n" +
- "$ {{.Command}}\n" +
- "{{.Output}}\n" +
- "{{.ErrorMessage}}\n" +
- "```",
- }
- PullNotApprovedFailureTmpl *CompiledTemplate = &CompiledTemplate{
- text: "Pull Request must be **Approved** before running apply.",
- }
- NoPlansFailureTmpl *CompiledTemplate = &CompiledTemplate{
- text: "0 plans found",
- }
- ErrorTmpl *CompiledTemplate = &CompiledTemplate{
- text: "**Atlantis encountered an error:**\n" +
- "```\n" +
- "{{.Error}}\n" +
- "```\n" +
- "Log:\n" +
- "```\n" +
- "{{.Log}}```",
- }
- GeneralErrorTmpl *CompiledTemplate = &CompiledTemplate{
- text: "{{.Error}}",
- }
- ErrTmpl *CompiledTemplate = &CompiledTemplate{
- text: "**{{.Command}} Error**\n" +
- "```\n" +
- "{{.Error}}\n" +
- "```\n",
- }
- ErrWithLogTmpl *CompiledTemplate = &CompiledTemplate{
- text: ErrTmpl.text + logTmpl,
- }
- FailureTmpl *CompiledTemplate = &CompiledTemplate{
- text: "**{{.Command}} Failed**: {{.Failure}}\n",
- }
- FailureWithLogTmpl *CompiledTemplate = &CompiledTemplate{
- text: FailureTmpl.text + logTmpl,
- }
-)
-
-var logTmpl = "{{if .Verbose}}\nLog
\n \n\n```\n{{.Log}}```\n
{{end}}\n"
-
-func init() {
- // compile the templates
- for _, t := range []*CompiledTemplate{
- SetupFailure,
- SinglePath,
- MultiPath,
- PlanSuccessTmpl,
- RunLockedFailureTmpl,
- TerraformFailureTmpl,
- EnvironmentFileNotFoundFailureTmpl,
- EnvironmentErrorTmpl,
- ApplySuccessTmpl,
- ApplyFailureTmpl,
- PullNotApprovedFailureTmpl,
- NoPlansFailureTmpl,
- ErrorTmpl,
- GeneralErrorTmpl,
- ErrTmpl,
- ErrWithLogTmpl,
- FailureTmpl,
- FailureWithLogTmpl,
- } {
- t.Template = template.Must(template.New("").Parse(t.text))
- }
-}
func (g *GithubCommentRenderer) render(res CommandResponse, log string, verbose bool) string {
commandStr := strings.Title(res.Command.String())
if res.Error != nil {
- return g.renderTemplate(ErrWithLogTmpl.Template, struct{
+ return g.renderTemplate(errWithLogTmpl, struct{
Command string
Error string
Verbose bool
@@ -157,7 +53,7 @@ func (g *GithubCommentRenderer) render(res CommandResponse, log string, verbose
}{commandStr, res.Error.Error(), verbose, log})
}
if res.Failure != "" {
- return g.renderTemplate(FailureWithLogTmpl.Template, struct{
+ return g.renderTemplate(failureWithLogTmpl, struct{
Command string
Failure string
Verbose bool
@@ -165,38 +61,13 @@ func (g *GithubCommentRenderer) render(res CommandResponse, log string, verbose
}{commandStr, res.Failure, verbose, log})
}
return g.renderProjectResults(res.ProjectResults, commandStr, log, verbose)
-
-
- if res.SetupError != nil {
- renderedError := g.renderTemplate(res.SetupError.Template().Template, res.SetupError)
- return g.renderTemplate(ErrorTmpl.Template, struct {
- Error string
- Log string
- }{renderedError, log})
- } else if res.SetupFailure != nil {
- renderedFailure := g.renderTemplate(res.SetupFailure.Template().Template, res.SetupFailure)
- return g.renderTemplate(SetupFailure.Template, struct {
- Command string
- Output string
- Log string
- Verbose bool
- }{commandStr, renderedFailure, log, verbose})
- } else {
- hasErrors := false
- for _, res := range res.ProjectResults {
- if res.Status == Error {
- hasErrors = true
- }
- }
- return g.renderProjectResults(res.ProjectResults, commandStr, log, hasErrors || verbose)
- }
}
func (g *GithubCommentRenderer) renderProjectResults(pathResults []ProjectResult, command string, log string, verbose bool) string {
renderedOutputs := make(map[string]string)
for _, result := range pathResults {
if result.Error != nil {
- renderedOutputs[result.Path] = g.renderTemplate(ErrTmpl.Template, struct{
+ renderedOutputs[result.Path] = g.renderTemplate(errTmpl, struct{
Command string
Output string
}{
@@ -204,7 +75,7 @@ func (g *GithubCommentRenderer) renderProjectResults(pathResults []ProjectResult
Output: result.Error.Error(),
})
} else if result.Failure != "" {
- renderedOutputs[result.Path] = g.renderTemplate(FailureTmpl.Template, struct{
+ renderedOutputs[result.Path] = g.renderTemplate(failureTmpl, struct{
Command string
Failure string
}{
@@ -212,9 +83,9 @@ func (g *GithubCommentRenderer) renderProjectResults(pathResults []ProjectResult
Failure: result.Failure,
})
} else if result.PlanSuccess != nil {
- renderedOutputs[result.Path] = g.renderTemplate(PlanSuccessTmpl.Template, *result.PlanSuccess)
+ renderedOutputs[result.Path] = g.renderTemplate(planSuccessTmpl, *result.PlanSuccess)
} else if result.ApplySuccess != "" {
- renderedOutputs[result.Path] = g.renderTemplate(ApplySuccessTmpl.Template, struct{Output string}{result.ApplySuccess})
+ renderedOutputs[result.Path] = g.renderTemplate(applySuccessTmpl, struct{Output string}{result.ApplySuccess})
} else {
renderedOutputs[result.Path] = "Found no template. This is a bug!"
}
@@ -222,9 +93,9 @@ func (g *GithubCommentRenderer) renderProjectResults(pathResults []ProjectResult
var tmpl *template.Template
if len(renderedOutputs) == 1 {
- tmpl = SinglePath.Template
+ tmpl = singlePathTmpl
} else {
- tmpl = MultiPath.Template
+ tmpl = multiPathTmpl
}
return g.renderTemplate(tmpl, struct {
Results map[string]string
diff --git a/server/github_status.go b/server/github_status.go
index 163a092c3..6d5367fef 100644
--- a/server/github_status.go
+++ b/server/github_status.go
@@ -47,7 +47,7 @@ func (g *GithubStatus) Update(repo models.Repo, pull models.PullRequest, status
func (g *GithubStatus) UpdatePathResult(ctx *CommandContext, pathResults []ProjectResult) error {
var statuses []Status
for _, p := range pathResults {
- statuses = append(statuses, p.Status)
+ statuses = append(statuses, p.Status())
}
worst := g.worstStatus(statuses)
return g.Update(ctx.BaseRepo, ctx.Pull, worst, ctx.Command.commandType.String())
diff --git a/server/plan_executor.go b/server/plan_executor.go
index 76752a55d..ffc846cb0 100644
--- a/server/plan_executor.go
+++ b/server/plan_executor.go
@@ -40,41 +40,6 @@ type PlanSuccess struct {
LockURL string
}
-func (p PlanSuccess) Template() *CompiledTemplate {
- return PlanSuccessTmpl
-}
-
-type RunLockedFailure struct {
- LockingPullNum int
-}
-
-func (r RunLockedFailure) Template() *CompiledTemplate {
- return RunLockedFailureTmpl
-}
-
-type EnvironmentFileNotFoundFailure struct {
- Filename string
-}
-
-func (e EnvironmentFileNotFoundFailure) Template() *CompiledTemplate {
- return EnvironmentFileNotFoundFailureTmpl
-}
-
-type TerraformFailure struct {
- Command string
- Output string
-}
-
-func (t TerraformFailure) Template() *CompiledTemplate {
- return TerraformFailureTmpl
-}
-
-type EnvironmentFailure struct{}
-
-func (e EnvironmentFailure) Template() *CompiledTemplate {
- return EnvironmentErrorTmpl
-}
-
func (p *PlanExecutor) execute(ctx *CommandContext, github *github.Client) {
p.githubStatus.Update(ctx.BaseRepo, ctx.Pull, Pending, PlanStep)
res := p.setupAndPlan(ctx)
diff --git a/server/server.go b/server/server.go
index e80b1981a..528ce24b0 100644
--- a/server/server.go
+++ b/server/server.go
@@ -72,40 +72,6 @@ type CommandContext struct {
Log *logging.SimpleLogger
}
-// todo: These structs have nothing to do with the server. Move to a different file/package #refactor
-type CommandResponse struct {
- Error error
- Failure string
- SetupError Templater
- SetupFailure Templater
- ProjectResults []ProjectResult
- Command CommandType
-}
-
-type ProjectResult struct {
- Path string
- Status Status
- Result Templater
- Error error
- Failure string
- PlanSuccess *PlanSuccess
- ApplySuccess string
-}
-
-type Templater interface {
- Template() *CompiledTemplate
-}
-
-type GeneralError struct {
- Error error
-}
-
-func (g GeneralError) Template() *CompiledTemplate {
- return GeneralErrorTmpl
-}
-
-// todo: /end
-
func NewServer(config ServerConfig) (*Server, error) {
// if ~ was used in data-dir convert that to actual home directory otherwise we'll
// create a directory call "~" instead of actually using home