Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

For Windows OS, revert the usage of cmd.exe by default #42

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 31 additions & 5 deletions src/main/java/org/codehaus/plexus/util/cli/Commandline.java
Original file line number Diff line number Diff line change
Expand Up @@ -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).<br/>
* Allow built-in commands (like <i>echo</i>) or <i>.cmd</i>/<i>.bat</i> files on PATH without extension
* suffix.<br/>
* 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.
*/
Expand Down Expand Up @@ -496,24 +505,26 @@ public String[] getEnvironmentVariables()

/**
* Returns the executable and all defined arguments.<br/>
* 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;
}
Expand Down Expand Up @@ -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).<br/>
* Allow built-in commands (like <i>echo</i>) or <i>.cmd</i>/<i>.bat</i> files on PATH without extension
* suffix.<br/>
* 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.
*/
Expand Down
77 changes: 67 additions & 10 deletions src/test/java/org/codehaus/plexus/util/cli/CommandlineTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -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() );
Expand Down Expand Up @@ -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" );
Expand All @@ -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() );
Expand All @@ -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() );
Expand All @@ -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() );
Expand All @@ -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( " " ) )
{
Expand Down Expand Up @@ -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 ) )
Expand Down