Improve events reporting for forked lifecycles (#411)

This commit is contained in:
Guillaume Nodet
2021-05-18 16:08:15 +02:00
committed by GitHub
parent 6a7f172412
commit 4cfaf7aaf9
11 changed files with 297 additions and 16 deletions

View File

@@ -20,6 +20,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.TreeMap; import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.apache.maven.execution.ExecutionEvent; import org.apache.maven.execution.ExecutionEvent;
import org.apache.maven.execution.MavenSession; import org.apache.maven.execution.MavenSession;
@@ -78,16 +79,26 @@ public class ClientDispatcher extends BuildEventListener {
throw new IllegalStateException("Could not compute the 90th percentile of the projects length from " + projects); throw new IllegalStateException("Could not compute the 90th percentile of the projects length from " + projects);
} }
public void projectStarted(ExecutionEvent event) { private final Map<String, Boolean> projects = new ConcurrentHashMap<>();
queue.add(Message.projectStarted(event.getProject().getArtifactId()));
public void projectStarted(String projectId) {
projects.put(projectId, Boolean.TRUE);
queue.add(Message.projectStarted(projectId));
} }
public void projectLogMessage(String projectId, String event) { public void projectLogMessage(String projectId, String event) {
if (projectId != null) {
Boolean b = projects.get(projectId);
if (b != Boolean.TRUE) {
}
}
queue.add(projectId == null ? Message.log(trimTrailingEols(event)) : Message.log(projectId, trimTrailingEols(event))); queue.add(projectId == null ? Message.log(trimTrailingEols(event)) : Message.log(projectId, trimTrailingEols(event)));
} }
public void projectFinished(ExecutionEvent event) { @Override
queue.add(Message.projectStopped(event.getProject().getArtifactId())); public void projectFinished(String projectId) {
projects.put(projectId, Boolean.FALSE);
queue.add(Message.projectStopped(projectId));
} }
public void mojoStarted(ExecutionEvent event) { public void mojoStarted(ExecutionEvent event) {

View File

@@ -27,13 +27,13 @@ public abstract class BuildEventListener {
public void sessionStarted(ExecutionEvent event) { public void sessionStarted(ExecutionEvent event) {
} }
public void projectStarted(ExecutionEvent event) { public void projectStarted(String projectId) {
} }
public void projectLogMessage(String projectId, String event) { public void projectLogMessage(String projectId, String event) {
} }
public void projectFinished(ExecutionEvent event) { public void projectFinished(String projectId) {
} }
public void mojoStarted(ExecutionEvent event) { public void mojoStarted(ExecutionEvent event) {
@@ -64,11 +64,11 @@ public abstract class BuildEventListener {
public abstract void sessionStarted(ExecutionEvent event); public abstract void sessionStarted(ExecutionEvent event);
public abstract void projectStarted(ExecutionEvent event); public abstract void projectStarted(String projectId);
public abstract void projectLogMessage(String projectId, String event); public abstract void projectLogMessage(String projectId, String event);
public abstract void projectFinished(ExecutionEvent event); public abstract void projectFinished(String projectId);
public abstract void mojoStarted(ExecutionEvent event); public abstract void mojoStarted(ExecutionEvent event);

View File

@@ -50,7 +50,7 @@ public class LoggingExecutionListener implements ExecutionListener {
@Override @Override
public void projectStarted(ExecutionEvent event) { public void projectStarted(ExecutionEvent event) {
setMdc(event); setMdc(event);
buildEventListener.projectStarted(event); buildEventListener.projectStarted(event.getProject().getArtifactId());
delegate.projectStarted(event); delegate.projectStarted(event);
} }
@@ -58,21 +58,21 @@ public class LoggingExecutionListener implements ExecutionListener {
public void projectSucceeded(ExecutionEvent event) { public void projectSucceeded(ExecutionEvent event) {
setMdc(event); setMdc(event);
delegate.projectSucceeded(event); delegate.projectSucceeded(event);
buildEventListener.projectFinished(event); buildEventListener.projectFinished(event.getProject().getArtifactId());
} }
@Override @Override
public void projectFailed(ExecutionEvent event) { public void projectFailed(ExecutionEvent event) {
setMdc(event); setMdc(event);
delegate.projectFailed(event); delegate.projectFailed(event);
buildEventListener.projectFinished(event); buildEventListener.projectFinished(event.getProject().getArtifactId());
} }
@Override @Override
public void projectSkipped(ExecutionEvent event) { public void projectSkipped(ExecutionEvent event) {
setMdc(event); setMdc(event);
delegate.projectSkipped(event); delegate.projectSkipped(event);
buildEventListener.projectFinished(event); buildEventListener.projectFinished(event.getProject().getArtifactId());
} }
@Override @Override
@@ -104,23 +104,25 @@ public class LoggingExecutionListener implements ExecutionListener {
public void forkStarted(ExecutionEvent event) { public void forkStarted(ExecutionEvent event) {
setMdc(event); setMdc(event);
delegate.forkStarted(event); delegate.forkStarted(event);
ProjectBuildLogAppender.setForkingProjectId(event.getProject().getArtifactId());
} }
@Override @Override
public void forkSucceeded(ExecutionEvent event) { public void forkSucceeded(ExecutionEvent event) {
setMdc(event);
delegate.forkSucceeded(event); delegate.forkSucceeded(event);
ProjectBuildLogAppender.setForkingProjectId(null);
} }
@Override @Override
public void forkFailed(ExecutionEvent event) { public void forkFailed(ExecutionEvent event) {
setMdc(event);
delegate.forkFailed(event); delegate.forkFailed(event);
ProjectBuildLogAppender.setForkingProjectId(null);
} }
@Override @Override
public void forkedProjectStarted(ExecutionEvent event) { public void forkedProjectStarted(ExecutionEvent event) {
setMdc(event); setMdc(event);
buildEventListener.projectStarted(ProjectBuildLogAppender.getProjectId());
delegate.forkedProjectStarted(event); delegate.forkedProjectStarted(event);
} }
@@ -128,12 +130,16 @@ public class LoggingExecutionListener implements ExecutionListener {
public void forkedProjectSucceeded(ExecutionEvent event) { public void forkedProjectSucceeded(ExecutionEvent event) {
setMdc(event); setMdc(event);
delegate.forkedProjectSucceeded(event); delegate.forkedProjectSucceeded(event);
buildEventListener.projectFinished(ProjectBuildLogAppender.getProjectId());
ProjectBuildLogAppender.setProjectId(null);
} }
@Override @Override
public void forkedProjectFailed(ExecutionEvent event) { public void forkedProjectFailed(ExecutionEvent event) {
setMdc(event); setMdc(event);
delegate.forkedProjectFailed(event); delegate.forkedProjectFailed(event);
buildEventListener.projectFinished(ProjectBuildLogAppender.getProjectId());
ProjectBuildLogAppender.setProjectId(null);
} }
private void setMdc(ExecutionEvent event) { private void setMdc(ExecutionEvent event) {

View File

@@ -35,12 +35,21 @@ public class ProjectBuildLogAppender extends AppenderBase<ILoggingEvent> impleme
private static final String KEY_PROJECT_ID = "maven.project.id"; private static final String KEY_PROJECT_ID = "maven.project.id";
private static final ThreadLocal<String> PROJECT_ID = new InheritableThreadLocal<>(); private static final ThreadLocal<String> PROJECT_ID = new InheritableThreadLocal<>();
private static final ThreadLocal<String> FORKING_PROJECT_ID = new InheritableThreadLocal<>();
public static String getProjectId() { public static String getProjectId() {
return PROJECT_ID.get(); return PROJECT_ID.get();
} }
public static void setProjectId(String projectId) { public static void setProjectId(String projectId) {
String forkingProjectId = FORKING_PROJECT_ID.get();
if (forkingProjectId != null) {
if (projectId != null) {
projectId = forkingProjectId + "/" + projectId;
} else {
projectId = forkingProjectId;
}
}
if (projectId != null) { if (projectId != null) {
PROJECT_ID.set(projectId); PROJECT_ID.set(projectId);
MDC.put(KEY_PROJECT_ID, projectId); MDC.put(KEY_PROJECT_ID, projectId);
@@ -50,6 +59,14 @@ public class ProjectBuildLogAppender extends AppenderBase<ILoggingEvent> impleme
} }
} }
public static void setForkingProjectId(String forkingProjectId) {
if (forkingProjectId != null) {
FORKING_PROJECT_ID.set(forkingProjectId);
} else {
FORKING_PROJECT_ID.remove();
}
}
public static void updateMdc() { public static void updateMdc() {
String id = getProjectId(); String id = getProjectId();
if (id != null) { if (id != null) {
@@ -92,8 +109,7 @@ public class ProjectBuildLogAppender extends AppenderBase<ILoggingEvent> impleme
@Override @Override
protected void append(ILoggingEvent event) { protected void append(ILoggingEvent event) {
Map<String, String> mdc = event.getMDCPropertyMap(); String projectId = event.getMDCPropertyMap().get(KEY_PROJECT_ID);
String projectId = mdc != null ? mdc.get(KEY_PROJECT_ID) : null;
buildEventListener.projectLogMessage(projectId, layout.doLayout(event)); buildEventListener.projectLogMessage(projectId, layout.doLayout(event));
} }

View File

@@ -0,0 +1,47 @@
/*
* Copyright 2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.mvndaemon.mvnd.it;
import java.io.IOException;
import javax.inject.Inject;
import org.junit.jupiter.api.Test;
import org.mvndaemon.mvnd.assertj.TestClientOutput;
import org.mvndaemon.mvnd.client.Client;
import org.mvndaemon.mvnd.client.DaemonParameters;
import org.mvndaemon.mvnd.junit.MvndTest;
import static org.junit.jupiter.api.Assertions.assertTrue;
@MvndTest(projectDir = "src/test/projects/forked")
public class ForkedTest {
@Inject
Client client;
@Inject
DaemonParameters parameters;
@Test
void cleanInstall() throws IOException, InterruptedException {
final TestClientOutput output = new TestClientOutput();
client.execute(output, "clean", "verify", "-e", "-B").assertSuccess();
assertTrue(output.messagesToString()
.contains(
"ProjectLogMessage{projectId='forked/forked-mod1', message='[INFO] Forking forked-mod1 0.0.1-SNAPSHOT'}"));
}
}

View File

@@ -0,0 +1,3 @@
-Dmaven.wagon.httpconnectionManager.ttlSeconds=120
-Dmaven.wagon.http.retryHandler.requestSentEnabled=true
-Dmaven.wagon.http.retryHandler.count=10

View File

@@ -0,0 +1,30 @@
<!--
Copyright 2019 the original author or authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.mvndaemon.mvnd.test.forked</groupId>
<artifactId>forked</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>forked-mod1</artifactId>
</project>

View File

@@ -0,0 +1,22 @@
/*
* Copyright 2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.mvndaemon.mvnd.test.forked.mod1;
public interface Greeting {
public String greet();
}

View File

@@ -0,0 +1,30 @@
<!--
Copyright 2019 the original author or authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.mvndaemon.mvnd.test.forked</groupId>
<artifactId>forked</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>forked-mod2</artifactId>
</project>

View File

@@ -0,0 +1,24 @@
/*
* Copyright 2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.mvndaemon.mvnd.test.forked.mod2;
public class Hi {
public String greet() {
return "Hi";
}
}

View File

@@ -0,0 +1,92 @@
<!--
Copyright 2019 the original author or authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.mvndaemon.mvnd.test.forked</groupId>
<artifactId>forked</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.source>1.8</maven.compiler.source>
<maven-clean-plugin.version>2.5</maven-clean-plugin.version>
<maven-compiler-plugin.version>3.8.0</maven-compiler-plugin.version>
<maven-install-plugin.version>2.4</maven-install-plugin.version>
<maven-resources-plugin.version>2.6</maven-resources-plugin.version>
<maven-surefire-plugin.version>2.22.2</maven-surefire-plugin.version>
</properties>
<modules>
<module>mod1</module>
<module>mod2</module>
</modules>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-clean-plugin</artifactId>
<version>${maven-clean-plugin.version}</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<version>${maven-install-plugin.version}</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>${maven-resources-plugin.version}</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven-surefire-plugin.version}</version>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.2.0</version>
<executions>
<execution>
<id>aggregate-jar</id>
<goals>
<goal>aggregate-jar</goal>
</goals>
<phase>package</phase>
<inherited>false</inherited>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>