Browse Source

Add a longfile='posix' option to tar task

git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@1350904 13f79535-47bb-0310-9956-ffa450edef68
master
Stefan Bodewig 13 years ago
parent
commit
ca10b52e34
5 changed files with 89 additions and 12 deletions
  1. +8
    -0
      WHATSNEW
  2. +28
    -8
      manual/Tasks/tar.html
  3. +15
    -2
      src/main/org/apache/tools/ant/taskdefs/Tar.java
  4. +25
    -0
      src/tests/antunit/taskdefs/tar-test.xml
  5. +13
    -2
      src/tests/junit/org/apache/tools/tar/TarRoundTripTest.java

+ 8
- 0
WHATSNEW View File

@@ -58,6 +58,14 @@ Other changes:
* <bunzip2> will now properly expand files created by pbzip2 and
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
===================================



+ 28
- 8
manual/Tasks/tar.html View File

@@ -43,23 +43,43 @@ to be applied to the tar entries. This is useful, for example, when preparing ar
for directories.</p>

<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
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
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
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
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
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
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"
or "bzip2".</p>
@@ -85,7 +105,7 @@ or "bzip2".</p>
<td valign="top">longfile</td>
<td valign="top">Determines how long files (&gt;100 chars) are to be
handled. Allowable values are &quot;truncate&quot;, &quot;fail&quot;,
&quot;warn&quot;, &quot;omit&quot; and &quot;gnu&quot;. Default is
&quot;warn&quot;, &quot;omit&quot;, &quot;gnu&quot; and &quot;posix&quot;. Default is
&quot;warn&quot;.</td>
<td valign="top" align="center">No</td>
</tr>


+ 15
- 2
src/main/org/apache/tools/ant/taskdefs/Tar.java View File

@@ -198,7 +198,8 @@ public class Tar extends MatchingTask {
* <li> truncate - paths are truncated to the maximum length
* <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> 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
* </ul>
* @param mode the mode to handle long file names.
@@ -299,6 +300,8 @@ public class Tar extends MatchingTask {
} else if (longFileMode.isFailMode()
|| longFileMode.isOmitMode()) {
tOut.setLongFileMode(TarOutputStream.LONGFILE_ERROR);
} else if (longFileMode.isPosixMode()) {
tOut.setLongFileMode(TarOutputStream.LONGFILE_POSIX);
} else {
// warn or GNU
tOut.setLongFileMode(TarOutputStream.LONGFILE_GNU);
@@ -844,9 +847,12 @@ public class Tar extends MatchingTask {
FAIL = "fail",
TRUNCATE = "truncate",
GNU = "gnu",
POSIX = "posix",
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" */
public TarLongFileMode() {
@@ -895,6 +901,13 @@ public class Tar extends MatchingTask {
public boolean isOmitMode() {
return OMIT.equalsIgnoreCase(getValue());
}

/**
* @return true if value is "posix".
*/
public boolean isPosixMode() {
return POSIX.equalsIgnoreCase(getValue());
}
}

/**


+ 25
- 0
src/tests/antunit/taskdefs/tar-test.xml View File

@@ -90,4 +90,29 @@
</tar>
<au:assertDestIsOutofdate src="${output}/foo.tar" dest="${output}/bar.tar"/>
</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>

+ 13
- 2
src/tests/junit/org/apache/tools/tar/TarRoundTripTest.java View File

@@ -35,7 +35,18 @@ public class TarRoundTripTest extends TestCase {
/**
* 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);
assertTrue("over 100 chars", LONG_NAME.length() > 100);
assertEquals("original name", LONG_NAME, original.getName());
@@ -43,7 +54,7 @@ public class TarRoundTripTest extends TestCase {

ByteArrayOutputStream buff = new ByteArrayOutputStream();
TarOutputStream tos = new TarOutputStream(buff);
tos.setLongFileMode(TarOutputStream.LONGFILE_GNU);
tos.setLongFileMode(mode);
tos.putNextEntry(original);
tos.closeEntry();
tos.close();


Loading…
Cancel
Save