org.apache.maven.plugins.invoker.InvokerSession Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of maven-invoker-plugin Show documentation
Show all versions of maven-invoker-plugin Show documentation
The Maven Invoker Plugin is used to run a set of Maven projects. The plugin can determine whether each project
execution is successful, and optionally can verify the output generated from a given project execution.
/*
* 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.
*/
package org.apache.maven.plugins.invoker;
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.plugin.logging.Log;
import org.apache.maven.plugins.invoker.model.BuildJob;
import org.codehaus.plexus.util.IOUtil;
import static org.apache.maven.shared.utils.logging.MessageUtils.buffer;
/**
* Tracks a set of build jobs and their results.
*
* @author Benjamin Bentmann
*/
class InvokerSession {
private static final String SEPARATOR =
buffer().strong("-------------------------------------------------").build();
private List buildJobs;
private List failedJobs;
private List errorJobs;
private List successfulJobs;
private List skippedJobs;
/**
* Creates a new empty session.
*/
InvokerSession() {
buildJobs = new ArrayList<>();
}
/**
* Creates a session that initially contains the specified build jobs.
*
* @param buildJobs The build jobs to set, must not be null
.
*/
InvokerSession(List buildJobs) {
this.buildJobs = new ArrayList<>(buildJobs);
}
/**
* Adds the specified build job to this session.
*
* @param buildJob The build job to add, must not be null
.
*/
public void addJob(BuildJob buildJob) {
buildJobs.add(buildJob);
resetStats();
}
/**
* Sets the build jobs of this session.
*
* @param buildJobs The build jobs to set, must not be null
.
*/
public void setJobs(List extends BuildJob> buildJobs) {
this.buildJobs = new ArrayList<>(buildJobs);
resetStats();
}
/**
* Gets the build jobs in this session.
*
* @return The build jobs in this session, can be empty but never null
.
*/
public List getJobs() {
return buildJobs;
}
/**
* Gets the successful build jobs in this session.
*
* @return The successful build jobs in this session, can be empty but never null
.
*/
public List getSuccessfulJobs() {
updateStats();
return successfulJobs;
}
/**
* Gets the failed build jobs in this session.
*
* @return The failed build jobs in this session, can be empty but never null
.
*/
public List getFailedJobs() {
updateStats();
return failedJobs;
}
/**
* Gets the build jobs which had errors for this session.
*
* @return The build jobs in error for this session, can be empty but never null
.
*/
public List getErrorJobs() {
updateStats();
return errorJobs;
}
/**
* Gets the skipped build jobs in this session.
*
* @return The skipped build jobs in this session, can be empty but never null
.
*/
public List getSkippedJobs() {
updateStats();
return skippedJobs;
}
private void resetStats() {
successfulJobs = null;
failedJobs = null;
skippedJobs = null;
errorJobs = null;
}
private void updateStats() {
if (successfulJobs != null && skippedJobs != null && failedJobs != null && errorJobs != null) {
return;
}
successfulJobs = new ArrayList<>();
failedJobs = new ArrayList<>();
skippedJobs = new ArrayList<>();
errorJobs = new ArrayList<>();
for (BuildJob buildJob : buildJobs) {
if (BuildJob.Result.SUCCESS.equals(buildJob.getResult())) {
successfulJobs.add(buildJob);
} else if (BuildJob.Result.SKIPPED.equals(buildJob.getResult())) {
skippedJobs.add(buildJob);
} else if (BuildJob.Result.ERROR.equals(buildJob.getResult())) {
errorJobs.add(buildJob);
} else if (buildJob.getResult() != null) {
failedJobs.add(buildJob);
}
}
}
/**
* Prints a summary of this session to the specified logger.
*
* @param logger The mojo logger to output messages to, must not be null
.
* @param ignoreFailures A flag whether failures should be ignored or whether a build failure should be signaled.
*/
public void logSummary(Log logger, boolean ignoreFailures) {
updateStats();
logger.info(SEPARATOR);
logger.info("Build Summary:");
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, true, "The following builds were skipped:", skippedJobs);
}
public void logFailedBuildLog(Log logger, boolean ignoreFailures) throws MojoFailureException {
updateStats();
List jobToLogs = new ArrayList<>(failedJobs);
jobToLogs.addAll(errorJobs);
for (BuildJob buildJob : jobToLogs) {
File buildLogFile = buildJob.getBuildlog() != null ? new File(buildJob.getBuildlog()) : null;
if (buildLogFile != null && buildLogFile.exists()) {
try {
// 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());
try (FileReader buildLogReader = new FileReader(buildLogFile)) {
buildLogMessage.append(IOUtil.toString(buildLogReader));
}
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, "");
} catch (IOException e) {
throw new MojoFailureException(e.getMessage(), e);
}
}
}
}
/**
* Handles the build failures in this session.
*
* @param logger The mojo logger to output messages to, must not be null
.
* @param ignoreFailures A flag whether failures should be ignored or whether a build failure should be signaled.
* @throws MojoFailureException If failures are present and not ignored.
*/
public void handleFailures(Log logger, boolean ignoreFailures) throws MojoFailureException {
updateStats();
if (!failedJobs.isEmpty()) {
String message = failedJobs.size() + " build" + (failedJobs.size() == 1 ? "" : "s") + " failed.";
if (ignoreFailures) {
logger.warn("Ignoring that " + message);
} else {
throw new MojoFailureException(message + " See console output above for details.");
}
}
if (!errorJobs.isEmpty()) {
String message = errorJobs.size() + " build" + (errorJobs.size() == 1 ? "" : "s") + " in error.";
if (ignoreFailures) {
logger.warn("Ignoring that " + message);
} else {
throw new MojoFailureException(message + " See console output above for details.");
}
}
}
/**
* 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 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);
}
}
}