git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@692081 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -196,6 +196,10 @@ Fixed bugs: | |||||
| contained line feeds some excess output ended up in Ant's log. | contained line feeds some excess output ended up in Ant's log. | ||||
| Bugzilla Report 45411. | Bugzilla Report 45411. | ||||
| * <symlink action="delete"> failed to delete a link that pointed to | |||||
| a parent directory. | |||||
| Bugzilla Report 45743. | |||||
| Other changes: | Other changes: | ||||
| -------------- | -------------- | ||||
| @@ -386,13 +386,19 @@ public class Symlink extends DispatchTask { | |||||
| * <p>This is a utility method that removes a unix symlink without removing | * <p>This is a utility method that removes a unix symlink without removing | ||||
| * the resource that the symlink points to. If it is accidentally invoked | * the resource that the symlink points to. If it is accidentally invoked | ||||
| * on a real file, the real file will not be harmed, but an exception | * on a real file, the real file will not be harmed, but an exception | ||||
| * will be thrown when the deletion is attempted. This method works by | |||||
| * will be thrown when the deletion is attempted.</p> | |||||
| * | |||||
| * <p>Normaly this method works by | |||||
| * getting the canonical path of the link, using the canonical path to | * getting the canonical path of the link, using the canonical path to | ||||
| * rename the resource (breaking the link) and then deleting the link. | * rename the resource (breaking the link) and then deleting the link. | ||||
| * The resource is then returned to its original name inside a finally | * The resource is then returned to its original name inside a finally | ||||
| * block to ensure that the resource is unharmed even in the event of | * block to ensure that the resource is unharmed even in the event of | ||||
| * an exception.</p> | * an exception.</p> | ||||
| * | * | ||||
| * <p>There may be cases where the algorithm described above doesn't work, | |||||
| * in that case the method tries to use the native "rm" command on | |||||
| * the symlink instead.</p> | |||||
| * | |||||
| * <p>Since Ant 1.8.0 this method will try to delete the File object if | * <p>Since Ant 1.8.0 this method will try to delete the File object if | ||||
| * it reports it wouldn't exist (as symlinks pointing nowhere usually do). | * it reports it wouldn't exist (as symlinks pointing nowhere usually do). | ||||
| * Prior version would throw a FileNotFoundException in that case.</p> | * Prior version would throw a FileNotFoundException in that case.</p> | ||||
| @@ -410,12 +416,22 @@ public class Symlink extends DispatchTask { | |||||
| linkfil.delete(); | linkfil.delete(); | ||||
| return; | return; | ||||
| } | } | ||||
| // find the resource of the existing link: | // find the resource of the existing link: | ||||
| File canfil = linkfil.getCanonicalFile(); | File canfil = linkfil.getCanonicalFile(); | ||||
| // rename the resource, thus breaking the link: | // rename the resource, thus breaking the link: | ||||
| File temp = FILE_UTILS.createTempFile("symlink", ".tmp", | File temp = FILE_UTILS.createTempFile("symlink", ".tmp", | ||||
| canfil.getParentFile(), false, false); | |||||
| canfil.getParentFile(), false, | |||||
| false); | |||||
| if (FILE_UTILS.isLeadingPath(canfil, linkfil)) { | |||||
| // link points to a parent directory, renaming the parent | |||||
| // will rename the file | |||||
| linkfil = new File(temp, | |||||
| FILE_UTILS.removeLeadingPath(canfil, linkfil)); | |||||
| } | |||||
| try { | try { | ||||
| try { | try { | ||||
| FILE_UTILS.rename(canfil, temp); | FILE_UTILS.rename(canfil, temp); | ||||
| @@ -81,9 +81,7 @@ | |||||
| <copy todir="${output}"> | <copy todir="${output}"> | ||||
| <fileset dir="${base}" followsymlinks="true"/> | <fileset dir="${base}" followsymlinks="true"/> | ||||
| </copy> | </copy> | ||||
| <exec executable="rm"> | |||||
| <arg file="${base}/A"/> | |||||
| </exec> | |||||
| <symlink action="delete" link="${base}/A"/> | |||||
| <au:assertFileExists file="${output}/A/B/file.txt"/> | <au:assertFileExists file="${output}/A/B/file.txt"/> | ||||
| </target> | </target> | ||||
| @@ -95,9 +93,7 @@ | |||||
| <include name="A/B/*"/> | <include name="A/B/*"/> | ||||
| </fileset> | </fileset> | ||||
| </copy> | </copy> | ||||
| <exec executable="rm"> | |||||
| <arg file="${base}/A"/> | |||||
| </exec> | |||||
| <symlink action="delete" link="${base}/A"/> | |||||
| <au:assertFileExists file="${output}/A/B/file.txt"/> | <au:assertFileExists file="${output}/A/B/file.txt"/> | ||||
| </target> | </target> | ||||
| @@ -110,9 +106,7 @@ | |||||
| <include name="A/base/A/B/*"/> | <include name="A/base/A/B/*"/> | ||||
| </fileset> | </fileset> | ||||
| </copy> | </copy> | ||||
| <exec executable="rm"> | |||||
| <arg file="${base}/A"/> | |||||
| </exec> | |||||
| <symlink action="delete" link="${base}/A"/> | |||||
| <au:assertFileExists file="${output}/A/base/A/B/file.txt"/> | <au:assertFileExists file="${output}/A/base/A/B/file.txt"/> | ||||
| </target> | </target> | ||||
| @@ -122,9 +116,7 @@ | |||||
| <copy todir="${output}"> | <copy todir="${output}"> | ||||
| <fileset dir="${base}" followsymlinks="false"/> | <fileset dir="${base}" followsymlinks="false"/> | ||||
| </copy> | </copy> | ||||
| <exec executable="rm"> | |||||
| <arg file="${base}/A"/> | |||||
| </exec> | |||||
| <symlink action="delete" link="${base}/A"/> | |||||
| <au:assertFileDoesntExist file="${output}/A/B/file.txt"/> | <au:assertFileDoesntExist file="${output}/A/B/file.txt"/> | ||||
| </target> | </target> | ||||
| @@ -134,9 +126,7 @@ | |||||
| <copy todir="${output}"> | <copy todir="${output}"> | ||||
| <fileset dir="${base}" followsymlinks="true"/> | <fileset dir="${base}" followsymlinks="true"/> | ||||
| </copy> | </copy> | ||||
| <exec executable="rm"> | |||||
| <arg file="${base}"/> | |||||
| </exec> | |||||
| <symlink action="delete" link="${base}"/> | |||||
| <assertDirIsEmpty/> | <assertDirIsEmpty/> | ||||
| </target> | </target> | ||||
| @@ -146,9 +136,7 @@ | |||||
| <copy todir="${output}"> | <copy todir="${output}"> | ||||
| <fileset dir="${base}" followsymlinks="false"/> | <fileset dir="${base}" followsymlinks="false"/> | ||||
| </copy> | </copy> | ||||
| <exec executable="rm"> | |||||
| <arg file="${base}"/> | |||||
| </exec> | |||||
| <symlink action="delete" link="${base}"/> | |||||
| <assertDirIsEmpty/> | <assertDirIsEmpty/> | ||||
| </target> | </target> | ||||
| @@ -69,4 +69,10 @@ | |||||
| <au:assertFileDoesntExist file="${output}/link"/> | <au:assertFileDoesntExist file="${output}/link"/> | ||||
| </target> | </target> | ||||
| <target name="testDeleteLinkToParent" depends="init" if="unix"> | |||||
| <symlink link="${output}/link" resource="${output}"/> | |||||
| <symlink link="${output}/link" action="delete"/> | |||||
| <au:assertFileDoesntExist file="${output}/link"/> | |||||
| </target> | |||||
| </project> | </project> | ||||