Provide an early display of build failures (fixes #361)

Also fix ordering of messages when projects are skipped at the end
This commit is contained in:
Guillaume Nodet
2021-09-01 15:55:38 +02:00
committed by GitHub
parent c98813f433
commit 230edac5ae
7 changed files with 173 additions and 17 deletions

View File

@@ -55,6 +55,7 @@ public abstract class Message {
public static final int TRANSFER_CORRUPTED = 21;
public static final int TRANSFER_SUCCEEDED = 22;
public static final int TRANSFER_FAILED = 23;
public static final int EXECUTION_FAILURE = 24;
final int type;
@@ -103,6 +104,8 @@ public abstract class Message {
case TRANSFER_SUCCEEDED:
case TRANSFER_FAILED:
return TransferEvent.read(type, input);
case EXECUTION_FAILURE:
return ExecutionFailureEvent.read(input);
}
throw new IllegalStateException("Unexpected message type: " + type);
}
@@ -821,6 +824,56 @@ public abstract class Message {
}
}
public static class ExecutionFailureEvent extends Message {
final String projectId;
final boolean halted;
final String exception;
private ExecutionFailureEvent(String projectId, boolean halted, String exception) {
super(EXECUTION_FAILURE);
this.projectId = projectId;
this.halted = halted;
this.exception = exception;
}
public String getProjectId() {
return projectId;
}
public boolean isHalted() {
return halted;
}
public String getException() {
return exception;
}
@Override
public String toString() {
return "ExecutionFailure{" +
"projectId='" + projectId + '\'' +
", halted=" + halted +
", exception='" + exception + '\'' +
'}';
}
@Override
public void write(DataOutputStream output) throws IOException {
super.write(output);
writeUTF(output, projectId);
output.writeBoolean(halted);
writeUTF(output, exception);
}
public static ExecutionFailureEvent read(DataInputStream input) throws IOException {
String projectId = readUTF(input);
boolean halted = input.readBoolean();
String exception = readUTF(input);
return new ExecutionFailureEvent(projectId, halted, exception);
}
}
public static class TransferEvent extends Message {
public static final int INITIATED = 0;
@@ -982,6 +1035,10 @@ public abstract class Message {
return new StringMessage(PROJECT_STOPPED, projectId);
}
public static ExecutionFailureEvent executionFailure(String projectId, boolean halted, String exception) {
return new ExecutionFailureEvent(projectId, halted, exception);
}
public static Message mojoStarted(String artifactId, String pluginGroupId, String pluginArtifactId,
String pluginVersion, String mojo, String executionId) {
return new MojoStartedEvent(artifactId, pluginGroupId, pluginArtifactId, pluginVersion, mojo, executionId);

View File

@@ -46,6 +46,7 @@ import org.jline.utils.Display;
import org.mvndaemon.mvnd.common.Message;
import org.mvndaemon.mvnd.common.Message.BuildException;
import org.mvndaemon.mvnd.common.Message.BuildStarted;
import org.mvndaemon.mvnd.common.Message.ExecutionFailureEvent;
import org.mvndaemon.mvnd.common.Message.MojoStartedEvent;
import org.mvndaemon.mvnd.common.Message.ProjectEvent;
import org.mvndaemon.mvnd.common.Message.StringMessage;
@@ -93,6 +94,7 @@ public class TerminalOutput implements ClientOutput {
private final Terminal.SignalHandler previousIntHandler;
private final Display display;
private final Map<String, Map<String, TransferEvent>> transfers = new LinkedHashMap<>();
private final ArrayList<ExecutionFailureEvent> failures = new ArrayList<>();
private final LinkedHashMap<String, Project> projects = new LinkedHashMap<>();
private final ClientLog log;
private final Thread reader;
@@ -409,6 +411,11 @@ public class TerminalOutput implements ClientOutput {
.remove(te.getResourceName());
break;
}
case Message.EXECUTION_FAILURE: {
final ExecutionFailureEvent efe = (ExecutionFailureEvent) entry;
failures.add(efe);
break;
}
default:
throw new IllegalStateException("Unexpected message " + entry);
}
@@ -521,12 +528,18 @@ public class TerminalOutput implements ClientOutput {
// so keep one more line empty at the end
dispLines--;
AttributedString globalTransfer = formatTransfers("");
dispLines -= globalTransfer != null ? 1 : 0;
addStatusLine(lines, dispLines, projectsCount);
AttributedString globalFailure = formatFailures();
if (globalFailure != null) {
lines.add(globalFailure);
dispLines--;
}
AttributedString globalTransfer = formatTransfers("");
if (globalTransfer != null) {
lines.add(globalTransfer);
dispLines--;
}
if (projectsCount <= dispLines) {
@@ -561,6 +574,43 @@ public class TerminalOutput implements ClientOutput {
display.update(trimmed, -1);
}
private AttributedString formatFailures() {
if (failures.isEmpty()) {
return null;
}
AttributedStringBuilder asb = new AttributedStringBuilder();
asb.style(AttributedStyle.DEFAULT.foreground(AttributedStyle.RED).bold());
if (failures.stream().anyMatch(ExecutionFailureEvent::isHalted)) {
asb.append("ABORTING ");
}
asb.append("FAILURE: ");
asb.style(AttributedStyle.DEFAULT.foreground(AttributedStyle.RED));
if (failures.size() == 1) {
ExecutionFailureEvent efe = failures.iterator().next();
asb.append(efe.getProjectId());
String exception = efe.getException();
if (exception != null) {
if (exception.startsWith("org.apache.maven.lifecycle.LifecycleExecutionException: ")) {
exception = exception
.substring("org.apache.maven.lifecycle.LifecycleExecutionException: ".length());
}
asb.append(": ").append(exception);
}
} else {
asb.append(String.valueOf(failures.size())).append(" projects failed: ");
asb.append(failures.stream().map(ExecutionFailureEvent::getProjectId).collect(Collectors.joining(", ")));
}
AttributedString as = asb.toAttributedString();
if (as.columnLength() >= getTerminalWidth() - 1) {
asb = new AttributedStringBuilder();
asb.append(as.columnSubSequence(0, getTerminalWidth() - 2));
asb.style(AttributedStyle.DEFAULT);
asb.append("");
as = asb.toAttributedString();
}
return as;
}
private AttributedString formatTransfers(String projectId) {
Collection<TransferEvent> transfers = this.transfers.getOrDefault(projectId, Collections.emptyMap()).values();
if (transfers.isEmpty()) {