diff --git a/src/etc/testcases/taskdefs/abstractcvstask.xml b/src/etc/testcases/taskdefs/abstractcvstask.xml index b9a2c2119..6928d2b9d 100644 --- a/src/etc/testcases/taskdefs/abstractcvstask.xml +++ b/src/etc/testcases/taskdefs/abstractcvstask.xml @@ -6,7 +6,6 @@ - diff --git a/src/main/org/apache/tools/ant/taskdefs/AbstractCvsTask.java b/src/main/org/apache/tools/ant/taskdefs/AbstractCvsTask.java index 0f8a291f9..aee479cac 100644 --- a/src/main/org/apache/tools/ant/taskdefs/AbstractCvsTask.java +++ b/src/main/org/apache/tools/ant/taskdefs/AbstractCvsTask.java @@ -60,11 +60,13 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.PrintStream; +import java.util.Vector; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Project; import org.apache.tools.ant.Task; import org.apache.tools.ant.types.Commandline; import org.apache.tools.ant.types.Environment; +import org.apache.tools.ant.util.StringUtils; /** * original Cvs.java 1.20 @@ -79,9 +81,13 @@ import org.apache.tools.ant.types.Environment; * @author Kevin Ross kevin.ross@bredex.com */ public abstract class AbstractCvsTask extends Task { - + /** Default compression level to use, if compression is enabled via setCompression( true ). */ + public static final int DEFAULT_COMPRESSION_LEVEL = 3; private Commandline cmd = new Commandline(); + /** list of Commandline children */ + private Vector vecCommandlines = new Vector(); + /** * the CVSROOT variable. */ @@ -97,16 +103,25 @@ public abstract class AbstractCvsTask extends Task { */ private String cvsPackage; + /** + * the default command. + */ + private static final String default_command = "checkout"; /** * the CVS command to execute. */ - private String command = "checkout"; + private String command = null; /** * suppress information messages. */ private boolean quiet = false; + /** + * compression level to use. + */ + private int compression = 0; + /** * report only, don't change any files. */ @@ -146,15 +161,19 @@ public abstract class AbstractCvsTask extends Task { */ private boolean failOnError = false; - /** * Create accessors for the following, to allow different handling of - * the output. + * the output. */ private ExecuteStreamHandler executeStreamHandler; private OutputStream outputStream; private OutputStream errorStream; + /** empty no-arg constructor*/ + public AbstractCvsTask() { + super(); + } + public void setExecuteStreamHandler(ExecuteStreamHandler executeStreamHandler){ this.executeStreamHandler = executeStreamHandler; @@ -222,42 +241,20 @@ public abstract class AbstractCvsTask extends Task { return this.errorStream; } - public void execute() throws BuildException { - + /** + * Sets up the environment for toExecute and then runs it. + * @throws BuildException + */ + protected void runCommand( Commandline toExecute ) throws BuildException { // XXX: we should use JCVS (www.ice.com/JCVS) instead of command line // execution so that we don't rely on having native CVS stuff around (SM) // We can't do it ourselves as jCVS is GPLed, a third party task // outside of jakarta repositories would be possible though (SB). - Commandline toExecute = new Commandline(); - - toExecute.setExecutable("cvs"); - if (cvsRoot != null) { - toExecute.createArgument().setValue("-d"); - toExecute.createArgument().setValue(cvsRoot); - } - if (noexec) { - toExecute.createArgument().setValue("-n"); - } - if (quiet) { - toExecute.createArgument().setValue("-q"); - } - - toExecute.createArgument().setLine(command); - - // - // get the other arguments. - // - toExecute.addArguments(cmd.getCommandline()); - - if (cvsPackage != null) { - toExecute.createArgument().setLine(cvsPackage); - } - Environment env = new Environment(); - if(port>0){ + if (port>0) { Environment.Variable var = new Environment.Variable(); var.setKey("CVS_CLIENT_PORT"); var.setValue(String.valueOf(port)); @@ -277,7 +274,7 @@ public abstract class AbstractCvsTask extends Task { } */ - if(passFile!=null){ + if (passFile!=null) { Environment.Variable var = new Environment.Variable(); var.setKey("CVS_PASSFILE"); var.setValue(String.valueOf(passFile)); @@ -285,7 +282,7 @@ public abstract class AbstractCvsTask extends Task { log("Using cvs passfile: " + String.valueOf(passFile), Project.MSG_INFO); } - if(cvsRsh!=null){ + if (cvsRsh!=null) { Environment.Variable var = new Environment.Variable(); var.setKey("CVS_RSH"); var.setValue(String.valueOf(cvsRsh)); @@ -309,16 +306,47 @@ public abstract class AbstractCvsTask extends Task { exe.setEnvironment(env.getVariables()); try { - log("Executing: " + executeToString(exe), Project.MSG_DEBUG); - + String actualCommandLine = executeToString(exe); + log("running cvs command: " + actualCommandLine, + Project.MSG_DEBUG); int retCode = exe.execute(); + log( "retCode="+retCode, Project.MSG_DEBUG ); /*Throw an exception if cvs exited with error. (Iulian)*/ if(failOnError && retCode != 0) { - throw new BuildException("cvs exited with error code "+ retCode); + throw new BuildException("cvs exited with error code " + + retCode + + StringUtils.LINE_SEP + + "Command line was [" + + actualCommandLine + "]", location ); } } catch (IOException e) { - throw new BuildException(e, location); + if( failOnError ) { + throw new BuildException(e, location); + } + else { + log("Caught exception: "+e.getMessage(), Project.MSG_WARN); + } + } + catch (BuildException e) { + if( failOnError ) { + throw( e ); + } + else { + Throwable t = e.getException(); + if (t == null) { + t = e; + } + log("Caught exception: "+t.getMessage(), Project.MSG_WARN); + } + } + catch (Exception e) { + if( failOnError ) { + throw new BuildException(e, location); + } + else { + log("Caught exception: "+e.getMessage(), Project.MSG_WARN); + } } finally { // @@ -330,7 +358,6 @@ public abstract class AbstractCvsTask extends Task { outputStream.close(); } catch (IOException e) {} } - if (errorStream != null) { try { errorStream.close(); @@ -339,6 +366,26 @@ public abstract class AbstractCvsTask extends Task { } } + public void execute() throws BuildException { + + + if( this.getCommand() == null + && vecCommandlines.size() == 0 ) { + // re-implement legacy behaviour: + this.setCommand( AbstractCvsTask.default_command ); + } + + String c = this.getCommand(); + if( c != null ) { + this.addConfiguredCommandline( this.cmd, true ); + this.cmd.createArgument().setLine(c); + } + + for( int i = 0; i < vecCommandlines.size(); i++ ) { + this.runCommand( (Commandline)vecCommandlines.elementAt( i ) ); + } + } + private String executeToString(Execute execute){ StringBuffer stringBuffer = new StringBuffer(250); @@ -348,18 +395,16 @@ public abstract class AbstractCvsTask extends Task { stringBuffer.append(commandLine[i]); stringBuffer.append(" "); } - String newLine = System.getProperty("line.separator"); - stringBuffer.append(newLine); - stringBuffer.append(newLine); - stringBuffer.append("environment:"); - stringBuffer.append(newLine); - + String newLine = StringUtils.LINE_SEP; String[] variableArray = execute.getEnvironment(); if(variableArray != null){ + stringBuffer.append(newLine); + stringBuffer.append(newLine); + stringBuffer.append("environment:"); + stringBuffer.append(newLine); for(int z=0; z 0) { addCommandArgument("-D"); @@ -465,6 +514,9 @@ public abstract class AbstractCvsTask extends Task { public void setCommand(String c) { this.command = c; } + public String getCommand() { + return this.command; + } public void setQuiet(boolean q) { quiet = q; @@ -489,6 +541,66 @@ public abstract class AbstractCvsTask extends Task { public void setFailOnError(boolean failOnError) { this.failOnError = failOnError; } -} + /** + * Configure a commandline element for things like cvsRoot, quiet, etc. + */ + protected void configureCommandline( Commandline c ) { + if( c == null ) { + return; + } + c.setExecutable( "cvs" ); + if (cvsPackage != null) { + c.createArgument(true).setLine(cvsPackage); + } + if ( this.compression > 0 && this.compression < 10 ) { + c.createArgument(true).setValue("-z"+this.compression); + } + if (quiet) { + c.createArgument(true).setValue("-q"); + } + if (noexec) { + c.createArgument(true).setValue("-n"); + } + if (cvsRoot != null) { + c.createArgument(true).setLine("-d"+cvsRoot); + } + } + public void addConfiguredCommandline( Commandline c ) { + this.addConfiguredCommandline( c, false ); + } + + /** + * Configures and adds the given Commandline. + * @param insertAtStart If true, c is + */ + public void addConfiguredCommandline( Commandline c, boolean insertAtStart ) { + if( c == null ) { return; } + this.configureCommandline( c ); + if( insertAtStart ) { + vecCommandlines.insertElementAt( c, 0 ); + } + else { + vecCommandlines.addElement( c ); + } + } + + /** + * If set to a value 1-9 it adds -zN to the cvs command line, else + * it disables compression. + */ + public void setCompression( int level ) { + this.compression = level; + } + + /** + * @param usecomp If true, turns on compression using default + * level, AbstractCvsTask.DEFAULT_COMPRESSION_LEVEL. + */ + public void setCompression( boolean usecomp ) { + this.setCompression( usecomp ? + AbstractCvsTask.DEFAULT_COMPRESSION_LEVEL : 0 ); + } + +} diff --git a/src/main/org/apache/tools/ant/types/Commandline.java b/src/main/org/apache/tools/ant/types/Commandline.java index 1875faaf0..17d52e50d 100644 --- a/src/main/org/apache/tools/ant/types/Commandline.java +++ b/src/main/org/apache/tools/ant/types/Commandline.java @@ -1,7 +1,7 @@ /* * The Apache Software License, Version 1.1 * - * Copyright (c) 2000-2001 The Apache Software Foundation. All rights + * Copyright (c) 2000-2002 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without @@ -80,7 +80,7 @@ import java.util.StringTokenizer; * createAcommandline which returns an instance of this class. * * @author thomas.haas@softwired-inc.com - * @author Stefan Bodewig + * @author Stefan Bodewig */ public class Commandline implements Cloneable { @@ -124,6 +124,9 @@ public class Commandline implements Cloneable { * @param line line to split into several commandline arguments */ public void setLine(String line) { + if( line == null ) { + return; + } parts = translateCommandline(line); } @@ -132,7 +135,7 @@ public class Commandline implements Cloneable { * PATH - ensures the right separator for the local platform * is used. * - * @param value a single commandline argument. + * @param value a single commandline argument. */ public void setPath(Path value) { parts = new String[] {value.toString()}; @@ -140,9 +143,9 @@ public class Commandline implements Cloneable { /** * Sets a single commandline argument to the absolute filename - * of the given file. + * of the given file. * - * @param value a single commandline argument. + * @param value a single commandline argument. */ public void setFile(File value) { parts = new String[] {value.getAbsolutePath()}; @@ -191,16 +194,37 @@ public class Commandline implements Cloneable { /** * Creates an argument object. - * Each commandline object has at most one instance of the argument class. + * + *

Each commandline object has at most one instance of the + * argument class. This method calls + * this.createArgument(false).

+ * + * @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. + * + *

Each commandline object has at most one instance of the + * argument class.

+ * + * @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(); - arguments.addElement(argument); + if(insertAtStart) { + arguments.insertElementAt(argument,0); + } else { + arguments.addElement(argument); + } return argument; } - /** * Sets the executable to run. */ @@ -248,11 +272,13 @@ public class Commandline implements Cloneable { for (int i=0; i * * @exception BuildException if the argument contains both, single - * and double quotes. + * and double quotes. */ public static String quoteArgument(String argument) { if (argument.indexOf("\"") > -1) { @@ -310,7 +336,7 @@ public class Commandline implements Cloneable { } // parse with a simple finite state machine - + final int normal = 0; final int inQuote = 1; final int inDoubleQuote = 2; @@ -390,7 +416,7 @@ public class Commandline implements Cloneable { public void clearArgs() { arguments.removeAllElements(); } - + /** * Return a marker. * @@ -401,4 +427,5 @@ public class Commandline implements Cloneable { public Marker createMarker() { return new Marker(arguments.size()); } + }