IVY-1594 Make sure FileUtil#symlink handles symlinking of directories correctly
authorJaikiran Pai <jaikiran@apache.org>
Tue, 23 Oct 2018 06:03:16 +0000 (11:33 +0530)
committerJaikiran Pai <jaikiran@apache.org>
Tue, 23 Oct 2018 06:03:47 +0000 (11:33 +0530)
src/java/org/apache/ivy/util/FileUtil.java
test/java/org/apache/ivy/core/retrieve/RetrieveTest.java
test/repositories/1/org1/mod1.1/ivys/ivy-3.0.xml [new file with mode: 0644]
test/repositories/1/org1/mod1.1/jars/zipped-artifact-3.0.zip [new file with mode: 0644]

index 5963d4e..2968708 100644 (file)
@@ -77,8 +77,20 @@ public final class FileUtil {
      */
     public static boolean symlink(final File target, final File link, final boolean overwrite)
             throws IOException {
-        if (!prepareCopy(target, link, overwrite)) {
-            return false;
+        // prepare for symlink
+        if (target.isFile()) {
+            // it's a file that is being symlinked, so do the necessary preparation
+            // for the linking, similar to what we do with preparation for copying
+            if (!prepareCopy(target, link, overwrite)) {
+                return false;
+            }
+        } else {
+            // it's a directory being symlinked, make sure the "link" that is being
+            // created has the necessary parent directories in place before triggering
+            // symlink creation
+            if (link.getParentFile() != null) {
+                link.getParentFile().mkdirs();
+            }
         }
         Files.createSymbolicLink(link.toPath(), target.getAbsoluteFile().toPath());
         return true;
index f5b18af..239cd36 100644 (file)
@@ -27,6 +27,7 @@ import org.apache.ivy.core.event.retrieve.EndRetrieveEvent;
 import org.apache.ivy.core.event.retrieve.StartRetrieveArtifactEvent;
 import org.apache.ivy.core.event.retrieve.StartRetrieveEvent;
 import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
+import org.apache.ivy.core.module.id.ModuleId;
 import org.apache.ivy.core.module.id.ModuleRevisionId;
 import org.apache.ivy.core.report.ArtifactDownloadReport;
 import org.apache.ivy.core.report.ResolveReport;
@@ -255,6 +256,32 @@ public class RetrieveTest {
     }
 
     /**
+     * Tests that retrieve, when invoked with "symlink" enabled, creates the necessary symlink
+     * when the artifact being retrieved is a directory instead of a regular file
+     *
+     * @throws Exception
+     * @see <a href="https://issues.apache.org/jira/browse/IVY-1594">IVY-1594</a>
+     */
+    @Test
+    public void testRetrieveZipArtifactWithSymlinks() throws Exception {
+        // resolve (inline) with org1:mod1.1:3.0 as a dependency
+        final ResolveReport report = ivy.resolve(new ModuleRevisionId(new ModuleId("org1", "mod1.1"), "3.0"),
+                getResolveOptions(new String[]{"*"}), false);
+        assertNotNull("Resolution report is null", report);
+        final ModuleDescriptor md = report.getModuleDescriptor();
+        assertNotNull("Module descriptor is null", md);
+
+        final String retrievePattern = "build/test/retrieve/[module]/[conf]/[artifact]-[revision]";
+        ivy.retrieve(md.getModuleRevisionId(),
+                getRetrieveOptions().setMakeSymlinks(true).setDestArtifactPattern(retrievePattern));
+
+        final String expectedRetrieveLocation = IvyPatternHelper.substitute(retrievePattern, "org1", "mod1.1",
+                "3.0", "zipped-artifact", null, null, "default");
+        // make sure it's retrieved as a symlink (on systems that support symlink)
+        assertLinkOrExists(expectedRetrieveLocation);
+    }
+
+    /**
      * This test is here to just test the deprecated {@code symlinkmass} option for retrieve task.
      * A version or two down the line, after 2.5 release, we can remove this test and the option
      * altogether.
diff --git a/test/repositories/1/org1/mod1.1/ivys/ivy-3.0.xml b/test/repositories/1/org1/mod1.1/ivys/ivy-3.0.xml
new file mode 100644 (file)
index 0000000..373ca31
--- /dev/null
@@ -0,0 +1,25 @@
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one or more
+  ~ contributor license agreements.  See the NOTICE file distributed with
+  ~ this work for additional information regarding copyright ownership.
+  ~ The ASF licenses this file to You under the Apache License, Version 2.0
+  ~ (the "License"); you may not use this file except in compliance with
+  ~ the License.  You may obtain a copy of the License at
+  ~
+  ~    http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<ivy-module version="1.0">
+    <info organisation="org1"
+          module="mod1.1"
+          revision="3.0"
+    />
+    <publications>
+        <artifact name="zipped-artifact" packaging="zip" ext="zip"/>
+    </publications>
+</ivy-module>
diff --git a/test/repositories/1/org1/mod1.1/jars/zipped-artifact-3.0.zip b/test/repositories/1/org1/mod1.1/jars/zipped-artifact-3.0.zip
new file mode 100644 (file)
index 0000000..df0b4ca
Binary files /dev/null and b/test/repositories/1/org1/mod1.1/jars/zipped-artifact-3.0.zip differ