ant-notifications mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bode...@apache.org
Subject svn commit: r942752 - in /ant/core/trunk: ./ docs/manual/CoreTasks/ src/main/org/apache/tools/ant/taskdefs/ src/main/org/apache/tools/ant/util/ src/tests/antunit/taskdefs/
Date Mon, 10 May 2010 14:35:56 GMT
Author: bodewig
Date: Mon May 10 14:35:56 2010
New Revision: 942752

URL: http://svn.apache.org/viewvc?rev=942752&view=rev
Log:
be consistent when it comes to overwriting read-only files, add an option to do just that
to <copy>.  PR 49261

Modified:
    ant/core/trunk/WHATSNEW
    ant/core/trunk/docs/manual/CoreTasks/copy.html
    ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/Copy.java
    ant/core/trunk/src/main/org/apache/tools/ant/util/FileUtils.java
    ant/core/trunk/src/main/org/apache/tools/ant/util/ResourceUtils.java
    ant/core/trunk/src/tests/antunit/taskdefs/copy-test.xml

Modified: ant/core/trunk/WHATSNEW
URL: http://svn.apache.org/viewvc/ant/core/trunk/WHATSNEW?rev=942752&r1=942751&r2=942752&view=diff
==============================================================================
--- ant/core/trunk/WHATSNEW (original)
+++ ant/core/trunk/WHATSNEW Mon May 10 14:35:56 2010
@@ -4,6 +4,15 @@ Changes from Ant 1.8.1 TO current SVN ve
 Changes that could break older environments:
 -------------------------------------------
 
+ * Prior to Ant 1.8.0 the <copy> task would overwrite read-only
+   destination files.  Starting with 1.8.0 it would only do so if
+   under special circumstances.  Ant 1.8.2 now consistently won't
+   replace a read-only file by default. The same is true for a number
+   of other tasks.
+   The <copy> task now has a new force attribute that can be used to
+   make the task overwrite read-only destinations.
+   Bugzilla Report 49261.
+
 Fixed bugs:
 -----------
 

Modified: ant/core/trunk/docs/manual/CoreTasks/copy.html
URL: http://svn.apache.org/viewvc/ant/core/trunk/docs/manual/CoreTasks/copy.html?rev=942752&r1=942751&r2=942752&view=diff
==============================================================================
--- ant/core/trunk/docs/manual/CoreTasks/copy.html (original)
+++ ant/core/trunk/docs/manual/CoreTasks/copy.html Mon May 10 14:35:56 2010
@@ -90,6 +90,12 @@ operation as <a href="../CoreTypes/filte
     <td valign="top" align="center">No; defaults to false.</td>
   </tr>
   <tr>
+    <td valign="top">force</td>
+    <td valign="top">Overwrite read-only destination
+      files.  <em>since Ant 1.8.2</em></td>
+    <td valign="top" align="center">No; defaults to false.</td>
+  </tr>
+  <tr>
     <td valign="top">filtering</td>
     <td valign="top">Indicates whether token filtering using the <a href="../using.html#filters">global
         build-file filters</a> should take place during the copy.

Modified: ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/Copy.java
URL: http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/Copy.java?rev=942752&r1=942751&r2=942752&view=diff
==============================================================================
--- ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/Copy.java (original)
+++ ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/Copy.java Mon May 10 14:35:56 2010
@@ -100,6 +100,7 @@ public class Copy extends Task {
     private String inputEncoding = null;
     private String outputEncoding = null;
     private long granularity = 0;
+    private boolean force = false;
 
     /**
      * Copy task constructor.
@@ -229,6 +230,17 @@ public class Copy extends Task {
     }
 
     /**
+     * Whether read-only destinations will be overwritten.
+     *
+     * <p>Defaults to false</p>
+     *
+     * @since Ant 1.8.2
+     */
+    public void setForce(boolean f) {
+        force = f;
+    }
+
+    /**
      * Set whether files copied from directory trees will be "flattened"
      * into a single directory.  If there are multiple files with
      * the same name in the source directory tree, only the first
@@ -838,10 +850,13 @@ public class Copy extends Task {
                             executionFilters
                                 .addFilterSet((FilterSet) filterEnum.nextElement());
                         }
-                        fileUtils.copyFile(fromFile, toFile, executionFilters,
+                        fileUtils.copyFile(new File(fromFile), new File(toFile),
+                                           executionFilters,
                                            filterChains, forceOverwrite,
-                                           preserveLastModified, inputEncoding,
-                                           outputEncoding, getProject());
+                                           preserveLastModified,
+                                           /* append: */ false, inputEncoding,
+                                           outputEncoding, getProject(),
+                                           force);
                     } catch (IOException ioe) {
                         String msg = "Failed to copy " + fromFile + " to " + toFile
                             + " due to " + getDueTo(ioe);
@@ -928,9 +943,11 @@ public class Copy extends Task {
                                                    filterChains,
                                                    forceOverwrite,
                                                    preserveLastModified,
+                                                   /* append: */ false,
                                                    inputEncoding,
                                                    outputEncoding,
-                                                   getProject());
+                                                   getProject(),
+                                                   force);
                     } catch (IOException ioe) {
                         String msg = "Failed to copy " + fromResource
                             + " to " + toFile

Modified: ant/core/trunk/src/main/org/apache/tools/ant/util/FileUtils.java
URL: http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/util/FileUtils.java?rev=942752&r1=942751&r2=942752&view=diff
==============================================================================
--- ant/core/trunk/src/main/org/apache/tools/ant/util/FileUtils.java (original)
+++ ant/core/trunk/src/main/org/apache/tools/ant/util/FileUtils.java Mon May 10 14:35:56 2010
@@ -513,12 +513,55 @@ public class FileUtils {
      */
     public void copyFile(File sourceFile, File destFile,
                          FilterSetCollection filters, Vector filterChains,
-                         boolean overwrite, boolean preserveLastModified, boolean append,
+                         boolean overwrite, boolean preserveLastModified,
+                         boolean append,
                          String inputEncoding, String outputEncoding,
                          Project project) throws IOException {
-        ResourceUtils.copyResource(new FileResource(sourceFile), new FileResource(destFile),
-                filters, filterChains, overwrite, preserveLastModified, append, inputEncoding,
-                outputEncoding, project);
+        copyFile(sourceFile, destFile, filters, filterChains, overwrite,
+                 preserveLastModified, append, inputEncoding, outputEncoding,
+                 project, /* force: */ false);
+    }
+
+    /**
+     * Convenience method to copy a file from a source to a
+     * destination specifying if token filtering must be used, if
+     * filter chains must be used, if source files may overwrite
+     * newer destination files and the last modified time of
+     * <code>destFile</code> file should be made equal
+     * to the last modified time of <code>sourceFile</code>.
+     *
+     * @param sourceFile the file to copy from.
+     *                   Must not be <code>null</code>.
+     * @param destFile the file to copy to.
+     *                 Must not be <code>null</code>.
+     * @param filters the collection of filters to apply to this copy.
+     * @param filterChains filterChains to apply during the copy.
+     * @param overwrite Whether or not the destination file should be
+     *                  overwritten if it already exists.
+     * @param preserveLastModified Whether or not the last modified time of
+     *                             the resulting file should be set to that
+     *                             of the source file.
+     * @param append whether to append to the destination file.
+     * @param inputEncoding the encoding used to read the files.
+     * @param outputEncoding the encoding used to write the files.
+     * @param project the project instance.
+     * @param force whether to overwrite read-only destination files.
+     *
+     * @throws IOException if the copying fails.
+     *
+     * @since Ant 1.8.2
+     */
+    public void copyFile(File sourceFile, File destFile,
+                         FilterSetCollection filters, Vector filterChains,
+                         boolean overwrite, boolean preserveLastModified,
+                         boolean append,
+                         String inputEncoding, String outputEncoding,
+                         Project project, boolean force) throws IOException {
+        ResourceUtils.copyResource(new FileResource(sourceFile),
+                                   new FileResource(destFile),
+                                   filters, filterChains, overwrite,
+                                   preserveLastModified, append, inputEncoding,
+                                   outputEncoding, project, force);
     }
 
     // CheckStyle:ParameterNumberCheck ON

Modified: ant/core/trunk/src/main/org/apache/tools/ant/util/ResourceUtils.java
URL: http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/util/ResourceUtils.java?rev=942752&r1=942751&r2=942752&view=diff
==============================================================================
--- ant/core/trunk/src/main/org/apache/tools/ant/util/ResourceUtils.java (original)
+++ ant/core/trunk/src/main/org/apache/tools/ant/util/ResourceUtils.java Mon May 10 14:35:56
2010
@@ -339,10 +339,51 @@ public class ResourceUtils {
      */
     public static void copyResource(Resource source, Resource dest,
                             FilterSetCollection filters, Vector filterChains,
-                            boolean overwrite, boolean preserveLastModified, boolean append,
+                            boolean overwrite, boolean preserveLastModified,
+                                    boolean append,
                             String inputEncoding, String outputEncoding,
                             Project project)
         throws IOException {
+        copyResource(source, dest, filters, filterChains, overwrite,
+                     preserveLastModified, append, inputEncoding,
+                     outputEncoding, project, /* force: */ false);
+    }
+
+    /**
+     * Convenience method to copy content from one Resource to another
+     * specifying whether token filtering must be used, whether filter chains
+     * must be used, whether newer destination files may be overwritten and
+     * whether the last modified time of <code>dest</code> file should be made
+     * equal to the last modified time of <code>source</code>.
+     *
+     * @param source the Resource to copy from.
+     *                   Must not be <code>null</code>.
+     * @param dest   the Resource to copy to.
+     *                 Must not be <code>null</code>.
+     * @param filters the collection of filters to apply to this copy.
+     * @param filterChains filterChains to apply during the copy.
+     * @param overwrite Whether or not the destination Resource should be
+     *                  overwritten if it already exists.
+     * @param preserveLastModified Whether or not the last modified time of
+     *                             the destination Resource should be set to that
+     *                             of the source.
+     * @param append Whether to append to an Appendable Resource.
+     * @param inputEncoding the encoding used to read the files.
+     * @param outputEncoding the encoding used to write the files.
+     * @param project the project instance.
+     * @param force whether read-only taret files will be overwritten
+     *
+     * @throws IOException if the copying fails.
+     *
+     * @since Ant 1.8.2
+     */
+    public static void copyResource(Resource source, Resource dest,
+                            FilterSetCollection filters, Vector filterChains,
+                            boolean overwrite, boolean preserveLastModified,
+                                    boolean append,
+                                    String inputEncoding, String outputEncoding,
+                                    Project project, boolean force)
+        throws IOException {
         if (!(overwrite || SelectorUtils.isOutOfDate(source, dest, FileUtils.getFileUtils()
                 .getFileTimestampGranularity()))) {
             return;
@@ -351,6 +392,21 @@ public class ResourceUtils {
                                              && filters.hasFilters());
         final boolean filterChainsAvailable = (filterChains != null
                                                && filterChains.size() > 0);
+
+        File destFile = null;
+        if (dest.as(FileProvider.class) != null) {
+            destFile = ((FileProvider) dest.as(FileProvider.class)).getFile();
+        }
+        if (destFile != null && destFile.isFile() && !destFile.canWrite())
{
+            if (!force) {
+                throw new IOException("can't write to read-only destination "
+                                      + "file " + destFile);
+            } else if (!FILE_UTILS.tryHardToDelete(destFile)) {
+                throw new IOException("failed to delete read-only "
+                                      + "destination file " + destFile);
+            }
+        }
+
         if (filterSetsAvailable) {
             BufferedReader in = null;
             BufferedWriter out = null;
@@ -444,11 +500,9 @@ public class ResourceUtils {
                 FileUtils.close(in);
             }
         } else if (source.as(FileProvider.class) != null
-                   && dest.as(FileProvider.class) != null) {
+                   && destFile != null) {
             File sourceFile =
                 ((FileProvider) source.as(FileProvider.class)).getFile();
-            File destFile =
-                ((FileProvider) dest.as(FileProvider.class)).getFile();
 
             File parent = destFile.getParentFile();
             if (parent != null && !parent.isDirectory()

Modified: ant/core/trunk/src/tests/antunit/taskdefs/copy-test.xml
URL: http://svn.apache.org/viewvc/ant/core/trunk/src/tests/antunit/taskdefs/copy-test.xml?rev=942752&r1=942751&r2=942752&view=diff
==============================================================================
--- ant/core/trunk/src/tests/antunit/taskdefs/copy-test.xml (original)
+++ ant/core/trunk/src/tests/antunit/taskdefs/copy-test.xml Mon May 10 14:35:56 2010
@@ -314,18 +314,69 @@ public class NullByteStreamResource exte
     <attrib file="${output}/${file}" readonly="true"/>
   </target>
 
-  <target name="XtestCopyOverReadOnlyFile" depends="makeFileUnwritable">
+  <target name="testCopyOverReadOnlyFile" depends="makeFileUnwritable">
     <sleep seconds="2"/>
     <touch file="${input}/${file}"/>
-    <copy toDir="${output}">
+    <au:expectfailure
+        expectedMessage="can't write to read-only destination file ">
+      <copy toDir="${output}">
+        <fileset dir="${input}"/>
+      </copy>
+    </au:expectfailure>
+  </target>
+
+  <target name="testFilteredCopyOverReadOnlyFile" depends="makeFileUnwritable">
+    <sleep seconds="2"/>
+    <touch file="${input}/${file}"/>
+    <au:expectfailure
+        expectedMessage="can't write to read-only destination file ">
+      <copy toDir="${output}">
+        <fileset dir="${input}"/>
+        <filterset>
+          <filter token="foo" value="bar"/>
+        </filterset>
+      </copy>
+    </au:expectfailure>
+  </target>
+
+  <target name="testCopyOverReadOnlyFileWithOverwrite"
+          depends="makeFileUnwritable">
+    <touch file="${input}/${file}"/>
+    <au:expectfailure
+        expectedMessage="can't write to read-only destination file ">
+      <copy toDir="${output}" overwrite="true">
+        <fileset dir="${input}"/>
+      </copy>
+    </au:expectfailure>
+  </target>
+
+  <target name="testFilteredCopyOverReadOnlyFileWithOverwrite"
+          depends="makeFileUnwritable">
+    <touch file="${input}/${file}"/>
+    <au:expectfailure
+        expectedMessage="can't write to read-only destination file ">
+      <copy toDir="${output}" overwrite="true">
+        <fileset dir="${input}"/>
+        <filterset>
+          <filter token="foo" value="bar"/>
+        </filterset>
+      </copy>
+    </au:expectfailure>
+  </target>
+
+  <target name="testForcedCopyOverReadOnlyFile" depends="makeFileUnwritable">
+    <sleep seconds="2"/>
+    <touch file="${input}/${file}"/>
+    <copy toDir="${output}" force="true">
       <fileset dir="${input}"/>
     </copy>
   </target>
 
-  <target name="testFilteredCopyOverReadOnlyFile" depends="makeFileUnwritable">
+  <target name="testForcedFilteredCopyOverReadOnlyFile"
+          depends="makeFileUnwritable">
     <sleep seconds="2"/>
     <touch file="${input}/${file}"/>
-    <copy toDir="${output}">
+    <copy toDir="${output}" force="true">
       <fileset dir="${input}"/>
       <filterset>
         <filter token="foo" value="bar"/>
@@ -333,18 +384,18 @@ public class NullByteStreamResource exte
     </copy>
   </target>
 
-  <target name="XtestCopyOverReadOnlyFileWithOverwrite"
+  <target name="testForcedCopyOverReadOnlyFileWithOverwrite"
           depends="makeFileUnwritable">
     <touch file="${input}/${file}"/>
-    <copy toDir="${output}" overwrite="true">
+    <copy toDir="${output}" overwrite="true" force="true">
       <fileset dir="${input}"/>
     </copy>
   </target>
 
-  <target name="testFilteredCopyOverReadOnlyFileWithOverwrite"
+  <target name="testForcedFilteredCopyOverReadOnlyFileWithOverwrite"
           depends="makeFileUnwritable">
     <touch file="${input}/${file}"/>
-    <copy toDir="${output}" overwrite="true">
+    <copy toDir="${output}" overwrite="true" force="true">
       <fileset dir="${input}"/>
       <filterset>
         <filter token="foo" value="bar"/>



Mime
View raw message