Skip to content

Commit

Permalink
[MNG-7338] Automatically activate batch-mode and make output quiet wh…
Browse files Browse the repository at this point in the history
…en running in CI.
  • Loading branch information
MartinKanters committed Mar 24, 2023
1 parent 54afd17 commit f6bb2be
Show file tree
Hide file tree
Showing 4 changed files with 149 additions and 16 deletions.
5 changes: 5 additions & 0 deletions maven-embedder/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,11 @@ under the License.
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ public class CLIManager {

public static final char BATCH_MODE = 'B';

public static final String NON_INTERACTIVE = "ni";

public static final String FORCE_INTERACTIVE = "fi";

public static final char SET_USER_PROPERTY = 'D';

/**
Expand Down Expand Up @@ -173,7 +177,17 @@ public CLIManager() {
.build());
options.addOption(Option.builder(Character.toString(BATCH_MODE))
.longOpt("batch-mode")
.desc("Run in non-interactive (batch) mode (disables output color)")
.desc(
"Run in non-interactive (batch) mode (disables output color) - alias for --non-interactive (kept for backwards compatability)")
.build());
options.addOption(Option.builder(NON_INTERACTIVE)
.longOpt("non-interactive")
.desc("Run in non-interactive (batch) mode (disables output color) - alias for --batch-mode")
.build());
options.addOption(Option.builder(FORCE_INTERACTIVE)
.longOpt("force-interactive")
.desc(
"Run in interactive mode - even when the environment variable CI is set to true and --non-interactive or --batch-mode are set")
.build());
options.addOption(Option.builder(SUPPRESS_SNAPSHOT_UPDATES)
.longOpt("no-snapshot-updates")
Expand Down
60 changes: 45 additions & 15 deletions maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,10 @@
import org.sonatype.plexus.components.sec.dispatcher.model.SettingsSecurity;

import static java.util.Comparator.comparing;
import static org.apache.maven.cli.CLIManager.BATCH_MODE;
import static org.apache.maven.cli.CLIManager.COLOR;
import static org.apache.maven.cli.CLIManager.FORCE_INTERACTIVE;
import static org.apache.maven.cli.CLIManager.NON_INTERACTIVE;
import static org.apache.maven.cli.ResolveFile.resolveFile;
import static org.apache.maven.shared.utils.logging.MessageUtils.buffer;

Expand Down Expand Up @@ -444,10 +447,10 @@ private CommandLine cliMerge(CommandLine mavenConfig, CommandLine mavenCli) {
*/
void logging(CliRequest cliRequest) {
// LOG LEVEL
cliRequest.verbose = cliRequest.commandLine.hasOption(CLIManager.VERBOSE)
|| cliRequest.commandLine.hasOption(CLIManager.DEBUG);
cliRequest.quiet = !cliRequest.verbose && cliRequest.commandLine.hasOption(CLIManager.QUIET);
cliRequest.showErrors = cliRequest.verbose || cliRequest.commandLine.hasOption(CLIManager.ERRORS);
CommandLine commandLine = cliRequest.commandLine;
cliRequest.verbose = commandLine.hasOption(CLIManager.VERBOSE) || commandLine.hasOption(CLIManager.DEBUG);
cliRequest.quiet = !cliRequest.verbose && commandLine.hasOption(CLIManager.QUIET);
cliRequest.showErrors = cliRequest.verbose || commandLine.hasOption(CLIManager.ERRORS);

slf4jLoggerFactory = LoggerFactory.getILoggerFactory();
Slf4jConfiguration slf4jConfiguration = Slf4jConfigurationFactory.getConfiguration(slf4jLoggerFactory);
Expand All @@ -464,22 +467,25 @@ void logging(CliRequest cliRequest) {

// LOG COLOR
String styleColor = cliRequest.getUserProperties().getProperty(STYLE_COLOR_PROPERTY, "auto");
styleColor = cliRequest.commandLine.getOptionValue(COLOR, styleColor);
styleColor = commandLine.getOptionValue(COLOR, styleColor);
if ("always".equals(styleColor) || "yes".equals(styleColor) || "force".equals(styleColor)) {
MessageUtils.setColorEnabled(true);
} else if ("never".equals(styleColor) || "no".equals(styleColor) || "none".equals(styleColor)) {
MessageUtils.setColorEnabled(false);
} else if (!"auto".equals(styleColor) && !"tty".equals(styleColor) && !"if-tty".equals(styleColor)) {
throw new IllegalArgumentException(
"Invalid color configuration value '" + styleColor + "'. Supported are 'auto', 'always', 'never'.");
} else if (cliRequest.commandLine.hasOption(CLIManager.BATCH_MODE)
|| cliRequest.commandLine.hasOption(CLIManager.LOG_FILE)) {
MessageUtils.setColorEnabled(false);
} else {
boolean isBatchMode = !commandLine.hasOption(FORCE_INTERACTIVE)
&& (commandLine.hasOption(BATCH_MODE) || commandLine.hasOption(NON_INTERACTIVE));
if (isBatchMode || commandLine.hasOption(CLIManager.LOG_FILE)) {
MessageUtils.setColorEnabled(false);
}
}

// LOG STREAMS
if (cliRequest.commandLine.hasOption(CLIManager.LOG_FILE)) {
File logFile = new File(cliRequest.commandLine.getOptionValue(CLIManager.LOG_FILE));
if (commandLine.hasOption(CLIManager.LOG_FILE)) {
File logFile = new File(commandLine.getOptionValue(CLIManager.LOG_FILE));
logFile = resolveFile(logFile, cliRequest.workingDirectory);

// redirect stdout and stderr to file
Expand All @@ -499,8 +505,8 @@ void logging(CliRequest cliRequest) {
plexusLoggerManager = new Slf4jLoggerManager();
slf4jLogger = slf4jLoggerFactory.getLogger(this.getClass().getName());

if (cliRequest.commandLine.hasOption(CLIManager.FAIL_ON_SEVERITY)) {
String logLevelThreshold = cliRequest.commandLine.getOptionValue(CLIManager.FAIL_ON_SEVERITY);
if (commandLine.hasOption(CLIManager.FAIL_ON_SEVERITY)) {
String logLevelThreshold = commandLine.getOptionValue(CLIManager.FAIL_ON_SEVERITY);

if (slf4jLoggerFactory instanceof MavenSlf4jWrapperFactory) {
LogLevelRecorder logLevelRecorder = new LogLevelRecorder(logLevelThreshold);
Expand All @@ -515,7 +521,7 @@ void logging(CliRequest cliRequest) {
}
}

if (cliRequest.commandLine.hasOption(CLIManager.DEBUG)) {
if (commandLine.hasOption(CLIManager.DEBUG)) {
slf4jLogger.warn("The option '--debug' is deprecated and may be repurposed as Java debug"
+ " in a future version. Use -X/--verbose instead.");
}
Expand Down Expand Up @@ -1174,7 +1180,7 @@ private MavenExecutionRequest populateRequest(CliRequest cliRequest, MavenExecut
request.setShowErrors(cliRequest.showErrors); // default: false
File baseDirectory = new File(workingDirectory, "").getAbsoluteFile();

disableOnPresentOption(commandLine, CLIManager.BATCH_MODE, request::setInteractiveMode);
disableInteractiveModeIfNeeded(cliRequest, request);
enableOnPresentOption(commandLine, CLIManager.SUPPRESS_SNAPSHOT_UPDATES, request::setNoSnapshotUpdates);
request.setGoals(commandLine.getArgList());
request.setReactorFailureBehavior(determineReactorFailureBehaviour(commandLine));
Expand Down Expand Up @@ -1234,6 +1240,27 @@ private MavenExecutionRequest populateRequest(CliRequest cliRequest, MavenExecut
return request;
}

private void disableInteractiveModeIfNeeded(final CliRequest cliRequest, final MavenExecutionRequest request) {
CommandLine commandLine = cliRequest.getCommandLine();
if (commandLine.hasOption(FORCE_INTERACTIVE)) {
return;
}

boolean runningOnCI = isRunningOnCI(cliRequest.getSystemProperties());
if (runningOnCI) {
slf4jLogger.info("Making this build non-interactive, because the environment variable CI equals \"true\"."
+ " Disable this detection by removing that variable or adding --force-interactive.");
request.setInteractiveMode(false);
} else if (commandLine.hasOption(BATCH_MODE) || commandLine.hasOption(NON_INTERACTIVE)) {
request.setInteractiveMode(false);
}
}

private static boolean isRunningOnCI(Properties systemProperties) {
String ciEnv = systemProperties.getProperty("env.CI");
return ciEnv != null && !"false".equals(ciEnv);
}

private String determineLocalRepositoryPath(final MavenExecutionRequest request) {
String userDefinedLocalRepo = request.getUserProperties().getProperty(MavenCli.LOCAL_REPO_PROPERTY);
if (userDefinedLocalRepo != null) {
Expand Down Expand Up @@ -1354,7 +1381,10 @@ private TransferListener determineTransferListener(
final boolean verbose,
final CommandLine commandLine,
final MavenExecutionRequest request) {
if (quiet || commandLine.hasOption(CLIManager.NO_TRANSFER_PROGRESS)) {
boolean runningOnCI = isRunningOnCI(request.getSystemProperties());
boolean quietCI = runningOnCI && !commandLine.hasOption(FORCE_INTERACTIVE);

if (quiet || commandLine.hasOption(CLIManager.NO_TRANSFER_PROGRESS) || quietCI) {
return new QuietMavenTransferListener();
} else if (request.isInteractiveMode() && !commandLine.hasOption(CLIManager.LOG_FILE)) {
//
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.List;
import java.util.stream.Stream;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
Expand All @@ -32,6 +33,9 @@
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.maven.Maven;
import org.apache.maven.cli.transfer.ConsoleMavenTransferListener;
import org.apache.maven.cli.transfer.QuietMavenTransferListener;
import org.apache.maven.cli.transfer.Slf4jMavenTransferListener;
import org.apache.maven.eventspy.internal.EventSpyDispatcher;
import org.apache.maven.execution.MavenExecutionRequest;
import org.apache.maven.execution.ProfileActivation;
Expand All @@ -42,9 +46,13 @@
import org.apache.maven.toolchain.building.ToolchainsBuildingResult;
import org.codehaus.plexus.DefaultPlexusContainer;
import org.codehaus.plexus.PlexusContainer;
import org.eclipse.aether.transfer.TransferListener;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import org.mockito.InOrder;

import static java.util.Arrays.asList;
Expand Down Expand Up @@ -330,6 +338,20 @@ public void testStyleColors() throws Exception {
cli.logging(request);
assertFalse(MessageUtils.isColorEnabled());

MessageUtils.setColorEnabled(true);
request = new CliRequest(new String[] {"--non-interactive"}, null);
cli.cli(request);
cli.properties(request);
cli.logging(request);
assertFalse(MessageUtils.isColorEnabled());

MessageUtils.setColorEnabled(true);
request = new CliRequest(new String[] {"--force-interactive", "--non-interactive"}, null);
cli.cli(request);
cli.properties(request);
cli.logging(request);
assertTrue(MessageUtils.isColorEnabled());

MessageUtils.setColorEnabled(true);
request = new CliRequest(new String[] {"-l", "target/temp/mvn.log"}, null);
request.workingDirectory = "target/temp";
Expand Down Expand Up @@ -544,6 +566,68 @@ public void populatePropertiesOverwrite() throws Exception {
assertThat(request.getUserProperties().getProperty("x"), is("false"));
}

@ParameterizedTest
@MethodSource("activateBatchModeArguments")
public void activateBatchMode(boolean ciEnv, String[] cliArgs, boolean isBatchMode) throws Exception {
CliRequest request = new CliRequest(cliArgs, null);
if (ciEnv) request.getSystemProperties().put("env.CI", "true");
cli.cli(request);

boolean batchMode = !cli.populateRequest(request).isInteractiveMode();

assertThat(batchMode, is(isBatchMode));
}

public static Stream<Arguments> activateBatchModeArguments() {
return Stream.of(
Arguments.of(false, new String[] {}, false),
Arguments.of(true, new String[] {}, true),
Arguments.of(true, new String[] {"--force-interactive"}, false),
Arguments.of(true, new String[] {"--force-interactive", "--non-interactive"}, false),
Arguments.of(true, new String[] {"--force-interactive", "--batch-mode"}, false),
Arguments.of(true, new String[] {"--force-interactive", "--non-interactive", "--batch-mode"}, false),
Arguments.of(false, new String[] {"--non-interactive"}, true),
Arguments.of(false, new String[] {"--batch-mode"}, true),
Arguments.of(false, new String[] {"--non-interactive", "--batch-mode"}, true));
}

@ParameterizedTest
@MethodSource("calculateTransferListenerArguments")
public void calculateTransferListener(boolean ciEnv, String[] cliArgs, Class<TransferListener> expectedSubClass)
throws Exception {
CliRequest request = new CliRequest(cliArgs, null);
if (ciEnv) request.getSystemProperties().put("env.CI", "true");
cli.cli(request);
cli.logging(request);

TransferListener transferListener = cli.populateRequest(request).getTransferListener();

assertThat(transferListener.getClass(), is(expectedSubClass));
}

public static Stream<Arguments> calculateTransferListenerArguments() {
return Stream.of(
Arguments.of(false, new String[] {}, ConsoleMavenTransferListener.class),
Arguments.of(true, new String[] {}, QuietMavenTransferListener.class),
Arguments.of(false, new String[] {"-ntp"}, QuietMavenTransferListener.class),
Arguments.of(false, new String[] {"--quiet"}, QuietMavenTransferListener.class),
Arguments.of(true, new String[] {"--force-interactive"}, ConsoleMavenTransferListener.class),
Arguments.of(
true,
new String[] {"--force-interactive", "--non-interactive"},
ConsoleMavenTransferListener.class),
Arguments.of(
true, new String[] {"--force-interactive", "--batch-mode"}, ConsoleMavenTransferListener.class),
Arguments.of(
true,
new String[] {"--force-interactive", "--non-interactive", "--batch-mode"},
ConsoleMavenTransferListener.class),
Arguments.of(false, new String[] {"--non-interactive"}, Slf4jMavenTransferListener.class),
Arguments.of(false, new String[] {"--batch-mode"}, Slf4jMavenTransferListener.class),
Arguments.of(
false, new String[] {"--non-interactive", "--batch-mode"}, Slf4jMavenTransferListener.class));
}

private MavenProject createMavenProject(String groupId, String artifactId) {
MavenProject project = new MavenProject();
project.setGroupId(groupId);
Expand Down

0 comments on commit f6bb2be

Please sign in to comment.