Browse Source

fix for bug#19630; no handling large files. Needs testing on mono!

git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@275555 13f79535-47bb-0310-9956-ffa450edef68
master
Steve Loughran 22 years ago
parent
commit
c0eecc68bb
6 changed files with 165 additions and 2 deletions
  1. +3
    -0
      WHATSNEW
  2. +25
    -0
      src/etc/testcases/taskdefs/optional/dotnet.xml
  3. +27
    -0
      src/main/org/apache/tools/ant/taskdefs/optional/dotnet/DotnetCompile.java
  4. +1
    -1
      src/main/org/apache/tools/ant/taskdefs/optional/dotnet/JSharp.java
  5. +101
    -1
      src/main/org/apache/tools/ant/taskdefs/optional/dotnet/NetCommand.java
  6. +8
    -0
      src/testcases/org/apache/tools/ant/taskdefs/optional/DotnetTest.java

+ 3
- 0
WHATSNEW View File

@@ -277,6 +277,9 @@ Fixed bugs:


* <xmlcatalog>s only worked when defined inside of tasks. Bugzilla * <xmlcatalog>s only worked when defined inside of tasks. Bugzilla
Report 20965. Report 20965.
* <csc> and siblings (<vbc> <jsharpc>) handle large filesets by
automatic use of response files. Bugzilla report #19630


Other changes: Other changes:
-------------- --------------


+ 25
- 0
src/etc/testcases/taskdefs/optional/dotnet.xml View File

@@ -101,6 +101,16 @@
</and> </and>
</condition> </condition>
<property name="mono.executable" value="mint"/> <property name="mono.executable" value="mint"/>

<!-- now set a prop of the compiler name to whatever we found -->
<condition property="cs.compiler" value="csc">
<isset property="csc.found"/>
</condition>

<condition property="cs.compiler" value="mcs">
<isset property="mcs.found"/>
</condition>
</target> </target>


<target name="init" depends="probe_for_apps"> <target name="init" depends="probe_for_apps">
@@ -334,6 +344,21 @@
<exec executable="${jsharp.exe}" failonerror="true" /> <exec executable="${jsharp.exe}" failonerror="true" />
</target> </target>


<target name="testCSCresponseFile" depends="validate_csc" >
<property name="testCSCresponseFile.exe"
location="${build.dir}/testCSCresponseFile.exe" />
<csc
destFile="${testCSCresponseFile.exe}"
targetType="exe"
executable="${cs.compiler}"
useResponseFile="true"
>
</csc>
<available property="app.created" file="${testCSCresponseFile.exe}"/>
<fail unless="app.created">No app ${testCSCresponseFile.exe} created</fail>
<delete file="${testCSCresponseFile.exe}"/>
</target>



</project> </project>



+ 27
- 0
src/main/org/apache/tools/ant/taskdefs/optional/dotnet/DotnetCompile.java View File

@@ -205,6 +205,11 @@ public abstract class DotnetCompile
*/ */
protected Vector referenceFilesets = new Vector(); protected Vector referenceFilesets = new Vector();


/**
* flag to set to to use @file based command cache
*/
private boolean useResponseFile = false;
private static final int AUTOMATIC_RESPONSE_FILE_THRESHOLD = 64;


/** /**
* constructor inits everything and set up the search pattern * constructor inits everything and set up the search pattern
@@ -796,6 +801,25 @@ public abstract class DotnetCompile
return "**/*." + getFileExtension(); return "**/*." + getFileExtension();
} }


/**
* getter for flag
* @return
*/
public boolean isUseResponseFile() {
return useResponseFile;
}

/**
* Flag to turn on response file use; default=false.
* When set the command params are saved to a file and
* this is passed in with @file. The task automatically switches
* to this mode with big commands; this option is here for
* testing and emergencies
* @param useResponseFile
*/
public void setUseResponseFile(boolean useResponseFile) {
this.useResponseFile = useResponseFile;
}


/** /**
* do the work by building the command line and then calling it * do the work by building the command line and then calling it
@@ -806,6 +830,9 @@ public abstract class DotnetCompile
throws BuildException { throws BuildException {
validate(); validate();
NetCommand command = createNetCommand(); NetCommand command = createNetCommand();
//set up response file options
command.setAutomaticResponseFileThreshold(AUTOMATIC_RESPONSE_FILE_THRESHOLD);
command.setUseResponseFile(useResponseFile);
//fill in args //fill in args
fillInSharedParameters(command); fillInSharedParameters(command);
addResources(command); addResources(command);


+ 1
- 1
src/main/org/apache/tools/ant/taskdefs/optional/dotnet/JSharp.java View File

@@ -69,7 +69,7 @@ import org.apache.tools.ant.BuildException;
* *
* @author Steve Loughran * @author Steve Loughran
* @since ant1.6 * @since ant1.6
* @ant.task category="dotnet"
* @ant.task category="dotnet" name="jsharpc"
*/ */
public class JSharp extends DotnetCompile { public class JSharp extends DotnetCompile {




+ 101
- 1
src/main/org/apache/tools/ant/taskdefs/optional/dotnet/NetCommand.java View File

@@ -65,12 +65,17 @@ package org.apache.tools.ant.taskdefs.optional.dotnet;


import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.io.BufferedOutputStream;
import java.io.FileNotFoundException;
import java.util.Hashtable; import java.util.Hashtable;


import org.apache.tools.ant.BuildException; import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project; import org.apache.tools.ant.Project;
import org.apache.tools.ant.Task; import org.apache.tools.ant.Task;
import org.apache.tools.ant.DirectoryScanner; import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.util.FileUtils;
import org.apache.tools.ant.taskdefs.Execute; import org.apache.tools.ant.taskdefs.Execute;
import org.apache.tools.ant.taskdefs.ExecuteStreamHandler; import org.apache.tools.ant.taskdefs.ExecuteStreamHandler;
import org.apache.tools.ant.taskdefs.LogStreamHandler; import org.apache.tools.ant.taskdefs.LogStreamHandler;
@@ -130,6 +135,21 @@ public class NetCommand {
*/ */
private File directory; private File directory;


/**
* flag to set to to use @file based command cache
*/
private boolean useResponseFile=false;

/**
* name of a temp file; may be null
*/
private File temporaryCommandFile;

/**
* internal threshold for auto-switch
*/
private int automaticResponseFileThreshold = 64;

/** /**
* constructor * constructor
* *
@@ -231,6 +251,38 @@ public class NetCommand {
} }
} }


/**
* getter
* @return response file state
*/
public boolean isUseResponseFile() {
return useResponseFile;
}

/**
* set this to true to always use the response file
* @param useResponseFile
*/
public void setUseResponseFile(boolean useResponseFile) {
this.useResponseFile = useResponseFile;
}

/**
* getter for threshold
* @return 0 for disabled, or a threshold for enabling response files
*/
public int getAutomaticResponseFileThreshold() {
return automaticResponseFileThreshold;
}

/**
* set threshold for automatically using response files -use 0 for off
* @param automaticResponseFileThreshold
*/
public void setAutomaticResponseFileThreshold(int automaticResponseFileThreshold) {
this.automaticResponseFileThreshold = automaticResponseFileThreshold;
}

/** /**
* set up the command sequence.. * set up the command sequence..
*/ */
@@ -272,7 +324,7 @@ public class NetCommand {
//in verbose mode we always log stuff //in verbose mode we always log stuff
logVerbose(commandLine.describeCommand()); logVerbose(commandLine.describeCommand());
} }
executable.setCommandline(commandLine.getCommandline());
setExecutableCommandLine();
err = executable.execute(); err = executable.execute();
if (Execute.isFailure(err)) { if (Execute.isFailure(err)) {
if (failOnError) { if (failOnError) {
@@ -283,6 +335,54 @@ public class NetCommand {
} }
} catch (IOException e) { } catch (IOException e) {
throw new BuildException(title + " failed: " + e, e, owner.getLocation()); throw new BuildException(title + " failed: " + e, e, owner.getLocation());
} finally {
if (temporaryCommandFile != null) {
temporaryCommandFile.delete();
}
}
}

/**
* set the executable command line
*/
private void setExecutableCommandLine() {

String[] commands = commandLine.getCommandline();
//always trigger file mode if commands are big enough
if (automaticResponseFileThreshold>0 &&
commands.length > automaticResponseFileThreshold) {
useResponseFile = true;
}
if (!useResponseFile || commands.length <= 1) {
//the simple action is to send the command line in as is
executable.setCommandline(commands);
} else {
//but for big operations, we save all the params to a temp file
//and set @tmpfile as the command -then we remember to delete the tempfile
//afterwards
FileOutputStream fos = null;
FileUtils fileUtils = FileUtils.newFileUtils();

temporaryCommandFile = fileUtils.createTempFile("cmd", ".txt", null);
owner.log("Using response file"+temporaryCommandFile,Project.MSG_VERBOSE);

try {
fos = new FileOutputStream(temporaryCommandFile);
PrintWriter out = new PrintWriter(new BufferedOutputStream(fos));
//start at 1 because element 0 is the executable name
for (int i = 1; i < commands.length; ++i) {
out.println(commands[i]);
}
out.flush();
out.close();
} catch (IOException ex) {
throw new BuildException("saving command stream to " + temporaryCommandFile, ex);
}

String newCommandLine[] = new String[2];
newCommandLine[0] = commands[0];
newCommandLine[1] = "@" + temporaryCommandFile.getAbsolutePath();
executable.setCommandline(newCommandLine);
} }
} }




+ 8
- 0
src/testcases/org/apache/tools/ant/taskdefs/optional/DotnetTest.java View File

@@ -157,5 +157,13 @@ public class DotnetTest extends BuildFileTest {
public void testJsharp() throws Exception { public void testJsharp() throws Exception {
executeTarget("jsharp"); executeTarget("jsharp");
} }

/**
* test we can handle jsharp (if found)
*/
public void testResponseFile() throws Exception {
executeTarget("testCSCresponseFile");
}

} }



Loading…
Cancel
Save