diff --git a/server/controllers/logstreaming_controller.go b/server/controllers/logstreaming_controller.go index 467125365..e913fe66e 100644 --- a/server/controllers/logstreaming_controller.go +++ b/server/controllers/logstreaming_controller.go @@ -11,6 +11,7 @@ import ( "github.com/gorilla/websocket" "github.com/runatlantis/atlantis/server/controllers/templates" "github.com/runatlantis/atlantis/server/core/db" + "github.com/runatlantis/atlantis/server/events/models" "github.com/runatlantis/atlantis/server/handlers" "github.com/runatlantis/atlantis/server/logging" ) @@ -100,6 +101,7 @@ func (j *JobsController) GetProjectJobs(w http.ResponseWriter, r *http.Request) AtlantisVersion: j.AtlantisVersion, ProjectPath: projectInfo.String(), CleanedBasePath: j.AtlantisURL.Path, + ClearMsg: models.LogStreamingClearMsg, } err = j.ProjectJobsTemplate.Execute(w, viewData) diff --git a/server/controllers/templates/web_templates.go b/server/controllers/templates/web_templates.go index 366c5a247..e7e934c73 100644 --- a/server/controllers/templates/web_templates.go +++ b/server/controllers/templates/web_templates.go @@ -357,6 +357,7 @@ type ProjectJobData struct { AtlantisVersion string ProjectPath string CleanedBasePath string + ClearMsg string } var ProjectJobsTemplate = template.Must(template.New("blank.html.tmpl").Parse(` @@ -413,6 +414,13 @@ var ProjectJobsTemplate = template.Must(template.New("blank.html.tmpl").Parse(` document.location.host + document.location.pathname + "/ws"); + socket.onmessage = function(event) { + var msg = String.fromCharCode.apply(null, new Uint8Array(event.data)) + if (msg.trim() === "-----Starting New Process-----") { + term.clear() + return + } + } var attachAddon = new AttachAddon.AttachAddon(socket); var fitAddon = new FitAddon.FitAddon(); term.loadAddon(attachAddon); diff --git a/server/events/models/models.go b/server/events/models/models.go index 565bcec1d..f4fc8f9e9 100644 --- a/server/events/models/models.go +++ b/server/events/models/models.go @@ -35,6 +35,7 @@ import ( const ( planfileSlashReplace = "::" + LogStreamingClearMsg = "\t\n-----Starting New Process-----\n" ) type PullReqStatus struct { diff --git a/server/handlers/project_command_output_handler.go b/server/handlers/project_command_output_handler.go index b8adce66d..5d91060b8 100644 --- a/server/handlers/project_command_output_handler.go +++ b/server/handlers/project_command_output_handler.go @@ -110,7 +110,6 @@ func (p *AsyncProjectCommandOutputHandler) Handle() { for msg := range p.projectCmdOutput { if msg.ClearBuffBefore { p.clearLogLines(msg.ProjectInfo) - continue } p.writeLogLine(msg.ProjectInfo, msg.Line) } @@ -119,8 +118,8 @@ func (p *AsyncProjectCommandOutputHandler) Handle() { func (p *AsyncProjectCommandOutputHandler) Clear(ctx models.ProjectCommandContext) { p.projectCmdOutput <- &models.ProjectCmdOutputLine{ ProjectInfo: ctx.PullInfo(), + Line: models.LogStreamingClearMsg, ClearBuffBefore: true, - Line: "", } } @@ -168,6 +167,11 @@ func (p *AsyncProjectCommandOutputHandler) writeLogLine(pull string, line string } p.receiverBuffersLock.Unlock() + // No need to write to projectOutputBuffers if clear msg. + if line == models.LogStreamingClearMsg { + return + } + p.projectOutputBuffersLock.Lock() if p.projectOutputBuffers[pull] == nil { p.projectOutputBuffers[pull] = []string{} diff --git a/server/handlers/project_command_output_handler_test.go b/server/handlers/project_command_output_handler_test.go index 8711f00f6..d2443cb33 100644 --- a/server/handlers/project_command_output_handler_test.go +++ b/server/handlers/project_command_output_handler_test.go @@ -86,6 +86,7 @@ func TestProjectCommandOutputHandler(t *testing.T) { }() projectOutputHandler.Send(ctx, Msg) + close(ch) // Wait for the msg to be read. wg.Wait() @@ -114,6 +115,7 @@ func TestProjectCommandOutputHandler(t *testing.T) { // Send a clear msg projectOutputHandler.Clear(ctx) + close(ch) dfProjectOutputHandler, ok := projectOutputHandler.(*handlers.AsyncProjectCommandOutputHandler) assert.True(t, ok) @@ -183,10 +185,10 @@ func TestProjectCommandOutputHandler(t *testing.T) { // Expecting two calls to callback. wg.Add(2) - expectedMsg := []string{} + receivedMsgs := []string{} go func() { err := projectOutputHandler.Receive(ctx.PullInfo(), ch, func(msg string) error { - expectedMsg = append(expectedMsg, msg) + receivedMsgs = append(receivedMsgs, msg) wg.Done() return nil }) @@ -201,7 +203,12 @@ func TestProjectCommandOutputHandler(t *testing.T) { // Wait for the message to be read. wg.Wait() close(ch) - assert.Equal(t, []string{Msg, Msg}, expectedMsg) + + expectedMsgs := []string{Msg, Msg} + assert.Equal(t, len(expectedMsgs), len(receivedMsgs)) + for i := range expectedMsgs { + assert.Equal(t, expectedMsgs[i], receivedMsgs[i]) + } }) t.Run("update project status with project jobs url", func(t *testing.T) {