mirror of https://github.com/apache/maven.git
Using Trygve's cli stuff to execute m2 and capture the output so that it can be logged for subsequent perusal.
{issue: MNG-81} git-svn-id: https://svn.apache.org/repos/asf/maven/components/trunk@163236 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
aa438b8137
commit
fe59dcf689
|
@ -1,29 +1,25 @@
|
||||||
package org.apache.maven.it;
|
package org.apache.maven.it;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import org.apache.xpath.XPathAPI;
|
||||||
import java.io.ByteArrayOutputStream;
|
import org.apache.maven.it.cli.Commandline;
|
||||||
import java.io.File;
|
import org.apache.maven.it.cli.CommandLineUtils;
|
||||||
import java.io.FileInputStream;
|
import org.apache.maven.it.cli.StreamConsumer;
|
||||||
import java.io.FileReader;
|
import org.w3c.dom.Document;
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.PrintStream;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.net.URLClassLoader;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Properties;
|
|
||||||
|
|
||||||
import javax.xml.parsers.DocumentBuilder;
|
import javax.xml.parsers.DocumentBuilder;
|
||||||
import javax.xml.parsers.DocumentBuilderFactory;
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
import javax.xml.parsers.ParserConfigurationException;
|
import java.io.BufferedReader;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
import org.apache.xml.utils.DOMBuilder;
|
import java.io.File;
|
||||||
import org.apache.xpath.XPathAPI;
|
import java.io.FileReader;
|
||||||
import org.w3c.dom.Document;
|
import java.io.InputStream;
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.io.Writer;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:jason@maven.org">Jason van Zyl </a>
|
* @author <a href="mailto:jason@maven.org">Jason van Zyl </a>
|
||||||
|
@ -37,6 +33,7 @@ public class Verifier
|
||||||
private final String basedir;
|
private final String basedir;
|
||||||
|
|
||||||
private final ByteArrayOutputStream outStream = new ByteArrayOutputStream();
|
private final ByteArrayOutputStream outStream = new ByteArrayOutputStream();
|
||||||
|
|
||||||
private final ByteArrayOutputStream errStream = new ByteArrayOutputStream();
|
private final ByteArrayOutputStream errStream = new ByteArrayOutputStream();
|
||||||
|
|
||||||
private final PrintStream originalOut;
|
private final PrintStream originalOut;
|
||||||
|
@ -47,31 +44,38 @@ public class Verifier
|
||||||
this.basedir = basedir;
|
this.basedir = basedir;
|
||||||
|
|
||||||
originalOut = System.out;
|
originalOut = System.out;
|
||||||
|
|
||||||
System.setOut( new PrintStream( outStream ) );
|
System.setOut( new PrintStream( outStream ) );
|
||||||
|
|
||||||
originalErr = System.err;
|
originalErr = System.err;
|
||||||
|
|
||||||
System.setErr( new PrintStream( errStream ) );
|
System.setErr( new PrintStream( errStream ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
public void resetStreams()
|
public void resetStreams()
|
||||||
{
|
{
|
||||||
System.setOut( originalOut );
|
System.setOut( originalOut );
|
||||||
|
|
||||||
System.setErr( originalErr );
|
System.setErr( originalErr );
|
||||||
}
|
}
|
||||||
|
|
||||||
public void displayStreamBuffers()
|
public void displayStreamBuffers()
|
||||||
{
|
{
|
||||||
String out = outStream.toString();
|
String out = outStream.toString();
|
||||||
|
|
||||||
if ( out != null && out.trim().length() > 0 )
|
if ( out != null && out.trim().length() > 0 )
|
||||||
{
|
{
|
||||||
System.out.println( "----- Standard Out -----" );
|
System.out.println( "----- Standard Out -----" );
|
||||||
|
|
||||||
System.out.println( out );
|
System.out.println( out );
|
||||||
}
|
}
|
||||||
|
|
||||||
String err = errStream.toString();
|
String err = errStream.toString();
|
||||||
|
|
||||||
if ( err != null && err.trim().length() > 0 )
|
if ( err != null && err.trim().length() > 0 )
|
||||||
{
|
{
|
||||||
System.err.println( "----- Standard Error -----" );
|
System.err.println( "----- Standard Error -----" );
|
||||||
|
|
||||||
System.err.println( err );
|
System.err.println( err );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -83,9 +87,11 @@ public class Verifier
|
||||||
public void verify() throws VerificationException
|
public void verify() throws VerificationException
|
||||||
{
|
{
|
||||||
List lines = loadFile( basedir, "expected-results.txt" );
|
List lines = loadFile( basedir, "expected-results.txt" );
|
||||||
|
|
||||||
for ( Iterator i = lines.iterator(); i.hasNext(); )
|
for ( Iterator i = lines.iterator(); i.hasNext(); )
|
||||||
{
|
{
|
||||||
String line = ( String ) i.next();
|
String line = ( String ) i.next();
|
||||||
|
|
||||||
verifyExpectedResult( line );
|
verifyExpectedResult( line );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -108,12 +114,14 @@ public class Verifier
|
||||||
while ( (line = reader.readLine()) != null )
|
while ( (line = reader.readLine()) != null )
|
||||||
{
|
{
|
||||||
line = line.trim();
|
line = line.trim();
|
||||||
|
|
||||||
if ( line.startsWith( "#" ) || line.length() == 0 )
|
if ( line.startsWith( "#" ) || line.length() == 0 )
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
line = replace( line, "${localRepository}", localRepo );
|
line = replace( line, "${localRepository}", localRepo );
|
||||||
|
|
||||||
lines.add( line );
|
lines.add( line );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -129,6 +137,7 @@ public class Verifier
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
File f = new File( basedir, filename );
|
File f = new File( basedir, filename );
|
||||||
|
|
||||||
if ( !f.exists() )
|
if ( !f.exists() )
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
@ -139,6 +148,7 @@ public class Verifier
|
||||||
for ( Iterator i = lines.iterator(); i.hasNext(); )
|
for ( Iterator i = lines.iterator(); i.hasNext(); )
|
||||||
{
|
{
|
||||||
String line = ( String ) i.next();
|
String line = ( String ) i.next();
|
||||||
|
|
||||||
executeCommand( line );
|
executeCommand( line );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -155,11 +165,15 @@ public class Verifier
|
||||||
private static void executeCommand( String line ) throws VerificationException
|
private static void executeCommand( String line ) throws VerificationException
|
||||||
{
|
{
|
||||||
int index = line.indexOf( " " );
|
int index = line.indexOf( " " );
|
||||||
|
|
||||||
String cmd;
|
String cmd;
|
||||||
|
|
||||||
String args = null;
|
String args = null;
|
||||||
|
|
||||||
if ( index >= 0 )
|
if ( index >= 0 )
|
||||||
{
|
{
|
||||||
cmd = line.substring( 0, index );
|
cmd = line.substring( 0, index );
|
||||||
|
|
||||||
args = line.substring( index + 1 );
|
args = line.substring( index + 1 );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -170,7 +184,9 @@ public class Verifier
|
||||||
if ( cmd.equals( "rm" ) )
|
if ( cmd.equals( "rm" ) )
|
||||||
{
|
{
|
||||||
System.out.println( "Removing file: " + args );
|
System.out.println( "Removing file: " + args );
|
||||||
|
|
||||||
File f = new File( args );
|
File f = new File( args );
|
||||||
|
|
||||||
if ( f.exists() && !f.delete() )
|
if ( f.exists() && !f.delete() )
|
||||||
{
|
{
|
||||||
throw new VerificationException( "Error removing file - delete failed" );
|
throw new VerificationException( "Error removing file - delete failed" );
|
||||||
|
@ -185,15 +201,18 @@ public class Verifier
|
||||||
private static String retrieveLocalRepo()
|
private static String retrieveLocalRepo()
|
||||||
{
|
{
|
||||||
String repo = System.getProperty( "maven.repo.local" );
|
String repo = System.getProperty( "maven.repo.local" );
|
||||||
|
|
||||||
if ( repo == null )
|
if ( repo == null )
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// parse ~/.m2/override.xml for it...
|
// parse ~/.m2/override.xml for it...
|
||||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||||
|
|
||||||
DocumentBuilder builder = factory.newDocumentBuilder();
|
DocumentBuilder builder = factory.newDocumentBuilder();
|
||||||
|
|
||||||
File pom = new File( System.getProperty( "user.home" ), ".m2/override.xml" );
|
File pom = new File( System.getProperty( "user.home" ), ".m2/override.xml" );
|
||||||
|
|
||||||
Document dom = builder.parse( pom );
|
Document dom = builder.parse( pom );
|
||||||
|
|
||||||
repo = XPathAPI.selectSingleNode( dom, "/project/local/repository/text()" ).getNodeValue();
|
repo = XPathAPI.selectSingleNode( dom, "/project/local/repository/text()" ).getNodeValue();
|
||||||
|
@ -235,6 +254,7 @@ public class Verifier
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
File expectedFile = new File( line );
|
File expectedFile = new File( line );
|
||||||
|
|
||||||
if ( !expectedFile.isAbsolute() && !line.startsWith( "/" ) )
|
if ( !expectedFile.isAbsolute() && !line.startsWith( "/" ) )
|
||||||
{
|
{
|
||||||
expectedFile = new File( basedir, line );
|
expectedFile = new File( basedir, line );
|
||||||
|
@ -269,10 +289,13 @@ public class Verifier
|
||||||
}
|
}
|
||||||
|
|
||||||
StringBuffer buf = new StringBuffer( text.length() );
|
StringBuffer buf = new StringBuffer( text.length() );
|
||||||
|
|
||||||
int start = 0, end = 0;
|
int start = 0, end = 0;
|
||||||
|
|
||||||
while ( (end = text.indexOf( repl, start )) != -1 )
|
while ( (end = text.indexOf( repl, start )) != -1 )
|
||||||
{
|
{
|
||||||
buf.append( text.substring( start, end ) ).append( with );
|
buf.append( text.substring( start, end ) ).append( with );
|
||||||
|
|
||||||
start = end + repl.length();
|
start = end + repl.length();
|
||||||
|
|
||||||
if ( --max == 0 )
|
if ( --max == 0 )
|
||||||
|
@ -280,40 +303,58 @@ public class Verifier
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
buf.append( text.substring( start ) );
|
buf.append( text.substring( start ) );
|
||||||
|
|
||||||
return buf.toString();
|
return buf.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void executeGoals( String filename ) throws VerificationException
|
public void executeGoals( String filename ) throws VerificationException
|
||||||
{
|
{
|
||||||
String mavenHome = System.getProperty( "maven.home" );
|
String mavenHome = System.getProperty( "maven.home" );
|
||||||
|
|
||||||
if ( mavenHome == null )
|
if ( mavenHome == null )
|
||||||
{
|
{
|
||||||
throw new VerificationException( "maven.home has not been specified" );
|
throw new VerificationException( "maven.home has not been specified" );
|
||||||
}
|
}
|
||||||
|
|
||||||
List goals = loadFile( basedir, filename );
|
List goals = loadFile( basedir, filename );
|
||||||
|
|
||||||
if ( goals.size() == 0 )
|
if ( goals.size() == 0 )
|
||||||
{
|
{
|
||||||
throw new VerificationException( "No goals specified" );
|
throw new VerificationException( "No goals specified" );
|
||||||
}
|
}
|
||||||
|
|
||||||
List allGoals = new ArrayList();
|
List allGoals = new ArrayList();
|
||||||
|
|
||||||
allGoals.add( "clean:clean" );
|
allGoals.add( "clean:clean" );
|
||||||
|
|
||||||
allGoals.addAll( goals );
|
allGoals.addAll( goals );
|
||||||
|
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
String prevUserDir = System.getProperty( "user.dir" );
|
Commandline cli = new Commandline();
|
||||||
System.setProperty( "user.dir", basedir );
|
|
||||||
System.setProperty( "classworlds.conf", mavenHome + "/bin/classworlds.conf" );
|
cli.setWorkingDirectory( basedir );
|
||||||
URL classWorldsUrl = new URL( "file:" + mavenHome + "/core/boot/classworlds-1.1-SNAPSHOT.jar" );
|
|
||||||
ClassLoader cl = URLClassLoader.newInstance( new URL[] { classWorldsUrl } );
|
cli.setExecutable( "m2" );
|
||||||
Class c = Class.forName( "org.codehaus.classworlds.Launcher", true, cl );
|
|
||||||
Method m = c.getMethod( "mainWithExitCode", new Class[] { String[].class } );
|
for ( Iterator i = allGoals.iterator(); i.hasNext(); )
|
||||||
Object o = m.invoke( null, new Object[] { allGoals.toArray( new String[0] ) } );
|
{
|
||||||
System.setProperty( "user.dir", prevUserDir );
|
cli.createArgument().setValue( (String) i.next() );
|
||||||
ret = ( ( Integer ) o ).intValue();
|
}
|
||||||
|
|
||||||
|
Writer logWriter = new FileWriter( new File( basedir, "log.txt" ) );
|
||||||
|
|
||||||
|
StreamConsumer out = new WriterStreamConsumer( logWriter );
|
||||||
|
|
||||||
|
StreamConsumer err = new WriterStreamConsumer( logWriter );
|
||||||
|
|
||||||
|
ret = CommandLineUtils.executeCommandLine( cli, out, err );
|
||||||
|
|
||||||
|
logWriter.close();
|
||||||
}
|
}
|
||||||
catch ( Exception e )
|
catch ( Exception e )
|
||||||
{
|
{
|
||||||
|
@ -323,6 +364,7 @@ public class Verifier
|
||||||
if ( ret > 0 )
|
if ( ret > 0 )
|
||||||
{
|
{
|
||||||
System.err.println( "Exit code: " + ret );
|
System.err.println( "Exit code: " + ret );
|
||||||
|
|
||||||
throw new VerificationException();
|
throw new VerificationException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -334,9 +376,11 @@ public class Verifier
|
||||||
public static void main( String args[] )
|
public static void main( String args[] )
|
||||||
{
|
{
|
||||||
String basedir = System.getProperty( "user.dir" );
|
String basedir = System.getProperty( "user.dir" );
|
||||||
|
|
||||||
localRepo = retrieveLocalRepo();
|
localRepo = retrieveLocalRepo();
|
||||||
|
|
||||||
List tests = null;
|
List tests = null;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
tests = loadFile( basedir, "integration-tests.txt" );
|
tests = loadFile( basedir, "integration-tests.txt" );
|
||||||
|
@ -344,7 +388,9 @@ public class Verifier
|
||||||
catch ( VerificationException e )
|
catch ( VerificationException e )
|
||||||
{
|
{
|
||||||
System.err.println( "Unable to load integration tests file" );
|
System.err.println( "Unable to load integration tests file" );
|
||||||
|
|
||||||
System.err.println( e.getMessage() );
|
System.err.println( e.getMessage() );
|
||||||
|
|
||||||
System.exit( 2 );
|
System.exit( 2 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -366,7 +412,9 @@ public class Verifier
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
verifier.executeHook( "prebuild-hook.txt" );
|
verifier.executeHook( "prebuild-hook.txt" );
|
||||||
|
|
||||||
verifier.executeGoals( "goals.txt" );
|
verifier.executeGoals( "goals.txt" );
|
||||||
|
|
||||||
verifier.executeHook( "postbuild-hook.txt" );
|
verifier.executeHook( "postbuild-hook.txt" );
|
||||||
|
|
||||||
verifier.verify();
|
verifier.verify();
|
||||||
|
@ -384,9 +432,11 @@ public class Verifier
|
||||||
verifier.displayStreamBuffers();
|
verifier.displayStreamBuffers();
|
||||||
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
|
||||||
exitCode = 1;
|
exitCode = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
System.exit( exitCode );
|
System.exit( exitCode );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
package org.apache.maven.it;
|
||||||
|
|
||||||
|
import org.apache.maven.it.cli.StreamConsumer;
|
||||||
|
|
||||||
|
import java.io.Writer;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:jason@maven.org">Jason van Zyl</a>
|
||||||
|
* @version $Id$
|
||||||
|
*/
|
||||||
|
public class WriterStreamConsumer
|
||||||
|
implements StreamConsumer
|
||||||
|
{
|
||||||
|
private PrintWriter writer;
|
||||||
|
|
||||||
|
public WriterStreamConsumer( Writer writer )
|
||||||
|
{
|
||||||
|
this.writer = new PrintWriter( writer );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void consumeLine( String s )
|
||||||
|
{
|
||||||
|
writer.println( s );
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
package org.apache.maven.it.cli;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2004, The Codehaus
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is furnished to do
|
||||||
|
* so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:trygvis@inamo.no">Trygve Laugstøl</a>
|
||||||
|
* @version $Id$
|
||||||
|
*/
|
||||||
|
public class CommandLineException
|
||||||
|
extends Exception
|
||||||
|
{
|
||||||
|
public CommandLineException( String message )
|
||||||
|
{
|
||||||
|
super( message );
|
||||||
|
}
|
||||||
|
|
||||||
|
public CommandLineException( String message, Throwable cause )
|
||||||
|
{
|
||||||
|
super( message, cause );
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,146 @@
|
||||||
|
package org.apache.maven.it.cli;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2004, The Codehaus
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is furnished to do
|
||||||
|
* so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:trygvis@inamo.no">Trygve Laugstøl </a>
|
||||||
|
* @version $Id$
|
||||||
|
*/
|
||||||
|
public abstract class CommandLineUtils
|
||||||
|
{
|
||||||
|
public static class StringStreamConsumer
|
||||||
|
implements StreamConsumer
|
||||||
|
{
|
||||||
|
private StringBuffer string = new StringBuffer();
|
||||||
|
|
||||||
|
private String ls = System.getProperty( "line.separator" );
|
||||||
|
|
||||||
|
public void consumeLine( String line )
|
||||||
|
{
|
||||||
|
string.append( line + ls );
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOutput()
|
||||||
|
{
|
||||||
|
return string.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int executeCommandLine( Commandline cl, StreamConsumer systemOut, StreamConsumer systemErr )
|
||||||
|
throws CommandLineException
|
||||||
|
{
|
||||||
|
return executeCommandLine( cl, null, systemOut, systemErr );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int executeCommandLine( Commandline cl, InputStream systemIn, StreamConsumer systemOut, StreamConsumer systemErr )
|
||||||
|
throws CommandLineException
|
||||||
|
{
|
||||||
|
if ( cl == null )
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException( "cl cannot be null." );
|
||||||
|
}
|
||||||
|
|
||||||
|
Process p;
|
||||||
|
|
||||||
|
p = cl.execute();
|
||||||
|
|
||||||
|
StreamFeeder inputFeeder = null;
|
||||||
|
|
||||||
|
if ( systemIn != null )
|
||||||
|
{
|
||||||
|
inputFeeder = new StreamFeeder( systemIn, p.getOutputStream() );
|
||||||
|
}
|
||||||
|
|
||||||
|
StreamPumper outputPumper = new StreamPumper( p.getInputStream(), systemOut );
|
||||||
|
|
||||||
|
StreamPumper errorPumper = new StreamPumper( p.getErrorStream(), systemErr );
|
||||||
|
|
||||||
|
if ( inputFeeder != null )
|
||||||
|
{
|
||||||
|
inputFeeder.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
outputPumper.start();
|
||||||
|
|
||||||
|
errorPumper.start();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
int returnValue = p.waitFor();
|
||||||
|
|
||||||
|
if ( inputFeeder != null )
|
||||||
|
{
|
||||||
|
synchronized ( inputFeeder )
|
||||||
|
{
|
||||||
|
if ( !inputFeeder.isDone() )
|
||||||
|
{
|
||||||
|
inputFeeder.wait();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( outputPumper != null)
|
||||||
|
{
|
||||||
|
synchronized ( outputPumper )
|
||||||
|
{
|
||||||
|
if ( !outputPumper.isDone() )
|
||||||
|
{
|
||||||
|
outputPumper.wait();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( errorPumper != null )
|
||||||
|
{
|
||||||
|
synchronized ( errorPumper )
|
||||||
|
{
|
||||||
|
if ( !errorPumper.isDone() )
|
||||||
|
{
|
||||||
|
errorPumper.wait();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
catch ( InterruptedException ex )
|
||||||
|
{
|
||||||
|
throw new CommandLineException( "Error while executing external command.", ex );
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if ( inputFeeder != null )
|
||||||
|
{
|
||||||
|
inputFeeder.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
outputPumper.close();
|
||||||
|
|
||||||
|
errorPumper.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,650 @@
|
||||||
|
package org.apache.maven.it.cli;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2004, The Codehaus
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is furnished to do
|
||||||
|
* so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/********************************************************************************
|
||||||
|
* CruiseControl, a Continuous Integration Toolkit
|
||||||
|
* Copyright (c) 2001-2003, ThoughtWorks, Inc.
|
||||||
|
* 651 W Washington Ave. Suite 500
|
||||||
|
* Chicago, IL 60661 USA
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* + Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* + Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
*
|
||||||
|
* + Neither the name of ThoughtWorks, Inc., CruiseControl, nor the
|
||||||
|
* names of its contributors may be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior
|
||||||
|
* written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
********************************************************************************/
|
||||||
|
|
||||||
|
/* ====================================================================
|
||||||
|
* Copyright 2003-2004 The Apache Software Foundation.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
* ====================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.StringTokenizer;
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Commandline objects help handling command lines specifying processes to
|
||||||
|
* execute.
|
||||||
|
*
|
||||||
|
* The class can be used to define a command line as nested elements or as a
|
||||||
|
* helper to define a command line by an application.
|
||||||
|
* <p>
|
||||||
|
* <code>
|
||||||
|
* <someelement><br>
|
||||||
|
* <acommandline executable="/executable/to/run"><br>
|
||||||
|
* <argument value="argument 1" /><br>
|
||||||
|
* <argument line="argument_1 argument_2 argument_3" /><br>
|
||||||
|
* <argument value="argument 4" /><br>
|
||||||
|
* </acommandline><br>
|
||||||
|
* </someelement><br>
|
||||||
|
* </code>
|
||||||
|
* The element <code>someelement</code> must provide a method
|
||||||
|
* <code>createAcommandline</code> which returns an instance of this class.
|
||||||
|
*
|
||||||
|
* @author thomas.haas@softwired-inc.com
|
||||||
|
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
|
||||||
|
*/
|
||||||
|
public class Commandline
|
||||||
|
implements Cloneable
|
||||||
|
{
|
||||||
|
|
||||||
|
protected static final String OS_NAME = "os.name";
|
||||||
|
protected static final String WINDOWS = "Windows";
|
||||||
|
|
||||||
|
private String shell = null;
|
||||||
|
private Vector shellArgs = new Vector();
|
||||||
|
protected String executable = null;
|
||||||
|
protected Vector arguments = new Vector();
|
||||||
|
private File workingDir = null;
|
||||||
|
|
||||||
|
public Commandline( String toProcess )
|
||||||
|
{
|
||||||
|
super();
|
||||||
|
setDefaultShell();
|
||||||
|
String[] tmp = new String[0];
|
||||||
|
try
|
||||||
|
{
|
||||||
|
tmp = translateCommandline( toProcess );
|
||||||
|
}
|
||||||
|
catch ( Exception e )
|
||||||
|
{
|
||||||
|
System.err.println( "Error translating Commandline." );
|
||||||
|
}
|
||||||
|
if ( tmp != null && tmp.length > 0 )
|
||||||
|
{
|
||||||
|
setExecutable( tmp[0] );
|
||||||
|
for ( int i = 1; i < tmp.length; i++ )
|
||||||
|
{
|
||||||
|
createArgument().setValue( tmp[i] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Commandline()
|
||||||
|
{
|
||||||
|
super();
|
||||||
|
setDefaultShell();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used for nested xml command line definitions.
|
||||||
|
*/
|
||||||
|
public static class Argument
|
||||||
|
{
|
||||||
|
|
||||||
|
private String[] parts;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a single commandline argument.
|
||||||
|
*
|
||||||
|
* @param value a single commandline argument.
|
||||||
|
*/
|
||||||
|
public void setValue( String value )
|
||||||
|
{
|
||||||
|
parts = new String[]{value};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Line to split into several commandline arguments.
|
||||||
|
*
|
||||||
|
* @param line line to split into several commandline arguments
|
||||||
|
*/
|
||||||
|
public void setLine( String line )
|
||||||
|
{
|
||||||
|
if ( line == null )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
parts = translateCommandline( line );
|
||||||
|
}
|
||||||
|
catch ( Exception e )
|
||||||
|
{
|
||||||
|
System.err.println( "Error translating Commandline." );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a single commandline argument to the absolute filename
|
||||||
|
* of the given file.
|
||||||
|
*
|
||||||
|
* @param value a single commandline argument.
|
||||||
|
*/
|
||||||
|
public void setFile( File value )
|
||||||
|
{
|
||||||
|
parts = new String[]{value.getAbsolutePath()};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the parts this Argument consists of.
|
||||||
|
*/
|
||||||
|
public String[] getParts()
|
||||||
|
{
|
||||||
|
return parts;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class to keep track of the position of an Argument.
|
||||||
|
*/
|
||||||
|
// <p>This class is there to support the srcfile and targetfile
|
||||||
|
// elements of <execon> and <transform> - don't know
|
||||||
|
// whether there might be additional use cases.</p> --SB
|
||||||
|
public class Marker
|
||||||
|
{
|
||||||
|
|
||||||
|
private int position;
|
||||||
|
private int realPos = -1;
|
||||||
|
|
||||||
|
Marker( int position )
|
||||||
|
{
|
||||||
|
this.position = position;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the number of arguments that preceeded this marker.
|
||||||
|
*
|
||||||
|
* <p>The name of the executable - if set - is counted as the
|
||||||
|
* very first argument.</p>
|
||||||
|
*/
|
||||||
|
public int getPosition()
|
||||||
|
{
|
||||||
|
if ( realPos == -1 )
|
||||||
|
{
|
||||||
|
realPos = ( executable == null ? 0 : 1 );
|
||||||
|
for ( int i = 0; i < position; i++ )
|
||||||
|
{
|
||||||
|
Argument arg = (Argument) arguments.elementAt( i );
|
||||||
|
realPos += arg.getParts().length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return realPos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>Sets the shell or command-line interpretor for the detected operating system,
|
||||||
|
* and the shell arguments.</p>
|
||||||
|
*/
|
||||||
|
private void setDefaultShell() {
|
||||||
|
String os = System.getProperty(OS_NAME);
|
||||||
|
|
||||||
|
//If this is windows set the shell to command.com or cmd.exe with correct arguments.
|
||||||
|
if ( os.indexOf(WINDOWS) != -1 )
|
||||||
|
{
|
||||||
|
if (os.indexOf("95") != -1 || os.indexOf("98") != -1 || os.indexOf("Me") != -1)
|
||||||
|
{
|
||||||
|
shell = "COMMAND.COM";
|
||||||
|
shellArgs.add("/C");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
shell = "CMD.EXE";
|
||||||
|
shellArgs.add("/X");
|
||||||
|
shellArgs.add("/C");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an argument object.
|
||||||
|
*
|
||||||
|
* <p>Each commandline object has at most one instance of the
|
||||||
|
* argument class. This method calls
|
||||||
|
* <code>this.createArgument(false)</code>.</p>
|
||||||
|
*
|
||||||
|
* @see #createArgument(boolean)
|
||||||
|
* @return the argument object.
|
||||||
|
*/
|
||||||
|
public Argument createArgument()
|
||||||
|
{
|
||||||
|
return this.createArgument( false );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an argument object and adds it to our list of args.
|
||||||
|
*
|
||||||
|
* <p>Each commandline object has at most one instance of the
|
||||||
|
* argument class.</p>
|
||||||
|
*
|
||||||
|
* @param insertAtStart if true, the argument is inserted at the
|
||||||
|
* beginning of the list of args, otherwise it is appended.
|
||||||
|
*/
|
||||||
|
public Argument createArgument( boolean insertAtStart )
|
||||||
|
{
|
||||||
|
Argument argument = new Argument();
|
||||||
|
if ( insertAtStart )
|
||||||
|
{
|
||||||
|
arguments.insertElementAt( argument, 0 );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
arguments.addElement( argument );
|
||||||
|
}
|
||||||
|
return argument;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the executable to run.
|
||||||
|
*/
|
||||||
|
public void setExecutable( String executable )
|
||||||
|
{
|
||||||
|
if ( executable == null || executable.length() == 0 )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.executable =
|
||||||
|
executable.replace( '/', File.separatorChar ).replace( '\\', File.separatorChar );
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getExecutable()
|
||||||
|
{
|
||||||
|
return executable;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addArguments( String[] line )
|
||||||
|
{
|
||||||
|
for ( int i = 0; i < line.length; i++ )
|
||||||
|
{
|
||||||
|
createArgument().setValue( line[i] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the executable and all defined arguments.
|
||||||
|
*/
|
||||||
|
public String[] getCommandline()
|
||||||
|
{
|
||||||
|
final String[] args = getArguments();
|
||||||
|
if ( executable == null )
|
||||||
|
{
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
final String[] result = new String[args.length + 1];
|
||||||
|
result[0] = executable;
|
||||||
|
System.arraycopy( args, 0, result, 1, args.length );
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the shell, executable and all defined arguments.
|
||||||
|
*/
|
||||||
|
public String[] getShellCommandline()
|
||||||
|
{
|
||||||
|
int shellCount = 0;
|
||||||
|
int arrayPos = 0;
|
||||||
|
if ( shell != null )
|
||||||
|
{
|
||||||
|
shellCount = 1;
|
||||||
|
}
|
||||||
|
shellCount += shellArgs.size();
|
||||||
|
final String[] args = getArguments();
|
||||||
|
|
||||||
|
String[] result = new String[shellCount + args.length + (( executable == null )? 0:1)];
|
||||||
|
//Build shell and arguments into result
|
||||||
|
if ( shell != null )
|
||||||
|
{
|
||||||
|
result[0] = shell;
|
||||||
|
arrayPos++;
|
||||||
|
}
|
||||||
|
System.arraycopy( shellArgs.toArray(), 0, result, arrayPos, shellArgs.size() );
|
||||||
|
arrayPos += shellArgs.size();
|
||||||
|
//Build excutable and arguments into result
|
||||||
|
if ( executable != null )
|
||||||
|
{
|
||||||
|
result[arrayPos] = executable;
|
||||||
|
arrayPos++;
|
||||||
|
}
|
||||||
|
System.arraycopy( args, 0, result, arrayPos, args.length );
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all arguments defined by <code>addLine</code>,
|
||||||
|
* <code>addValue</code> or the argument object.
|
||||||
|
*/
|
||||||
|
public String[] getArguments()
|
||||||
|
{
|
||||||
|
Vector result = new Vector( arguments.size() * 2 );
|
||||||
|
for ( int i = 0; i < arguments.size(); i++ )
|
||||||
|
{
|
||||||
|
Argument arg = (Argument) arguments.elementAt( i );
|
||||||
|
String[] s = arg.getParts();
|
||||||
|
if ( s != null )
|
||||||
|
{
|
||||||
|
for ( int j = 0; j < s.length; j++ )
|
||||||
|
{
|
||||||
|
result.addElement( s[j] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String[] res = new String[result.size()];
|
||||||
|
result.copyInto( res );
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
return toString( getCommandline() );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Put quotes around the given String if necessary.
|
||||||
|
*
|
||||||
|
* <p>If the argument doesn't include spaces or quotes, return it
|
||||||
|
* as is. If it contains double quotes, use single quotes - else
|
||||||
|
* surround the argument by double quotes.</p>
|
||||||
|
*
|
||||||
|
* @exception CommandLineException if the argument contains both, single
|
||||||
|
* and double quotes.
|
||||||
|
*/
|
||||||
|
public static String quoteArgument( String argument ) throws CommandLineException
|
||||||
|
{
|
||||||
|
if ( argument.indexOf( "\"" ) > -1 )
|
||||||
|
{
|
||||||
|
if ( argument.indexOf( "\'" ) > -1 )
|
||||||
|
{
|
||||||
|
throw new CommandLineException( "Can't handle single and double quotes in same argument" );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return '\'' + argument + '\'';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( argument.indexOf( "\'" ) > -1 || argument.indexOf( " " ) > -1 )
|
||||||
|
{
|
||||||
|
return '\"' + argument + '\"';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return argument;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String toString( String[] line )
|
||||||
|
{
|
||||||
|
// empty path return empty string
|
||||||
|
if ( line == null || line.length == 0 )
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
// path containing one or more elements
|
||||||
|
final StringBuffer result = new StringBuffer();
|
||||||
|
for ( int i = 0; i < line.length; i++ )
|
||||||
|
{
|
||||||
|
if ( i > 0 )
|
||||||
|
{
|
||||||
|
result.append( ' ' );
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
result.append( quoteArgument( line[i] ) );
|
||||||
|
}
|
||||||
|
catch ( Exception e )
|
||||||
|
{
|
||||||
|
System.err.println( "Error quoting argument." );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String[] translateCommandline( String toProcess ) throws Exception
|
||||||
|
{
|
||||||
|
if ( toProcess == null || toProcess.length() == 0 )
|
||||||
|
{
|
||||||
|
return new String[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
// parse with a simple finite state machine
|
||||||
|
|
||||||
|
final int normal = 0;
|
||||||
|
final int inQuote = 1;
|
||||||
|
final int inDoubleQuote = 2;
|
||||||
|
int state = normal;
|
||||||
|
StringTokenizer tok = new StringTokenizer( toProcess, "\"\' ", true );
|
||||||
|
Vector v = new Vector();
|
||||||
|
StringBuffer current = new StringBuffer();
|
||||||
|
|
||||||
|
while ( tok.hasMoreTokens() )
|
||||||
|
{
|
||||||
|
String nextTok = tok.nextToken();
|
||||||
|
switch ( state )
|
||||||
|
{
|
||||||
|
case inQuote:
|
||||||
|
if ( "\'".equals( nextTok ) )
|
||||||
|
{
|
||||||
|
state = normal;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
current.append( nextTok );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case inDoubleQuote:
|
||||||
|
if ( "\"".equals( nextTok ) )
|
||||||
|
{
|
||||||
|
state = normal;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
current.append( nextTok );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default :
|
||||||
|
if ( "\'".equals( nextTok ) )
|
||||||
|
{
|
||||||
|
state = inQuote;
|
||||||
|
}
|
||||||
|
else if ( "\"".equals( nextTok ) )
|
||||||
|
{
|
||||||
|
state = inDoubleQuote;
|
||||||
|
}
|
||||||
|
else if ( " ".equals( nextTok ) )
|
||||||
|
{
|
||||||
|
if ( current.length() != 0 )
|
||||||
|
{
|
||||||
|
v.addElement( current.toString() );
|
||||||
|
current.setLength( 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
current.append( nextTok );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( current.length() != 0 )
|
||||||
|
{
|
||||||
|
v.addElement( current.toString() );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( state == inQuote || state == inDoubleQuote )
|
||||||
|
{
|
||||||
|
throw new CommandLineException( "unbalanced quotes in " + toProcess );
|
||||||
|
}
|
||||||
|
|
||||||
|
String[] args = new String[v.size()];
|
||||||
|
v.copyInto( args );
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int size()
|
||||||
|
{
|
||||||
|
return getCommandline().length;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object clone()
|
||||||
|
{
|
||||||
|
Commandline c = new Commandline();
|
||||||
|
c.setExecutable( executable );
|
||||||
|
c.addArguments( getArguments() );
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear out the whole command line. */
|
||||||
|
public void clear()
|
||||||
|
{
|
||||||
|
executable = null;
|
||||||
|
arguments.removeAllElements();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear out the arguments but leave the executable in place for another operation.
|
||||||
|
*/
|
||||||
|
public void clearArgs()
|
||||||
|
{
|
||||||
|
arguments.removeAllElements();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a marker.
|
||||||
|
*
|
||||||
|
* <p>This marker can be used to locate a position on the
|
||||||
|
* commandline - to insert something for example - when all
|
||||||
|
* parameters have been set.</p>
|
||||||
|
*/
|
||||||
|
public Marker createMarker()
|
||||||
|
{
|
||||||
|
return new Marker( arguments.size() );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets execution directory.
|
||||||
|
*/
|
||||||
|
public void setWorkingDirectory( String path )
|
||||||
|
{
|
||||||
|
if ( path != null )
|
||||||
|
{
|
||||||
|
workingDir = new File( path );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public File getWorkingDirectory()
|
||||||
|
{
|
||||||
|
return workingDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes the command.
|
||||||
|
*/
|
||||||
|
public Process execute()
|
||||||
|
throws CommandLineException
|
||||||
|
{
|
||||||
|
Process process = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if ( workingDir == null )
|
||||||
|
{
|
||||||
|
process = Runtime.getRuntime().exec( getShellCommandline() );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( !workingDir.exists() )
|
||||||
|
{
|
||||||
|
throw new CommandLineException( "Working directory \"" + workingDir.getPath() + "\" does not exist!" );
|
||||||
|
}
|
||||||
|
else if ( !workingDir.isDirectory() )
|
||||||
|
{
|
||||||
|
throw new CommandLineException( "Path \"" + workingDir.getPath() + "\" does not specify a directory." );
|
||||||
|
}
|
||||||
|
|
||||||
|
process = Runtime.getRuntime().exec( getShellCommandline(), null, workingDir );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch( IOException ex )
|
||||||
|
{
|
||||||
|
throw new CommandLineException( "Error while executing process.", ex );
|
||||||
|
}
|
||||||
|
|
||||||
|
return process;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
package org.apache.maven.it.cli;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2004, The Codehaus
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is furnished to do
|
||||||
|
* so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* ====================================================================
|
||||||
|
* Copyright 2003-2004 The Apache Software Foundation.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
* ====================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:evenisse@apache.org">Emmanuel Venisse</a>
|
||||||
|
* @version $Id$
|
||||||
|
*/
|
||||||
|
public class DefaultConsumer
|
||||||
|
implements StreamConsumer
|
||||||
|
{
|
||||||
|
public void consumeLine(String line)
|
||||||
|
{
|
||||||
|
System.out.println(line);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,150 @@
|
||||||
|
package org.apache.maven.it.cli;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2004, The Codehaus
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is furnished to do
|
||||||
|
* so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* ====================================================================
|
||||||
|
* Copyright 2003-2004 The Apache Software Foundation.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
* ====================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.util.StringTokenizer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The java.util.StringTokenizer is horribly broken.
|
||||||
|
* Given the string 1,,,3,,4 (, delim)
|
||||||
|
* It will return 1,3,4
|
||||||
|
* Which is clearly wrong - 1,EMPTY,EMPTY,3,EMPTY,4 is what it should return
|
||||||
|
*/
|
||||||
|
public final class EnhancedStringTokenizer
|
||||||
|
{
|
||||||
|
private StringTokenizer cst = null;
|
||||||
|
String cdelim;
|
||||||
|
final boolean cdelimSingleChar;
|
||||||
|
final char cdelimChar;
|
||||||
|
boolean creturnDelims;
|
||||||
|
String lastToken = null;
|
||||||
|
boolean delimLast = true;
|
||||||
|
|
||||||
|
public EnhancedStringTokenizer(String str)
|
||||||
|
{
|
||||||
|
this(str, " \t\n\r\f", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public EnhancedStringTokenizer(String str, String delim)
|
||||||
|
{
|
||||||
|
this(str, delim, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public EnhancedStringTokenizer(String str, String delim, boolean returnDelims)
|
||||||
|
{
|
||||||
|
cst = new StringTokenizer(str, delim, true);
|
||||||
|
cdelim = delim;
|
||||||
|
creturnDelims = returnDelims;
|
||||||
|
cdelimSingleChar = (delim.length() == 1);
|
||||||
|
cdelimChar = delim.charAt(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasMoreTokens()
|
||||||
|
{
|
||||||
|
return cst.hasMoreTokens();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String internalNextToken()
|
||||||
|
{
|
||||||
|
if (lastToken != null)
|
||||||
|
{
|
||||||
|
String last = lastToken;
|
||||||
|
lastToken = null;
|
||||||
|
return last;
|
||||||
|
}
|
||||||
|
|
||||||
|
String token = cst.nextToken();
|
||||||
|
if (isDelim(token))
|
||||||
|
{
|
||||||
|
if (delimLast)
|
||||||
|
{
|
||||||
|
lastToken = token;
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
delimLast = true;
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
delimLast = false;
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String nextToken()
|
||||||
|
{
|
||||||
|
String token = internalNextToken();
|
||||||
|
if (creturnDelims)
|
||||||
|
return token;
|
||||||
|
if (isDelim(token))
|
||||||
|
return hasMoreTokens() ? internalNextToken() : "";
|
||||||
|
else
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isDelim(String str)
|
||||||
|
{
|
||||||
|
if (str.length() == 1)
|
||||||
|
{
|
||||||
|
char ch = str.charAt(0);
|
||||||
|
if (cdelimSingleChar)
|
||||||
|
{
|
||||||
|
if (cdelimChar == ch)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (cdelim.indexOf(ch) >= 0)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,78 @@
|
||||||
|
package org.apache.maven.it.cli;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2004, The Codehaus
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is furnished to do
|
||||||
|
* so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/********************************************************************************
|
||||||
|
* CruiseControl, a Continuous Integration Toolkit
|
||||||
|
* Copyright (c) 2003, ThoughtWorks, Inc.
|
||||||
|
* 651 W Washington Ave. Suite 500
|
||||||
|
* Chicago, IL 60661 USA
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* + Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* + Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
*
|
||||||
|
* + Neither the name of ThoughtWorks, Inc., CruiseControl, nor the
|
||||||
|
* names of its contributors may be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior
|
||||||
|
* written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
********************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Works in concert with the StreamPumper class to
|
||||||
|
* allow implementations to gain access to the lines being
|
||||||
|
* "Pumped".
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:fvancea@maxiq.com">Florin Vancea</a>
|
||||||
|
* @author <a href="mailto:pj@thoughtworks.com">Paul Julius</a>
|
||||||
|
*/
|
||||||
|
public interface StreamConsumer
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Called when the StreamPumper pumps a line from the Stream.
|
||||||
|
*/
|
||||||
|
public void consumeLine( String line );
|
||||||
|
}
|
|
@ -0,0 +1,143 @@
|
||||||
|
package org.apache.maven.it.cli;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2004, The Codehaus
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is furnished to do
|
||||||
|
* so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:trygvis@inamo.no">Trygve Laugstøl</a>
|
||||||
|
* @version $Id$
|
||||||
|
*/
|
||||||
|
public class StreamFeeder
|
||||||
|
extends Thread
|
||||||
|
{
|
||||||
|
private InputStream input;
|
||||||
|
|
||||||
|
private OutputStream output;
|
||||||
|
|
||||||
|
private boolean done;
|
||||||
|
|
||||||
|
public StreamFeeder( InputStream input, OutputStream output )
|
||||||
|
{
|
||||||
|
this.input = input;
|
||||||
|
|
||||||
|
this.output = output;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Runnable implementation
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
feed();
|
||||||
|
}
|
||||||
|
catch ( Throwable ex )
|
||||||
|
{
|
||||||
|
// Catched everything so the streams will be closed and flagged as done.
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
close();
|
||||||
|
|
||||||
|
done = true;
|
||||||
|
|
||||||
|
synchronized ( this )
|
||||||
|
{
|
||||||
|
this.notifyAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
public void close()
|
||||||
|
{
|
||||||
|
if ( input != null )
|
||||||
|
{
|
||||||
|
synchronized ( input )
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
input.close();
|
||||||
|
}
|
||||||
|
catch ( IOException ex )
|
||||||
|
{
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
|
||||||
|
input = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( output != null )
|
||||||
|
{
|
||||||
|
synchronized ( output )
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
output.close();
|
||||||
|
}
|
||||||
|
catch ( IOException ex )
|
||||||
|
{
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
|
||||||
|
output = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDone()
|
||||||
|
{
|
||||||
|
return done;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
private void feed()
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
int data = input.read();
|
||||||
|
|
||||||
|
while ( !done && data != -1 )
|
||||||
|
{
|
||||||
|
synchronized ( output )
|
||||||
|
{
|
||||||
|
output.write( data );
|
||||||
|
|
||||||
|
data = input.read();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,225 @@
|
||||||
|
package org.apache.maven.it.cli;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2004, The Codehaus
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
* of the Software, and to permit persons to whom the Software is furnished to do
|
||||||
|
* so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/********************************************************************************
|
||||||
|
* CruiseControl, a Continuous Integration Toolkit
|
||||||
|
* Copyright (c) 2001-2003, ThoughtWorks, Inc.
|
||||||
|
* 651 W Washington Ave. Suite 500
|
||||||
|
* Chicago, IL 60661 USA
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* + Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* + Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
*
|
||||||
|
* + Neither the name of ThoughtWorks, Inc., CruiseControl, nor the
|
||||||
|
* names of its contributors may be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior
|
||||||
|
* written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
********************************************************************************/
|
||||||
|
|
||||||
|
/* ====================================================================
|
||||||
|
* Copyright 2003-2004 The Apache Software Foundation.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
* ====================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.io.Reader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class to pump the error stream during Process's runtime. Copied from the Ant
|
||||||
|
* built-in task.
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:fvancea@maxiq.com">Florin Vancea </a>
|
||||||
|
* @author <a href="mailto:pj@thoughtworks.com">Paul Julius </a>
|
||||||
|
* @since June 11, 2001
|
||||||
|
*/
|
||||||
|
public class StreamPumper
|
||||||
|
extends Thread
|
||||||
|
{
|
||||||
|
private BufferedReader in;
|
||||||
|
|
||||||
|
private StreamConsumer consumer = null;
|
||||||
|
|
||||||
|
private PrintWriter out = null;
|
||||||
|
|
||||||
|
private static final int SIZE = 1024;
|
||||||
|
|
||||||
|
boolean done;
|
||||||
|
|
||||||
|
public StreamPumper( InputStream in )
|
||||||
|
{
|
||||||
|
this.in = new BufferedReader( new InputStreamReader( in ), SIZE );
|
||||||
|
}
|
||||||
|
|
||||||
|
public StreamPumper( InputStream in, StreamConsumer consumer )
|
||||||
|
{
|
||||||
|
this( in );
|
||||||
|
|
||||||
|
this.consumer = consumer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StreamPumper( InputStream in, PrintWriter writer )
|
||||||
|
{
|
||||||
|
this( in );
|
||||||
|
|
||||||
|
out = writer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StreamPumper( InputStream in, PrintWriter writer, StreamConsumer consumer )
|
||||||
|
{
|
||||||
|
this( in );
|
||||||
|
this.out = writer;
|
||||||
|
this.consumer = consumer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String s = in.readLine();
|
||||||
|
|
||||||
|
while ( s != null )
|
||||||
|
{
|
||||||
|
consumeLine( s );
|
||||||
|
|
||||||
|
if ( out != null )
|
||||||
|
{
|
||||||
|
out.println( s );
|
||||||
|
|
||||||
|
out.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
s = in.readLine();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch ( Throwable e )
|
||||||
|
{
|
||||||
|
// Catched everything so the streams will be closed and flagged as done.
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
closeInputStream( in );
|
||||||
|
|
||||||
|
done = true;
|
||||||
|
|
||||||
|
synchronized ( this )
|
||||||
|
{
|
||||||
|
this.notifyAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void flush()
|
||||||
|
{
|
||||||
|
if ( out != null )
|
||||||
|
{
|
||||||
|
out.flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void close()
|
||||||
|
{
|
||||||
|
closeOutputStream( out );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void closeInputStream( Reader in )
|
||||||
|
{
|
||||||
|
if ( in == null )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
in.close();
|
||||||
|
}
|
||||||
|
catch ( IOException e )
|
||||||
|
{
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void closeOutputStream( PrintWriter out )
|
||||||
|
{
|
||||||
|
if ( out == null )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
out.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public boolean isDone()
|
||||||
|
{
|
||||||
|
return done;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void consumeLine( String line )
|
||||||
|
{
|
||||||
|
if ( consumer != null )
|
||||||
|
{
|
||||||
|
consumer.consumeLine( line );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue