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 c06147a9..31351ebb 100644
--- a/src/main/java/org/codehaus/plexus/util/cli/Commandline.java
+++ b/src/main/java/org/codehaus/plexus/util/cli/Commandline.java
@@ -119,6 +119,15 @@ public class Commandline
private Shell shell;
+ /**
+ * For {@link Os#FAMILY_WINDOWS} (only), force the usage of {@link CmdShell} (sample: '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 forceShellOsSpecific;
+
/**
* @deprecated Use {@link Commandline#setExecutable(String)} instead.
*/
@@ -492,11 +501,12 @@ public String[] getEnvironmentVariables()
/**
* @return Returns the executable and all defined arguments.
- * For Windows Family, {@link Commandline#getShellCommandline()} is returned
+ * For Windows Family when {@link Commandline#setForceShellOsSpecific(boolean)} is used,
+ * {@link Commandline#getShellCommandline()} is returned
*/
public String[] getCommandline()
{
- if ( Os.isFamily( Os.FAMILY_WINDOWS ) )
+ if ( this.forceShellOsSpecific && Os.isFamily( Os.FAMILY_WINDOWS ) )
{
return getShellCommandline();
}
@@ -511,14 +521,14 @@ public String[] getCommandline()
public String[] getRawCommandline()
{
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;
}
@@ -741,6 +751,21 @@ public Shell getShell()
return shell;
}
+ /**
+ * For {@link Os#FAMILY_WINDOWS} (only), force the usage of {@link CmdShell} (sample: '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 forceShellOsSpecific boolean
+ * @since 3.4.0
+ */
+ public void setForceShellOsSpecific( boolean forceShellOsSpecific )
+ {
+ this.forceShellOsSpecific = forceShellOsSpecific;
+ }
+
/**
* @param toProcess the process
* @return the command line arguments
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 28ec8297..99119916 100644
--- a/src/test/java/org/codehaus/plexus/util/cli/CommandlineTest.java
+++ b/src/test/java/org/codehaus/plexus/util/cli/CommandlineTest.java
@@ -55,8 +55,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() );
@@ -78,6 +78,29 @@ public void testExecuteBinaryOnPath()
{
// Maven startup script on PATH is required for this test
Commandline cmd = new Commandline();
+ String executable = "mvn";
+ if ( Os.isFamily( Os.FAMILY_WINDOWS ) )
+ {
+ executable += ".cmd";
+ }
+ cmd.setWorkingDirectory( baseDir );
+ cmd.setExecutable( executable );
+ assertEquals( executable, 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:" ) );
+ }
+
+ @Test
+ public void testExecuteBinaryOnPathWithOsShell()
+ throws Exception
+ {
+ // Maven startup script on PATH is required for this test
+ Commandline cmd = new Commandline();
+ cmd.setForceShellOsSpecific( true );
cmd.setWorkingDirectory( baseDir );
cmd.setExecutable( "mvn" );
assertEquals( "mvn", cmd.getShell().getOriginalExecutable() );
@@ -92,13 +115,36 @@ public void testExecuteBinaryOnPath()
@Test
public void testExecute()
throws Exception
+ {
+ String executable = "echo";
+ Commandline cmd = new Commandline();
+ cmd.setWorkingDirectory( baseDir );
+ if ( Os.isFamily( Os.FAMILY_WINDOWS ) )
+ {
+ executable = "cmd";
+ cmd.createArg().setValue( "/X" );
+ cmd.createArg().setValue( "/C" );
+ cmd.createArg().setValue( "echo" );
+ }
+ cmd.setExecutable( executable );
+ assertEquals( executable, cmd.getShell().getOriginalExecutable() );
+ cmd.createArg().setValue( "Hello" );
+
+ Process process = cmd.execute();
+ assertEquals( "Hello", IOUtil.toString( process.getInputStream() ).trim() );
+ }
+
+ @Test
+ public void testExecuteWithOsShell()
+ throws Exception
{
// allow it to detect the proper shell here.
Commandline cmd = new Commandline();
+ cmd.setForceShellOsSpecific( 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() );
@@ -110,8 +156,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() );
@@ -122,8 +168,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() );
@@ -134,9 +180,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( " " ) )
{
@@ -455,7 +501,7 @@ public void testDollarSignInArgumentPath()
}
Commandline cmd = new Commandline();
- // cmd.getShell().setShellCommand( "/bin/sh" );
+ cmd.setForceShellOsSpecific( true );
cmd.getShell().setQuotedArgumentsEnabled( true );
cmd.setExecutable( "cat" );
if ( Os.isFamily( Os.FAMILY_WINDOWS ) )