changes:
- refactored a bit. execute() now calls protected runCommand(), then handles 
character data by calling setCommand()/runCommand() for each line of cdata. 
This change was a cleaner way than doing the stupid 
horribleProcessCDataKludge i had in there yesterday, and also helps 
subclasses a bit, i think.

Patch attached.

Other than the refactoring it's functionally the same as the patches from 
last night:
<cvs>
status build.xml
up -r 1.7 subproject.xml
diff -u src/main/org/apache/tools/ant/taskdefs
</cvs>

(and since Recorder/RecorderEntry now support the -emacs flag (and 
emacsmode='true|false'), any patches created this way could be easily snarfed 
from the build log file (assuming emacsmode).


i'll add support for nested <command> elements once i've gotten more 
comfortable with the API.

Does this format sound okay:

<cvs>
<command line="....."/>
<command line="....."/>
<command line="....."/>
<command line="....."/>
</cvs>
(using 'line' to be consistent with the syntax from <exec>'s args)

maybe an optional attribute:
<command line="....." outputfile="..."/>

that would allow creating patches via:
<command line="diff -u ${my.patched.files}" outputfile="mypatches.patch"/>

???

And idea for an extension on this would be multiple types of nested elements:
<cvs>
<diff revision="1.3" file="...."/>
<update revision="3.4" files="...."/>
<!-- 
though a fileset would be more proper, it would be 
Bad to have a revision of other than HEAD with multiple files in an update.
In diff it'd be okay, though.
-->
</cvs>

Of course, i'm getting ahead of myself here. ;)

----- stephan
Generic Universal Computer Guy
[EMAIL PROTECTED] - http://www.einsurance.de
Office: +49 (89) �552 92 862 Handy: �+49 (179) 211 97 67
Student: "Master, you must teach me the way of liberation!"
Master:  "Tell me who it is that binds you."
Student: "No one binds me!"
Master:  "Then why do you seek liberation?"
Index: src/main/org/apache/tools/ant/taskdefs/AbstractCvsTask.java
===================================================================
RCS file: /home/cvspublic/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/AbstractCvsTask.java,v
retrieving revision 1.2
diff -u -r1.2 AbstractCvsTask.java
--- src/main/org/apache/tools/ant/taskdefs/AbstractCvsTask.java	7 Feb 2002 02:15:47 -0000	1.2
+++ src/main/org/apache/tools/ant/taskdefs/AbstractCvsTask.java	22 Mar 2002 11:51:48 -0000
@@ -100,7 +100,8 @@
     /**
      * the CVS command to execute.
      */
-    private String command = "checkout";
+    private String default_command = "checkout";
+    private String command = default_command;
 
     /**
      * suppress information messages.
@@ -146,6 +147,11 @@
      */
     private boolean failOnError = false;
 
+    /**
+     * see addText()
+     *
+     */
+	private String cdata = null;
 
     /**
      * Create accessors for the following, to allow different handling of
@@ -222,8 +228,45 @@
         return this.errorStream;
     }
 
-    public void execute() throws BuildException {
+    /**
+This reads in any data set via addText() and treats each line as one cvs command,
+executing it via runCommand(). It is horribly inefficient because it calls runCommand()
+for every line, causing a lot of unnecessary object crunching. The simple fact is
+that i'm not yet comfortable enough with the Ant APIs yet to try to deal with
+CommandLine, Execute, etc. in a loop, re-using those objects. It would be much more
+efficient to do so, though. My eyes wouldn't notice the difference, but the garbage
+collector will ;).
+    */
+    protected synchronized void processCData() throws BuildException {
+	if( this.cdata == null || this.cdata.length() < 1 ) return;
+	java.util.StringTokenizer st = new java.util.StringTokenizer( this.cdata, org.apache.tools.ant.util.StringUtils.LINE_SEP );
+	String mycmd = null;
+	try {
+	    while( st.hasMoreElements() )
+	    {
+		mycmd = ((String)st.nextElement()).trim();
+		if( mycmd.length() < 1 ) continue;
+		if( mycmd.startsWith( ";" ) ) { continue; }
+		if( mycmd.startsWith( "#" ) ) { continue; }
+		mycmd = getProject().replaceProperties(mycmd);
+		log( "processCData() cvs command: ["+mycmd+"]", Project.MSG_DEBUG );
+ 		this.setCommand( mycmd );
+ 		this.runCommand();
+	    }
+	}
+	catch( BuildException e ) {
+	    throw( e );
+	}
+	catch( Exception e ) {
+	    throw new BuildException( e, location );
+	}
+    }
 
+    /**
+     * Does the actual setting up of environment, etc. Moved here from execute()
+     * to allow easier adding of some extensions. ([EMAIL PROTECTED])
+     */
+    protected void runCommand() 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)
 
@@ -244,7 +287,7 @@
             toExecute.createArgument().setValue("-q");
         }
 
-        toExecute.createArgument().setLine(command);
+	toExecute.createArgument().setLine(command);
 
         //
         // get the other arguments.
@@ -308,19 +351,50 @@
         exe.setCommandline(toExecute.getCommandline());
         exe.setEnvironment(env.getVariables());
 
+	String warning = "ACHTUNG, BABY: proceeding only by the grace of failonerror='false': ";
         try {
-            log("Executing: " + executeToString(exe), Project.MSG_DEBUG);
-
-            int retCode = exe.execute();
+	    String actualCommandLine = this.executeToString(exe);
+	    log("Executing: " + actualCommandLine, Project.MSG_DEBUG);
+            int retCode = 0;
+	    if( this.command == null && cdata == null ) {
+		throw new BuildException( "No command and no command list set!", location );
+	    }
+	    if( this.command != null ) {
+		retCode = exe.execute();
+	    }
             /*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 +
+					 org.apache.tools.ant.util.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( warning+e.getMessage(), Project.MSG_INFO);
+	    }
+        }
+        catch (BuildException e) {
+	    if( failOnError ) {
+		throw( e );
+	    }
+	    else {
+		log( warning+e.getMessage(), Project.MSG_INFO);
+	    }
+        }
+        catch (Exception e) {
+	    if( failOnError ) {
+		throw new BuildException(e, location);
+	    }
+	    else {
+		log( warning+e.getMessage(), Project.MSG_INFO);
+	    }
         }
-        finally {
+	finally {
             //
             // condition used to be if(output == null) outputStream.close().  This is
             //      not appropriate.  Check if the stream itself is not null, then close().
@@ -330,7 +404,6 @@
                     outputStream.close();
                 } catch (IOException e) {}
             }
-
             if (errorStream != null) {
                 try {
                     errorStream.close();
@@ -339,6 +412,14 @@
         }
     }
 
+    public void execute() throws BuildException {
+	if( this.getCommand() == null && this.getText() == null ) {
+	    throw new BuildException( "You must specify either the command property or supply character data (one cvs command per line)!", location );
+	}
+	this.runCommand();
+	this.processCData();
+    }
+
     private String executeToString(Execute execute){
 
         StringBuffer stringBuffer = new StringBuffer(250);
@@ -349,17 +430,14 @@
             stringBuffer.append(" ");
         }
         String newLine = System.getProperty("line.separator");
-        stringBuffer.append(newLine);
-        stringBuffer.append(newLine);
-        stringBuffer.append("environment:");
-        stringBuffer.append(newLine);
-
-
         String[] variableArray = execute.getEnvironment();
 
         if(variableArray != null){
+	    stringBuffer.append(newLine);
+	    stringBuffer.append(newLine);
+	    stringBuffer.append("environment:");
+	    stringBuffer.append(newLine);
             for(int z=0; z<variableArray.length; z++){
-
                 stringBuffer.append(newLine);
                 stringBuffer.append("\t");
                 stringBuffer.append(variableArray[z]);
@@ -465,6 +543,9 @@
     public void setCommand(String c) {
         this.command = c;
     }
+    public String getCommand() {
+        return this.command;
+    }
 
     public void setQuiet(boolean q) {
         quiet = q;
@@ -489,6 +570,27 @@
     public void setFailOnError(boolean failOnError) {
         this.failOnError = failOnError;
     }
-}
 
+    /**
+     * Accepts cvs commands, one command per line, and executes them in order after any
+     * other commands. Example:
+     * <code>
+     * <cvs>
+     * up -r 1.8 some/file
+     * status some/other/file
+     * ; comment lines, too.
+     * # and for Perl fans...
+     *</cvs>
+     * </code>
+     * 'command' is ignored if this is set (sorry).
+     */
+    public void addText( String text ) {
+        this.cdata = text;
+	if( text == null ) return;
+	this.setCommand( null ); // this is a very lame workaround. Ask me someday. ([EMAIL PROTECTED])
+    }
 
+    public String getText() {
+	return this.cdata;
+    }
+}
--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to