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(); | ||||