You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@ant.apache.org by bo...@apache.org on 2021/09/25 11:10:17 UTC

[ant] branch 1.9.x updated: Merge branch 'feature/tarfileset-preserve-symlinks' of https://github.com/mstrap/ant into mstrap-feature/tarfileset-preserve-symlinks

This is an automated email from the ASF dual-hosted git repository.

bodewig pushed a commit to branch 1.9.x
in repository https://gitbox.apache.org/repos/asf/ant.git


The following commit(s) were added to refs/heads/1.9.x by this push:
     new 0f110ea  Merge branch 'feature/tarfileset-preserve-symlinks' of https://github.com/mstrap/ant into mstrap-feature/tarfileset-preserve-symlinks
0f110ea is described below

commit 0f110eac27c17cf3bdbcfee77bc5b9b4aead9f4e
Author: Stefan Bodewig <bo...@apache.org>
AuthorDate: Sat Sep 25 12:45:23 2021 +0200

    Merge branch 'feature/tarfileset-preserve-symlinks' of https://github.com/mstrap/ant into mstrap-feature/tarfileset-preserve-symlinks
---
 WHATSNEW                                           |   6 +++++
 src/etc/testcases/taskdefs/tar.xml                 |   8 +++++++
 src/etc/testcases/testtarwithsymlinks.tar.gz       | Bin 0 -> 199 bytes
 src/main/org/apache/tools/ant/taskdefs/Tar.java    |  24 +++++++++++++++-----
 .../tools/ant/types/resources/TarResource.java     |  21 +++++++++++++++++
 src/main/org/apache/tools/tar/TarEntry.java        |  20 +++++++++++++++++
 .../org/apache/tools/ant/taskdefs/TarTest.java     |  25 +++++++++++++++++++++
 7 files changed, 98 insertions(+), 6 deletions(-)

diff --git a/WHATSNEW b/WHATSNEW
index f3f9ddf..7ad9c45 100644
--- a/WHATSNEW
+++ b/WHATSNEW
@@ -9,6 +9,12 @@ Fixed bugs:
    the shorter alias names.
    Bugzilla Report 65539
 
+Other changes:
+--------------
+
+ * The tar task now preserves symlinks of nested tarfilesets.
+   Github Pull Request #142
+
 Changes from Ant 1.9.15 TO Ant 1.9.16
 =====================================
 
diff --git a/src/etc/testcases/taskdefs/tar.xml b/src/etc/testcases/taskdefs/tar.xml
index 2eda0b5..e76b7ad 100644
--- a/src/etc/testcases/taskdefs/tar.xml
+++ b/src/etc/testcases/taskdefs/tar.xml
@@ -197,4 +197,12 @@
     <untar src="${output}/testout/test.tar" dest="${output}/untar"/>
   </target>
 
+  <target name="testTarFilesetWithSymlinks">
+    <gunzip src="../testtarwithsymlinks.tar.gz" dest="${output}/source.tar"/>
+    <tar destfile="${output}/result.tar">
+      <tarfileset prefix="pre" src="${output}/source.tar"/>
+    </tar>
+    <echo message="asd ${output}"/>
+  </target>
+
 </project>
diff --git a/src/etc/testcases/testtarwithsymlinks.tar.gz b/src/etc/testcases/testtarwithsymlinks.tar.gz
new file mode 100644
index 0000000..782a237
Binary files /dev/null and b/src/etc/testcases/testtarwithsymlinks.tar.gz differ
diff --git a/src/main/org/apache/tools/ant/taskdefs/Tar.java b/src/main/org/apache/tools/ant/taskdefs/Tar.java
index 0d319d1..1ab2d33 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Tar.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Tar.java
@@ -412,12 +412,7 @@ public class Tar extends MatchingTask {
                     return;
                 }
 
-                String prefix = tarFileSet.getPrefix(this.getProject());
-                // '/' is appended for compatibility with the zip task.
-                if (prefix.length() > 0 && !prefix.endsWith("/")) {
-                    prefix = prefix + "/";
-                }
-                vPath = prefix + vPath;
+                vPath = getCanonicalPrefix(tarFileSet, this.getProject()) + vPath;
             }
 
             preserveLeadingSlashes = tarFileSet.getPreserveLeadingSlashes();
@@ -469,6 +464,14 @@ public class Tar extends MatchingTask {
                 te.setUserId(tr.getUid());
                 te.setGroupName(tr.getGroup());
                 te.setGroupId(tr.getGid());
+                String linkName = tr.getLinkName();
+                byte linkFlag = tr.getLinkFlag();
+                if (linkFlag == TarConstants.LF_LINK &&
+                    linkName != null && linkName.length() > 0 && !linkName.startsWith("/")) {
+                    linkName = getCanonicalPrefix(tarFileSet, this.getProject()) + linkName;
+                }
+                te.setLinkName(linkName);
+                te.setLinkFlag(linkFlag);
             }
         }
 
@@ -799,6 +802,15 @@ public class Tar extends MatchingTask {
         return tfs;
     }
 
+    private static String getCanonicalPrefix(TarFileSet tarFileSet, Project project) {
+        String prefix = tarFileSet.getPrefix(project);
+        // '/' is appended for compatibility with the zip task.
+        if (prefix.isEmpty() || prefix.endsWith("/")) {
+            return prefix;
+        }
+        return prefix += "/";
+    }
+
     /**
      * This is a FileSet with the option to specify permissions
      * and other attributes.
diff --git a/src/main/org/apache/tools/ant/types/resources/TarResource.java b/src/main/org/apache/tools/ant/types/resources/TarResource.java
index b906a65..3011406 100644
--- a/src/main/org/apache/tools/ant/types/resources/TarResource.java
+++ b/src/main/org/apache/tools/ant/types/resources/TarResource.java
@@ -26,6 +26,7 @@ import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.Project;
 import org.apache.tools.ant.types.Resource;
 import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.tar.TarConstants;
 import org.apache.tools.tar.TarEntry;
 import org.apache.tools.tar.TarInputStream;
 
@@ -39,6 +40,8 @@ public class TarResource extends ArchiveResource {
     private String groupName = "";
     private int    uid;
     private int    gid;
+    private byte   linkFlag = TarConstants.LF_NORMAL;
+    private String linkName = "";
 
     /**
      * Default constructor.
@@ -153,6 +156,22 @@ public class TarResource extends ArchiveResource {
     }
 
     /**
+     * @return the link "name" (=path) of this entry; an empty string if this is no link
+     * @since 1.9.17
+     */
+    public String getLinkName() {
+        return linkName;
+    }
+
+    /**
+     * @return the link "flag" (=type) of this entry
+     * @since 1.9.17
+     */
+    public byte getLinkFlag() {
+        return linkFlag;
+    }
+
+    /**
      * fetches information from the named entry inside the archive.
      */
     protected void fetchEntry() {
@@ -191,6 +210,8 @@ public class TarResource extends ArchiveResource {
         groupName = e.getGroupName();
         uid = e.getUserId();
         gid = e.getGroupId();
+        linkName = e.getLinkName();
+        linkFlag = e.getLinkFlag();
     }
 
 }
diff --git a/src/main/org/apache/tools/tar/TarEntry.java b/src/main/org/apache/tools/tar/TarEntry.java
index afdd951..af0db02 100644
--- a/src/main/org/apache/tools/tar/TarEntry.java
+++ b/src/main/org/apache/tools/tar/TarEntry.java
@@ -399,6 +399,26 @@ public class TarEntry implements TarConstants {
     }
 
     /**
+     * Get this entry's link flag.
+     *
+     * @return This entry's link flag.
+     * @since 1.9.17
+     */
+    public byte getLinkFlag() {
+        return linkFlag;
+    }
+
+    /**
+     * Set this entry's link flag.
+     *
+     * @param link the link flag to use.
+     * @since 1.9.17
+     */
+    public void setLinkFlag(byte linkFlag) {
+        this.linkFlag = linkFlag;
+    }
+
+    /**
      * Get this entry's link name.
      *
      * @return This entry's link name.
diff --git a/src/tests/junit/org/apache/tools/ant/taskdefs/TarTest.java b/src/tests/junit/org/apache/tools/ant/taskdefs/TarTest.java
index 9650dfc..f747c42 100644
--- a/src/tests/junit/org/apache/tools/ant/taskdefs/TarTest.java
+++ b/src/tests/junit/org/apache/tools/ant/taskdefs/TarTest.java
@@ -20,16 +20,20 @@ package org.apache.tools.ant.taskdefs;
 
 import java.io.IOException;
 import java.io.File;
+import java.io.FileInputStream;
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.BuildFileRule;
 import org.apache.tools.ant.FileUtilities;
+import org.apache.tools.tar.TarEntry;
+import org.apache.tools.tar.TarInputStream;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.fail;
+import static org.junit.Assert.assertNull;
 
 public class TarTest {
 
@@ -206,5 +210,26 @@ public class TarTest {
                 FileUtilities.getFileContents(new File(buildRule.getProject().getProperty("output"), "untar/asf-logo.gif.gz")));
     }
 
+    @Test
+    public void testTarFilesetWithSymlinks() throws IOException {
+        buildRule.executeTarget("testTarFilesetWithSymlinks");
+        final File f = new File(buildRule.getProject().getProperty("output"), "result.tar");
+        final TarInputStream tis = new TarInputStream(new FileInputStream(f));
+        try {
+            final TarEntry e1 = tis.getNextEntry();
+            assertEquals("pre/dir/file", e1.getName());
+            assertEquals("", e1.getLinkName());
+            assertEquals(48, e1.getLinkFlag());
+
+            final TarEntry e2 = tis.getNextEntry();
+            assertEquals("pre/sub/file", e2.getName());
+            assertEquals("../dir/file", e2.getLinkName());
+            assertEquals(50, e2.getLinkFlag());
 
+            assertNull(tis.getNextEntry());
+        }
+        finally {
+            tis.close();
+        }
+    }
 }