From c0eecc68bbb2cfaa9d6b87479a7466df68928a3a Mon Sep 17 00:00:00 2001 From: Steve Loughran Date: Fri, 24 Oct 2003 05:53:13 +0000 Subject: [PATCH] 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 --- WHATSNEW | 3 + .../testcases/taskdefs/optional/dotnet.xml | 25 +++++ .../optional/dotnet/DotnetCompile.java | 27 +++++ .../ant/taskdefs/optional/dotnet/JSharp.java | 2 +- .../taskdefs/optional/dotnet/NetCommand.java | 102 +++++++++++++++++- .../ant/taskdefs/optional/DotnetTest.java | 8 ++ 6 files changed, 165 insertions(+), 2 deletions(-) diff --git a/WHATSNEW b/WHATSNEW index 0a885507c..579368f7d 100644 --- a/WHATSNEW +++ b/WHATSNEW @@ -277,6 +277,9 @@ Fixed bugs: * s only worked when defined inside of tasks. Bugzilla Report 20965. + +* and siblings ( ) handle large filesets by +automatic use of response files. Bugzilla report #19630 Other changes: -------------- diff --git a/src/etc/testcases/taskdefs/optional/dotnet.xml b/src/etc/testcases/taskdefs/optional/dotnet.xml index c8f4c1759..a3111f6e1 100644 --- a/src/etc/testcases/taskdefs/optional/dotnet.xml +++ b/src/etc/testcases/taskdefs/optional/dotnet.xml @@ -101,6 +101,16 @@ + + + + + + + + + + @@ -334,6 +344,21 @@ + + + + + + No app ${testCSCresponseFile.exe} created + + + diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/dotnet/DotnetCompile.java b/src/main/org/apache/tools/ant/taskdefs/optional/dotnet/DotnetCompile.java index a9636828f..85c311241 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/dotnet/DotnetCompile.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/dotnet/DotnetCompile.java @@ -205,6 +205,11 @@ public abstract class DotnetCompile */ 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 @@ -796,6 +801,25 @@ public abstract class DotnetCompile 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 @@ -806,6 +830,9 @@ public abstract class DotnetCompile throws BuildException { validate(); NetCommand command = createNetCommand(); + //set up response file options + command.setAutomaticResponseFileThreshold(AUTOMATIC_RESPONSE_FILE_THRESHOLD); + command.setUseResponseFile(useResponseFile); //fill in args fillInSharedParameters(command); addResources(command); diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/dotnet/JSharp.java b/src/main/org/apache/tools/ant/taskdefs/optional/dotnet/JSharp.java index a23d6b3f6..344e22f80 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/dotnet/JSharp.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/dotnet/JSharp.java @@ -69,7 +69,7 @@ import org.apache.tools.ant.BuildException; * * @author Steve Loughran * @since ant1.6 - * @ant.task category="dotnet" + * @ant.task category="dotnet" name="jsharpc" */ public class JSharp extends DotnetCompile { diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/dotnet/NetCommand.java b/src/main/org/apache/tools/ant/taskdefs/optional/dotnet/NetCommand.java index 64badbe35..f5a9122b7 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/dotnet/NetCommand.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/dotnet/NetCommand.java @@ -65,12 +65,17 @@ package org.apache.tools.ant.taskdefs.optional.dotnet; import java.io.File; 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 org.apache.tools.ant.BuildException; import org.apache.tools.ant.Project; import org.apache.tools.ant.Task; 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.ExecuteStreamHandler; import org.apache.tools.ant.taskdefs.LogStreamHandler; @@ -130,6 +135,21 @@ public class NetCommand { */ 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 * @@ -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.. */ @@ -272,7 +324,7 @@ public class NetCommand { //in verbose mode we always log stuff logVerbose(commandLine.describeCommand()); } - executable.setCommandline(commandLine.getCommandline()); + setExecutableCommandLine(); err = executable.execute(); if (Execute.isFailure(err)) { if (failOnError) { @@ -283,6 +335,54 @@ public class NetCommand { } } catch (IOException e) { 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); } } diff --git a/src/testcases/org/apache/tools/ant/taskdefs/optional/DotnetTest.java b/src/testcases/org/apache/tools/ant/taskdefs/optional/DotnetTest.java index 47857cec1..c454f8ad9 100644 --- a/src/testcases/org/apache/tools/ant/taskdefs/optional/DotnetTest.java +++ b/src/testcases/org/apache/tools/ant/taskdefs/optional/DotnetTest.java @@ -157,5 +157,13 @@ public class DotnetTest extends BuildFileTest { public void testJsharp() throws Exception { executeTarget("jsharp"); } + + /** + * test we can handle jsharp (if found) + */ + public void testResponseFile() throws Exception { + executeTarget("testCSCresponseFile"); + } + }