Browse Source

Make <move> behave consistently for read-only destinations. PR 49261

git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@943056 13f79535-47bb-0310-9956-ffa450edef68
master
Stefan Bodewig 15 years ago
parent
commit
508bb0dae1
5 changed files with 145 additions and 10 deletions
  1. +7
    -7
      WHATSNEW
  2. +6
    -0
      docs/manual/CoreTasks/move.html
  3. +11
    -2
      src/main/org/apache/tools/ant/taskdefs/Copy.java
  4. +14
    -1
      src/main/org/apache/tools/ant/taskdefs/Move.java
  5. +107
    -0
      src/tests/antunit/taskdefs/move-test.xml

+ 7
- 7
WHATSNEW View File

@@ -4,13 +4,13 @@ Changes from Ant 1.8.1 TO current SVN version
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.
* Prior to Ant 1.8.0 the <copy> task and several other tasks 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> and <move> task now have a new force attribute that can
be used to make the task overwrite read-only destinations.
Bugzilla Report 49261.

Fixed bugs:


+ 6
- 0
docs/manual/CoreTasks/move.html View File

@@ -85,6 +85,12 @@ there is a directory by the same name in <i>todir</i>, the action will fail.
files are newer (default is &quot;true&quot;)</td>
<td valign="top" align="center">No</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 should take place during


+ 11
- 2
src/main/org/apache/tools/ant/taskdefs/Copy.java View File

@@ -240,6 +240,15 @@ public class Copy extends Task {
force = f;
}

/**
* Whether read-only destinations will be overwritten.
*
* @since Ant 1.8.2
*/
public boolean getForce() {
return force;
}

/**
* Set whether files copied from directory trees will be "flattened"
* into a single directory. If there are multiple files with
@@ -856,7 +865,7 @@ public class Copy extends Task {
preserveLastModified,
/* append: */ false, inputEncoding,
outputEncoding, getProject(),
force);
getForce());
} catch (IOException ioe) {
String msg = "Failed to copy " + fromFile + " to " + toFile
+ " due to " + getDueTo(ioe);
@@ -947,7 +956,7 @@ public class Copy extends Task {
inputEncoding,
outputEncoding,
getProject(),
force);
getForce());
} catch (IOException ioe) {
String msg = "Failed to copy " + fromResource
+ " to " + toFile


+ 14
- 1
src/main/org/apache/tools/ant/taskdefs/Move.java View File

@@ -233,9 +233,10 @@ public class Move extends Copy {
getFilterChains(),
forceOverwrite,
getPreserveLastModified(),
/* append: */ false,
getEncoding(),
getOutputEncoding(),
getProject());
getProject(), getForce());
} catch (IOException ioe) {
String msg = "Failed to copy " + fromFile
+ " to " + toFile + " due to " + ioe.getMessage();
@@ -329,6 +330,18 @@ public class Move extends Copy {
|| getFilterChains().size() > 0) {
return false;
}

// identical logic lives in ResourceUtils.copyResource():
if (destFile.isFile() && !destFile.canWrite()) {
if (!getForce()) {
throw new IOException("can't replace read-only destination "
+ "file " + destFile);
} else if (!getFileUtils().tryHardToDelete(destFile)) {
throw new IOException("failed to delete read-only "
+ "destination file " + destFile);
}
}

// identical logic lives in FileUtils.rename():
File parent = destFile.getParentFile();
if (parent != null && !parent.exists()) {


+ 107
- 0
src/tests/antunit/taskdefs/move-test.xml View File

@@ -124,4 +124,111 @@
value="Y"/>
</target>

<!-- stolen from ../types/readwrite-test.xml - create a read-only file -->
<property name="file" value="testfile"/>
<condition property="unix">
<os family="unix"/>
</condition>
<target name="createTestdir">
<mkdir dir="${output}"/>
<mkdir dir="${input}"/>
<touch file="${output}/${file}"/>
</target>
<target name="makeFileUnwritable"
depends="createTestdir,makeFileUnwritable-Unix,makeFileUnwritable-Windows"/>
<target name="makeFileUnwritable-Unix" id="unix">
<chmod file="${output}/${file}" perm="444"/>
</target>
<target name="makeFileUnwritable-Windows" unless="unix">
<attrib file="${output}/${file}" readonly="true"/>
</target>

<target name="testMoveOverReadOnlyFile" depends="makeFileUnwritable">
<sleep seconds="2"/>
<touch file="${input}/${file}"/>
<au:expectfailure
expectedMessage="can't replace read-only destination file ">
<move toDir="${output}">
<fileset dir="${input}"/>
</move>
</au:expectfailure>
</target>

<target name="testFilteredMoveOverReadOnlyFile" depends="makeFileUnwritable">
<sleep seconds="2"/>
<touch file="${input}/${file}"/>
<au:expectfailure
expectedMessage="can't write to read-only destination file ">
<move toDir="${output}">
<fileset dir="${input}"/>
<filterset>
<filter token="foo" value="bar"/>
</filterset>
</move>
</au:expectfailure>
</target>

<target name="testMoveOverReadOnlyFileWithOverwrite"
depends="makeFileUnwritable">
<touch file="${input}/${file}"/>
<au:expectfailure
expectedMessage="can't replace read-only destination file ">
<move toDir="${output}" overwrite="true">
<fileset dir="${input}"/>
</move>
</au:expectfailure>
</target>

<target name="testFilteredMoveOverReadOnlyFileWithOverwrite"
depends="makeFileUnwritable">
<touch file="${input}/${file}"/>
<au:expectfailure
expectedMessage="can't write to read-only destination file ">
<move toDir="${output}" overwrite="true">
<fileset dir="${input}"/>
<filterset>
<filter token="foo" value="bar"/>
</filterset>
</move>
</au:expectfailure>
</target>

<target name="testForcedMoveOverReadOnlyFile" depends="makeFileUnwritable">
<sleep seconds="2"/>
<touch file="${input}/${file}"/>
<move toDir="${output}" force="true">
<fileset dir="${input}"/>
</move>
</target>

<target name="testForcedFilteredMoveOverReadOnlyFile"
depends="makeFileUnwritable">
<sleep seconds="2"/>
<touch file="${input}/${file}"/>
<move toDir="${output}" force="true">
<fileset dir="${input}"/>
<filterset>
<filter token="foo" value="bar"/>
</filterset>
</move>
</target>

<target name="testForcedMoveOverReadOnlyFileWithOverwrite"
depends="makeFileUnwritable">
<touch file="${input}/${file}"/>
<move toDir="${output}" overwrite="true" force="true">
<fileset dir="${input}"/>
</move>
</target>

<target name="testForcedFilteredMoveOverReadOnlyFileWithOverwrite"
depends="makeFileUnwritable">
<touch file="${input}/${file}"/>
<move toDir="${output}" overwrite="true" force="true">
<fileset dir="${input}"/>
<filterset>
<filter token="foo" value="bar"/>
</filterset>
</move>
</target>
</project>

Loading…
Cancel
Save