mirror of
https://github.com/apache/maven-mvnd.git
synced 2025-09-09 14:49:06 +00:00
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:
@@ -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);
|
||||
|
@@ -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()) {
|
||||
|
Reference in New Issue
Block a user