Skip to content

Commit

Permalink
[MSHARED-1007] Add MavenHome and MavenExecutable options to Invocatio…
Browse files Browse the repository at this point in the history
…nRequest
  • Loading branch information
slawekjaranowski committed Dec 29, 2021
1 parent 2a1e609 commit 1841a8e
Show file tree
Hide file tree
Showing 4 changed files with 197 additions and 67 deletions.
Expand Up @@ -107,6 +107,10 @@ public class DefaultInvocationRequest

private boolean quiet;

private File mavenHome;

private File mavenExecutable;

/**
* <p>getBaseDirectory.</p>
*
Expand Down Expand Up @@ -724,4 +728,42 @@ public InvocationRequest setQuiet( boolean quiet )
this.quiet = quiet;
return this;
}

/**
* {@inheritDoc}
*/
@Override
public File getMavenHome()
{
return mavenHome;
}

/**
* {@inheritDoc}
*/
@Override
public InvocationRequest setMavenHome( File mavenHome )
{
this.mavenHome = mavenHome;
return this;
}

/**
* {@inheritDoc}
*/
@Override
public File getMavenExecutable()
{
return mavenExecutable;
}

/**
* {@inheritDoc}
*/
@Override
public InvocationRequest setMavenExecutable( File mavenExecutable )
{
this.mavenExecutable = mavenExecutable;
return this;
}
}
Expand Up @@ -763,4 +763,45 @@ enum CheckSumPolicy
*/
void setTimeoutInSeconds( int timeoutInSeconds );

/**
* Gets the path to the base directory of the Maven installation used to invoke Maven.
*
* @return The path to the base directory of the Maven installation or <code>null</code> if using the default
* Maven installation.
*
* @since 3.1.1
*/
File getMavenHome();

/**
* Sets the path to the base directory of the Maven installation used to invoke Maven. This parameter may be left
* unspecified to use the default Maven installation which will be discovered by evaluating the system property
* <code>maven.home</code> and the environment variable <code>M2_HOME</code>.
*
* @param mavenHome The path to the base directory of the Maven installation, may be <code>null</code> to use the
* default Maven installation.
* @return This invocation request
*
* @since 3.1.1
*/
InvocationRequest setMavenHome( File mavenHome );

/**
* Get the customized File of the Maven executable.
*
* @return the custom Maven executable, otherwise {@code null}
*
* @since 3.1.1
*/
File getMavenExecutable();

/**
* {@code mavenExecutable} can either be a file relative to ${maven.home}/bin/ or an absolute file.
*
* @param mavenExecutable the executable
* @return This invocation request
*
* @since 3.1.1
*/
InvocationRequest setMavenExecutable( File mavenExecutable );
}
Expand Up @@ -64,26 +64,22 @@ public class MavenCommandLineBuilder
public Commandline build( InvocationRequest request )
throws CommandLineConfigurationException
{

setupMavenHome( request );
checkRequiredState();

try
{
checkRequiredState();
}
catch ( IOException e )
{
throw new CommandLineConfigurationException( e.getMessage(), e );
}
File mvn;
try
{
mvn = findMavenExecutable();
setupMavenExecutable( request );
}
catch ( IOException e )
{
throw new CommandLineConfigurationException( e.getMessage(), e );
}

Commandline cli = new Commandline();

cli.setExecutable( mvn.getAbsolutePath() );
cli.setExecutable( mavenExecutable.getAbsolutePath() );

// handling for OS-level envars
setShellEnvironment( request, cli );
Expand Down Expand Up @@ -119,28 +115,13 @@ public Commandline build( InvocationRequest request )

/**
* <p>checkRequiredState.</p>
*
* @throws java.io.IOException if any.
*/
protected void checkRequiredState()
throws IOException
{
if ( logger == null )
{
throw new IllegalStateException( "A logger instance is required." );
}

if ( ( mavenHome == null ) && ( System.getProperty( "maven.home" ) == null ) )
// can be restored with 1.5
// && ( System.getenv( "M2_HOME" ) != null ) )
{
if ( !getSystemEnvVars().containsKey( "M2_HOME" ) )
{
throw new IllegalStateException( "Maven application directory was not "
+ "specified, and ${maven.home} is not provided in the system "
+ "properties. Specify at least one of these." );
}
}
}

/**
Expand Down Expand Up @@ -221,10 +202,8 @@ protected void setToolchainsLocation( InvocationRequest request, Commandline cli
*
* @param request a {@link org.apache.maven.shared.invoker.InvocationRequest} object.
* @param cli a {@link org.apache.maven.shared.utils.cli.Commandline} object.
* @throws org.apache.maven.shared.invoker.CommandLineConfigurationException if any.
*/
protected void setShellEnvironment( InvocationRequest request, Commandline cli )
throws CommandLineConfigurationException
{
if ( request.isShellEnvironmentInherited() )
{
Expand Down Expand Up @@ -600,46 +579,61 @@ protected void setThreads( InvocationRequest request, Commandline cli )

}

/**
* <p>findMavenExecutable.</p>
*
* @return a {@link java.io.File} object.
* @throws org.apache.maven.shared.invoker.CommandLineConfigurationException if any.
* @throws java.io.IOException if any.
*/
protected File findMavenExecutable()
throws CommandLineConfigurationException, IOException
void setupMavenHome( InvocationRequest request )
{
if ( request.getMavenHome() != null )
{
mavenHome = request.getMavenHome();
}

if ( mavenHome == null )
{
String mavenHomeProperty = System.getProperty( "maven.home" );
if ( mavenHomeProperty == null && getSystemEnvVars().getProperty( "M2_HOME" ) != null )
{
mavenHomeProperty = getSystemEnvVars().getProperty( "M2_HOME" );
}

if ( mavenHomeProperty != null )
{
mavenHome = new File( mavenHomeProperty );
if ( !mavenHome.isDirectory() )
{
File binDir = mavenHome.getParentFile();
if ( binDir != null && "bin".equals( binDir.getName() ) )
{
// ah, they specified the mvn
// executable instead...
mavenHome = binDir.getParentFile();
}
else
{
throw new IllegalStateException( "${maven.home} is not specified as a directory: '"
+ mavenHomeProperty + "'." );
}
}
}
}

if ( ( mavenHome == null ) && ( getSystemEnvVars().getProperty( "M2_HOME" ) != null ) )
if ( mavenHome != null && !mavenHome.isDirectory() )
{
File binDir = mavenHome.getParentFile();
if ( binDir != null && "bin".equals( binDir.getName() ) )
{
mavenHome = new File( getSystemEnvVars().getProperty( "M2_HOME" ) );
// ah, they specified the mvn
// executable instead...
mavenHome = binDir.getParentFile();
}
}

logger.debug( "Using ${maven.home} of: '" + mavenHome + "'." );
if ( mavenHome != null && !mavenHome.isDirectory() )
{
throw new IllegalStateException( "maven home is not specified as a directory: '" + mavenHome + "'." );
}

logger.debug( "Using maven.home of: '" + mavenHome + "'." );
}


/**
* <p>setupMavenExecutable.</p>
*
* @param request a Invoker request
* @throws org.apache.maven.shared.invoker.CommandLineConfigurationException if any.
* @throws java.io.IOException if any.
*/
protected void setupMavenExecutable( InvocationRequest request )
throws CommandLineConfigurationException, IOException
{
if ( request.getMavenExecutable() != null )
{
mavenExecutable = request.getMavenExecutable();
}

if ( mavenExecutable == null || !mavenExecutable.isAbsolute() )
{
Expand Down Expand Up @@ -680,8 +674,6 @@ else if ( Os.isFamily( "windows" ) )
throw new CommandLineConfigurationException( "Maven executable not found at: " + mavenExecutable );
}
}

return mavenExecutable;
}

private Properties getSystemEnvVars()
Expand Down
Expand Up @@ -45,7 +45,7 @@
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.junit.Assume.assumeThat;
import static org.junit.Assume.assumeTrue;

public class MavenCommandLineBuilderTest
{
Expand Down Expand Up @@ -228,7 +228,7 @@ private File setupTempMavenHomeIfMissing( boolean forceDummy )
}

@Test
public void testShouldFailIfLoggerSetToNull() throws Exception
public void testShouldFailIfLoggerSetToNull()
{
mclb.setLogger( null );

Expand Down Expand Up @@ -259,10 +259,32 @@ public void testShouldFindDummyMavenExecutable()
}

mclb.setMavenHome( dummyMavenHomeBin.getParentFile() );
mclb.setupMavenExecutable( newRequest() );

File mavenExe = mclb.findMavenExecutable();
assertEquals( check.getCanonicalPath(), mclb.getMavenExecutable().getCanonicalPath() );
}

@Test
public void testShouldFindDummyMavenExecutableWithMavenHomeFromRequest()
throws Exception
{
File dummyMavenHomeBin = temporaryFolder.newFolder( "invoker-tests", "dummy-maven-home", "bin" );

File check;
if ( Os.isFamily( Os.FAMILY_WINDOWS ) )
{
check = createDummyFile( dummyMavenHomeBin, "mvn.bat" );
}
else
{
check = createDummyFile( dummyMavenHomeBin, "mvn" );
}

assertEquals( check.getCanonicalPath(), mavenExe.getCanonicalPath() );
// default value should be not used
mclb.setMavenHome( new File( "not-present-1234" ) );
mclb.build( newRequest().setMavenHome( dummyMavenHomeBin.getParentFile() ) );

assertEquals( check.getCanonicalPath(), mclb.getMavenExecutable().getCanonicalPath() );
}

@Test
Expand Down Expand Up @@ -869,16 +891,49 @@ public void testShouldSetEnvVar_M2_HOME()
}

@Test
public void testMvnCommand()
public void testMvnExecutableFromInvoker()
throws Exception
{
assumeThat( "Test only works when called with surefire", System.getProperty( "maven.home" ),
is( notNullValue() ) );
assumeTrue( "Test only works when maven home can be assigned",
System.getProperty( "maven.home" ) != null || System.getenv( "M2_HOME" ) != null );

File mavenExecutable = new File( "mvnDebug" );

mclb.setMavenExecutable( mavenExecutable );
File executable = mclb.findMavenExecutable();
assertTrue( "Expected executable to exist", executable.exists() );
assertTrue( "Expected executable to be absolute", executable.isAbsolute() );
mclb.build( newRequest() );

assertTrue( "Expected executable to exist", mclb.getMavenExecutable().exists() );
assertTrue( "Expected executable to be absolute", mclb.getMavenExecutable().isAbsolute() );
assertTrue( "Expected mvnDebug as command mvnDebug", mclb.getMavenExecutable().getName().contains( "mvnDebug" ) );
}

@Test
public void testMvnExecutableFormRequest()
throws Exception
{
assumeTrue( "Test only works when maven home can be assigned",
System.getProperty( "maven.home" ) != null || System.getenv( "M2_HOME" ) != null );

File mavenExecutable = new File( "mvnDebug" );

mclb.build( newRequest().setMavenExecutable( mavenExecutable ) );

assertTrue( "Expected executable to exist", mclb.getMavenExecutable().exists() );
assertTrue( "Expected executable to be absolute", mclb.getMavenExecutable().isAbsolute() );
assertTrue( "Expected mvnDebug as command", mclb.getMavenExecutable().getName().contains( "mvnDebug" ) );
}

@Test
public void testDefaultMavenCommand()
throws Exception
{
assumeTrue( "Test only works when maven home can be assigned",
System.getProperty( "maven.home" ) != null || System.getenv( "M2_HOME" ) != null );

mclb.build( newRequest() );

assertTrue( "Expected executable to exist", mclb.getMavenExecutable().exists() );
assertTrue( "Expected executable to be absolute", mclb.getMavenExecutable().isAbsolute() );
}

@Test
Expand Down

0 comments on commit 1841a8e

Please sign in to comment.