git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@1350904 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -58,6 +58,14 @@ Other changes: | |||||
| * <bunzip2> will now properly expand files created by pbzip2 and | * <bunzip2> will now properly expand files created by pbzip2 and | ||||
| similar tools that create files with multiple bzip2 streams. | similar tools that create files with multiple bzip2 streams. | ||||
| * <tar> now supports a new "posix" option for longfile-mode which | |||||
| will make it create PAX extension headers for long file names. PAX | |||||
| extension headers are supported by all modern implementations of | |||||
| tar including GNU tar. | |||||
| This option should now be used in preference to "warn" or "gnu" as | |||||
| it is more portable. For backwards compatibility reasons "warn" | |||||
| will still create "gnu" extensions rather than "posix" extensions. | |||||
| Changes from Ant 1.8.3 TO Ant 1.8.4 | Changes from Ant 1.8.3 TO Ant 1.8.4 | ||||
| =================================== | =================================== | ||||
| @@ -43,23 +43,43 @@ to be applied to the tar entries. This is useful, for example, when preparing ar | |||||
| for directories.</p> | for directories.</p> | ||||
| <p>Early versions of tar did not support path lengths greater than 100 | <p>Early versions of tar did not support path lengths greater than 100 | ||||
| characters. Modern versions of tar do so, but in incompatible ways. | |||||
| The behaviour of the tar task when it encounters such paths is | |||||
| controlled by the <i>longfile</i> attribute. | |||||
| characters. Over time several incompatible extensions have been | |||||
| developed until a new POSIX standard was created that added so | |||||
| called PAX extension headers (as the pax utility first introduced | |||||
| them) that among another things addressed file names longer than 100 | |||||
| characters. All modern implementations of tar support PAX extension | |||||
| headers.</p> | |||||
| <p>Ant's tar support predates the standard with PAX extension headers, | |||||
| it supports different dialects that can be enabled using the | |||||
| <i>longfile</i> attribute. | |||||
| If the longfile attribute is set to <code>fail</code>, any long paths will | If the longfile attribute is set to <code>fail</code>, any long paths will | ||||
| cause the tar task to fail. If the longfile attribute is set to | cause the tar task to fail. If the longfile attribute is set to | ||||
| <code>truncate</code>, any long paths will be truncated to the 100 character | <code>truncate</code>, any long paths will be truncated to the 100 character | ||||
| maximum length prior to adding to the archive. If the value of the longfile | maximum length prior to adding to the archive. If the value of the longfile | ||||
| attribute is set to <code>omit</code> then files containing long paths will be | attribute is set to <code>omit</code> then files containing long paths will be | ||||
| omitted from the archive. Either option ensures that the archive can be | omitted from the archive. Either option ensures that the archive can be | ||||
| untarred by any compliant version of tar. If the loss of path or file | |||||
| untarred by any compliant version of tar.</p> | |||||
| <p>If the loss of path or file | |||||
| information is not acceptable, and it rarely is, longfile may be set to the | information is not acceptable, and it rarely is, longfile may be set to the | ||||
| value <code>gnu</code>. The tar task will then produce a GNU tar file which | |||||
| value <code>gnu</code> or <code>posix</code>. With <code>posix</code> | |||||
| Ant will add PAX extension headers, with <code>gnu</code> it adds | |||||
| GNU tar specific extensions that newer versions of GNU tar call | |||||
| "oldgnu". GNU tar still creates these extensions by default but | |||||
| supports PAX extension headers as well. Either choice will produce | |||||
| a tar file which | |||||
| can have arbitrary length paths. Note however, that the resulting archive will | can have arbitrary length paths. Note however, that the resulting archive will | ||||
| only be able to be untarred with GNU tar. The default for the longfile | |||||
| only be able to be untarred with tar tools that support the chosen format. | |||||
| <p>The default for the longfile | |||||
| attribute is <code>warn</code> which behaves just like the gnu option except | attribute is <code>warn</code> which behaves just like the gnu option except | ||||
| that it produces a warning for each file path encountered that does not match | that it produces a warning for each file path encountered that does not match | ||||
| the limit.</p> | |||||
| the limit. It uses gnu rather than posix for backwards compatibility | |||||
| reasons.</p> | |||||
| <p>To achivieve best interoperability you should use | |||||
| either <code>fail</code> or <code>posix</code> for the longfile attribute.</p> | |||||
| <p>This task can perform compression by setting the compression attribute to "gzip" | <p>This task can perform compression by setting the compression attribute to "gzip" | ||||
| or "bzip2".</p> | or "bzip2".</p> | ||||
| @@ -85,7 +105,7 @@ or "bzip2".</p> | |||||
| <td valign="top">longfile</td> | <td valign="top">longfile</td> | ||||
| <td valign="top">Determines how long files (>100 chars) are to be | <td valign="top">Determines how long files (>100 chars) are to be | ||||
| handled. Allowable values are "truncate", "fail", | handled. Allowable values are "truncate", "fail", | ||||
| "warn", "omit" and "gnu". Default is | |||||
| "warn", "omit", "gnu" and "posix". Default is | |||||
| "warn".</td> | "warn".</td> | ||||
| <td valign="top" align="center">No</td> | <td valign="top" align="center">No</td> | ||||
| </tr> | </tr> | ||||
| @@ -198,7 +198,8 @@ public class Tar extends MatchingTask { | |||||
| * <li> truncate - paths are truncated to the maximum length | * <li> truncate - paths are truncated to the maximum length | ||||
| * <li> fail - paths greater than the maximum cause a build exception | * <li> fail - paths greater than the maximum cause a build exception | ||||
| * <li> warn - paths greater than the maximum cause a warning and GNU is used | * <li> warn - paths greater than the maximum cause a warning and GNU is used | ||||
| * <li> gnu - GNU extensions are used for any paths greater than the maximum. | |||||
| * <li> gnu - extensions used by older versions of GNU tar are used for any paths greater than the maximum. | |||||
| * <li> posix - use POSIX PAX extension headers for any paths greater than the maximum. Supported by all modern tar implementations. | |||||
| * <li> omit - paths greater than the maximum are omitted from the archive | * <li> omit - paths greater than the maximum are omitted from the archive | ||||
| * </ul> | * </ul> | ||||
| * @param mode the mode to handle long file names. | * @param mode the mode to handle long file names. | ||||
| @@ -299,6 +300,8 @@ public class Tar extends MatchingTask { | |||||
| } else if (longFileMode.isFailMode() | } else if (longFileMode.isFailMode() | ||||
| || longFileMode.isOmitMode()) { | || longFileMode.isOmitMode()) { | ||||
| tOut.setLongFileMode(TarOutputStream.LONGFILE_ERROR); | tOut.setLongFileMode(TarOutputStream.LONGFILE_ERROR); | ||||
| } else if (longFileMode.isPosixMode()) { | |||||
| tOut.setLongFileMode(TarOutputStream.LONGFILE_POSIX); | |||||
| } else { | } else { | ||||
| // warn or GNU | // warn or GNU | ||||
| tOut.setLongFileMode(TarOutputStream.LONGFILE_GNU); | tOut.setLongFileMode(TarOutputStream.LONGFILE_GNU); | ||||
| @@ -844,9 +847,12 @@ public class Tar extends MatchingTask { | |||||
| FAIL = "fail", | FAIL = "fail", | ||||
| TRUNCATE = "truncate", | TRUNCATE = "truncate", | ||||
| GNU = "gnu", | GNU = "gnu", | ||||
| POSIX = "posix", | |||||
| OMIT = "omit"; | OMIT = "omit"; | ||||
| private final String[] validModes = {WARN, FAIL, TRUNCATE, GNU, OMIT}; | |||||
| private final String[] validModes = { | |||||
| WARN, FAIL, TRUNCATE, GNU, POSIX, OMIT | |||||
| }; | |||||
| /** Constructor, defaults to "warn" */ | /** Constructor, defaults to "warn" */ | ||||
| public TarLongFileMode() { | public TarLongFileMode() { | ||||
| @@ -895,6 +901,13 @@ public class Tar extends MatchingTask { | |||||
| public boolean isOmitMode() { | public boolean isOmitMode() { | ||||
| return OMIT.equalsIgnoreCase(getValue()); | return OMIT.equalsIgnoreCase(getValue()); | ||||
| } | } | ||||
| /** | |||||
| * @return true if value is "posix". | |||||
| */ | |||||
| public boolean isPosixMode() { | |||||
| return POSIX.equalsIgnoreCase(getValue()); | |||||
| } | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -90,4 +90,29 @@ | |||||
| </tar> | </tar> | ||||
| <au:assertDestIsOutofdate src="${output}/foo.tar" dest="${output}/bar.tar"/> | <au:assertDestIsOutofdate src="${output}/foo.tar" dest="${output}/bar.tar"/> | ||||
| </target> | </target> | ||||
| <target name="-longfileSetup" depends="setUp"> | |||||
| <property name="longfile.dir.name" | |||||
| value="this/path/name/contains/more/than/one/hundred/characters/in/order/to/test/the/GNU/and/POSIX/long/file/name/capability/round"/> | |||||
| <property name="longfile.file.name" | |||||
| value="${longfile.dir.name}/tripped"/> | |||||
| <mkdir dir="${input}/${longfile.dir.name}"/> | |||||
| <touch file="${input}/${longfile.file.name}"/> | |||||
| </target> | |||||
| <target name="testLongfileGNU" depends="-longfileSetup"> | |||||
| <tar destfile="${output}/x.tar" longfile="gnu"> | |||||
| <fileset dir="${input}"/> | |||||
| </tar> | |||||
| <untar dest="${output}" src="${output}/x.tar"/> | |||||
| <au:assertFileExists file="${output}/${longfile.file.name}"/> | |||||
| </target> | |||||
| <target name="testLongfilePOSIX" depends="-longfileSetup"> | |||||
| <tar destfile="${output}/x.tar" longfile="posix"> | |||||
| <fileset dir="${input}"/> | |||||
| </tar> | |||||
| <untar dest="${output}" src="${output}/x.tar"/> | |||||
| <au:assertFileExists file="${output}/${longfile.file.name}"/> | |||||
| </target> | |||||
| </project> | </project> | ||||
| @@ -35,7 +35,18 @@ public class TarRoundTripTest extends TestCase { | |||||
| /** | /** | ||||
| * test round-tripping long (GNU) entries | * test round-tripping long (GNU) entries | ||||
| */ | */ | ||||
| public void testLongRoundTripping() throws IOException { | |||||
| public void testLongRoundTrippingGNU() throws IOException { | |||||
| testLongRoundTripping(TarOutputStream.LONGFILE_GNU); | |||||
| } | |||||
| /** | |||||
| * test round-tripping long (POSIX) entries | |||||
| */ | |||||
| public void testLongRoundTrippingPOSIX() throws IOException { | |||||
| testLongRoundTripping(TarOutputStream.LONGFILE_POSIX); | |||||
| } | |||||
| private void testLongRoundTripping(int mode) throws IOException { | |||||
| TarEntry original = new TarEntry(LONG_NAME); | TarEntry original = new TarEntry(LONG_NAME); | ||||
| assertTrue("over 100 chars", LONG_NAME.length() > 100); | assertTrue("over 100 chars", LONG_NAME.length() > 100); | ||||
| assertEquals("original name", LONG_NAME, original.getName()); | assertEquals("original name", LONG_NAME, original.getName()); | ||||
| @@ -43,7 +54,7 @@ public class TarRoundTripTest extends TestCase { | |||||
| ByteArrayOutputStream buff = new ByteArrayOutputStream(); | ByteArrayOutputStream buff = new ByteArrayOutputStream(); | ||||
| TarOutputStream tos = new TarOutputStream(buff); | TarOutputStream tos = new TarOutputStream(buff); | ||||
| tos.setLongFileMode(TarOutputStream.LONGFILE_GNU); | |||||
| tos.setLongFileMode(mode); | |||||
| tos.putNextEntry(original); | tos.putNextEntry(original); | ||||
| tos.closeEntry(); | tos.closeEntry(); | ||||
| tos.close(); | tos.close(); | ||||