-rf " + resumeFromSelector);
- }
- }
-
- if (MavenExecutionRequest.REACTOR_FAIL_NEVER.equals(cliRequest.request.getReactorFailureBehavior())) {
- slf4jLogger.info("Build failures were ignored.");
-
- return 0;
- } else {
- return 1;
- }
- } else {
- Path directory = Paths.get(request.getBaseDirectory()).resolve("target");
- new DefaultBuildResumptionDataRepository().removeResumptionData(directory);
- return 0;
- }
- }
-
- private void logBuildResumeHint(String resumeBuildHint) {
- slf4jLogger.error("");
- slf4jLogger.error("After correcting the problems, you can resume the build with the command");
- slf4jLogger.error(buffer().a(" ").strong(resumeBuildHint).toString());
- }
-
- /**
- * A helper method to determine the value to resume the build with {@code -rf} taking into account the
- * edge case where multiple modules in the reactor have the same artifactId.
- *
- * {@code -rf :artifactId} will pick up the first module which matches, but when multiple modules in the
- * reactor have the same artifactId, effective failed module might be later in build reactor.
- * This means that developer will either have to type groupId or wait for build execution of all modules
- * which were fine, but they are still before one which reported errors.
- *
- * Then the returned value is {@code groupId:artifactId} when there is a name clash and
- * {@code :artifactId} if there is no conflict.
- *
- * @param mavenProjects Maven projects which are part of build execution.
- * @param failedProject Project which has failed.
- * @return Value for -rf flag to resume build exactly from place where it failed ({@code :artifactId} in
- * general and {@code groupId:artifactId} when there is a name clash).
- */
- private String getResumeFromSelector(List mavenProjects, MavenProject failedProject) {
- for (MavenProject buildProject : mavenProjects) {
- if (failedProject.getArtifactId().equals(buildProject.getArtifactId())
- && !failedProject.equals(buildProject)) {
- return failedProject.getGroupId() + ":" + failedProject.getArtifactId();
- }
- }
- return ":" + failedProject.getArtifactId();
- }
-
- private void logSummary(
- ExceptionSummary summary, Map references, String indent, boolean showErrors) {
- String msg = summary.getMessage();
-
- if (!summary.getReference().isEmpty()) {
- String referenceKey =
- references.computeIfAbsent(summary.getReference(), k -> "[Help " + (references.size() + 1) + "]");
- if (msg.indexOf('\n') < 0) {
- msg += " -> " + buffer().strong(referenceKey);
- } else {
- msg += "\n-> " + buffer().strong(referenceKey);
- }
- }
-
- String[] lines = msg.split("(\r\n)|(\r)|(\n)");
- String currentColor = "";
-
- for (int i = 0; i < lines.length; i++) {
- // add eventual current color inherited from previous line
- String line = currentColor + lines[i];
-
- // look for last ANSI escape sequence to check if nextColor
- Matcher matcher = LAST_ANSI_SEQUENCE.matcher(line);
- String nextColor = "";
- if (matcher.find()) {
- nextColor = matcher.group(1);
- if (ANSI_RESET.equals(nextColor)) {
- // last ANSI escape code is reset: no next color
- nextColor = "";
- }
- }
-
- // effective line, with indent and reset if end is colored
- line = indent + line + ("".equals(nextColor) ? "" : ANSI_RESET);
-
- if ((i == lines.length - 1) && (showErrors || (summary.getException() instanceof InternalErrorException))) {
- slf4jLogger.error(line, summary.getException());
- } else {
- slf4jLogger.error(line);
- }
-
- currentColor = nextColor;
- }
-
- indent += " ";
-
- for (ExceptionSummary child : summary.getChildren()) {
- logSummary(child, references, indent, showErrors);
- }
- }
-
- private static final Pattern LAST_ANSI_SEQUENCE = Pattern.compile("(\u001B\\[[;\\d]*[ -/]*[@-~])[^\u001B]*$");
-
- private static final String ANSI_RESET = "\u001B\u005Bm";
-
- private static void configure(
- CliRequest cliRequest,
- EventSpyDispatcher eventSpyDispatcher,
- Map configurationProcessors)
- throws Exception {
- //
- // This is not ideal but there are events specifically for configuration from the CLI which I don't
- // believe are really valid but there are ITs which assert the right events are published so this
- // needs to be supported so the EventSpyDispatcher needs to be put in the CliRequest so that
- // it can be accessed by configuration processors.
- //
- cliRequest.request.setEventSpyDispatcher(eventSpyDispatcher);
-
- //
- // We expect at most 2 implementations to be available. The SettingsXmlConfigurationProcessor implementation
- // is always available in the core and likely always will be, but we may have another ConfigurationProcessor
- // present supplied by the user. The rule is that we only allow the execution of one ConfigurationProcessor.
- // If there is more than one then we execute the one supplied by the user, otherwise we execute the
- // the default SettingsXmlConfigurationProcessor.
- //
- int userSuppliedConfigurationProcessorCount = configurationProcessors.size() - 1;
-
- if (userSuppliedConfigurationProcessorCount == 0) {
- //
- // Our settings.xml source is historically how we have configured Maven from the CLI so we are going to
- // have to honour its existence forever. So let's run it.
- //
- configurationProcessors.get(SettingsXmlConfigurationProcessor.HINT).process(cliRequest);
- } else if (userSuppliedConfigurationProcessorCount == 1) {
- //
- // Run the user supplied ConfigurationProcessor
- //
- for (Entry entry : configurationProcessors.entrySet()) {
- String hint = entry.getKey();
- if (!hint.equals(SettingsXmlConfigurationProcessor.HINT)) {
- ConfigurationProcessor configurationProcessor = entry.getValue();
- configurationProcessor.process(cliRequest);
- }
- }
- } else if (userSuppliedConfigurationProcessorCount > 1) {
- //
- // There are too many ConfigurationProcessors so we don't know which one to run so report the error.
- //
- StringBuilder sb = new StringBuilder(String.format(
- "\nThere can only be one user supplied ConfigurationProcessor, there are %s:\n\n",
- userSuppliedConfigurationProcessorCount));
- for (Entry entry : configurationProcessors.entrySet()) {
- String hint = entry.getKey();
- if (!hint.equals(SettingsXmlConfigurationProcessor.HINT)) {
- ConfigurationProcessor configurationProcessor = entry.getValue();
- sb.append(String.format(
- "%s\n", configurationProcessor.getClass().getName()));
- }
- }
- sb.append("\n");
- throw new Exception(sb.toString());
- }
- }
-
- void toolchains(CliRequest cliRequest) throws Exception {
- File userToolchainsFile;
-
- if (cliRequest.commandLine.hasOption(CLIManager.ALTERNATE_USER_TOOLCHAINS)) {
- userToolchainsFile = new File(cliRequest.commandLine.getOptionValue(CLIManager.ALTERNATE_USER_TOOLCHAINS));
- userToolchainsFile = resolveFile(userToolchainsFile, cliRequest.workingDirectory);
-
- if (!userToolchainsFile.isFile()) {
- throw new FileNotFoundException(
- "The specified user toolchains file does not exist: " + userToolchainsFile);
- }
- } else {
- userToolchainsFile = DEFAULT_USER_TOOLCHAINS_FILE;
- }
-
- File globalToolchainsFile;
-
- if (cliRequest.commandLine.hasOption(CLIManager.ALTERNATE_GLOBAL_TOOLCHAINS)) {
- globalToolchainsFile =
- new File(cliRequest.commandLine.getOptionValue(CLIManager.ALTERNATE_GLOBAL_TOOLCHAINS));
- globalToolchainsFile = resolveFile(globalToolchainsFile, cliRequest.workingDirectory);
-
- if (!globalToolchainsFile.isFile()) {
- throw new FileNotFoundException(
- "The specified global toolchains file does not exist: " + globalToolchainsFile);
- }
- } else {
- globalToolchainsFile = DEFAULT_GLOBAL_TOOLCHAINS_FILE;
- }
-
- cliRequest.request.setGlobalToolchainsFile(globalToolchainsFile);
- cliRequest.request.setUserToolchainsFile(userToolchainsFile);
-
- DefaultToolchainsBuildingRequest toolchainsRequest = new DefaultToolchainsBuildingRequest();
- if (globalToolchainsFile.isFile()) {
- toolchainsRequest.setGlobalToolchainsSource(new FileSource(globalToolchainsFile));
- }
- if (userToolchainsFile.isFile()) {
- toolchainsRequest.setUserToolchainsSource(new FileSource(userToolchainsFile));
- }
-
- eventSpyDispatcher.onEvent(toolchainsRequest);
-
- slf4jLogger.debug(
- "Reading global toolchains from {}",
- getLocation(toolchainsRequest.getGlobalToolchainsSource(), globalToolchainsFile));
- slf4jLogger.debug(
- "Reading user toolchains from {}",
- getLocation(toolchainsRequest.getUserToolchainsSource(), userToolchainsFile));
-
- ToolchainsBuildingResult toolchainsResult = toolchainsBuilder.build(toolchainsRequest);
-
- eventSpyDispatcher.onEvent(toolchainsResult);
-
- executionRequestPopulator.populateFromToolchains(cliRequest.request, toolchainsResult.getEffectiveToolchains());
-
- if (!toolchainsResult.getProblems().isEmpty() && slf4jLogger.isWarnEnabled()) {
- slf4jLogger.warn("");
- slf4jLogger.warn("Some problems were encountered while building the effective toolchains");
-
- for (Problem problem : toolchainsResult.getProblems()) {
- slf4jLogger.warn("{} @ {}", problem.getMessage(), problem.getLocation());
- }
-
- slf4jLogger.warn("");
- }
- }
-
- private Object getLocation(Source source, File defaultLocation) {
- if (source != null) {
- return source.getLocation();
- }
- return defaultLocation;
- }
-
- private void populateRequest(CliRequest cliRequest) {
- populateRequest(
- cliRequest,
- cliRequest.request,
- slf4jLogger,
- eventSpyDispatcher,
- modelProcessor,
- createTransferListener(cliRequest),
- buildEventListener,
- executionListener);
- }
-
- private static void populateRequest(
- CliRequest cliRequest,
- MavenExecutionRequest request,
- Logger slf4jLogger,
- EventSpyDispatcher eventSpyDispatcher,
- ModelProcessor modelProcessor,
- TransferListener transferListener,
- BuildEventListener buildEventListener,
- 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 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;
- }
-
- File baseDirectory = new File(workingDirectory, "").getAbsoluteFile();
-
- // ----------------------------------------------------------------------
- // Profile Activation
- // ----------------------------------------------------------------------
-
- List activeProfiles = new ArrayList<>();
-
- List 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);
- }
- }
- }
- }
- }
-
- 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 inclProjects = new ArrayList<>();
- List 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);
- }
-
- request.setCacheNotFound(true);
- request.setCacheTransferError(false);
-
- //
- // Builder, concurrency and parallelism
- //
- // We preserve the existing methods for builder selection which is to look for various inputs in the threading
- // configuration. We don't have an easy way to allow a pluggable builder to provide its own configuration
- // 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;
-
- if (threadConfiguration != null) {
- //
- // Default to the standard multithreaded builder
- //
- request.setBuilderId("multithreaded");
-
- if (threadConfiguration.contains("C")) {
- request.setDegreeOfConcurrency(calculateDegreeOfConcurrencyWithCoreMultiplier(threadConfiguration));
- } else {
- request.setDegreeOfConcurrency(Integer.parseInt(threadConfiguration));
- }
- }
-
- //
- // 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));
- }
- }
-
- static int calculateDegreeOfConcurrencyWithCoreMultiplier(String threadConfiguration) {
- int procs = Runtime.getRuntime().availableProcessors();
- return (int) (Float.parseFloat(threadConfiguration.replace("C", "")) * procs);
- }
-
- static File resolveFile(File file, String workingDirectory) {
- if (file == null) {
- return null;
- } else if (file.isAbsolute()) {
- return file;
- } else if (file.getPath().startsWith(File.separator)) {
- // drive-relative Windows path
- return file.getAbsoluteFile();
- } else {
- return new File(workingDirectory, file.getPath()).getAbsoluteFile();
- }
- }
-
- // ----------------------------------------------------------------------
- // System properties handling
- // ----------------------------------------------------------------------
-
- static void populateProperties(CliRequest cliRequest, Properties systemProperties, Properties userProperties)
- throws InterpolationException {
- addEnvVars(systemProperties);
-
- // ----------------------------------------------------------------------
- // Options that are set on the command line become system properties
- // and therefore are set in the session properties. System properties
- // are most dominant.
- // ----------------------------------------------------------------------
-
- Properties cliProperties = new Properties();
- if (cliRequest.commandLine.hasOption(CLIManager.SET_SYSTEM_PROPERTY)) {
- String[] defStrs = cliRequest.commandLine.getOptionValues(CLIManager.SET_SYSTEM_PROPERTY);
-
- if (defStrs != null) {
- for (String defStr : defStrs) {
- setCliProperty(defStr, cliProperties);
- }
- }
- }
-
- SystemProperties.addSystemProperties(systemProperties);
-
- StringSearchInterpolator interpolator = createInterpolator(cliRequest, cliProperties, systemProperties);
- for (Map.Entry