PR: 22863 git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@276806 13f79535-47bb-0310-9956-ffa450edef68master
@@ -42,7 +42,10 @@ Other changes: | |||
wsdl run on mono, as well as most of the .NET WSE2.0 options. Extra | |||
schemas (files or urls) can be named in the <schema> element. | |||
Compilers can be selected using the compiler attribute, which defaults | |||
to "microsoft" on windows, and "mono" on everything else. | |||
to "microsoft" on windows, and "mono" on everything else. | |||
* Allow file attribute of <move> to rename a directory. | |||
Bugzilla Report 22863. | |||
Changes from Ant 1.6.2 to current Ant 1.6 CVS version | |||
===================================================== | |||
@@ -16,6 +16,10 @@ turned off, then files are only moved if the source file is newer than | |||
the destination file, or when the destination file does not exist.</p> | |||
<p><a href="../CoreTypes/fileset.html">FileSet</a>s are used to select sets of files | |||
to move to the <var>todir</var> directory.</p> | |||
<p><b>Since Ant 1.6.3</b>, the <i>file</i> attribute may be used to move | |||
(rename) an entire directory. If <i>tofile</i> denotes an existing file, or | |||
there is a directory by the same name in <i>todir</i>, the action will fail. | |||
</p> | |||
<h3>Parameters</h3> | |||
<table border="1" cellpadding="2" cellspacing="0"> | |||
<tr> | |||
@@ -25,7 +29,7 @@ to move to the <var>todir</var> directory.</p> | |||
</tr> | |||
<tr> | |||
<td valign="top">file</td> | |||
<td valign="top">the file to move</td> | |||
<td valign="top">the file or directory to move</td> | |||
<td valign="top" align="center">One of <var>file</var> or | |||
at least one nested fileset element</td> | |||
</tr> | |||
@@ -78,7 +82,7 @@ to move to the <var>todir</var> directory.</p> | |||
</tr> | |||
<tr> | |||
<td valign="top">failonerror</td> | |||
<td valign="top">Log a warning message, but do not stop the | |||
<td valign="top">If false, log a warning message, but do not stop the | |||
build, when the file to copy does not exist or one of the nested | |||
filesets points to a directory that doesn't exist or an error occurs | |||
while moving. | |||
@@ -154,6 +158,10 @@ followed by <filterset> elements. | |||
<move todir="new/dir/to/move/to"> | |||
<fileset dir="src/dir"/> | |||
</move> | |||
</pre> | |||
<i>or, since Ant 1.6.3:</i> | |||
<pre> | |||
<move file="src/dir" tofile="new/dir/to/move/to" /> | |||
</pre> | |||
<p><b>Move a set of files to a new directory</b></p> | |||
<pre> | |||
@@ -59,11 +59,78 @@ | |||
</move> | |||
</target> | |||
<target name="testCompleteDirectoryMoveFileToFile"> | |||
<mkdir dir="A"/> | |||
<touch file="A/1"/> | |||
<move file="A" tofile="E" /> | |||
<fail message="E/1 not available"> | |||
<condition> | |||
<not> | |||
<available file="E/1" type="file" /> | |||
</not> | |||
</condition> | |||
</fail> | |||
<fail message="A remains"> | |||
<condition> | |||
<available file="A" type="dir" /> | |||
</condition> | |||
</fail> | |||
</target> | |||
<target name="testCompleteDirectoryMoveFileToDir"> | |||
<mkdir dir="A"/> | |||
<touch file="A/1"/> | |||
<move file="A" todir="E" /> | |||
<fail message="E/A/1 not available"> | |||
<condition> | |||
<not> | |||
<available file="E/A/1" type="file" /> | |||
</not> | |||
</condition> | |||
</fail> | |||
<fail message="A remains"> | |||
<condition> | |||
<available file="A" type="dir" /> | |||
</condition> | |||
</fail> | |||
</target> | |||
<target name="testCompleteDirectoryMoveFileToExistingFile"> | |||
<mkdir dir="A"/> | |||
<touch file="A/1"/> | |||
<touch file="B"/> | |||
<move file="A" tofile="B" /> | |||
</target> | |||
<target name="testCompleteDirectoryMoveFileToExistingDir"> | |||
<mkdir dir="A"/> | |||
<touch file="A/1"/> | |||
<mkdir dir="E"/> | |||
<move file="A" tofile="E" /> | |||
</target> | |||
<target name="testCompleteDirectoryMoveFileToDirWithExistingFile"> | |||
<mkdir dir="A"/> | |||
<touch file="A/1"/> | |||
<mkdir dir="E"/> | |||
<touch file="E/A"/> | |||
<move file="A" todir="E" /> | |||
</target> | |||
<target name="testCompleteDirectoryMoveFileToDirWithExistingDir"> | |||
<mkdir dir="A"/> | |||
<touch file="A/1"/> | |||
<mkdir dir="E"/> | |||
<mkdir dir="E/A"/> | |||
<move file="A" todir="E" /> | |||
</target> | |||
<target name="cleanup"> | |||
<delete file="move.filterset.tmp"/> | |||
<delete file="move.filterchain.tmp"/> | |||
<delete dir="A"/> | |||
<delete dir="E"/> | |||
<delete dir="A" /> | |||
<delete file="B" /> | |||
<delete dir="E" /> | |||
</target> | |||
</project> |
@@ -61,6 +61,58 @@ public class Move extends Copy { | |||
setOverwrite(true); | |||
} | |||
/** | |||
* Performs the move operation. | |||
*/ | |||
public void execute() throws BuildException { | |||
if (file != null && file.isDirectory()) { | |||
if (destFile != null && destDir != null) { | |||
throw new BuildException("Only one of tofile and todir " | |||
+ "may be set."); | |||
} | |||
if (destFile == null && destDir == null) { | |||
throw new BuildException("One of tofile or todir must be set."); | |||
} | |||
destFile = (destFile != null) | |||
? destFile : new File(destDir, file.getName()); | |||
try { | |||
boolean renamed = false; | |||
log("Moving directory " + file | |||
+ " to " + destFile, Project.MSG_INFO); | |||
try { | |||
renamed = | |||
renameFile(file, destFile, filtering, forceOverwrite); | |||
} catch (IOException eyeOhEx) { | |||
throw new BuildException(eyeOhEx.getMessage()); | |||
} | |||
if (!renamed) { | |||
StringBuffer buf = new StringBuffer( | |||
"Failed to move directory ").append( | |||
file.getAbsolutePath()); | |||
if ((getFilterChains() != null && getFilterChains().size() > 0) | |||
|| (getFilterSets() != null && getFilterSets().size() > 0) | |||
|| filtering) { | |||
buf.append( | |||
"; use a fileset to move directories with filtering"); | |||
} | |||
throw new BuildException(buf.append('.').toString()); | |||
} | |||
} catch (BuildException e) { | |||
if (!failonerror) { | |||
log("Warning: " + e.getMessage(), Project.MSG_ERR); | |||
} else { | |||
throw e; | |||
} | |||
} | |||
} else { | |||
super.execute(); | |||
} | |||
} | |||
//************************************************************************ | |||
// protected and private methods | |||
//************************************************************************ | |||
@@ -325,17 +377,19 @@ public class Move extends Copy { | |||
} else { | |||
if (!filtering) { | |||
// ensure that parent dir of dest file exists! | |||
// not using getParentFile method to stay 1.1 compatibility | |||
String parentPath = destFile.getParent(); | |||
if (parentPath != null) { | |||
File parent = new File(parentPath); | |||
if (!parent.exists()) { | |||
parent.mkdirs(); | |||
} | |||
File parent = destFile.getParentFile(); | |||
if (parent != null && !parent.exists()) { | |||
parent.mkdirs(); | |||
} | |||
if (destFile.exists() && destFile.isFile()) { | |||
if (!destFile.delete()) { | |||
if (destFile.exists()) { | |||
if (sourceFile.isDirectory()) { | |||
throw new BuildException( | |||
new StringBuffer("Cannot replace ").append( | |||
((destFile.isFile()) ? "file " : "directory ")).append( | |||
destFile).append(" with directory ").append( | |||
sourceFile).toString()); | |||
} else if (destFile.isFile() && !destFile.delete()) { | |||
throw new BuildException("Unable to remove existing " | |||
+ "file " + destFile); | |||
} | |||
@@ -88,4 +88,33 @@ public class MoveTest extends BuildFileTest { | |||
assertTrue(!getProject().resolveFile("A/1").exists()); | |||
assertTrue(!getProject().resolveFile("A").exists()); | |||
} | |||
public void testCompleteDirectoryMoveFileToFile() { | |||
executeTarget("testCompleteDirectoryMoveFileToFile"); | |||
} | |||
public void testCompleteDirectoryMoveFileToDir() { | |||
executeTarget("testCompleteDirectoryMoveFileToDir"); | |||
} | |||
public void testCompleteDirectoryMoveFileToExistingFile() { | |||
expectBuildExceptionContaining("testCompleteDirectoryMoveFileToExistingFile", | |||
"", "Cannot replace file"); | |||
} | |||
public void testCompleteDirectoryMoveFileToExistingDir() { | |||
expectBuildExceptionContaining("testCompleteDirectoryMoveFileToExistingDir", | |||
"", "Cannot replace directory"); | |||
} | |||
public void testCompleteDirectoryMoveFileToDirWithExistingFile() { | |||
expectBuildExceptionContaining("testCompleteDirectoryMoveFileToDirWithExistingFile", | |||
"", "Cannot replace file"); | |||
} | |||
public void testCompleteDirectoryMoveFileToDirWithExistingDir() { | |||
expectBuildExceptionContaining("testCompleteDirectoryMoveFileToDirWithExistingDir", | |||
"", "Cannot replace directory"); | |||
} | |||
} |