Provide smarter output on the client, fixes #77

All events are directly forwarded to the client.  The client is now responsible for ordering them per project and displaying them if needed.  A thread is now started to read the terminal input with support for '+' to display one more line per project, '-' to display one line less, and 'Ctrl+L' to redraw the display which could become messed if the build messages are a bit unusual (this may require a better fix though).
This commit is contained in:
Guillaume Nodet
2020-10-07 13:44:48 +02:00
parent 41869a7115
commit dd32f41580
13 changed files with 305 additions and 156 deletions

View File

@@ -514,7 +514,6 @@ public class Server implements AutoCloseable, Runnable {
@Override
public void close() throws Exception {
sendBuildMessages();
super.close();
}
@@ -529,43 +528,38 @@ public class Server implements AutoCloseable, Runnable {
}
@Override
protected void onStartProject(ProjectBuild project) {
super.onStartProject(project);
sendEvent(Type.ProjectStarted, project);
protected void onStartProject(String projectId, String display) {
super.onStartProject(projectId, display);
sendEvent(Type.ProjectStarted, projectId, display);
}
@Override
protected void onStopProject(ProjectBuild project) {
sendEvent(Type.ProjectStopped, project);
super.onStopProject(project);
protected void onStopProject(String projectId, String display) {
sendEvent(Type.ProjectStopped, projectId, display);
super.onStopProject(projectId, display);
}
@Override
protected void onStartMojo(ProjectBuild project) {
super.onStartMojo(project);
sendEvent(Type.MojoStarted, project);
protected void onStartMojo(String projectId, String display) {
super.onStartMojo(projectId, display);
sendEvent(Type.MojoStarted, projectId, display);
}
@Override
protected void onStopMojo(ProjectBuild project) {
sendEvent(Type.MojoStopped, project);
super.onStopMojo(project);
protected void onStopMojo(String projectId, String display) {
sendEvent(Type.MojoStopped, projectId, display);
super.onStopMojo(projectId, display);
}
private void sendEvent(Type type, ProjectBuild project) {
String projectId = project.projectId();
String disp = project.toDisplay().toAnsi(256, false);
queue.add(new BuildEvent(type, projectId, disp));
sendBuildMessages();
@Override
protected void onProjectLog(String projectId, String message) {
queue.add(new BuildMessage(projectId, message));
super.onProjectLog(projectId, message);
}
private synchronized void sendBuildMessages() {
if (events != null) {
events.stream()
.map(s -> s.endsWith("\n") ? s.substring(0, s.length() - 1) : s)
.map(BuildMessage::new).forEachOrdered(queue::add);
events.clear();
}
private void sendEvent(Type type, String projectId, String display) {
queue.add(new BuildEvent(type, projectId, display));
}
}
}

View File

@@ -15,14 +15,13 @@
*/
package org.jboss.fuse.mvnd.logging.smart;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.apache.maven.eventspy.AbstractEventSpy;
import org.apache.maven.execution.ExecutionEvent;
import org.apache.maven.plugin.MojoExecution;
import org.apache.maven.project.MavenProject;
import org.jboss.fuse.mvnd.common.Message;
import org.jline.utils.AttributedString;
import org.slf4j.MDC;
@@ -44,17 +43,14 @@ public abstract class AbstractLoggingSpy extends AbstractEventSpy {
}
protected Map<String, ProjectBuild> projects;
protected List<String> events;
protected List<Message.BuildMessage> events;
@Override
public synchronized void init(Context context) throws Exception {
projects = new LinkedHashMap<>();
events = new ArrayList<>();
}
@Override
public synchronized void close() throws Exception {
events = null;
projects = null;
}
@@ -97,73 +93,67 @@ public abstract class AbstractLoggingSpy extends AbstractEventSpy {
protected void notifySessionFinish(ExecutionEvent event) {
}
protected synchronized void notifyProjectBuildStart(ExecutionEvent event) {
ProjectBuild pb = new ProjectBuild();
pb.project = event.getProject();
pb.execution = event.getMojoExecution();
pb.events = new ArrayList<>();
projects.putIfAbsent(event.getProject().getId(), pb);
onStartProject(pb);
protected void notifyProjectBuildStart(ExecutionEvent event) {
onStartProject(getProjectId(event), getProjectDisplay(event));
}
protected void onStartProject(ProjectBuild project) {
MDC.put(KEY_PROJECT_ID, project.project.getId());
protected void notifyProjectBuildFinish(ExecutionEvent event) throws Exception {
onStopProject(getProjectId(event), getProjectDisplay(event));
}
protected void notifyMojoExecutionStart(ExecutionEvent event) {
onStartMojo(getProjectId(event), getProjectDisplay(event));
}
protected void notifyMojoExecutionFinish(ExecutionEvent event) {
onStopMojo(getProjectId(event), getProjectDisplay(event));
}
protected void onStartProject(String projectId, String display) {
MDC.put(KEY_PROJECT_ID, projectId);
update();
}
protected synchronized void notifyProjectBuildFinish(ExecutionEvent event) throws Exception {
ProjectBuild pb = projects.remove(event.getProject().getId());
if (pb != null) {
events.addAll(pb.events);
onStopProject(pb);
}
}
protected void onStopProject(ProjectBuild project) {
protected void onStopProject(String projectId, String display) {
update();
MDC.remove(KEY_PROJECT_ID);
}
protected synchronized void notifyMojoExecutionStart(ExecutionEvent event) {
ProjectBuild pb = projects.get(event.getProject().getId());
if (pb != null) {
pb.execution = event.getMojoExecution();
onStartMojo(pb);
}
}
protected void onStartMojo(ProjectBuild project) {
protected void onStartMojo(String projectId, String display) {
update();
}
protected synchronized void notifyMojoExecutionFinish(ExecutionEvent event) {
ProjectBuild pb = projects.get(event.getProject().getId());
if (pb != null) {
pb.execution = null;
onStopMojo(pb);
}
protected void onStopMojo(String projectId, String display) {
update();
}
protected void onStopMojo(ProjectBuild project) {
protected void onProjectLog(String projectId, String message) {
update();
}
protected void update() {
}
public synchronized void append(String projectId, String event) {
ProjectBuild project = projectId != null ? projects.get(projectId) : null;
if (project != null) {
project.events.add(event);
} else {
events.add(event);
}
private String getProjectId(ExecutionEvent event) {
return event.getProject().getArtifactId();
}
private String getProjectDisplay(ExecutionEvent event) {
String projectId = getProjectId(event);
String disp = event.getMojoExecution() != null
? ":" + projectId + ":" + event.getMojoExecution().toString()
: ":" + projectId;
return disp;
}
public void append(String projectId, String event) {
String msg = event.endsWith("\n") ? event.substring(0, event.length() - 1) : event;
onProjectLog(projectId, msg);
}
protected static class ProjectBuild {
MavenProject project;
volatile MojoExecution execution;
List<String> events;
@Override
public String toString() {

View File

@@ -17,7 +17,9 @@ package org.jboss.fuse.mvnd.logging.smart;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.jline.terminal.Size;
import org.jline.terminal.Terminal;
import org.jline.terminal.TerminalBuilder;
@@ -26,6 +28,7 @@ import org.jline.utils.Display;
public class MavenLoggingSpy extends AbstractLoggingSpy {
private Map<String, String> projects = new LinkedHashMap<>();
private Terminal terminal;
private Display display;
@@ -45,9 +48,6 @@ public class MavenLoggingSpy extends AbstractLoggingSpy {
@Override
public void close() throws Exception {
display.update(Collections.emptyList(), 0);
for (String event : events) {
terminal.writer().print(event);
}
terminal.flush();
terminal.close();
terminal = null;
@@ -55,13 +55,42 @@ public class MavenLoggingSpy extends AbstractLoggingSpy {
super.close();
}
@Override
protected void onStartProject(String projectId, String display) {
projects.put(projectId, display);
super.onStartProject(projectId, display);
}
@Override
protected void onStopProject(String projectId, String display) {
projects.remove(projectId);
super.onStopProject(projectId, display);
}
@Override
protected void onStartMojo(String projectId, String display) {
projects.put(projectId, display);
super.onStartMojo(projectId, display);
}
@Override
protected void onStopMojo(String projectId, String display) {
projects.put(projectId, display);
super.onStopMojo(projectId, display);
}
@Override
protected void onProjectLog(String projectId, String message) {
super.onProjectLog(projectId, message);
}
protected void update() {
Size size = terminal.getSize();
display.resize(size.getRows(), size.getColumns());
List<AttributedString> lines = new ArrayList<>();
lines.add(new AttributedString("Building..."));
for (ProjectBuild build : projects.values()) {
lines.add(build.toDisplay());
for (String build : projects.values()) {
lines.add(new AttributedString(build));
}
display.update(lines, -1);
}