diff --git a/src/main/java/org/codehaus/plexus/util/cli/Commandline.java b/src/main/java/org/codehaus/plexus/util/cli/Commandline.java
index 58ddfe35..812e873d 100644
--- a/src/main/java/org/codehaus/plexus/util/cli/Commandline.java
+++ b/src/main/java/org/codehaus/plexus/util/cli/Commandline.java
@@ -123,6 +123,15 @@ public class Commandline
private Shell shell;
+ /**
+ * For {@link Os#FAMILY_WINDOWS} (only), force the usage of {@link CmdShell} (=> 'cmd.exe /X /C' prefix).
+ * Allow built-in commands (like echo) or .cmd/.bat files on PATH without extension
+ * suffix.
+ * Warning: This usage breaks the capacity to terminate the launched sub process when SIGINT signal (CTRL+C) is
+ * catched ; So use at your own risk.
+ */
+ private boolean forceShellOsSpefic;
+
/**
* @deprecated Use {@link Commandline#setExecutable(String)} instead.
*/
@@ -496,24 +505,26 @@ public String[] getEnvironmentVariables()
/**
* Returns the executable and all defined arguments.
- * For Windows Family, {@link Commandline#getShellCommandline()} is returned
+ * For Windows Family when {@link Commandline#setForceShellOsSpefic(boolean)} is used,
+ * {@link Commandline#getShellCommandline()} is returned
*/
public String[] getCommandline()
{
- if ( Os.isFamily( Os.FAMILY_WINDOWS ) )
+
+ if ( this.forceShellOsSpefic && Os.isFamily( Os.FAMILY_WINDOWS ) )
{
return getShellCommandline();
}
final String[] args = getArguments();
- String executable = getLiteralExecutable();
+ String executableTmp = getLiteralExecutable();
- if ( executable == null )
+ if ( executableTmp == null )
{
return args;
}
final String[] result = new String[args.length + 1];
- result[0] = executable;
+ result[0] = executableTmp;
System.arraycopy( args, 0, result, 1, args.length );
return result;
}
@@ -728,6 +739,21 @@ public Shell getShell()
return shell;
}
+ /**
+ * For {@link Os#FAMILY_WINDOWS} (only), force the usage of {@link CmdShell} (=> 'cmd.exe /X /C' prefix).
+ * Allow built-in commands (like echo) or .cmd/.bat files on PATH without extension
+ * suffix.
+ * Warning: This usage breaks the capacity to terminate the launched sub process when SIGINT signal (CTRL+C) is
+ * catched ; So use at your own risk.
+ *
+ * @param forceShellOsSpefic boolean
+ * @since 3.1.1
+ */
+ public void setForceShellOsSpefic( boolean forceShellOsSpefic )
+ {
+ this.forceShellOsSpefic = forceShellOsSpefic;
+ }
+
/**
* @deprecated Use {@link CommandLineUtils#translateCommandline(String)} instead.
*/
diff --git a/src/test/java/org/codehaus/plexus/util/cli/CommandlineTest.java b/src/test/java/org/codehaus/plexus/util/cli/CommandlineTest.java
index 8cd96f6c..3b2df1c9 100644
--- a/src/test/java/org/codehaus/plexus/util/cli/CommandlineTest.java
+++ b/src/test/java/org/codehaus/plexus/util/cli/CommandlineTest.java
@@ -60,8 +60,8 @@ public void testCommandlineWithoutCommandInConstructor()
{
Commandline cmd = new Commandline( new Shell() );
cmd.setWorkingDirectory( baseDir );
- cmd.createArgument().setValue( "cd" );
- cmd.createArgument().setValue( "." );
+ cmd.createArg().setValue( "cd" );
+ cmd.createArg().setValue( "." );
// NOTE: cmd.toString() uses CommandLineUtils.toString( String[] ), which *quotes* the result.
assertEquals( "cd .", cmd.toString() );
@@ -93,8 +93,37 @@ public void testExecuteBinaryOnPath()
try
{
// Maven startup script on PATH is required for this test
+ String binary = "mvn";
+ if ( Os.isFamily( Os.FAMILY_WINDOWS ) )
+ {
+ binary += ".cmd";
+ }
Commandline cmd = new Commandline();
cmd.setWorkingDirectory( baseDir );
+ cmd.setExecutable( binary );
+ assertEquals( binary, cmd.getShell().getOriginalExecutable() );
+ cmd.createArg().setValue( "-version" );
+ Process process = cmd.execute();
+ String out = IOUtil.toString( process.getInputStream() );
+ assertTrue( out.contains( "Apache Maven" ) );
+ assertTrue( out.contains( "Maven home:" ) );
+ assertTrue( out.contains( "Java version:" ) );
+ assertTrue( out.contains( "Java home:" ) );
+ }
+ catch ( Exception e )
+ {
+ fail( "Maven startup script seems not on the PATH: " + e.getMessage() );
+ }
+ }
+
+ public void testExecuteBinaryOnPathWithOsShell()
+ {
+ try
+ {
+ // Maven startup script on PATH is required for this test
+ Commandline cmd = new Commandline();
+ cmd.setForceShellOsSpefic( true );
+ cmd.setWorkingDirectory( baseDir );
cmd.setExecutable( "mvn" );
assertEquals( "mvn", cmd.getShell().getOriginalExecutable() );
cmd.createArg().setValue( "-version" );
@@ -112,15 +141,43 @@ public void testExecuteBinaryOnPath()
}
public void testExecute()
+ {
+ try
+ {
+ String binary = "echo";
+ Commandline cmd = new Commandline();
+ cmd.setWorkingDirectory( baseDir );
+ if ( Os.isFamily( Os.FAMILY_WINDOWS ) )
+ {
+ binary = "cmd";
+ cmd.createArg().setValue( "/X" );
+ cmd.createArg().setValue( "/C" );
+ cmd.createArg().setValue( "echo" );
+ }
+ cmd.setExecutable( binary );
+ assertEquals( binary, cmd.getShell().getOriginalExecutable() );
+ cmd.createArg().setValue( "Hello" );
+
+ Process process = cmd.execute();
+ assertEquals( "Hello", IOUtil.toString( process.getInputStream() ).trim() );
+ }
+ catch ( Exception e )
+ {
+ fail( e.getMessage() );
+ }
+ }
+
+ public void testExecuteWithOsShell()
{
try
{
// allow it to detect the proper shell here.
Commandline cmd = new Commandline();
+ cmd.setForceShellOsSpefic( true );
cmd.setWorkingDirectory( baseDir );
cmd.setExecutable( "echo" );
assertEquals( "echo", cmd.getShell().getOriginalExecutable() );
- cmd.createArgument().setValue( "Hello" );
+ cmd.createArg().setValue( "Hello" );
Process process = cmd.execute();
assertEquals( "Hello", IOUtil.toString( process.getInputStream() ).trim() );
@@ -138,8 +195,8 @@ public void testSetLine()
Commandline cmd = new Commandline( new Shell() );
cmd.setWorkingDirectory( baseDir );
cmd.setExecutable( "echo" );
- cmd.createArgument().setLine( null );
- cmd.createArgument().setLine( "Hello" );
+ cmd.createArg().setValue( null );
+ cmd.createArg().setLine( "Hello" );
// NOTE: cmd.toString() uses CommandLineUtils.toString( String[] ), which *quotes* the result.
assertEquals( "echo Hello", cmd.toString() );
@@ -156,8 +213,8 @@ public void testCreateCommandInReverseOrder()
{
Commandline cmd = new Commandline( new Shell() );
cmd.setWorkingDirectory( baseDir );
- cmd.createArgument().setValue( "." );
- cmd.createArgument( true ).setValue( "cd" );
+ cmd.createArg().setValue( "." );
+ cmd.createArg( true ).setValue( "cd" );
// NOTE: cmd.toString() uses CommandLineUtils.toString( String[] ), which *quotes* the result.
assertEquals( "cd .", cmd.toString() );
@@ -174,9 +231,9 @@ public void testSetFile()
{
Commandline cmd = new Commandline( new Shell() );
cmd.setWorkingDirectory( baseDir );
- cmd.createArgument().setValue( "more" );
+ cmd.createArg().setValue( "more" );
File f = new File( "test.txt" );
- cmd.createArgument().setFile( f );
+ cmd.createArg().setFile( f );
String fileName = f.getAbsolutePath();
if ( fileName.contains( " " ) )
{
@@ -486,7 +543,7 @@ public void testDollarSignInArgumentPath()
}
Commandline cmd = new Commandline();
- // cmd.getShell().setShellCommand( "/bin/sh" );
+ cmd.setForceShellOsSpefic( true );
cmd.getShell().setQuotedArgumentsEnabled( true );
cmd.setExecutable( "cat" );
if ( Os.isFamily( Os.FAMILY_WINDOWS ) )