You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by ma...@apache.org on 2022/11/10 15:47:31 UTC
[maven] branch feature/MNG-7338-automatic-non-interactive-mode-in-ci created (now 2a87384e9)
This is an automated email from the ASF dual-hosted git repository.
martinkanters pushed a change to branch feature/MNG-7338-automatic-non-interactive-mode-in-ci
in repository https://gitbox.apache.org/repos/asf/maven.git
at 2a87384e9 [MNG-7338] Automatically activate batch-mode and make output quiet when running in CI.
This branch includes the following new commits:
new 2a87384e9 [MNG-7338] Automatically activate batch-mode and make output quiet when running in CI.
The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
[maven] 01/01: [MNG-7338] Automatically activate batch-mode and make output quiet when running in CI.
Posted by ma...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
martinkanters pushed a commit to branch feature/MNG-7338-automatic-non-interactive-mode-in-ci
in repository https://gitbox.apache.org/repos/asf/maven.git
commit 2a87384e92aed08178aeda45796c72c1ce1d42d6
Author: Martin Kanters <ma...@apache.org>
AuthorDate: Thu Nov 10 16:47:16 2022 +0100
[MNG-7338] Automatically activate batch-mode and make output quiet when running in CI.
---
maven-embedder/pom.xml | 5 ++
.../main/java/org/apache/maven/cli/CLIManager.java | 8 ++-
.../main/java/org/apache/maven/cli/MavenCli.java | 62 +++++++++++++----
.../java/org/apache/maven/cli/MavenCliTest.java | 81 ++++++++++++++++++++++
4 files changed, 140 insertions(+), 16 deletions(-)
diff --git a/maven-embedder/pom.xml b/maven-embedder/pom.xml
index 1e6c98968..892adb1b7 100644
--- a/maven-embedder/pom.xml
+++ b/maven-embedder/pom.xml
@@ -156,6 +156,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>
diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/CLIManager.java b/maven-embedder/src/main/java/org/apache/maven/cli/CLIManager.java
index b6005fddf..eaebd5a37 100644
--- a/maven-embedder/src/main/java/org/apache/maven/cli/CLIManager.java
+++ b/maven-embedder/src/main/java/org/apache/maven/cli/CLIManager.java
@@ -40,6 +40,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';
/**
@@ -138,7 +142,9 @@ public class CLIManager
options.addOption( Option.builder( Character.toString( NON_RECURSIVE ) ).longOpt( "non-recursive" ).desc( "Do not recurse into sub-projects. When used together with -pl, do not recurse into sub-projects of selected aggregators" ).build() );
options.addOption( Option.builder( Character.toString( UPDATE_SNAPSHOTS ) ).longOpt( "update-snapshots" ).desc( "Forces a check for missing releases and updated snapshots on remote repositories" ).build() );
options.addOption( Option.builder( Character.toString( ACTIVATE_PROFILES ) ).longOpt( "activate-profiles" ).desc( "Comma-delimited list of profiles to activate. Prefixing a profile with ! excludes it, and ? marks it as optional" ).hasArg().build() );
- options.addOption( Option.builder( Character.toString( BATCH_MODE ) ).longOpt( "batch-mode" ).desc( "Run in non-interactive (batch) mode (disables output color)" ).build() );
+ options.addOption( Option.builder( Character.toString( BATCH_MODE ) ).longOpt( "batch-mode" ).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" ).desc( "Suppress SNAPSHOT updates" ).build() );
options.addOption( Option.builder( Character.toString( CHECKSUM_FAILURE_POLICY ) ).longOpt( "strict-checksums" ).desc( "Fail the build if checksums don't match" ).build() );
options.addOption( Option.builder( Character.toString( CHECKSUM_WARNING_POLICY ) ).longOpt( "lax-checksums" ).desc( "Warn if checksums don't match" ).build() );
diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java b/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java
index ebfb0830b..2c9ae0ce3 100644
--- a/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java
+++ b/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java
@@ -121,7 +121,10 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
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;
@@ -504,10 +507,11 @@ public class 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 );
@@ -527,7 +531,7 @@ public class MavenCli
// 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 );
@@ -541,16 +545,20 @@ public class MavenCli
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 ) )
+ else
{
- MessageUtils.setColorEnabled( false );
+ 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 ) )
+ if ( commandLine.hasOption( CLIManager.LOG_FILE ) )
{
- File logFile = new File( cliRequest.commandLine.getOptionValue( CLIManager.LOG_FILE ) );
+ File logFile = new File( commandLine.getOptionValue( CLIManager.LOG_FILE ) );
logFile = resolveFile( logFile, cliRequest.workingDirectory );
// redirect stdout and stderr to file
@@ -573,9 +581,9 @@ public class MavenCli
plexusLoggerManager = new Slf4jLoggerManager();
slf4jLogger = slf4jLoggerFactory.getLogger( this.getClass().getName() );
- if ( cliRequest.commandLine.hasOption( CLIManager.FAIL_ON_SEVERITY ) )
+ if ( commandLine.hasOption( CLIManager.FAIL_ON_SEVERITY ) )
{
- String logLevelThreshold = cliRequest.commandLine.getOptionValue( CLIManager.FAIL_ON_SEVERITY );
+ String logLevelThreshold = commandLine.getOptionValue( CLIManager.FAIL_ON_SEVERITY );
if ( slf4jLoggerFactory instanceof MavenSlf4jWrapperFactory )
{
@@ -591,7 +599,7 @@ public class MavenCli
}
}
- 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." );
@@ -1374,7 +1382,7 @@ public class MavenCli
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 ) );
@@ -1438,6 +1446,27 @@ public class MavenCli
return request;
}
+ private void disableInteractiveModeIfNeeded( final CliRequest cliRequest, final MavenExecutionRequest request )
+ {
+ CommandLine commandLine = cliRequest.getCommandLine();
+ if ( commandLine.hasOption( FORCE_INTERACTIVE ) )
+ {
+ return;
+ }
+
+ String ciEnv = cliRequest.getSystemProperties().getProperty( "env.CI" );
+ if ( "true".equals( ciEnv ) )
+ {
+ slf4jLogger.info( "Detected a CI build, 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 String determineLocalRepositoryPath( final MavenExecutionRequest request )
{
String userDefinedLocalRepo = request.getUserProperties().getProperty( MavenCli.LOCAL_REPO_PROPERTY );
@@ -1593,7 +1622,10 @@ public class MavenCli
final CommandLine commandLine,
final MavenExecutionRequest request )
{
- if ( quiet || commandLine.hasOption( CLIManager.NO_TRANSFER_PROGRESS ) )
+ String ciEnv = request.getSystemProperties().getProperty( "env.CI" );
+ boolean quietCI = "true".equals( ciEnv ) && !commandLine.hasOption( FORCE_INTERACTIVE );
+
+ if ( quiet || commandLine.hasOption( CLIManager.NO_TRANSFER_PROGRESS ) || quietCI )
{
return new QuietMavenTransferListener();
}
diff --git a/maven-embedder/src/test/java/org/apache/maven/cli/MavenCliTest.java b/maven-embedder/src/test/java/org/apache/maven/cli/MavenCliTest.java
index c4fb01a91..54637c3fa 100644
--- a/maven-embedder/src/test/java/org/apache/maven/cli/MavenCliTest.java
+++ b/maven-embedder/src/test/java/org/apache/maven/cli/MavenCliTest.java
@@ -43,6 +43,7 @@ import java.io.PrintStream;
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;
@@ -51,6 +52,9 @@ import org.apache.commons.cli.Option;
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;
@@ -61,9 +65,13 @@ import org.apache.maven.toolchain.building.ToolchainsBuildingRequest;
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;
public class MavenCliTest
@@ -359,6 +367,20 @@ public class MavenCliTest
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";
@@ -588,6 +610,65 @@ public class MavenCliTest
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();