mirror of
https://github.com/apache/maven-mvnd.git
synced 2025-10-14 14:10:52 +00:00
Switch to maven 4.0.0-alpha-2 (#718)
This commit is contained in:
@@ -24,8 +24,6 @@ import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
@@ -37,7 +35,7 @@ import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -45,6 +43,7 @@ import java.util.stream.Stream;
|
||||
import org.apache.commons.cli.CommandLine;
|
||||
import org.apache.commons.cli.Option;
|
||||
import org.apache.commons.cli.ParseException;
|
||||
import org.apache.commons.lang3.math.NumberUtils;
|
||||
import org.apache.maven.InternalErrorException;
|
||||
import org.apache.maven.Maven;
|
||||
import org.apache.maven.building.FileSource;
|
||||
@@ -61,10 +60,7 @@ import org.apache.maven.eventspy.internal.EventSpyDispatcher;
|
||||
import org.apache.maven.exception.DefaultExceptionHandler;
|
||||
import org.apache.maven.exception.ExceptionHandler;
|
||||
import org.apache.maven.exception.ExceptionSummary;
|
||||
import org.apache.maven.execution.MavenExecutionRequest;
|
||||
import org.apache.maven.execution.MavenExecutionRequestPopulationException;
|
||||
import org.apache.maven.execution.MavenExecutionRequestPopulator;
|
||||
import org.apache.maven.execution.MavenExecutionResult;
|
||||
import org.apache.maven.execution.*;
|
||||
import org.apache.maven.execution.scope.internal.MojoExecutionScopeModule;
|
||||
import org.apache.maven.extension.internal.CoreExports;
|
||||
import org.apache.maven.extension.internal.CoreExtensionEntry;
|
||||
@@ -101,9 +97,6 @@ import org.mvndaemon.mvnd.cache.invalidating.InvalidatingProjectArtifactsCache;
|
||||
import org.mvndaemon.mvnd.cli.EnvHelper;
|
||||
import org.mvndaemon.mvnd.common.Environment;
|
||||
import org.mvndaemon.mvnd.common.Os;
|
||||
import org.mvndaemon.mvnd.execution.BuildResumptionPersistenceException;
|
||||
import org.mvndaemon.mvnd.execution.DefaultBuildResumptionAnalyzer;
|
||||
import org.mvndaemon.mvnd.execution.DefaultBuildResumptionDataRepository;
|
||||
import org.mvndaemon.mvnd.logging.internal.Slf4jLoggerManager;
|
||||
import org.mvndaemon.mvnd.logging.smart.BuildEventListener;
|
||||
import org.mvndaemon.mvnd.logging.smart.LoggingExecutionListener;
|
||||
@@ -177,7 +170,9 @@ public class DaemonMavenCli {
|
||||
|
||||
private final LoggingExecutionListener executionListener;
|
||||
|
||||
/** Non-volatile, assuming that it is accessed only from the main thread */
|
||||
/**
|
||||
* Non-volatile, assuming that it is accessed only from the main thread
|
||||
*/
|
||||
private BuildEventListener buildEventListener = BuildEventListener.dummy();
|
||||
|
||||
public DaemonMavenCli() throws Exception {
|
||||
@@ -354,12 +349,12 @@ public class DaemonMavenCli {
|
||||
*/
|
||||
void logging(CliRequest cliRequest) {
|
||||
// LOG LEVEL
|
||||
cliRequest.debug = cliRequest.commandLine.hasOption(CLIManager.DEBUG);
|
||||
cliRequest.quiet = !cliRequest.debug && cliRequest.commandLine.hasOption(CLIManager.QUIET);
|
||||
cliRequest.showErrors = cliRequest.debug || cliRequest.commandLine.hasOption(CLIManager.ERRORS);
|
||||
cliRequest.verbose = cliRequest.commandLine.hasOption(CLIManager.VERBOSE);
|
||||
cliRequest.quiet = !cliRequest.verbose && cliRequest.commandLine.hasOption(CLIManager.QUIET);
|
||||
cliRequest.showErrors = cliRequest.verbose || cliRequest.commandLine.hasOption(CLIManager.ERRORS);
|
||||
|
||||
ch.qos.logback.classic.Level level;
|
||||
if (cliRequest.debug) {
|
||||
if (cliRequest.verbose) {
|
||||
level = ch.qos.logback.classic.Level.DEBUG;
|
||||
} else if (cliRequest.quiet) {
|
||||
level = ch.qos.logback.classic.Level.WARN;
|
||||
@@ -413,7 +408,7 @@ public class DaemonMavenCli {
|
||||
}
|
||||
|
||||
private void version(CliRequest cliRequest) throws ExitException {
|
||||
if (cliRequest.debug || cliRequest.commandLine.hasOption(CLIManager.VERSION)) {
|
||||
if (cliRequest.verbose || cliRequest.commandLine.hasOption(CLIManager.VERSION)) {
|
||||
buildEventListener.log(CLIReportingUtils.showVersion());
|
||||
if (cliRequest.commandLine.hasOption(CLIManager.VERSION)) {
|
||||
throw new ExitException(0);
|
||||
@@ -576,7 +571,7 @@ public class DaemonMavenCli {
|
||||
properties(cliRequest);
|
||||
configure(cliRequest, eventSpyDispatcher, configurationProcessors);
|
||||
LoggingExecutionListener executionListener = container.lookup(LoggingExecutionListener.class);
|
||||
populateRequest(cliRequest, cliRequest.request, slf4jLogger, eventSpyDispatcher,
|
||||
populateRequest(cliRequest, cliRequest.request, eventSpyDispatcher,
|
||||
container.lookup(ModelProcessor.class), createTransferListener(cliRequest), buildEventListener,
|
||||
executionListener);
|
||||
executionRequestPopulator.populateDefaults(cliRequest.request);
|
||||
@@ -729,18 +724,7 @@ public class DaemonMavenCli {
|
||||
}
|
||||
}
|
||||
|
||||
boolean canResume = new DefaultBuildResumptionAnalyzer().determineBuildResumptionData(result).map(resumption -> {
|
||||
try {
|
||||
Path directory = Paths.get(request.getBaseDirectory()).resolve("target");
|
||||
new DefaultBuildResumptionDataRepository().persistResumptionData(directory, resumption);
|
||||
return true;
|
||||
} catch (BuildResumptionPersistenceException e) {
|
||||
slf4jLogger.warn("Could not persist build resumption data", e);
|
||||
}
|
||||
return false;
|
||||
}).orElse(false);
|
||||
|
||||
if (canResume) {
|
||||
if (result.canResume()) {
|
||||
logBuildResumeHint("mvn <args> -r");
|
||||
} else if (!failedProjects.isEmpty()) {
|
||||
List<MavenProject> sortedProjects = result.getTopologicallySortedProjects();
|
||||
@@ -763,8 +747,6 @@ public class DaemonMavenCli {
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
Path directory = Paths.get(request.getBaseDirectory()).resolve("target");
|
||||
new DefaultBuildResumptionDataRepository().removeResumptionData(directory);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -999,14 +981,13 @@ public class DaemonMavenCli {
|
||||
}
|
||||
|
||||
private void populateRequest(CliRequest cliRequest) {
|
||||
populateRequest(cliRequest, cliRequest.request, slf4jLogger, eventSpyDispatcher, modelProcessor,
|
||||
populateRequest(cliRequest, cliRequest.request, eventSpyDispatcher, modelProcessor,
|
||||
createTransferListener(cliRequest), buildEventListener, executionListener);
|
||||
}
|
||||
|
||||
private static void populateRequest(
|
||||
private void populateRequest(
|
||||
CliRequest cliRequest,
|
||||
MavenExecutionRequest request,
|
||||
Logger slf4jLogger,
|
||||
EventSpyDispatcher eventSpyDispatcher,
|
||||
ModelProcessor modelProcessor,
|
||||
TransferListener transferListener,
|
||||
@@ -1014,208 +995,50 @@ public class DaemonMavenCli {
|
||||
LoggingExecutionListener executionListener) {
|
||||
CommandLine commandLine = cliRequest.commandLine;
|
||||
String workingDirectory = cliRequest.workingDirectory;
|
||||
boolean showErrors = cliRequest.showErrors;
|
||||
|
||||
String[] deprecatedOptions = { "up", "npu", "cpu", "npr" };
|
||||
for (String deprecatedOption : deprecatedOptions) {
|
||||
if (commandLine.hasOption(deprecatedOption)) {
|
||||
slf4jLogger.warn("Command line option -{} is deprecated and will be removed in future Maven versions.",
|
||||
deprecatedOption);
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Now that we have everything that we need we will fire up plexus and
|
||||
// bring the maven component to life for use.
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
if (commandLine.hasOption(CLIManager.BATCH_MODE)) {
|
||||
request.setInteractiveMode(false);
|
||||
}
|
||||
|
||||
boolean noSnapshotUpdates = false;
|
||||
if (commandLine.hasOption(CLIManager.SUPRESS_SNAPSHOT_UPDATES)) {
|
||||
noSnapshotUpdates = true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
//
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
List<String> goals = commandLine.getArgList();
|
||||
|
||||
boolean recursive = true;
|
||||
|
||||
// this is the default behavior.
|
||||
String reactorFailureBehaviour = MavenExecutionRequest.REACTOR_FAIL_FAST;
|
||||
|
||||
if (commandLine.hasOption(CLIManager.NON_RECURSIVE)) {
|
||||
recursive = false;
|
||||
}
|
||||
|
||||
if (commandLine.hasOption(CLIManager.FAIL_FAST)) {
|
||||
reactorFailureBehaviour = MavenExecutionRequest.REACTOR_FAIL_FAST;
|
||||
} else if (commandLine.hasOption(CLIManager.FAIL_AT_END)) {
|
||||
reactorFailureBehaviour = MavenExecutionRequest.REACTOR_FAIL_AT_END;
|
||||
} else if (commandLine.hasOption(CLIManager.FAIL_NEVER)) {
|
||||
reactorFailureBehaviour = MavenExecutionRequest.REACTOR_FAIL_NEVER;
|
||||
}
|
||||
|
||||
if (commandLine.hasOption(CLIManager.OFFLINE)) {
|
||||
request.setOffline(true);
|
||||
}
|
||||
|
||||
boolean updateSnapshots = false;
|
||||
|
||||
if (commandLine.hasOption(CLIManager.UPDATE_SNAPSHOTS)) {
|
||||
updateSnapshots = true;
|
||||
}
|
||||
|
||||
String globalChecksumPolicy = null;
|
||||
|
||||
if (commandLine.hasOption(CLIManager.CHECKSUM_FAILURE_POLICY)) {
|
||||
globalChecksumPolicy = MavenExecutionRequest.CHECKSUM_POLICY_FAIL;
|
||||
} else if (commandLine.hasOption(CLIManager.CHECKSUM_WARNING_POLICY)) {
|
||||
globalChecksumPolicy = MavenExecutionRequest.CHECKSUM_POLICY_WARN;
|
||||
}
|
||||
|
||||
boolean quiet = cliRequest.quiet;
|
||||
boolean verbose = cliRequest.verbose;
|
||||
request.setShowErrors(cliRequest.showErrors); // default: false
|
||||
File baseDirectory = new File(workingDirectory, "").getAbsoluteFile();
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Profile Activation
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
List<String> activeProfiles = new ArrayList<>();
|
||||
|
||||
List<String> inactiveProfiles = new ArrayList<>();
|
||||
|
||||
if (commandLine.hasOption(CLIManager.ACTIVATE_PROFILES)) {
|
||||
String[] profileOptionValues = commandLine.getOptionValues(CLIManager.ACTIVATE_PROFILES);
|
||||
if (profileOptionValues != null) {
|
||||
for (String profileOptionValue : profileOptionValues) {
|
||||
StringTokenizer profileTokens = new StringTokenizer(profileOptionValue, ",");
|
||||
|
||||
while (profileTokens.hasMoreTokens()) {
|
||||
String profileAction = profileTokens.nextToken().trim();
|
||||
|
||||
if (profileAction.startsWith("-") || profileAction.startsWith("!")) {
|
||||
inactiveProfiles.add(profileAction.substring(1));
|
||||
} else if (profileAction.startsWith("+")) {
|
||||
activeProfiles.add(profileAction.substring(1));
|
||||
} else {
|
||||
activeProfiles.add(profileAction);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
disableOnPresentOption(commandLine, CLIManager.BATCH_MODE, request::setInteractiveMode);
|
||||
enableOnPresentOption(commandLine, CLIManager.SUPPRESS_SNAPSHOT_UPDATES, request::setNoSnapshotUpdates);
|
||||
request.setGoals(commandLine.getArgList());
|
||||
request.setReactorFailureBehavior(determineReactorFailureBehaviour(commandLine));
|
||||
disableOnPresentOption(commandLine, CLIManager.NON_RECURSIVE, request::setRecursive);
|
||||
enableOnPresentOption(commandLine, CLIManager.OFFLINE, request::setOffline);
|
||||
enableOnPresentOption(commandLine, CLIManager.UPDATE_SNAPSHOTS, request::setUpdateSnapshots);
|
||||
request.setGlobalChecksumPolicy(determineGlobalCheckPolicy(commandLine));
|
||||
request.setBaseDirectory(baseDirectory);
|
||||
request.setSystemProperties(cliRequest.systemProperties);
|
||||
request.setUserProperties(cliRequest.userProperties);
|
||||
request.setMultiModuleProjectDirectory(cliRequest.multiModuleProjectDirectory);
|
||||
request.setPom(determinePom(modelProcessor, commandLine, workingDirectory, baseDirectory));
|
||||
request.setTransferListener(transferListener);
|
||||
request.setExecutionListener(executionListener);
|
||||
|
||||
ExecutionEventLogger executionEventLogger = new ExecutionEventLogger();
|
||||
executionListener.init(
|
||||
eventSpyDispatcher.chainListener(executionEventLogger),
|
||||
buildEventListener);
|
||||
|
||||
String alternatePomFile = null;
|
||||
if (commandLine.hasOption(CLIManager.ALTERNATE_POM_FILE)) {
|
||||
alternatePomFile = commandLine.getOptionValue(CLIManager.ALTERNATE_POM_FILE);
|
||||
}
|
||||
|
||||
request.setBaseDirectory(baseDirectory)
|
||||
.setGoals(goals)
|
||||
.setSystemProperties(cliRequest.systemProperties)
|
||||
.setUserProperties(cliRequest.userProperties)
|
||||
.setReactorFailureBehavior(reactorFailureBehaviour) // default: fail fast
|
||||
.setRecursive(recursive) // default: true
|
||||
.setShowErrors(showErrors) // default: false
|
||||
.addActiveProfiles(activeProfiles) // optional
|
||||
.addInactiveProfiles(inactiveProfiles) // optional
|
||||
.setExecutionListener(executionListener)
|
||||
.setTransferListener(transferListener) // default: batch mode which goes along with interactive
|
||||
.setUpdateSnapshots(updateSnapshots) // default: false
|
||||
.setNoSnapshotUpdates(noSnapshotUpdates) // default: false
|
||||
.setGlobalChecksumPolicy(globalChecksumPolicy) // default: warn
|
||||
.setMultiModuleProjectDirectory(cliRequest.getMultiModuleProjectDirectory());
|
||||
|
||||
if (alternatePomFile != null) {
|
||||
File pom = resolveFile(new File(alternatePomFile), workingDirectory);
|
||||
if (pom.isDirectory()) {
|
||||
pom = new File(pom, "pom.xml");
|
||||
}
|
||||
|
||||
request.setPom(pom);
|
||||
} else if (modelProcessor != null) {
|
||||
File pom = modelProcessor.locatePom(baseDirectory);
|
||||
|
||||
if (pom.isFile()) {
|
||||
request.setPom(pom);
|
||||
}
|
||||
}
|
||||
|
||||
if ((request.getPom() != null) && (request.getPom().getParentFile() != null)) {
|
||||
request.setBaseDirectory(request.getPom().getParentFile());
|
||||
}
|
||||
|
||||
if (commandLine.hasOption(RESUME)) {
|
||||
new DefaultBuildResumptionDataRepository()
|
||||
.applyResumptionData(request, Paths.get(request.getBaseDirectory()).resolve("target"));
|
||||
}
|
||||
|
||||
if (commandLine.hasOption(CLIManager.RESUME_FROM)) {
|
||||
request.setResumeFrom(commandLine.getOptionValue(CLIManager.RESUME_FROM));
|
||||
}
|
||||
|
||||
if (commandLine.hasOption(CLIManager.PROJECT_LIST)) {
|
||||
String[] projectOptionValues = commandLine.getOptionValues(CLIManager.PROJECT_LIST);
|
||||
|
||||
List<String> inclProjects = new ArrayList<>();
|
||||
List<String> exclProjects = new ArrayList<>();
|
||||
|
||||
if (projectOptionValues != null) {
|
||||
for (String projectOptionValue : projectOptionValues) {
|
||||
StringTokenizer projectTokens = new StringTokenizer(projectOptionValue, ",");
|
||||
|
||||
while (projectTokens.hasMoreTokens()) {
|
||||
String projectAction = projectTokens.nextToken().trim();
|
||||
|
||||
if (projectAction.startsWith("-") || projectAction.startsWith("!")) {
|
||||
exclProjects.add(projectAction.substring(1));
|
||||
} else if (projectAction.startsWith("+")) {
|
||||
inclProjects.add(projectAction.substring(1));
|
||||
} else {
|
||||
inclProjects.add(projectAction);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
request.setSelectedProjects(inclProjects);
|
||||
request.setExcludedProjects(exclProjects);
|
||||
}
|
||||
|
||||
if (commandLine.hasOption(CLIManager.ALSO_MAKE) && !commandLine.hasOption(
|
||||
CLIManager.ALSO_MAKE_DEPENDENTS)) {
|
||||
request.setMakeBehavior(MavenExecutionRequest.REACTOR_MAKE_UPSTREAM);
|
||||
} else if (!commandLine.hasOption(CLIManager.ALSO_MAKE) && commandLine.hasOption(
|
||||
CLIManager.ALSO_MAKE_DEPENDENTS)) {
|
||||
request.setMakeBehavior(MavenExecutionRequest.REACTOR_MAKE_DOWNSTREAM);
|
||||
} else if (commandLine.hasOption(CLIManager.ALSO_MAKE) && commandLine.hasOption(
|
||||
CLIManager.ALSO_MAKE_DEPENDENTS)) {
|
||||
request.setMakeBehavior(MavenExecutionRequest.REACTOR_MAKE_BOTH);
|
||||
}
|
||||
|
||||
String localRepoProperty = request.getUserProperties().getProperty(MavenCli.LOCAL_REPO_PROPERTY);
|
||||
|
||||
if (localRepoProperty == null) {
|
||||
localRepoProperty = request.getSystemProperties().getProperty(MavenCli.LOCAL_REPO_PROPERTY);
|
||||
}
|
||||
|
||||
if (localRepoProperty != null) {
|
||||
request.setLocalRepositoryPath(localRepoProperty);
|
||||
}
|
||||
|
||||
enableOnPresentOption(commandLine, CLIManager.RESUME, request::setResume);
|
||||
request.setMakeBehavior(determineMakeBehavior(commandLine));
|
||||
request.setCacheNotFound(true);
|
||||
request.setCacheTransferError(false);
|
||||
|
||||
performProjectActivation(commandLine, request.getProjectActivation());
|
||||
performProfileActivation(commandLine, request.getProfileActivation());
|
||||
|
||||
final String localRepositoryPath = determineLocalRepositoryPath(request);
|
||||
if (localRepositoryPath != null) {
|
||||
request.setLocalRepositoryPath(localRepositoryPath);
|
||||
}
|
||||
|
||||
//
|
||||
// Builder, concurrency and parallelism
|
||||
//
|
||||
@@ -1224,34 +1047,233 @@ public class DaemonMavenCli {
|
||||
// parameters but this is sufficient for now. Ultimately we want components like Builders to provide a way to
|
||||
// extend the command line to accept its own configuration parameters.
|
||||
//
|
||||
final String threadConfiguration = commandLine.hasOption(CLIManager.THREADS)
|
||||
? commandLine.getOptionValue(CLIManager.THREADS)
|
||||
: null;
|
||||
final String threadConfiguration = commandLine.getOptionValue(CLIManager.THREADS);
|
||||
|
||||
if (threadConfiguration != null) {
|
||||
//
|
||||
// Default to the standard multithreaded builder
|
||||
//
|
||||
int degreeOfConcurrency = calculateDegreeOfConcurrency(threadConfiguration);
|
||||
if (degreeOfConcurrency > 1) {
|
||||
request.setBuilderId("multithreaded");
|
||||
|
||||
if (threadConfiguration.contains("C")) {
|
||||
request.setDegreeOfConcurrency(calculateDegreeOfConcurrencyWithCoreMultiplier(threadConfiguration));
|
||||
} else {
|
||||
request.setDegreeOfConcurrency(Integer.parseInt(threadConfiguration));
|
||||
request.setDegreeOfConcurrency(degreeOfConcurrency);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Allow the builder to be overridden by the user if requested. The builders are now pluggable.
|
||||
//
|
||||
if (commandLine.hasOption(CLIManager.BUILDER)) {
|
||||
request.setBuilderId(commandLine.getOptionValue(CLIManager.BUILDER));
|
||||
request.setBuilderId(commandLine.getOptionValue(CLIManager.BUILDER, request.getBuilderId()));
|
||||
}
|
||||
|
||||
private String determineLocalRepositoryPath(final MavenExecutionRequest request) {
|
||||
String userDefinedLocalRepo = request.getUserProperties().getProperty(MavenCli.LOCAL_REPO_PROPERTY);
|
||||
if (userDefinedLocalRepo != null) {
|
||||
return userDefinedLocalRepo;
|
||||
}
|
||||
|
||||
return request.getSystemProperties().getProperty(MavenCli.LOCAL_REPO_PROPERTY);
|
||||
}
|
||||
|
||||
private File determinePom(ModelProcessor modelProcessor, final CommandLine commandLine, final String workingDirectory,
|
||||
final File baseDirectory) {
|
||||
String alternatePomFile = null;
|
||||
if (commandLine.hasOption(CLIManager.ALTERNATE_POM_FILE)) {
|
||||
alternatePomFile = commandLine.getOptionValue(CLIManager.ALTERNATE_POM_FILE);
|
||||
}
|
||||
|
||||
if (alternatePomFile != null) {
|
||||
File pom = resolveFile(new File(alternatePomFile), workingDirectory);
|
||||
if (pom.isDirectory()) {
|
||||
pom = new File(pom, "pom.xml");
|
||||
}
|
||||
|
||||
return pom;
|
||||
} else if (modelProcessor != null) {
|
||||
File pom = modelProcessor.locatePom(baseDirectory);
|
||||
|
||||
if (pom.isFile()) {
|
||||
return pom;
|
||||
}
|
||||
}
|
||||
|
||||
static int calculateDegreeOfConcurrencyWithCoreMultiplier(String threadConfiguration) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Visible for testing
|
||||
static void performProjectActivation(final CommandLine commandLine, final ProjectActivation projectActivation) {
|
||||
if (commandLine.hasOption(CLIManager.PROJECT_LIST)) {
|
||||
final String[] optionValues = commandLine.getOptionValues(CLIManager.PROJECT_LIST);
|
||||
|
||||
if (optionValues == null || optionValues.length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (final String optionValue : optionValues) {
|
||||
for (String token : optionValue.split(",")) {
|
||||
String selector = token.trim();
|
||||
boolean active = true;
|
||||
if (selector.charAt(0) == '-' || selector.charAt(0) == '!') {
|
||||
active = false;
|
||||
selector = selector.substring(1);
|
||||
} else if (token.charAt(0) == '+') {
|
||||
selector = selector.substring(1);
|
||||
}
|
||||
|
||||
boolean optional = selector.charAt(0) == '?';
|
||||
selector = selector.substring(optional ? 1 : 0);
|
||||
|
||||
projectActivation.addProjectActivation(selector, active, optional);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Visible for testing
|
||||
static void performProfileActivation(final CommandLine commandLine, final ProfileActivation profileActivation) {
|
||||
if (commandLine.hasOption(CLIManager.ACTIVATE_PROFILES)) {
|
||||
final String[] optionValues = commandLine.getOptionValues(CLIManager.ACTIVATE_PROFILES);
|
||||
|
||||
if (optionValues == null || optionValues.length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (final String optionValue : optionValues) {
|
||||
for (String token : optionValue.split(",")) {
|
||||
String profileId = token.trim();
|
||||
boolean active = true;
|
||||
if (profileId.charAt(0) == '-' || profileId.charAt(0) == '!') {
|
||||
active = false;
|
||||
profileId = profileId.substring(1);
|
||||
} else if (token.charAt(0) == '+') {
|
||||
profileId = profileId.substring(1);
|
||||
}
|
||||
|
||||
boolean optional = profileId.charAt(0) == '?';
|
||||
profileId = profileId.substring(optional ? 1 : 0);
|
||||
|
||||
profileActivation.addProfileActivation(profileId, active, optional);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ExecutionListener determineExecutionListener(EventSpyDispatcher eventSpyDispatcher) {
|
||||
ExecutionListener executionListener = new ExecutionEventLogger();
|
||||
if (eventSpyDispatcher != null) {
|
||||
return eventSpyDispatcher.chainListener(executionListener);
|
||||
} else {
|
||||
return executionListener;
|
||||
}
|
||||
}
|
||||
|
||||
private String determineReactorFailureBehaviour(final CommandLine commandLine) {
|
||||
if (commandLine.hasOption(CLIManager.FAIL_FAST)) {
|
||||
return MavenExecutionRequest.REACTOR_FAIL_FAST;
|
||||
} else if (commandLine.hasOption(CLIManager.FAIL_AT_END)) {
|
||||
return MavenExecutionRequest.REACTOR_FAIL_AT_END;
|
||||
} else if (commandLine.hasOption(CLIManager.FAIL_NEVER)) {
|
||||
return MavenExecutionRequest.REACTOR_FAIL_NEVER;
|
||||
} else {
|
||||
// this is the default behavior.
|
||||
return MavenExecutionRequest.REACTOR_FAIL_FAST;
|
||||
}
|
||||
}
|
||||
|
||||
private String determineMakeBehavior(final CommandLine cl) {
|
||||
if (cl.hasOption(CLIManager.ALSO_MAKE) && !cl.hasOption(CLIManager.ALSO_MAKE_DEPENDENTS)) {
|
||||
return MavenExecutionRequest.REACTOR_MAKE_UPSTREAM;
|
||||
} else if (!cl.hasOption(CLIManager.ALSO_MAKE) && cl.hasOption(CLIManager.ALSO_MAKE_DEPENDENTS)) {
|
||||
return MavenExecutionRequest.REACTOR_MAKE_DOWNSTREAM;
|
||||
} else if (cl.hasOption(CLIManager.ALSO_MAKE) && cl.hasOption(CLIManager.ALSO_MAKE_DEPENDENTS)) {
|
||||
return MavenExecutionRequest.REACTOR_MAKE_BOTH;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private String determineGlobalCheckPolicy(final CommandLine commandLine) {
|
||||
if (commandLine.hasOption(CLIManager.CHECKSUM_FAILURE_POLICY)) {
|
||||
return MavenExecutionRequest.CHECKSUM_POLICY_FAIL;
|
||||
} else if (commandLine.hasOption(CLIManager.CHECKSUM_WARNING_POLICY)) {
|
||||
return MavenExecutionRequest.CHECKSUM_POLICY_WARN;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void disableOnPresentOption(final CommandLine commandLine,
|
||||
final String option,
|
||||
final Consumer<Boolean> setting) {
|
||||
if (commandLine.hasOption(option)) {
|
||||
setting.accept(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void disableOnPresentOption(final CommandLine commandLine,
|
||||
final char option,
|
||||
final Consumer<Boolean> setting) {
|
||||
disableOnPresentOption(commandLine, String.valueOf(option), setting);
|
||||
}
|
||||
|
||||
private void enableOnPresentOption(final CommandLine commandLine,
|
||||
final String option,
|
||||
final Consumer<Boolean> setting) {
|
||||
if (commandLine.hasOption(option)) {
|
||||
setting.accept(true);
|
||||
}
|
||||
}
|
||||
|
||||
private void enableOnPresentOption(final CommandLine commandLine,
|
||||
final char option,
|
||||
final Consumer<Boolean> setting) {
|
||||
enableOnPresentOption(commandLine, String.valueOf(option), setting);
|
||||
}
|
||||
|
||||
private void enableOnAbsentOption(final CommandLine commandLine,
|
||||
final char option,
|
||||
final Consumer<Boolean> setting) {
|
||||
if (!commandLine.hasOption(option)) {
|
||||
setting.accept(true);
|
||||
}
|
||||
}
|
||||
|
||||
int calculateDegreeOfConcurrency(String threadConfiguration) {
|
||||
if (threadConfiguration.endsWith("C")) {
|
||||
threadConfiguration = threadConfiguration.substring(0, threadConfiguration.length() - 1);
|
||||
|
||||
if (!NumberUtils.isParsable(threadConfiguration)) {
|
||||
throw new IllegalArgumentException("Invalid threads core multiplier value: '" + threadConfiguration
|
||||
+ "C'. Supported are int and float values ending with C.");
|
||||
}
|
||||
|
||||
float coreMultiplier = Float.parseFloat(threadConfiguration);
|
||||
|
||||
if (coreMultiplier <= 0.0f) {
|
||||
throw new IllegalArgumentException("Invalid threads core multiplier value: '" + threadConfiguration
|
||||
+ "C'. Value must be positive.");
|
||||
}
|
||||
|
||||
int procs = Runtime.getRuntime().availableProcessors();
|
||||
return (int) (Float.parseFloat(threadConfiguration.replace("C", "")) * procs);
|
||||
int threads = (int) (coreMultiplier * procs);
|
||||
return threads == 0 ? 1 : threads;
|
||||
} else {
|
||||
if (!NumberUtils.isParsable(threadConfiguration)) {
|
||||
throw new IllegalArgumentException("Invalid threads value: '" + threadConfiguration
|
||||
+ "'. Supported are int values.");
|
||||
}
|
||||
|
||||
try {
|
||||
int threads = Integer.parseInt(threadConfiguration);
|
||||
|
||||
if (threads <= 0) {
|
||||
throw new IllegalArgumentException("Invalid threads value: '" + threadConfiguration
|
||||
+ "'. Value must be positive.");
|
||||
}
|
||||
|
||||
return threads;
|
||||
} catch (NumberFormatException e) {
|
||||
throw new IllegalArgumentException("Invalid threads value: '" + threadConfiguration
|
||||
+ "'. Supported are integer values.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static File resolveFile(File file, String workingDirectory) {
|
||||
@@ -1280,15 +1302,10 @@ public class DaemonMavenCli {
|
||||
// are most dominant.
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
if (commandLine.hasOption(CLIManager.SET_SYSTEM_PROPERTY)) {
|
||||
String[] defStrs = commandLine.getOptionValues(CLIManager.SET_SYSTEM_PROPERTY);
|
||||
|
||||
if (defStrs != null) {
|
||||
for (String defStr : defStrs) {
|
||||
setCliProperty(defStr, userProperties);
|
||||
}
|
||||
}
|
||||
}
|
||||
final Properties userSpecifiedProperties = commandLine.getOptionProperties(
|
||||
String.valueOf(CLIManager.SET_SYSTEM_PROPERTY));
|
||||
userSpecifiedProperties.forEach(
|
||||
(prop, value) -> setCliProperty((String) prop, (String) value, userProperties));
|
||||
|
||||
SystemProperties.addSystemProperties(systemProperties);
|
||||
|
||||
@@ -1316,23 +1333,7 @@ public class DaemonMavenCli {
|
||||
}
|
||||
}
|
||||
|
||||
private static void setCliProperty(String property, Properties properties) {
|
||||
String name;
|
||||
|
||||
String value;
|
||||
|
||||
int i = property.indexOf('=');
|
||||
|
||||
if (i <= 0) {
|
||||
name = property.trim();
|
||||
|
||||
value = "true";
|
||||
} else {
|
||||
name = property.substring(0, i).trim();
|
||||
|
||||
value = property.substring(i + 1);
|
||||
}
|
||||
|
||||
private static void setCliProperty(String name, String value, Properties properties) {
|
||||
properties.setProperty(name, value);
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
@@ -31,6 +31,7 @@ import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
@@ -41,6 +42,7 @@ import org.apache.maven.artifact.InvalidRepositoryException;
|
||||
import org.apache.maven.artifact.repository.ArtifactRepository;
|
||||
import org.apache.maven.artifact.repository.LegacyLocalRepositoryManager;
|
||||
import org.apache.maven.bridge.MavenRepositorySystem;
|
||||
import org.apache.maven.feature.Features;
|
||||
import org.apache.maven.model.Build;
|
||||
import org.apache.maven.model.Dependency;
|
||||
import org.apache.maven.model.DependencyManagement;
|
||||
@@ -50,6 +52,7 @@ import org.apache.maven.model.Model;
|
||||
import org.apache.maven.model.Plugin;
|
||||
import org.apache.maven.model.Profile;
|
||||
import org.apache.maven.model.ReportPlugin;
|
||||
import org.apache.maven.model.building.ArtifactModelSource;
|
||||
import org.apache.maven.model.building.DefaultModelBuildingRequest;
|
||||
import org.apache.maven.model.building.DefaultModelProblem;
|
||||
import org.apache.maven.model.building.FileModelSource;
|
||||
@@ -62,11 +65,15 @@ import org.apache.maven.model.building.ModelProblem;
|
||||
import org.apache.maven.model.building.ModelProcessor;
|
||||
import org.apache.maven.model.building.ModelSource;
|
||||
import org.apache.maven.model.building.StringModelSource;
|
||||
import org.apache.maven.model.building.TransformerContext;
|
||||
import org.apache.maven.model.building.TransformerContextBuilder;
|
||||
import org.apache.maven.model.resolution.ModelResolver;
|
||||
import org.apache.maven.repository.internal.ArtifactDescriptorUtils;
|
||||
import org.apache.maven.repository.internal.DefaultModelCache;
|
||||
import org.codehaus.plexus.logging.Logger;
|
||||
import org.codehaus.plexus.util.Os;
|
||||
import org.codehaus.plexus.util.StringUtils;
|
||||
import org.eclipse.aether.DefaultRepositorySystemSession;
|
||||
import org.eclipse.aether.RepositorySystemSession;
|
||||
import org.eclipse.aether.RequestTrace;
|
||||
import org.eclipse.aether.impl.RemoteRepositoryManager;
|
||||
@@ -76,17 +83,12 @@ import org.eclipse.aether.repository.WorkspaceRepository;
|
||||
import org.eclipse.aether.resolution.ArtifactRequest;
|
||||
import org.eclipse.aether.resolution.ArtifactResult;
|
||||
import org.eclipse.sisu.Priority;
|
||||
import org.eclipse.sisu.Typed;
|
||||
|
||||
/**
|
||||
* DefaultProjectBuilder
|
||||
*
|
||||
* File origin:
|
||||
* https://github.com/apache/maven/blob/maven-3.6.2/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuilder.java
|
||||
* CachingProjectBuilder
|
||||
*/
|
||||
@Named
|
||||
@Singleton
|
||||
@Typed(ProjectBuilder.class)
|
||||
@Priority(10)
|
||||
public class CachingProjectBuilder
|
||||
implements ProjectBuilder {
|
||||
@@ -115,10 +117,7 @@ public class CachingProjectBuilder
|
||||
@Inject
|
||||
private ProjectDependenciesResolver dependencyResolver;
|
||||
|
||||
private final ModelCache modelCache = new ReactorModelCache();
|
||||
|
||||
public CachingProjectBuilder() {
|
||||
}
|
||||
private final ModelCache modelCache = DefaultModelCache.newInstance(new DefaultRepositorySystemSession());
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// MavenProjectBuilder Implementation
|
||||
@@ -128,14 +127,14 @@ public class CachingProjectBuilder
|
||||
public ProjectBuildingResult build(File pomFile, ProjectBuildingRequest request)
|
||||
throws ProjectBuildingException {
|
||||
return build(pomFile, new FileModelSource(pomFile),
|
||||
new InternalConfig(request, null, new SnapshotModelCache(getModelCache())));
|
||||
new InternalConfig(request, null, null));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProjectBuildingResult build(ModelSource modelSource, ProjectBuildingRequest request)
|
||||
throws ProjectBuildingException {
|
||||
return build(null, modelSource,
|
||||
new InternalConfig(request, null, new SnapshotModelCache(getModelCache())));
|
||||
new InternalConfig(request, null, null));
|
||||
}
|
||||
|
||||
private ProjectBuildingResult build(File pomFile, ModelSource modelSource, InternalConfig config)
|
||||
@@ -170,8 +169,7 @@ public class CachingProjectBuilder
|
||||
} catch (ModelBuildingException e) {
|
||||
result = e.getResult();
|
||||
if (result == null || result.getEffectiveModel() == null) {
|
||||
throw (ProjectBuildingException) new ProjectBuildingException(e.getModelId(), e.getMessage(), pomFile)
|
||||
.initCause(e);
|
||||
throw new ProjectBuildingException(e.getModelId(), e.getMessage(), pomFile, e);
|
||||
}
|
||||
// validation error, continue project building and delay failing to help IDEs
|
||||
error = e;
|
||||
@@ -179,8 +177,8 @@ public class CachingProjectBuilder
|
||||
|
||||
modelProblems = result.getProblems();
|
||||
|
||||
initProject(project, Collections.<String, MavenProject> emptyMap(), true,
|
||||
result, new HashMap<File, Boolean>(), projectBuildingRequest);
|
||||
initProject(project, Collections.emptyMap(), true,
|
||||
result, new HashMap<>(), projectBuildingRequest);
|
||||
} else if (projectBuildingRequest.isResolveDependencies()) {
|
||||
projectBuildingHelper.selectProjectRealm(project);
|
||||
}
|
||||
@@ -235,13 +233,7 @@ public class CachingProjectBuilder
|
||||
}
|
||||
|
||||
private List<String> getProfileIds(List<Profile> profiles) {
|
||||
List<String> ids = new ArrayList<>(profiles.size());
|
||||
|
||||
for (Profile profile : profiles) {
|
||||
ids.add(profile.getId());
|
||||
}
|
||||
|
||||
return ids;
|
||||
return profiles.stream().map(Profile::getId).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private ModelBuildingRequest getModelBuildingRequest(InternalConfig config) {
|
||||
@@ -264,7 +256,11 @@ public class CachingProjectBuilder
|
||||
request.setUserProperties(configuration.getUserProperties());
|
||||
request.setBuildStartTime(configuration.getBuildStartTime());
|
||||
request.setModelResolver(resolver);
|
||||
request.setModelCache(config.modelCache);
|
||||
// this is a hint that we want to build 1 file, so don't cache. See MNG-7063
|
||||
if (config.modelPool != null) {
|
||||
request.setModelCache(new SnapshotModelCache(modelCache, DefaultModelCache.newInstance(config.session)));
|
||||
}
|
||||
request.setTransformerContextBuilder(config.transformerContextBuilder);
|
||||
|
||||
return request;
|
||||
}
|
||||
@@ -281,7 +277,7 @@ public class CachingProjectBuilder
|
||||
org.eclipse.aether.artifact.Artifact pomArtifact = RepositoryUtils.toArtifact(artifact);
|
||||
pomArtifact = ArtifactDescriptorUtils.toPomArtifact(pomArtifact);
|
||||
|
||||
InternalConfig config = new InternalConfig(request, null, new SnapshotModelCache(getModelCache()));
|
||||
InternalConfig config = new InternalConfig(request, null, null);
|
||||
|
||||
boolean localProject;
|
||||
|
||||
@@ -309,7 +305,13 @@ public class CachingProjectBuilder
|
||||
artifact.setResolved(true);
|
||||
}
|
||||
|
||||
return build(localProject ? pomFile : null, new FileModelSource(pomFile), config);
|
||||
if (localProject) {
|
||||
return build(pomFile, new FileModelSource(pomFile), config);
|
||||
} else {
|
||||
return build(null, new ArtifactModelSource(pomFile, artifact.getGroupId(), artifact.getArtifactId(),
|
||||
artifact.getVersion()),
|
||||
config);
|
||||
}
|
||||
}
|
||||
|
||||
private ModelSource createStubModelSource(Artifact artifact) {
|
||||
@@ -334,26 +336,32 @@ public class CachingProjectBuilder
|
||||
|
||||
List<InterimResult> interimResults = new ArrayList<>();
|
||||
|
||||
ReactorModelPool modelPool = new ReactorModelPool();
|
||||
ReactorModelPool.Builder poolBuilder = new ReactorModelPool.Builder();
|
||||
final ReactorModelPool modelPool = poolBuilder.build();
|
||||
|
||||
InternalConfig config = new InternalConfig(request, modelPool, new SnapshotModelCache(getModelCache()));
|
||||
InternalConfig config = new InternalConfig(request, modelPool, modelBuilder.newTransformerContextBuilder());
|
||||
|
||||
Map<String, MavenProject> projectIndex = new HashMap<>(256);
|
||||
Map<File, MavenProject> projectIndex = new HashMap<>(256);
|
||||
|
||||
boolean noErrors = build(results, interimResults, projectIndex, pomFiles, new LinkedHashSet<File>(), true, recursive,
|
||||
config);
|
||||
|
||||
populateReactorModelPool(modelPool, interimResults);
|
||||
// phase 1: get file Models from the reactor.
|
||||
boolean noErrors = build(results, interimResults, projectIndex, pomFiles, new LinkedHashSet<>(), true, recursive,
|
||||
config, poolBuilder);
|
||||
|
||||
ClassLoader oldContextClassLoader = Thread.currentThread().getContextClassLoader();
|
||||
|
||||
try {
|
||||
noErrors = build(results, new ArrayList<MavenProject>(), projectIndex, interimResults, request,
|
||||
new HashMap<File, Boolean>(), config.session) && noErrors;
|
||||
// Phase 2: get effective models from the reactor
|
||||
noErrors = build(results, new ArrayList<>(), projectIndex, interimResults, request,
|
||||
new HashMap<>(), config.session) && noErrors;
|
||||
} finally {
|
||||
Thread.currentThread().setContextClassLoader(oldContextClassLoader);
|
||||
}
|
||||
|
||||
if (Features.buildConsumer(request.getUserProperties()).isActive()) {
|
||||
request.getRepositorySession().getData().set(TransformerContext.KEY,
|
||||
config.transformerContextBuilder.build());
|
||||
}
|
||||
|
||||
if (!noErrors) {
|
||||
throw new ProjectBuildingException(results);
|
||||
}
|
||||
@@ -363,14 +371,16 @@ public class CachingProjectBuilder
|
||||
|
||||
@SuppressWarnings("checkstyle:parameternumber")
|
||||
private boolean build(List<ProjectBuildingResult> results, List<InterimResult> interimResults,
|
||||
Map<String, MavenProject> projectIndex, List<File> pomFiles, Set<File> aggregatorFiles,
|
||||
boolean isRoot, boolean recursive, InternalConfig config) {
|
||||
Map<File, MavenProject> projectIndex, List<File> pomFiles, Set<File> aggregatorFiles,
|
||||
boolean root, boolean recursive, InternalConfig config,
|
||||
ReactorModelPool.Builder poolBuilder) {
|
||||
boolean noErrors = true;
|
||||
|
||||
for (File pomFile : pomFiles) {
|
||||
aggregatorFiles.add(pomFile);
|
||||
|
||||
if (!build(results, interimResults, projectIndex, pomFile, aggregatorFiles, isRoot, recursive, config)) {
|
||||
if (!build(results, interimResults, projectIndex, pomFile, aggregatorFiles, root, recursive, config,
|
||||
poolBuilder)) {
|
||||
noErrors = false;
|
||||
}
|
||||
|
||||
@@ -382,18 +392,18 @@ public class CachingProjectBuilder
|
||||
|
||||
@SuppressWarnings("checkstyle:parameternumber")
|
||||
private boolean build(List<ProjectBuildingResult> results, List<InterimResult> interimResults,
|
||||
Map<String, MavenProject> projectIndex, File pomFile, Set<File> aggregatorFiles,
|
||||
boolean isRoot, boolean recursive, InternalConfig config) {
|
||||
Map<File, MavenProject> projectIndex, File pomFile, Set<File> aggregatorFiles,
|
||||
boolean isRoot, boolean recursive, InternalConfig config,
|
||||
ReactorModelPool.Builder poolBuilder) {
|
||||
boolean noErrors = true;
|
||||
|
||||
ModelBuildingRequest request = getModelBuildingRequest(config);
|
||||
|
||||
MavenProject project = new MavenProject();
|
||||
project.setFile(pomFile);
|
||||
|
||||
request.setPomFile(pomFile);
|
||||
request.setTwoPhaseBuilding(true);
|
||||
request.setLocationTracking(true);
|
||||
ModelBuildingRequest request = getModelBuildingRequest(config)
|
||||
.setPomFile(pomFile)
|
||||
.setTwoPhaseBuilding(true)
|
||||
.setLocationTracking(true);
|
||||
|
||||
DefaultModelBuildingListener listener = new DefaultModelBuildingListener(project, projectBuildingHelper,
|
||||
config.request);
|
||||
@@ -404,7 +414,7 @@ public class CachingProjectBuilder
|
||||
result = modelBuilder.build(request);
|
||||
} catch (ModelBuildingException e) {
|
||||
result = e.getResult();
|
||||
if (result == null || result.getEffectiveModel() == null) {
|
||||
if (result == null || result.getFileModel() == null) {
|
||||
results.add(new DefaultProjectBuildingResult(e.getModelId(), pomFile, e.getProblems()));
|
||||
|
||||
return false;
|
||||
@@ -414,25 +424,16 @@ public class CachingProjectBuilder
|
||||
noErrors = false;
|
||||
}
|
||||
|
||||
Model model = result.getEffectiveModel();
|
||||
try {
|
||||
// first pass: build without building parent.
|
||||
initProject(project, projectIndex, false, result, new HashMap<File, Boolean>(0), config.request);
|
||||
} catch (InvalidArtifactRTException iarte) {
|
||||
result.getProblems().add(new DefaultModelProblem(null, ModelProblem.Severity.ERROR, null, model, -1, -1,
|
||||
iarte));
|
||||
}
|
||||
Model model = result.getFileModel().clone();
|
||||
|
||||
projectIndex.put(result.getModelIds().get(0), project);
|
||||
poolBuilder.put(model.getPomFile().toPath(), model);
|
||||
|
||||
InterimResult interimResult = new InterimResult(pomFile, request, result, listener, isRoot);
|
||||
interimResults.add(interimResult);
|
||||
|
||||
if (recursive && !model.getModules().isEmpty()) {
|
||||
if (recursive) {
|
||||
File basedir = pomFile.getParentFile();
|
||||
|
||||
List<File> moduleFiles = new ArrayList<>();
|
||||
|
||||
for (String module : model.getModules()) {
|
||||
if (StringUtils.isEmpty(module)) {
|
||||
continue;
|
||||
@@ -491,11 +492,13 @@ public class CachingProjectBuilder
|
||||
interimResult.modules = new ArrayList<>();
|
||||
|
||||
if (!build(results, interimResult.modules, projectIndex, moduleFiles, aggregatorFiles, false,
|
||||
recursive, config)) {
|
||||
recursive, config, poolBuilder)) {
|
||||
noErrors = false;
|
||||
}
|
||||
}
|
||||
|
||||
projectIndex.put(pomFile, project);
|
||||
|
||||
return noErrors;
|
||||
}
|
||||
|
||||
@@ -524,17 +527,8 @@ public class CachingProjectBuilder
|
||||
|
||||
}
|
||||
|
||||
private void populateReactorModelPool(ReactorModelPool reactorModelPool, List<InterimResult> interimResults) {
|
||||
for (InterimResult interimResult : interimResults) {
|
||||
Model model = interimResult.result.getEffectiveModel();
|
||||
reactorModelPool.put(model.getGroupId(), model.getArtifactId(), model.getVersion(), model.getPomFile());
|
||||
|
||||
populateReactorModelPool(reactorModelPool, interimResult.modules);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean build(List<ProjectBuildingResult> results, List<MavenProject> projects,
|
||||
Map<String, MavenProject> projectIndex, List<InterimResult> interimResults,
|
||||
Map<File, MavenProject> projectIndex, List<InterimResult> interimResults,
|
||||
ProjectBuildingRequest request, Map<File, Boolean> profilesXmls,
|
||||
RepositorySystemSession session) {
|
||||
boolean noErrors = true;
|
||||
@@ -569,9 +563,11 @@ public class CachingProjectBuilder
|
||||
results.add(new DefaultProjectBuildingResult(project, result.getProblems(), resolutionResult));
|
||||
} catch (ModelBuildingException e) {
|
||||
DefaultProjectBuildingResult result = null;
|
||||
if (project == null) {
|
||||
if (project == null || interimResult.result.getEffectiveModel() == null) {
|
||||
result = new DefaultProjectBuildingResult(e.getModelId(), interimResult.pomFile, e.getProblems());
|
||||
} else {
|
||||
project.setModel(interimResult.result.getEffectiveModel());
|
||||
|
||||
result = new DefaultProjectBuildingResult(project, e.getProblems(), null);
|
||||
}
|
||||
results.add(result);
|
||||
@@ -584,14 +580,13 @@ public class CachingProjectBuilder
|
||||
}
|
||||
|
||||
@SuppressWarnings("checkstyle:methodlength")
|
||||
private void initProject(MavenProject project, Map<String, MavenProject> projects,
|
||||
private void initProject(MavenProject project, Map<File, MavenProject> projects,
|
||||
boolean buildParentIfNotExisting, ModelBuildingResult result,
|
||||
Map<File, Boolean> profilesXmls, ProjectBuildingRequest projectBuildingRequest) {
|
||||
Model model = result.getEffectiveModel();
|
||||
|
||||
project.setModel(model);
|
||||
project.setOriginalModel(result.getRawModel());
|
||||
project.setFile(model.getPomFile());
|
||||
project.setOriginalModel(result.getFileModel());
|
||||
|
||||
initParent(project, projects, buildParentIfNotExisting, result, projectBuildingRequest);
|
||||
|
||||
@@ -618,14 +613,6 @@ public class CachingProjectBuilder
|
||||
project.setInjectedProfileIds(modelId, getProfileIds(result.getActivePomProfiles(modelId)));
|
||||
}
|
||||
|
||||
String modelId = findProfilesXml(result, profilesXmls);
|
||||
if (modelId != null) {
|
||||
ModelProblem problem = new DefaultModelProblem("Detected profiles.xml alongside " + modelId
|
||||
+ ", this file is no longer supported and was ignored" + ", please use the settings.xml instead",
|
||||
ModelProblem.Severity.WARNING, ModelProblem.Version.V30, model, -1, -1, null);
|
||||
result.getProblems().add(problem);
|
||||
}
|
||||
|
||||
//
|
||||
// All the parts that were taken out of MavenProject for Maven 4.0.0
|
||||
//
|
||||
@@ -747,7 +734,7 @@ public class CachingProjectBuilder
|
||||
try {
|
||||
DeploymentRepository r = project.getDistributionManagement().getRepository();
|
||||
if (!StringUtils.isEmpty(r.getId()) && !StringUtils.isEmpty(r.getUrl())) {
|
||||
ArtifactRepository repo = repositorySystem.buildArtifactRepository(r);
|
||||
ArtifactRepository repo = MavenRepositorySystem.buildArtifactRepository(r);
|
||||
repositorySystem.injectProxy(projectBuildingRequest.getRepositorySession(),
|
||||
Arrays.asList(repo));
|
||||
repositorySystem.injectAuthentication(projectBuildingRequest.getRepositorySession(),
|
||||
@@ -766,7 +753,7 @@ public class CachingProjectBuilder
|
||||
try {
|
||||
DeploymentRepository r = project.getDistributionManagement().getSnapshotRepository();
|
||||
if (!StringUtils.isEmpty(r.getId()) && !StringUtils.isEmpty(r.getUrl())) {
|
||||
ArtifactRepository repo = repositorySystem.buildArtifactRepository(r);
|
||||
ArtifactRepository repo = MavenRepositorySystem.buildArtifactRepository(r);
|
||||
repositorySystem.injectProxy(projectBuildingRequest.getRepositorySession(),
|
||||
Arrays.asList(repo));
|
||||
repositorySystem.injectAuthentication(projectBuildingRequest.getRepositorySession(),
|
||||
@@ -780,7 +767,7 @@ public class CachingProjectBuilder
|
||||
}
|
||||
}
|
||||
|
||||
private void initParent(MavenProject project, Map<String, MavenProject> projects, boolean buildParentIfNotExisting,
|
||||
private void initParent(MavenProject project, Map<File, MavenProject> projects, boolean buildParentIfNotExisting,
|
||||
ModelBuildingResult result, ProjectBuildingRequest projectBuildingRequest) {
|
||||
Model parentModel = result.getModelIds().size() > 1 && !result.getModelIds().get(1).isEmpty()
|
||||
? result.getRawModel(result.getModelIds().get(1))
|
||||
@@ -797,7 +784,7 @@ public class CachingProjectBuilder
|
||||
// org.apache.maven.its.mng4834:parent:0.1
|
||||
String parentModelId = result.getModelIds().get(1);
|
||||
File parentPomFile = result.getRawModel(parentModelId).getPomFile();
|
||||
MavenProject parent = projects.get(parentModelId);
|
||||
MavenProject parent = projects.get(parentPomFile);
|
||||
if (parent == null && buildParentIfNotExisting) {
|
||||
//
|
||||
// At this point the DefaultModelBuildingListener has fired and it populates the
|
||||
@@ -872,28 +859,6 @@ public class CachingProjectBuilder
|
||||
return version;
|
||||
}
|
||||
|
||||
private String findProfilesXml(ModelBuildingResult result, Map<File, Boolean> profilesXmls) {
|
||||
for (String modelId : result.getModelIds()) {
|
||||
Model model = result.getRawModel(modelId);
|
||||
|
||||
File basedir = model.getProjectDirectory();
|
||||
if (basedir == null) {
|
||||
break;
|
||||
}
|
||||
|
||||
Boolean profilesXml = profilesXmls.get(basedir);
|
||||
if (profilesXml == null) {
|
||||
profilesXml = new File(basedir, "profiles.xml").exists();
|
||||
profilesXmls.put(basedir, profilesXml);
|
||||
}
|
||||
if (profilesXml) {
|
||||
return modelId;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* InternalConfig
|
||||
*/
|
||||
@@ -907,21 +872,20 @@ public class CachingProjectBuilder
|
||||
|
||||
private final ReactorModelPool modelPool;
|
||||
|
||||
private final ModelCache modelCache;
|
||||
private final TransformerContextBuilder transformerContextBuilder;
|
||||
|
||||
InternalConfig(ProjectBuildingRequest request, ReactorModelPool modelPool, ModelCache modelCache) {
|
||||
InternalConfig(ProjectBuildingRequest request, ReactorModelPool modelPool,
|
||||
TransformerContextBuilder transformerContextBuilder) {
|
||||
this.request = request;
|
||||
this.modelPool = modelPool;
|
||||
this.modelCache = modelCache;
|
||||
this.transformerContextBuilder = transformerContextBuilder;
|
||||
|
||||
session = LegacyLocalRepositoryManager.overlay(request.getLocalRepository(), request.getRepositorySession(),
|
||||
repoSystem);
|
||||
repositories = RepositoryUtils.toRepos(request.getRemoteRepositories());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private ModelCache getModelCache() {
|
||||
return this.modelCache;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -22,9 +22,9 @@ public class SnapshotModelCache implements ModelCache {
|
||||
private final ModelCache globalCache;
|
||||
private final ModelCache reactorCache;
|
||||
|
||||
public SnapshotModelCache(ModelCache globalCache) {
|
||||
public SnapshotModelCache(ModelCache globalCache, ModelCache reactorCache) {
|
||||
this.globalCache = globalCache;
|
||||
this.reactorCache = new ReactorModelCache();
|
||||
this.reactorCache = reactorCache;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
* 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.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.
|
||||
*/
|
||||
import java.util.Optional;
|
||||
import org.apache.maven.execution.MavenExecutionResult;
|
||||
|
||||
/**
|
||||
* Instances of this class are responsible for determining whether it makes sense to "resume" a build (i.e., using
|
||||
* the {@code --resume} flag.
|
||||
*/
|
||||
public interface BuildResumptionAnalyzer {
|
||||
/**
|
||||
* Construct an instance of {@link BuildResumptionData} based on the outcome of the current Maven build.
|
||||
*
|
||||
* @param result Outcome of the current Maven build.
|
||||
* @return A {@link BuildResumptionData} instance or {@link Optional#empty()} if resuming the build is not
|
||||
* possible.
|
||||
*/
|
||||
Optional<BuildResumptionData> determineBuildResumptionData(final MavenExecutionResult result);
|
||||
}
|
@@ -1,60 +0,0 @@
|
||||
/*
|
||||
* 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.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.
|
||||
*/
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* This class holds the information required to enable resuming a Maven build with {@code --resume}.
|
||||
*/
|
||||
public class BuildResumptionData {
|
||||
/**
|
||||
* The list of projects that remain to be built.
|
||||
*/
|
||||
private final List<String> remainingProjects;
|
||||
|
||||
public BuildResumptionData(final List<String> remainingProjects) {
|
||||
this.remainingProjects = remainingProjects;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the projects that still need to be built when resuming.
|
||||
*
|
||||
* @return A list containing the group and artifact id of the projects.
|
||||
*/
|
||||
public List<String> getRemainingProjects() {
|
||||
return this.remainingProjects;
|
||||
}
|
||||
|
||||
}
|
@@ -1,72 +0,0 @@
|
||||
/*
|
||||
* 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.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.
|
||||
*/
|
||||
import org.apache.maven.execution.MavenExecutionRequest;
|
||||
import org.apache.maven.project.MavenProject;
|
||||
|
||||
/**
|
||||
* Instances of this interface retrieve and store data for the --resume / -r feature. This data is used to ensure newer
|
||||
* builds of the same project, that have the -r command-line flag, skip successfully built projects during earlier
|
||||
* invocations of Maven.
|
||||
*/
|
||||
public interface BuildResumptionDataRepository {
|
||||
/**
|
||||
* Persists any data needed to resume the build at a later point in time, using a new Maven invocation. This method
|
||||
* may also decide it is not needed or meaningful to persist such data, and return <code>false</code> to indicate
|
||||
* so.
|
||||
*
|
||||
* @param rootProject The root project that is being built.
|
||||
* @param buildResumptionData Information needed to resume the build.
|
||||
* @throws BuildResumptionPersistenceException When an error occurs while persisting data.
|
||||
*/
|
||||
void persistResumptionData(final MavenProject rootProject, final BuildResumptionData buildResumptionData)
|
||||
throws BuildResumptionPersistenceException;
|
||||
|
||||
/**
|
||||
* Uses previously stored resumption data to enrich an existing execution request.
|
||||
*
|
||||
* @param request The execution request that will be enriched.
|
||||
* @param rootProject The root project that is being built.
|
||||
*/
|
||||
void applyResumptionData(final MavenExecutionRequest request, final MavenProject rootProject);
|
||||
|
||||
/**
|
||||
* Removes previously stored resumption data.
|
||||
*
|
||||
* @param rootProject The root project that is being built.
|
||||
*/
|
||||
void removeResumptionData(final MavenProject rootProject);
|
||||
|
||||
}
|
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
* 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.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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* This exception will be thrown when something fails while persisting build resumption data.
|
||||
*
|
||||
* @see BuildResumptionDataRepository#persistResumptionData
|
||||
*/
|
||||
public class BuildResumptionPersistenceException extends Exception {
|
||||
public BuildResumptionPersistenceException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
@@ -1,85 +0,0 @@
|
||||
/*
|
||||
* 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.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.
|
||||
*/
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
import org.apache.maven.execution.BuildFailure;
|
||||
import org.apache.maven.execution.BuildSuccess;
|
||||
import org.apache.maven.execution.MavenExecutionResult;
|
||||
import org.apache.maven.project.MavenProject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Default implementation of {@link BuildResumptionAnalyzer}.
|
||||
*/
|
||||
@Named
|
||||
@Singleton
|
||||
public class DefaultBuildResumptionAnalyzer implements BuildResumptionAnalyzer {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(DefaultBuildResumptionAnalyzer.class);
|
||||
|
||||
@Override
|
||||
public Optional<BuildResumptionData> determineBuildResumptionData(final MavenExecutionResult result) {
|
||||
if (!result.hasExceptions()) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
List<MavenProject> sortedProjects = result.getTopologicallySortedProjects();
|
||||
|
||||
boolean hasNoSuccess = sortedProjects.stream()
|
||||
.noneMatch(project -> result.getBuildSummary(project) instanceof BuildSuccess);
|
||||
|
||||
if (hasNoSuccess) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
List<String> remainingProjects = sortedProjects.stream()
|
||||
.filter(project -> result.getBuildSummary(project) == null
|
||||
|| result.getBuildSummary(project) instanceof BuildFailure)
|
||||
.map(project -> project.getGroupId() + ":" + project.getArtifactId())
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (remainingProjects.isEmpty()) {
|
||||
LOGGER.info("No remaining projects found, resuming the build would not make sense.");
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
return Optional.of(new BuildResumptionData(remainingProjects));
|
||||
}
|
||||
|
||||
}
|
@@ -1,150 +0,0 @@
|
||||
/*
|
||||
* 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.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.
|
||||
*/
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.io.Writer;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Properties;
|
||||
import java.util.stream.Stream;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.maven.execution.MavenExecutionRequest;
|
||||
import org.apache.maven.project.MavenProject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* This implementation of {@link BuildResumptionDataRepository} persists information in a properties file. The file is
|
||||
* stored in the build output directory under the Maven execution root.
|
||||
*/
|
||||
@Named
|
||||
@Singleton
|
||||
public class DefaultBuildResumptionDataRepository implements BuildResumptionDataRepository {
|
||||
private static final String RESUME_PROPERTIES_FILENAME = "resume.properties";
|
||||
private static final String REMAINING_PROJECTS = "remainingProjects";
|
||||
private static final String PROPERTY_DELIMITER = ", ";
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(DefaultBuildResumptionDataRepository.class);
|
||||
|
||||
@Override
|
||||
public void persistResumptionData(MavenProject rootProject, BuildResumptionData buildResumptionData)
|
||||
throws BuildResumptionPersistenceException {
|
||||
Path directory = Paths.get(rootProject.getBuild().getDirectory());
|
||||
persistResumptionData(directory, buildResumptionData);
|
||||
}
|
||||
|
||||
public void persistResumptionData(Path directory, BuildResumptionData buildResumptionData)
|
||||
throws BuildResumptionPersistenceException {
|
||||
Properties properties = convertToProperties(buildResumptionData);
|
||||
|
||||
Path resumeProperties = directory.resolve(RESUME_PROPERTIES_FILENAME);
|
||||
try {
|
||||
Files.createDirectories(resumeProperties.getParent());
|
||||
try (Writer writer = Files.newBufferedWriter(resumeProperties)) {
|
||||
properties.store(writer, null);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
String message = "Could not create " + RESUME_PROPERTIES_FILENAME + " file.";
|
||||
throw new BuildResumptionPersistenceException(message, e);
|
||||
}
|
||||
}
|
||||
|
||||
private Properties convertToProperties(final BuildResumptionData buildResumptionData) {
|
||||
Properties properties = new Properties();
|
||||
|
||||
String value = String.join(PROPERTY_DELIMITER, buildResumptionData.getRemainingProjects());
|
||||
properties.setProperty(REMAINING_PROJECTS, value);
|
||||
|
||||
return properties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyResumptionData(MavenExecutionRequest request, MavenProject rootProject) {
|
||||
Path directory = Paths.get(rootProject.getBuild().getDirectory());
|
||||
applyResumptionData(request, directory);
|
||||
}
|
||||
|
||||
public void applyResumptionData(MavenExecutionRequest request, Path directory) {
|
||||
Properties properties = loadResumptionFile(directory);
|
||||
applyResumptionProperties(request, properties);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeResumptionData(MavenProject rootProject) {
|
||||
Path directory = Paths.get(rootProject.getBuild().getDirectory());
|
||||
removeResumptionData(directory);
|
||||
}
|
||||
|
||||
public void removeResumptionData(Path directory) {
|
||||
Path resumeProperties = directory.resolve(RESUME_PROPERTIES_FILENAME);
|
||||
try {
|
||||
Files.deleteIfExists(resumeProperties);
|
||||
} catch (IOException e) {
|
||||
LOGGER.warn("Could not delete {} file. ", RESUME_PROPERTIES_FILENAME, e);
|
||||
}
|
||||
}
|
||||
|
||||
private Properties loadResumptionFile(Path rootBuildDirectory) {
|
||||
Properties properties = new Properties();
|
||||
Path path = rootBuildDirectory.resolve(RESUME_PROPERTIES_FILENAME);
|
||||
if (!Files.exists(path)) {
|
||||
LOGGER.warn("The {} file does not exist. The --resume / -r feature will not work.", path);
|
||||
return properties;
|
||||
}
|
||||
|
||||
try (Reader reader = Files.newBufferedReader(path)) {
|
||||
properties.load(reader);
|
||||
} catch (IOException e) {
|
||||
LOGGER.warn("Unable to read {}. The --resume / -r feature will not work.", path);
|
||||
}
|
||||
|
||||
return properties;
|
||||
}
|
||||
|
||||
// This method is made package-private for testing purposes
|
||||
void applyResumptionProperties(MavenExecutionRequest request, Properties properties) {
|
||||
if (properties.containsKey(REMAINING_PROJECTS)
|
||||
&& StringUtils.isEmpty(request.getResumeFrom())) {
|
||||
String propertyValue = properties.getProperty(REMAINING_PROJECTS);
|
||||
Stream.of(propertyValue.split(PROPERTY_DELIMITER))
|
||||
.filter(StringUtils::isNotEmpty)
|
||||
.forEach(request.getSelectedProjects()::add);
|
||||
LOGGER.info("Resuming from {} due to the --resume / -r feature.", propertyValue);
|
||||
}
|
||||
}
|
||||
}
|
@@ -19,15 +19,20 @@ import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
import org.apache.maven.artifact.repository.metadata.io.MetadataReader;
|
||||
import org.apache.maven.plugin.MavenPluginManager;
|
||||
import org.apache.maven.plugin.version.PluginVersionRequest;
|
||||
import org.apache.maven.plugin.version.PluginVersionResolutionException;
|
||||
import org.apache.maven.plugin.version.PluginVersionResolver;
|
||||
import org.apache.maven.plugin.version.PluginVersionResult;
|
||||
import org.apache.maven.plugin.version.internal.DefaultPluginVersionResolver;
|
||||
import org.eclipse.aether.RepositorySystem;
|
||||
import org.eclipse.aether.SessionData;
|
||||
import org.eclipse.aether.repository.RemoteRepository;
|
||||
import org.eclipse.aether.version.VersionScheme;
|
||||
import org.eclipse.sisu.Priority;
|
||||
import org.eclipse.sisu.Typed;
|
||||
|
||||
@@ -39,6 +44,12 @@ public class CachingPluginVersionResolver extends DefaultPluginVersionResolver {
|
||||
|
||||
private static final Object CACHE_KEY = new Object();
|
||||
|
||||
@Inject
|
||||
public CachingPluginVersionResolver(RepositorySystem repositorySystem, MetadataReader metadataReader,
|
||||
MavenPluginManager pluginManager, VersionScheme versionScheme) {
|
||||
super(repositorySystem, metadataReader, pluginManager, versionScheme);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PluginVersionResult resolve(PluginVersionRequest request) throws PluginVersionResolutionException {
|
||||
Map<String, PluginVersionResult> cache = getCache(request.getRepositorySession().getData());
|
||||
|
@@ -47,13 +47,11 @@ import org.apache.maven.classrealm.ClassRealmManager;
|
||||
import org.apache.maven.execution.MavenSession;
|
||||
import org.apache.maven.execution.scope.internal.MojoExecutionScopeModule;
|
||||
import org.apache.maven.model.Plugin;
|
||||
import org.apache.maven.monitor.logging.DefaultLog;
|
||||
import org.apache.maven.plugin.ContextEnabled;
|
||||
import org.apache.maven.plugin.DebugConfigurationListener;
|
||||
import org.apache.maven.plugin.ExtensionRealmCache;
|
||||
import org.apache.maven.plugin.InvalidPluginDescriptorException;
|
||||
import org.apache.maven.plugin.MavenPluginManager;
|
||||
import org.apache.maven.plugin.MavenPluginValidator;
|
||||
import org.apache.maven.plugin.Mojo;
|
||||
import org.apache.maven.plugin.MojoExecution;
|
||||
import org.apache.maven.plugin.MojoNotFoundException;
|
||||
@@ -72,6 +70,7 @@ import org.apache.maven.plugin.descriptor.MojoDescriptor;
|
||||
import org.apache.maven.plugin.descriptor.Parameter;
|
||||
import org.apache.maven.plugin.descriptor.PluginDescriptor;
|
||||
import org.apache.maven.plugin.descriptor.PluginDescriptorBuilder;
|
||||
import org.apache.maven.plugin.internal.MojoLogWrapper;
|
||||
import org.apache.maven.plugin.internal.PluginDependenciesResolver;
|
||||
import org.apache.maven.plugin.version.DefaultPluginVersionRequest;
|
||||
import org.apache.maven.plugin.version.PluginVersionRequest;
|
||||
@@ -97,7 +96,6 @@ import org.codehaus.plexus.component.repository.exception.ComponentLookupExcepti
|
||||
import org.codehaus.plexus.configuration.PlexusConfiguration;
|
||||
import org.codehaus.plexus.configuration.PlexusConfigurationException;
|
||||
import org.codehaus.plexus.configuration.xml.XmlPlexusConfiguration;
|
||||
import org.codehaus.plexus.logging.Logger;
|
||||
import org.codehaus.plexus.logging.LoggerManager;
|
||||
import org.codehaus.plexus.util.ReaderFactory;
|
||||
import org.codehaus.plexus.util.StringUtils;
|
||||
@@ -112,6 +110,8 @@ import org.eclipse.sisu.Priority;
|
||||
import org.eclipse.sisu.Typed;
|
||||
import org.mvndaemon.mvnd.cache.invalidating.InvalidatingPluginDescriptorCache;
|
||||
import org.mvndaemon.mvnd.cache.invalidating.InvalidatingPluginRealmCache;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/*
|
||||
* gnodet: This file is based on maven DefaultMavenPluginManager and changed in order
|
||||
@@ -143,8 +143,7 @@ public class CliMavenPluginManager
|
||||
*/
|
||||
public static final String KEY_EXTENSIONS_REALMS = CliMavenPluginManager.class.getName() + "/extensionsRealms";
|
||||
|
||||
@Inject
|
||||
private Logger logger;
|
||||
private final Logger logger = LoggerFactory.getLogger(getClass());
|
||||
|
||||
@Inject
|
||||
private LoggerManager loggerManager;
|
||||
@@ -236,13 +235,12 @@ public class CliMavenPluginManager
|
||||
throw new PluginDescriptorParsingException(plugin, pluginFile.getAbsolutePath(), e);
|
||||
}
|
||||
|
||||
MavenPluginValidator validator = new MavenPluginValidator(pluginArtifact);
|
||||
List<String> errors = new ArrayList<>();
|
||||
validate(pluginArtifact, pluginDescriptor, errors);
|
||||
|
||||
validator.validate(pluginDescriptor);
|
||||
|
||||
if (validator.hasErrors()) {
|
||||
if (!errors.isEmpty()) {
|
||||
throw new InvalidPluginDescriptorException(
|
||||
"Invalid plugin descriptor for " + plugin.getId() + " (" + pluginFile + ")", validator.getErrors());
|
||||
"Invalid plugin descriptor for " + plugin.getId() + " (" + pluginFile + ")", errors);
|
||||
}
|
||||
|
||||
pluginDescriptor.setPluginArtifact(pluginArtifact);
|
||||
@@ -250,6 +248,20 @@ public class CliMavenPluginManager
|
||||
return pluginDescriptor;
|
||||
}
|
||||
|
||||
private void validate(Artifact pluginArtifact, PluginDescriptor pluginDescriptor, List<String> errors) {
|
||||
if (!pluginArtifact.getGroupId().equals(pluginDescriptor.getGroupId())) {
|
||||
errors.add("Plugin's descriptor contains the wrong group ID: " + pluginDescriptor.getGroupId());
|
||||
}
|
||||
|
||||
if (!pluginArtifact.getArtifactId().equals(pluginDescriptor.getArtifactId())) {
|
||||
errors.add("Plugin's descriptor contains the wrong artifact ID: " + pluginDescriptor.getArtifactId());
|
||||
}
|
||||
|
||||
if (!pluginArtifact.getBaseVersion().equals(pluginDescriptor.getVersion())) {
|
||||
errors.add("Plugin's descriptor contains the wrong version: " + pluginDescriptor.getVersion());
|
||||
}
|
||||
}
|
||||
|
||||
private String getPluginDescriptorLocation() {
|
||||
return "META-INF/maven/plugin.xml";
|
||||
}
|
||||
@@ -516,8 +528,8 @@ public class CliMavenPluginManager
|
||||
}
|
||||
|
||||
if (mojo instanceof Mojo) {
|
||||
Logger mojoLogger = loggerManager.getLoggerForComponent(mojoDescriptor.getImplementation());
|
||||
((Mojo) mojo).setLog(new DefaultLog(mojoLogger));
|
||||
org.slf4j.Logger mojoLogger = LoggerFactory.getLogger(mojoDescriptor.getImplementation());
|
||||
((Mojo) mojo).setLog(new MojoLogWrapper(mojoLogger));
|
||||
}
|
||||
|
||||
Xpp3Dom dom = mojoExecution.getConfiguration();
|
||||
|
@@ -21,5 +21,10 @@ under the License.
|
||||
<extension>
|
||||
<exportedPackages>
|
||||
<exportedPackage>org.apache.commons.logging.*</exportedPackage>
|
||||
<exportedPackage>org.codehaus.plexus.components.interactivity.*</exportedPackage>
|
||||
</exportedPackages>
|
||||
|
||||
<exportedArtifacts>
|
||||
<exportedArtifact>org.codehaus.plexus:plexus-interactivity-api</exportedArtifact>
|
||||
</exportedArtifacts>
|
||||
</extension>
|
||||
|
8
dist/src/main/provisio/maven-distro.xml
vendored
8
dist/src/main/provisio/maven-distro.xml
vendored
@@ -20,12 +20,13 @@
|
||||
<artifactSet to="/mvn">
|
||||
<artifact id="org.apache.maven:apache-maven:tar.gz:bin">
|
||||
<unpack useRoot="false"
|
||||
excludes="lib/*slf4j*,conf/logging/*,lib/maven-slf4j-provider*,bin/mvn*,lib/jansi-*.jar,lib/jansi-native/*,lib/maven-resolver-api-*,lib/maven-resolver-impl-*,lib/maven-resolver-spi-*,lib/maven-resolver-util-*,lib/maven-resolver-connector-*,lib/maven-resolver-transport-*"/>
|
||||
excludes="conf/logging/*,lib/maven-slf4j-provider*,bin/mvn*,lib/jansi-*.jar,lib/jansi-native/*,lib/plexus-utils-3.*"/>
|
||||
</artifact>
|
||||
</artifactSet>
|
||||
|
||||
<artifactSet to="/mvn/lib">
|
||||
<exclusion id="javax.annotation:javax.annotation-api"/>
|
||||
<exclusion id="org.codehaus.plexus:plexus-utils"/>
|
||||
<artifact id="org.apache.maven.resolver:maven-resolver-api"/>
|
||||
<artifact id="org.apache.maven.resolver:maven-resolver-impl"/>
|
||||
<artifact id="org.apache.maven.resolver:maven-resolver-spi"/>
|
||||
@@ -38,6 +39,7 @@
|
||||
<exclusion id="org.slf4j:slf4j-api"/>
|
||||
<artifact id="org.apache.maven.daemon:mvnd-daemon:${project.version}">
|
||||
<exclusion id="org.codehaus.plexus:plexus-classworlds"/>
|
||||
<exclusion id="org.codehaus.plexus:plexus-utils"/>
|
||||
<exclusion id="*:cdi-api"/>
|
||||
<exclusion id="*:commons-cli"/>
|
||||
<exclusion id="*:commons-io"/>
|
||||
@@ -45,7 +47,10 @@
|
||||
<exclusion id="*:guava"/>
|
||||
<exclusion id="*:guice"/>
|
||||
<exclusion id="*:javax.inject"/>
|
||||
<exclusion id="*:jcl-over-slf4j"/>
|
||||
<exclusion id="*:jul-to-slf4j"/>
|
||||
<exclusion id="*:jsr250-api"/>
|
||||
<exclusion id="*:log4j-over-slf4j"/>
|
||||
<exclusion id="*:maven-artifact"/>
|
||||
<exclusion id="*:maven-builder-support"/>
|
||||
<exclusion id="*:maven-core"/>
|
||||
@@ -70,6 +75,7 @@
|
||||
<exclusion id="*:plexus-sec-dispatcher"/>
|
||||
<exclusion id="*:plexus-utils"/>
|
||||
<exclusion id="*:plexus-container-default"/>
|
||||
<exclusion id="*:slf4j-api"/>
|
||||
</artifact>
|
||||
<artifact id="org.apache.maven.daemon:mvnd-client:${project.version}">
|
||||
<exclusion id="*:*"/>
|
||||
|
@@ -19,6 +19,7 @@ import java.io.IOException;
|
||||
import javax.inject.Inject;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.Timeout;
|
||||
import org.mvndaemon.mvnd.assertj.TestClientOutput;
|
||||
import org.mvndaemon.mvnd.client.Client;
|
||||
import org.mvndaemon.mvnd.client.DaemonParameters;
|
||||
@@ -27,6 +28,7 @@ import org.mvndaemon.mvnd.common.Message.Prompt;
|
||||
import org.mvndaemon.mvnd.junit.MvndTest;
|
||||
|
||||
@MvndTest(projectDir = "src/test/projects/single-module")
|
||||
@Timeout(300)
|
||||
public class InteractiveTest {
|
||||
|
||||
@Inject
|
||||
|
@@ -61,6 +61,10 @@ public class NewManagedModuleNativeIT {
|
||||
registry.awaitIdle(d.getId());
|
||||
|
||||
/* Do the changes */
|
||||
System.gc();
|
||||
Thread.sleep(100);
|
||||
System.gc();
|
||||
|
||||
final Path srcDir = parentDir.resolve("../changes").normalize();
|
||||
try (Stream<Path> files = Files.walk(srcDir)) {
|
||||
files.forEach(source -> {
|
||||
|
11
pom.xml
11
pom.xml
@@ -64,8 +64,8 @@
|
||||
<jline.version>3.21.0</jline.version>
|
||||
<junit.jupiter.version>5.7.2</junit.jupiter.version>
|
||||
<logback.version>1.2.10</logback.version>
|
||||
<maven.version>3.8.6</maven.version>
|
||||
<maven.resolver.version>1.7.3</maven.resolver.version>
|
||||
<maven.version>4.0.0-alpha-2</maven.version>
|
||||
<maven.resolver.version>1.8.2</maven.resolver.version>
|
||||
<slf4j.version>1.7.35</slf4j.version>
|
||||
<sisu.version>0.3.5</sisu.version>
|
||||
|
||||
@@ -412,6 +412,13 @@ limitations under the License.</inlineHeader>
|
||||
<skip>${format.skip}</skip>
|
||||
<cachedir>${project.build.directory}/cache</cachedir>
|
||||
</configuration>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.maven</groupId>
|
||||
<artifactId>plexus-utils</artifactId>
|
||||
<version>${maven.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
|
Reference in New Issue
Block a user