You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by ol...@apache.org on 2020/05/20 20:53:54 UTC
[maven-invoker-plugin] branch master updated: [MINVOKER-250]
streamLogsOnFailures
This is an automated email from the ASF dual-hosted git repository.
olamy pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/maven-invoker-plugin.git
The following commit(s) were added to refs/heads/master by this push:
new 1c55108 [MINVOKER-250] streamLogsOnFailures
1c55108 is described below
commit 1c55108ecbde03bf615fd490a5c63b2fd3d6b421
Author: Slawomir Jaranowski <s....@gmail.com>
AuthorDate: Sat Mar 28 11:51:51 2020 +0100
[MINVOKER-250] streamLogsOnFailures
---
pom.xml | 3 +
.../invoker.properties | 18 ++++
src/it/fail-build-streamLogsOnFailures/pom.xml | 64 ++++++++++++
.../src/it/project/pom.xml | 35 +++++++
.../fail-build-streamLogsOnFailures/verify.groovy | 29 ++++++
.../invoker.properties | 18 ++++
.../pom.xml | 65 ++++++++++++
.../src/it/project/pom.xml | 35 +++++++
.../verify.groovy | 31 ++++++
.../maven/plugins/invoker/AbstractInvokerMojo.java | 74 ++++++-------
.../apache/maven/plugins/invoker/InvokerMojo.java | 13 +++
.../maven/plugins/invoker/InvokerSession.java | 114 ++++++++++++++++-----
.../apache/maven/plugins/invoker/VerifyMojo.java | 13 +++
src/main/mdo/invocation.mdo | 7 ++
src/site/apt/examples/logs-for-failed-tests.apt.vm | 56 ++++++++++
src/site/site.xml | 1 +
16 files changed, 510 insertions(+), 66 deletions(-)
diff --git a/pom.xml b/pom.xml
index 3adbc7c..a6be5ad 100644
--- a/pom.xml
+++ b/pom.xml
@@ -336,6 +336,9 @@ under the License.
<maven.compiler.source>${maven.compiler.source}</maven.compiler.source>
<maven.compiler.target>${maven.compiler.target}</maven.compiler.target>
</properties>
+ <scriptVariables>
+ <projectVersion>${project.version}</projectVersion>
+ </scriptVariables>
<goals>
<goal>clean</goal>
<goal>initialize</goal>
diff --git a/src/it/fail-build-streamLogsOnFailures/invoker.properties b/src/it/fail-build-streamLogsOnFailures/invoker.properties
new file mode 100644
index 0000000..e64d99e
--- /dev/null
+++ b/src/it/fail-build-streamLogsOnFailures/invoker.properties
@@ -0,0 +1,18 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+
+invoker.buildResult = failure
diff --git a/src/it/fail-build-streamLogsOnFailures/pom.xml b/src/it/fail-build-streamLogsOnFailures/pom.xml
new file mode 100644
index 0000000..49ec32d
--- /dev/null
+++ b/src/it/fail-build-streamLogsOnFailures/pom.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you 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="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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.apache.maven.plugins.invoker</groupId>
+ <artifactId>fail-build-streamLogsOnFailures</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <packaging>pom</packaging>
+
+ <description>Test to check that a failure in the forked Maven build fails the parent build with streamed logs.</description>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-invoker-plugin</artifactId>
+ <version>@pom.version@</version>
+ <configuration>
+ <writeJunitReport>true</writeJunitReport>
+ <debug>false</debug>
+ <cloneProjectsTo>${project.build.directory}/it</cloneProjectsTo>
+ <pomIncludes>
+ <pomInclude>*/pom.xml</pomInclude>
+ </pomIncludes>
+ <streamLogsOnFailures>true</streamLogsOnFailures>
+ </configuration>
+ <executions>
+ <execution>
+ <id>integration-test</id>
+ <phase>initialize</phase>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
diff --git a/src/it/fail-build-streamLogsOnFailures/src/it/project/pom.xml b/src/it/fail-build-streamLogsOnFailures/src/it/project/pom.xml
new file mode 100644
index 0000000..cf9bbe9
--- /dev/null
+++ b/src/it/fail-build-streamLogsOnFailures/src/it/project/pom.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you 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="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <!-- invalid model version to make build fail -->
+ <modelVersion>99.0.0</modelVersion>
+ <groupId>test</groupId>
+ <artifactId>fail-build</artifactId>
+ <version>0.1-SNAPSHOT</version>
+ <packaging>jar</packaging>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+
+ <invalidElementShouldFailBuild/>
+</project>
diff --git a/src/it/fail-build-streamLogsOnFailures/verify.groovy b/src/it/fail-build-streamLogsOnFailures/verify.groovy
new file mode 100644
index 0000000..06e686d
--- /dev/null
+++ b/src/it/fail-build-streamLogsOnFailures/verify.groovy
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+def FS = File.separator
+def buildLogOfProject = new File( basedir, 'target/it/project/build.log' ).text
+
+def buildLog = new File( basedir, 'build.log' ).text
+
+assert buildLog.contains( '*** begin build.log for: project' + FS + 'pom.xml ***' )
+assert buildLog.contains( buildLogOfProject )
+assert buildLog.contains( '*** end build.log for: project' + FS + 'pom.xml ***' )
+
+assert buildLog.contains( 'ERROR] Failed to execute goal org.apache.maven.plugins:maven-invoker-plugin:' + projectVersion + ':run' )
diff --git a/src/it/fail-build-with-verify-streamLogsOnFailures/invoker.properties b/src/it/fail-build-with-verify-streamLogsOnFailures/invoker.properties
new file mode 100644
index 0000000..e64d99e
--- /dev/null
+++ b/src/it/fail-build-with-verify-streamLogsOnFailures/invoker.properties
@@ -0,0 +1,18 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+
+invoker.buildResult = failure
diff --git a/src/it/fail-build-with-verify-streamLogsOnFailures/pom.xml b/src/it/fail-build-with-verify-streamLogsOnFailures/pom.xml
new file mode 100644
index 0000000..e366ff1
--- /dev/null
+++ b/src/it/fail-build-with-verify-streamLogsOnFailures/pom.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you 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="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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.apache.maven.plugins.invoker</groupId>
+ <artifactId>fail-build-with-verify-streamLogsOnFailures</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <packaging>pom</packaging>
+
+ <description>Test to check that a failure in the forked Maven build fails the parent build with streamed logs.</description>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-invoker-plugin</artifactId>
+ <version>@project.version@</version>
+ <configuration>
+ <writeJunitReport>true</writeJunitReport>
+ <debug>false</debug>
+ <cloneProjectsTo>${project.build.directory}/it</cloneProjectsTo>
+ <pomIncludes>
+ <pomInclude>*/pom.xml</pomInclude>
+ </pomIncludes>
+ <streamLogsOnFailures>true</streamLogsOnFailures>
+ </configuration>
+ <executions>
+ <execution>
+ <id>integration-test</id>
+ <phase>initialize</phase>
+ <goals>
+ <goal>integration-test</goal>
+ <goal>verify</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
diff --git a/src/it/fail-build-with-verify-streamLogsOnFailures/src/it/project/pom.xml b/src/it/fail-build-with-verify-streamLogsOnFailures/src/it/project/pom.xml
new file mode 100644
index 0000000..cf9bbe9
--- /dev/null
+++ b/src/it/fail-build-with-verify-streamLogsOnFailures/src/it/project/pom.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you 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="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <!-- invalid model version to make build fail -->
+ <modelVersion>99.0.0</modelVersion>
+ <groupId>test</groupId>
+ <artifactId>fail-build</artifactId>
+ <version>0.1-SNAPSHOT</version>
+ <packaging>jar</packaging>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+
+ <invalidElementShouldFailBuild/>
+</project>
diff --git a/src/it/fail-build-with-verify-streamLogsOnFailures/verify.groovy b/src/it/fail-build-with-verify-streamLogsOnFailures/verify.groovy
new file mode 100644
index 0000000..7d5bdd1
--- /dev/null
+++ b/src/it/fail-build-with-verify-streamLogsOnFailures/verify.groovy
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+def FS = File.separator
+def buildLogOfProject = new File( basedir, 'target/it/project/build.log' ).text
+
+def buildLog = new File( basedir, 'build.log' ).text
+
+assert buildLog.contains( '*** begin build.log for: project' + FS + 'pom.xml ***' )
+assert buildLog.contains( buildLogOfProject )
+assert buildLog.contains( '*** end build.log for: project' + FS + 'pom.xml ***' )
+
+assert buildLog.contains( 'maven-invoker-plugin:' + projectVersion + ':integration-test' )
+assert buildLog.contains( '[ERROR] Failed to execute goal org.apache.maven.plugins:maven-invoker-plugin:' + projectVersion + ':verify' )
+
diff --git a/src/main/java/org/apache/maven/plugins/invoker/AbstractInvokerMojo.java b/src/main/java/org/apache/maven/plugins/invoker/AbstractInvokerMojo.java
index abcbb96..6a5c879 100644
--- a/src/main/java/org/apache/maven/plugins/invoker/AbstractInvokerMojo.java
+++ b/src/main/java/org/apache/maven/plugins/invoker/AbstractInvokerMojo.java
@@ -1659,7 +1659,6 @@ public abstract class AbstractInvokerMojo
// let's set what details we can
buildJob.setName( invokerProperties.getJobName() );
buildJob.setDescription( invokerProperties.getJobDescription() );
- ExecutionResult executionResult = null;
try
{
@@ -1668,18 +1667,27 @@ public abstract class AbstractInvokerMojo
{
long milliseconds = System.currentTimeMillis();
boolean executed;
+
+ FileLogger buildLogger = setupBuildLogFile( basedir );
+ if ( buildLogger != null )
+ {
+ buildJob.setBuildlog( buildLogger.getOutputFile().getAbsolutePath() );
+ }
+
try
{
- // CHECKSTYLE_OFF: LineLength
- executionResult =
- runBuild( basedir, interpolatedPomFile, settingsFile, actualJavaHome, invokerProperties );
- // CHECKSTYLE_ON: LineLength
- executed = executionResult.executed;
+ executed = runBuild( basedir, interpolatedPomFile, settingsFile, actualJavaHome,
+ invokerProperties, buildLogger );
}
finally
{
milliseconds = System.currentTimeMillis() - milliseconds;
buildJob.setTime( milliseconds / 1000.0 );
+
+ if ( buildLogger != null )
+ {
+ buildLogger.close();
+ }
}
if ( executed )
@@ -1779,7 +1787,7 @@ public abstract class AbstractInvokerMojo
finally
{
deleteInterpolatedPomFile( interpolatedPomFile );
- writeBuildReport( buildJob, executionResult );
+ writeBuildReport( buildJob );
}
}
@@ -1846,7 +1854,7 @@ public abstract class AbstractInvokerMojo
* @param buildJob The build job whose report should be written, must not be <code>null</code>.
* @throws org.apache.maven.plugin.MojoExecutionException If the report could not be written.
*/
- private void writeBuildReport( BuildJob buildJob, ExecutionResult executionResult )
+ private void writeBuildReport( BuildJob buildJob )
throws MojoExecutionException
{
if ( disableReports )
@@ -1875,11 +1883,11 @@ public abstract class AbstractInvokerMojo
if ( writeJunitReport )
{
- writeJunitReport( buildJob, safeFileName, executionResult );
+ writeJunitReport( buildJob, safeFileName );
}
}
- private void writeJunitReport( BuildJob buildJob, String safeFileName, ExecutionResult executionResult )
+ private void writeJunitReport( BuildJob buildJob, String safeFileName )
throws MojoExecutionException
{
File reportFile = new File( reportsDirectory, "TEST-" + safeFileName + ".xml" );
@@ -1922,23 +1930,26 @@ public abstract class AbstractInvokerMojo
Xpp3Dom systemOut = new Xpp3Dom( "system-out" );
testcase.addChild( systemOut );
- if ( executionResult != null && executionResult.fileLogger != null )
+
+ File buildLogFile = buildJob.getBuildlog() != null ? new File( buildJob.getBuildlog() ) : null;
+
+ if ( buildLogFile != null && buildLogFile.exists() )
{
- getLog().debug( "fileLogger:" + executionResult.fileLogger.getOutputFile() );
+ getLog().debug( "fileLogger:" + buildLogFile );
try
{
- systemOut.setValue( FileUtils.fileRead( executionResult.fileLogger.getOutputFile() ) );
+ systemOut.setValue( FileUtils.fileRead( buildLogFile ) );
}
catch ( IOException e )
{
- throw new MojoExecutionException( "Failed to read logfile " + executionResult.fileLogger.getOutputFile()
- , e );
+ throw new MojoExecutionException( "Failed to read logfile " + buildLogFile, e );
}
}
else
{
- getLog().debug( safeFileName + ", executionResult:" + executionResult );
+ getLog().debug( safeFileName + "not exists buildLogFile = " + buildLogFile );
}
+
try ( FileOutputStream fos = new FileOutputStream( reportFile );
Writer osw = new OutputStreamWriter( fos, buildJob.getModelEncoding() ) )
{
@@ -1968,14 +1979,15 @@ public abstract class AbstractInvokerMojo
* @param settingsFile The (already interpolated) user settings file for the build, may be <code>null</code>. Will
* be merged with the settings file of the invoking Maven process.
* @param invokerProperties The properties to use.
+ * @param logger file logger to write execution build.log
* @return <code>true</code> if the project was launched or <code>false</code> if the selector script indicated that
* the project should be skipped.
* @throws org.apache.maven.plugin.MojoExecutionException If the project could not be launched.
* @throws org.apache.maven.shared.scriptinterpreter.RunFailureException If either a hook script or the build itself
* failed.
*/
- private ExecutionResult runBuild( File basedir, File pomFile, File settingsFile, File actualJavaHome,
- InvokerProperties invokerProperties )
+ private boolean runBuild( File basedir, File pomFile, File settingsFile, File actualJavaHome,
+ InvokerProperties invokerProperties, FileLogger logger )
throws MojoExecutionException, RunFailureException
{
if ( getLog().isDebugEnabled() && !invokerProperties.getProperties().isEmpty() )
@@ -1995,9 +2007,8 @@ public abstract class AbstractInvokerMojo
Map<String, Object> context = new LinkedHashMap<>();
- FileLogger logger = setupBuildLogFile( basedir );
boolean selectorResult = true;
- ExecutionResult executionResult = new ExecutionResult();
+
try
{
try
@@ -2013,8 +2024,7 @@ public abstract class AbstractInvokerMojo
catch ( RunFailureException e )
{
selectorResult = false;
- executionResult.executed = false;
- return executionResult;
+ return false;
}
scriptRunner.run( "pre-build script", basedir, preBuildHookScript, context, logger,
@@ -2137,14 +2147,8 @@ public abstract class AbstractInvokerMojo
{
runPostBuildHook( basedir, context, logger );
}
- if ( logger != null )
- {
- logger.close();
- }
}
- executionResult.executed = true;
- executionResult. fileLogger = logger;
- return executionResult;
+ return true;
}
int getParallelThreadsCount()
@@ -2161,18 +2165,6 @@ public abstract class AbstractInvokerMojo
}
}
- private static class ExecutionResult
- {
- boolean executed;
- FileLogger fileLogger;
-
- @Override
- public String toString()
- {
- return "ExecutionResult{" + "executed=" + executed + ", fileLogger=" + fileLogger + '}';
- }
- }
-
private void runPostBuildHook( File basedir, Map<String, Object> context, FileLogger logger )
throws MojoExecutionException, RunFailureException
{
diff --git a/src/main/java/org/apache/maven/plugins/invoker/InvokerMojo.java b/src/main/java/org/apache/maven/plugins/invoker/InvokerMojo.java
index 5459a7e..6dbbbd4 100644
--- a/src/main/java/org/apache/maven/plugins/invoker/InvokerMojo.java
+++ b/src/main/java/org/apache/maven/plugins/invoker/InvokerMojo.java
@@ -57,6 +57,14 @@ public class InvokerMojo
@Parameter( property = "invoker.failIfNoProjects" )
private Boolean failIfNoProjects;
+ /**
+ * Set to <code>true</code> to output build.log to mojo log in case of failed jobs.
+ *
+ * @since 3.2.2
+ */
+ @Parameter( property = "invoker.streamLogsOnFailures", defaultValue = "false" )
+ private boolean streamLogsOnFailures;
+
void processResults( InvokerSession invokerSession )
throws MojoFailureException
{
@@ -65,6 +73,11 @@ public class InvokerMojo
invokerSession.logSummary( getLog(), ignoreFailures );
}
+ if ( streamLogsOnFailures )
+ {
+ invokerSession.logFailedBuildLog( getLog(), ignoreFailures );
+ }
+
invokerSession.handleFailures( getLog(), ignoreFailures );
}
diff --git a/src/main/java/org/apache/maven/plugins/invoker/InvokerSession.java b/src/main/java/org/apache/maven/plugins/invoker/InvokerSession.java
index 43ed9bb..1cba4a0 100644
--- a/src/main/java/org/apache/maven/plugins/invoker/InvokerSession.java
+++ b/src/main/java/org/apache/maven/plugins/invoker/InvokerSession.java
@@ -21,12 +21,16 @@ package org.apache.maven.plugins.invoker;
import static org.apache.maven.shared.utils.logging.MessageUtils.buffer;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.invoker.model.BuildJob;
import org.apache.maven.plugin.logging.Log;
+import org.apache.maven.shared.utils.io.IOUtil;
/**
* Tracks a set of build jobs and their results.
@@ -35,6 +39,8 @@ import org.apache.maven.plugin.logging.Log;
*/
class InvokerSession
{
+ private static final String SEPARATOR = buffer().strong(
+ "-------------------------------------------------" ).toString();
private List<BuildJob> buildJobs;
@@ -197,43 +203,58 @@ class InvokerSession
{
updateStats();
- String separator = buffer().strong( "-------------------------------------------------" ).toString();
-
- logger.info( separator );
+ logger.info( SEPARATOR );
logger.info( "Build Summary:" );
- logger.info( " Passed: " + successfulJobs.size() + ", Failed: " + failedJobs.size() + ", Errors: "
- + errorJobs.size() + ", Skipped: " + skippedJobs.size() );
- logger.info( separator );
+ logger.info( " Passed: " + successfulJobs.size()
+ + ", Failed: " + failedJobs.size()
+ + ", Errors: " + errorJobs.size()
+ + ", Skipped: " + skippedJobs.size() );
+ logger.info( SEPARATOR );
+
+ logBuildJobList( logger, ignoreFailures, "The following builds failed:", failedJobs );
+ logBuildJobList( logger, ignoreFailures, "The following builds finished with error:", errorJobs );
+ logBuildJobList( logger, ignoreFailures, "The following builds was skipped:", skippedJobs );
+ }
- if ( !failedJobs.isEmpty() )
- {
- String heading = "The following builds failed:";
- if ( ignoreFailures )
- {
- logger.warn( heading );
- }
- else
- {
- logger.error( heading );
- }
+ public void logFailedBuildLog( Log logger, boolean ignoreFailures )
+ throws MojoFailureException
+ {
+ List<BuildJob> jobToLogs = new ArrayList<>( failedJobs );
+ jobToLogs.addAll( errorJobs );
- for ( BuildJob buildJob : failedJobs )
+ for ( BuildJob buildJob: jobToLogs )
+ {
+ File buildLogFile = buildJob.getBuildlog() != null ? new File( buildJob.getBuildlog() ) : null;
+ if ( buildLogFile != null && buildLogFile.exists() )
{
- String item = "* " + buildJob.getProject();
- if ( ignoreFailures )
+ try
{
- logger.warn( item );
+ // prepare message with build.log in one string to omit begin [ERROR], [WARN]
+ // so whole log will be displayed without decoration
+ StringBuilder buildLogMessage = new StringBuilder( );
+ buildLogMessage.append( System.lineSeparator() );
+ buildLogMessage.append( System.lineSeparator() );
+ buildLogMessage.append( "*** begin build.log for: " + buildJob.getProject() + " ***" );
+ buildLogMessage.append( System.lineSeparator() );
+ buildLogMessage.append( IOUtil.toString( new FileReader( buildLogFile ) ) );
+ buildLogMessage.append( "*** end build.log for: " + buildJob.getProject() + " ***" );
+ buildLogMessage.append( System.lineSeparator() );
+
+ logWithLevel( logger, ignoreFailures, SEPARATOR );
+ logWithLevel( logger, ignoreFailures, buildLogMessage.toString() );
+ logWithLevel( logger, ignoreFailures, SEPARATOR );
+ logWithLevel( logger, ignoreFailures, "" );
+
}
- else
+ catch ( IOException e )
{
- logger.error( item );
+ throw new MojoFailureException( e.getMessage(), e );
}
}
-
- logger.info( separator );
}
}
+
/**
* Handles the build failures in this session.
*
@@ -275,4 +296,47 @@ class InvokerSession
}
}
+ /**
+ * Log list of jobs.
+ *
+ * @param logger logger to write
+ * @param warn flag indicate log level
+ * @param buildJobs jobs to list
+ */
+ private void logBuildJobList( Log logger, boolean warn, String header, List<BuildJob> buildJobs )
+ {
+ if ( buildJobs.isEmpty() )
+ {
+ return;
+ }
+
+ logWithLevel( logger, warn, header );
+
+ for ( BuildJob buildJob : buildJobs )
+ {
+ logWithLevel( logger, warn, "* " + buildJob.getProject() );
+ }
+
+ logger.info( SEPARATOR );
+ }
+
+ /**
+ * Log message in correct level depends on flag.
+ *
+ * @param logger logger to write
+ * @param warn flag indicate log level
+ * @param message message to write
+ */
+ private void logWithLevel( Log logger, boolean warn, String message )
+ {
+
+ if ( warn )
+ {
+ logger.warn( message );
+ }
+ else
+ {
+ logger.error( message );
+ }
+ }
}
diff --git a/src/main/java/org/apache/maven/plugins/invoker/VerifyMojo.java b/src/main/java/org/apache/maven/plugins/invoker/VerifyMojo.java
index 5592f3d..bc4abc4 100644
--- a/src/main/java/org/apache/maven/plugins/invoker/VerifyMojo.java
+++ b/src/main/java/org/apache/maven/plugins/invoker/VerifyMojo.java
@@ -86,6 +86,14 @@ public class VerifyMojo
private Boolean failIfNoProjects;
/**
+ * Set to <code>true</code> to output build.log to mojo log in case of failed jobs.
+ *
+ * @since 3.2.2
+ */
+ @Parameter( property = "invoker.streamLogsOnFailures", defaultValue = "false" )
+ private boolean streamLogsOnFailures;
+
+ /**
* Invokes Maven on the configured test projects.
*
* @throws org.apache.maven.plugin.MojoExecutionException If the goal encountered severe errors.
@@ -137,6 +145,11 @@ public class VerifyMojo
invokerSession.logSummary( getLog(), ignoreFailures );
}
+ if ( streamLogsOnFailures )
+ {
+ invokerSession.logFailedBuildLog( getLog(), ignoreFailures );
+ }
+
invokerSession.handleFailures( getLog(), ignoreFailures );
}
diff --git a/src/main/mdo/invocation.mdo b/src/main/mdo/invocation.mdo
index ad8b0c4..bc488f4 100644
--- a/src/main/mdo/invocation.mdo
+++ b/src/main/mdo/invocation.mdo
@@ -103,6 +103,13 @@ under the License.
<type>int</type>
<description>BuildJobs will be sorted in the descending order of the ordinal. In other words, the BuildJobs with the highest numbers will be executed first</description>
</field>
+ <field xml.attribute="true">
+ <name>buildlog</name>
+ <version>1.0.0</version>
+ <required>false</required>
+ <type>String</type>
+ <description>The build log filename</description>
+ </field>
</fields>
<codeSegments>
<codeSegment>
diff --git a/src/site/apt/examples/logs-for-failed-tests.apt.vm b/src/site/apt/examples/logs-for-failed-tests.apt.vm
new file mode 100644
index 0000000..57e3f62
--- /dev/null
+++ b/src/site/apt/examples/logs-for-failed-tests.apt.vm
@@ -0,0 +1,56 @@
+ ------
+ Inspect logs for failed tests
+ ------
+ Slawomir Jaranowski
+ ------
+ 2020-05-20
+ ------
+
+ ~~ Licensed to the Apache Software Foundation (ASF) under one
+ ~~ or more contributor license agreements. See the NOTICE file
+ ~~ distributed with this work for additional information
+ ~~ regarding copyright ownership. The ASF licenses this file
+ ~~ to you 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.
+
+ ~~ NOTE: For help with the syntax of this file, see:
+ ~~ http://maven.apache.org/doxia/references/apt-format.html
+
+Inspect logs for failed tests
+
+ In the usual build all tests pass as we expect,
+ so printing logs from all tests to project build log make our standard build log illegible.
+ The problem begin when some of test was failed,
+ especially when happened on CI system when access to files from build workspace is difficult.
+
+ In order to help investigation on failed test we can use option: <<<streamLogsOnFailures>>>.
+ Now logs from all failed test will be printed to project build log when all test will have finished.
+
++---+
+<project>
+ ...
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-invoker-plugin</artifactId>
+ <version>${project.version}</version>
+ <configuration>
+ <streamLogsOnFailures>true</streamLogsOnFailures>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ ...
+</project>
++---+
diff --git a/src/site/site.xml b/src/site/site.xml
index c754d61..5c9f2c2 100644
--- a/src/site/site.xml
+++ b/src/site/site.xml
@@ -69,6 +69,7 @@ under the License.
<item name="Fast Build Configuration" href="examples/fast-use.html"/>
<item name="Installing Artifacts" href="examples/install-artifacts.html"/>
<item name="Invoker Properties" href="examples/invoker-properties.html"/>
+ <item name="Inspect logs for failed tests" href="examples/logs-for-failed-tests.html"/>
<item name="Selector Conditions" href="examples/selector-conditions.html"/>
<item name="Selector Scripts" href="examples/selector-scripts.html"/>
<item name="Using a Post Build Script" href="examples/post-build-script.html"/>