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]>