You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@ant.apache.org by jh...@apache.org on 2017/06/13 13:11:37 UTC

[1/2] ant-ivy git commit: IVY-1475 Throw an error if a common base directory cannot be determined for cachefileset task

Repository: ant-ivy
Updated Branches:
  refs/heads/master c07d659cf -> 545536e34


IVY-1475 Throw an error if a common base directory cannot be determined for cachefileset task


Project: http://git-wip-us.apache.org/repos/asf/ant-ivy/repo
Commit: http://git-wip-us.apache.org/repos/asf/ant-ivy/commit/7f293a06
Tree: http://git-wip-us.apache.org/repos/asf/ant-ivy/tree/7f293a06
Diff: http://git-wip-us.apache.org/repos/asf/ant-ivy/diff/7f293a06

Branch: refs/heads/master
Commit: 7f293a06a0b7ec9b554d51f150991efa9b7dd54e
Parents: c07d659
Author: Jaikiran Pai <ja...@gmail.com>
Authored: Fri Jun 2 16:57:36 2017 +0530
Committer: Jaikiran Pai <ja...@gmail.com>
Committed: Tue Jun 13 15:17:51 2017 +0530

----------------------------------------------------------------------
 doc/use/cachefileset.html                       |   8 +-
 .../org/apache/ivy/ant/IvyCacheFileset.java     | 120 ++++++++++++-------
 .../org/apache/ivy/ant/IvyCacheFilesetTest.java |  37 +++++-
 3 files changed, 120 insertions(+), 45 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/7f293a06/doc/use/cachefileset.html
----------------------------------------------------------------------
diff --git a/doc/use/cachefileset.html b/doc/use/cachefileset.html
index aeba54f..747db0d 100644
--- a/doc/use/cachefileset.html
+++ b/doc/use/cachefileset.html
@@ -32,7 +32,13 @@ Please prefer the use of retrieve + standard ant path creation, which make your
 more independent from ivy (once artifacts are properly retrieved, ivy is not required any more).<br/><br/>
 Built fileset is registered in ant with a given id, and can thus be used like any other ant fileset using
 refid.
-  
+
+<h2>Limitation</h2>
+A fileset, in Ant, requires a base directory from within which the files are included/excluded. The cachefileset task, in Ivy, internally tries to determine a common base directory across all the resolved artifacts' files that have been downloaded in the Ivy repository cache(s). Given that Ivy can be configured to consist multiple repository caches and each one can potentially be on a different filesystem root, there are times, when cachefileset cannot determine a common base directory for these resolved artifacts. The cachefileset throws an exception in such cases.
+
+<h2>Alternative task</h2>
+If cachefileset doesn't fit the need of your use case (maybe due to the limitations noted above), the [[use/resources]] task could be an alternative task to use in certain cases.
+
 <table class="ant">
 <thead>
     <tr><th class="ant-att">Attribute</th><th class="ant-desc">Description</th><th class="ant-req">Required</th></tr>

http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/7f293a06/src/java/org/apache/ivy/ant/IvyCacheFileset.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/ivy/ant/IvyCacheFileset.java b/src/java/org/apache/ivy/ant/IvyCacheFileset.java
index 9a60f2e..bc85eaf 100644
--- a/src/java/org/apache/ivy/ant/IvyCacheFileset.java
+++ b/src/java/org/apache/ivy/ant/IvyCacheFileset.java
@@ -60,35 +60,68 @@ public class IvyCacheFileset extends IvyCacheTask {
             throw new BuildException("setid is required in ivy cachefileset");
         }
         try {
-            List paths = getArtifactReports();
-            File base = null;
-            for (Iterator iter = paths.iterator(); iter.hasNext();) {
-                ArtifactDownloadReport a = (ArtifactDownloadReport) iter.next();
-                if (a.getLocalFile() != null) {
-                    base = getBaseDir(base, a.getLocalFile());
+            final List<ArtifactDownloadReport> artifactDownloadReports = getArtifactReports();
+            if (artifactDownloadReports.isEmpty()) {
+                // generate an empty fileset
+                final FileSet emptyFileSet = new EmptyFileSet();
+                emptyFileSet.setProject(getProject());
+                getProject().addReference(setid, emptyFileSet);
+                return;
+            }
+            // find a common base dir of the resolved artifacts
+            final File baseDir = this.requireCommonBaseDir(artifactDownloadReports);
+            final FileSet fileset = new FileSet();
+            fileset.setDir(baseDir);
+            fileset.setProject(getProject());
+            // enroll each of the artifact files into the fileset
+            for (final ArtifactDownloadReport artifactDownloadReport : artifactDownloadReports) {
+                if (artifactDownloadReport.getLocalFile() == null) {
+                    continue;
                 }
+                final NameEntry ne = fileset.createInclude();
+                ne.setName(getPath(baseDir, artifactDownloadReport.getLocalFile()));
             }
+            getProject().addReference(setid, fileset);
+        } catch (Exception ex) {
+            throw new BuildException("impossible to build ivy cache fileset: " + ex, ex);
+        }
+    }
 
-            FileSet fileset;
+    /**
+     * Returns a common base directory, determined from the {@link ArtifactDownloadReport#getLocalFile() local files} of the
+     * passed <code>artifactDownloadReports</code>. If no common base directory can be determined, this method throws a
+     * {@link BuildException}
+     *
+     * @param artifactDownloadReports The artifact download reports for which the common base directory of the artifacts
+     *                                has to be determined
+     * @return
+     */
+    private File requireCommonBaseDir(final List<ArtifactDownloadReport> artifactDownloadReports) {
+        File base = null;
+        for (final ArtifactDownloadReport artifactDownloadReport : artifactDownloadReports) {
+            if (artifactDownloadReport.getLocalFile() == null) {
+                continue;
+            }
             if (base == null) {
-                fileset = new EmptyFileSet();
+                // use the parent dir of the artifact as the base
+                base = artifactDownloadReport.getLocalFile().getParentFile().getAbsoluteFile();
             } else {
-                fileset = new FileSet();
-                fileset.setDir(base);
-                for (Iterator iter = paths.iterator(); iter.hasNext();) {
-                    ArtifactDownloadReport a = (ArtifactDownloadReport) iter.next();
-                    if (a.getLocalFile() != null) {
-                        NameEntry ne = fileset.createInclude();
-                        ne.setName(getPath(base, a.getLocalFile()));
-                    }
+                // try and find a common base directory between the current base
+                // directory and the artifact's file
+                base = getBaseDir(base, artifactDownloadReport.getLocalFile());
+                if (base == null) {
+                    // fail fast - we couldn't determine a common base directory, throw an error
+                    throw new BuildException("Cannot find a common base directory, from resolved artifacts, " +
+                            "for generating a cache fileset");
                 }
             }
-
-            fileset.setProject(getProject());
-            getProject().addReference(setid, fileset);
-        } catch (Exception ex) {
-            throw new BuildException("impossible to build ivy cache fileset: " + ex, ex);
         }
+        if (base == null) {
+            // finally, we couldn't determine a common base directory, throw an error
+            throw new BuildException("Cannot find a common base directory, from resolved artifacts, for generating " +
+                    "a cache fileset");
+        }
+        return base;
     }
 
     /**
@@ -115,34 +148,35 @@ public class IvyCacheFileset extends IvyCacheTask {
     }
 
     /**
-     * Returns the common base directory between a current base directory and a given file.
+     * Returns the common base directory between the passed <code>file1</code> and <code>file2</code>.
      * <p>
-     * The returned base directory must be a parent of both the current base and the given file.
+     * The returned base directory must be a parent of both the <code>file1</code> and <code>file2</code>.
      * </p>
      *
-     * @param base
-     *            the current base directory, may be null.
-     * @param file
-     *            the file for which the new base directory should be returned.
-     * @return the common base directory between a current base directory and a given file.
+     * @param file1
+     *            One of the files, for which the common base directory is being sought, may be null.
+     * @param file2
+     *            The other file for which the common base directory should be returned.
+     * @return the common base directory between a <code>file1</code> and <code>file2</code>. Returns null
+     *          if no common base directory could be determined or if either <code>file1</code> or <code>file2</code>
+     *          is null
      */
-    File getBaseDir(File base, File file) {
-        if (base == null) {
-            return file.getParentFile().getAbsoluteFile();
-        } else {
-            Iterator bases = getParents(base).iterator();
-            Iterator fileParents = getParents(file.getAbsoluteFile()).iterator();
-            File result = null;
-            while (bases.hasNext() && fileParents.hasNext()) {
-                File next = (File) bases.next();
-                if (next.equals(fileParents.next())) {
-                    result = next;
-                } else {
-                    break;
-                }
+    File getBaseDir(final File file1, final File file2) {
+        if (file1 == null || file2 == null) {
+            return null;
+        }
+        final Iterator bases = getParents(file1).iterator();
+        final Iterator fileParents = getParents(file2.getAbsoluteFile()).iterator();
+        File result = null;
+        while (bases.hasNext() && fileParents.hasNext()) {
+            File next = (File) bases.next();
+            if (next.equals(fileParents.next())) {
+                result = next;
+            } else {
+                break;
             }
-            return result;
         }
+        return result;
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/7f293a06/test/java/org/apache/ivy/ant/IvyCacheFilesetTest.java
----------------------------------------------------------------------
diff --git a/test/java/org/apache/ivy/ant/IvyCacheFilesetTest.java b/test/java/org/apache/ivy/ant/IvyCacheFilesetTest.java
index fb01916..dbb98f7 100644
--- a/test/java/org/apache/ivy/ant/IvyCacheFilesetTest.java
+++ b/test/java/org/apache/ivy/ant/IvyCacheFilesetTest.java
@@ -173,12 +173,47 @@ public class IvyCacheFilesetTest {
     public void testGetBaseDir() {
         File base = null;
         base = fileset.getBaseDir(base, new File("x/aa/b/c"));
-        assertEquals(new File("x/aa/b").getAbsoluteFile(), base);
+        assertNull("Base directory was expected to be null", base);
+
+        base = new File("x/aa/b/c").getParentFile().getAbsoluteFile();
 
         base = fileset.getBaseDir(base, new File("x/aa/b/d/e"));
         assertEquals(new File("x/aa/b").getAbsoluteFile(), base);
 
         base = fileset.getBaseDir(base, new File("x/ab/b/d"));
         assertEquals(new File("x").getAbsoluteFile(), base);
+
+        final File[] filesytemRoots = File.listRoots();
+        final File root1 = filesytemRoots[0];
+        final File file1 = new File(root1, "abcd/xyz");
+        final File file2 = new File(root1, "pqrs/xyz");
+        final File commonBase = fileset.getBaseDir(file1, file2);
+        assertEquals("Unexpected common base dir between '" + file1 + "' and '" + file2 + "'", root1.getAbsoluteFile(), commonBase.getAbsoluteFile());
+
+    }
+
+    /**
+     * Tests that the {@link IvyCacheFileset} fails with an exception if it can't determine a common base directory
+     * while dealing with cached artifacts
+     *
+     * @see <a href="https://issues.apache.org/jira/browse/IVY-1475">IVY-1475</a> for more details
+     */
+    @Test
+    public void testNoCommonBaseDir() {
+        final File[] fileSystemRoots = File.listRoots();
+        if (fileSystemRoots.length == 1) {
+            // single file system root isn't what we are interested in, in this test method
+            return;
+        }
+        // we expect a BuildException when we try to find a (non-existent) common base dir
+        // across file system roots
+        expExc.expect(BuildException.class);
+
+        final File root1 = fileSystemRoots[0];
+        final File root2 = fileSystemRoots[1];
+        final File fileOnRoot1 = new File(root1, "abc/file1");
+        final File fileOnRoot2 = new File(root2, "abc/file2");
+        fileset.getBaseDir(fileOnRoot1, fileOnRoot2);
+        fail("A BuildException was expected when trying to find a common base dir between '" + fileOnRoot1 + "' and '" + fileOnRoot2 + "'");
     }
 }


[2/2] ant-ivy git commit: - rename some derived variables according to their sources - javadoc improvement - more tests

Posted by jh...@apache.org.
- rename some derived variables according to their sources
- javadoc improvement
- more tests


Project: http://git-wip-us.apache.org/repos/asf/ant-ivy/repo
Commit: http://git-wip-us.apache.org/repos/asf/ant-ivy/commit/545536e3
Tree: http://git-wip-us.apache.org/repos/asf/ant-ivy/tree/545536e3
Diff: http://git-wip-us.apache.org/repos/asf/ant-ivy/diff/545536e3

Branch: refs/heads/master
Commit: 545536e34f180edd32fbb21b0a5613e6407f0980
Parents: 7f293a0
Author: Jan Matèrne <jh...@apache.org>
Authored: Tue Jun 13 15:11:01 2017 +0200
Committer: Jan Matèrne <jh...@apache.org>
Committed: Tue Jun 13 15:11:01 2017 +0200

----------------------------------------------------------------------
 .../org/apache/ivy/ant/IvyCacheFileset.java     | 21 ++---
 .../org/apache/ivy/ant/IvyCacheFilesetTest.java | 91 ++++++++++++++++----
 2 files changed, 83 insertions(+), 29 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/545536e3/src/java/org/apache/ivy/ant/IvyCacheFileset.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/ivy/ant/IvyCacheFileset.java b/src/java/org/apache/ivy/ant/IvyCacheFileset.java
index bc85eaf..fb526ad 100644
--- a/src/java/org/apache/ivy/ant/IvyCacheFileset.java
+++ b/src/java/org/apache/ivy/ant/IvyCacheFileset.java
@@ -96,7 +96,7 @@ public class IvyCacheFileset extends IvyCacheTask {
      *                                has to be determined
      * @return
      */
-    private File requireCommonBaseDir(final List<ArtifactDownloadReport> artifactDownloadReports) {
+    File requireCommonBaseDir(final List<ArtifactDownloadReport> artifactDownloadReports) {
         File base = null;
         for (final ArtifactDownloadReport artifactDownloadReport : artifactDownloadReports) {
             if (artifactDownloadReport.getLocalFile() == null) {
@@ -150,13 +150,14 @@ public class IvyCacheFileset extends IvyCacheTask {
     /**
      * Returns the common base directory between the passed <code>file1</code> and <code>file2</code>.
      * <p>
-     * The returned base directory must be a parent of both the <code>file1</code> and <code>file2</code>.
+     * The returned base directory will be a parent of both the <code>file1</code> and <code>file2</code> or
+     * it will be <code>null</code>.
      * </p>
      *
      * @param file1
      *            One of the files, for which the common base directory is being sought, may be null.
      * @param file2
-     *            The other file for which the common base directory should be returned.
+     *            The other file for which the common base directory should be returned, may be null.
      * @return the common base directory between a <code>file1</code> and <code>file2</code>. Returns null
      *          if no common base directory could be determined or if either <code>file1</code> or <code>file2</code>
      *          is null
@@ -165,12 +166,12 @@ public class IvyCacheFileset extends IvyCacheTask {
         if (file1 == null || file2 == null) {
             return null;
         }
-        final Iterator bases = getParents(file1).iterator();
-        final Iterator fileParents = getParents(file2.getAbsoluteFile()).iterator();
+        final Iterator file1Parents = getParents(file1).iterator();
+        final Iterator file2Parents = getParents(file2.getAbsoluteFile()).iterator();
         File result = null;
-        while (bases.hasNext() && fileParents.hasNext()) {
-            File next = (File) bases.next();
-            if (next.equals(fileParents.next())) {
+        while (file1Parents.hasNext() && file2Parents.hasNext()) {
+            File next = (File) file1Parents.next();
+            if (next.equals(file2Parents.next())) {
                 result = next;
             } else {
                 break;
@@ -182,8 +183,8 @@ public class IvyCacheFileset extends IvyCacheTask {
     /**
      * @return a list of files, starting with the root and ending with the file itself
      */
-    private LinkedList/* <File> */getParents(File file) {
-        LinkedList r = new LinkedList();
+    private LinkedList<File> getParents(File file) {
+        LinkedList<File> r = new LinkedList<>();
         while (file != null) {
             r.addFirst(file);
             file = file.getParentFile();

http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/545536e3/test/java/org/apache/ivy/ant/IvyCacheFilesetTest.java
----------------------------------------------------------------------
diff --git a/test/java/org/apache/ivy/ant/IvyCacheFilesetTest.java b/test/java/org/apache/ivy/ant/IvyCacheFilesetTest.java
index dbb98f7..b02c78c 100644
--- a/test/java/org/apache/ivy/ant/IvyCacheFilesetTest.java
+++ b/test/java/org/apache/ivy/ant/IvyCacheFilesetTest.java
@@ -18,8 +18,11 @@
 package org.apache.ivy.ant;
 
 import java.io.File;
+import java.util.Arrays;
+import java.util.List;
 
 import org.apache.ivy.TestHelper;
+import org.apache.ivy.core.report.ArtifactDownloadReport;
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.DirectoryScanner;
@@ -170,26 +173,30 @@ public class IvyCacheFilesetTest {
     }
 
     @Test
-    public void testGetBaseDir() {
-        File base = null;
-        base = fileset.getBaseDir(base, new File("x/aa/b/c"));
-        assertNull("Base directory was expected to be null", base);
+    public void getBaseDirCommonBaseDir() {
+        final File file1 = new File("x/aa/b/c").getParentFile().getAbsoluteFile();
+        final File file2 = new File("x/aa/b/d/e");
+        final File file3 = new File("x/ab/b/d");
 
-        base = new File("x/aa/b/c").getParentFile().getAbsoluteFile();
-
-        base = fileset.getBaseDir(base, new File("x/aa/b/d/e"));
+        // A common base deep inside the tree
+        File base = fileset.getBaseDir(file1, file2);
         assertEquals(new File("x/aa/b").getAbsoluteFile(), base);
 
-        base = fileset.getBaseDir(base, new File("x/ab/b/d"));
+        // A common base on top directory of the tree
+        base = fileset.getBaseDir(base, file3);
         assertEquals(new File("x").getAbsoluteFile(), base);
 
+        // A common base only on the fs-root.
         final File[] filesytemRoots = File.listRoots();
         final File root1 = filesytemRoots[0];
-        final File file1 = new File(root1, "abcd/xyz");
-        final File file2 = new File(root1, "pqrs/xyz");
-        final File commonBase = fileset.getBaseDir(file1, file2);
-        assertEquals("Unexpected common base dir between '" + file1 + "' and '" + file2 + "'", root1.getAbsoluteFile(), commonBase.getAbsoluteFile());
-
+        final File file4 = new File(root1, "abcd/xyz");
+        final File file5 = new File(root1, "pqrs/xyz");
+        final File commonBase = fileset.getBaseDir(file4, file5);
+        assertEquals(
+            "Unexpected common base dir between '" + file4 + "' and '" + file5 + "'",
+            root1.getAbsoluteFile(),
+            commonBase.getAbsoluteFile()
+        );
     }
 
     /**
@@ -199,21 +206,67 @@ public class IvyCacheFilesetTest {
      * @see <a href="https://issues.apache.org/jira/browse/IVY-1475">IVY-1475</a> for more details
      */
     @Test
-    public void testNoCommonBaseDir() {
+    public void getBaseDirNoCommonBaseDir() {
         final File[] fileSystemRoots = File.listRoots();
         if (fileSystemRoots.length == 1) {
             // single file system root isn't what we are interested in, in this test method
             return;
         }
-        // we expect a BuildException when we try to find a (non-existent) common base dir
-        // across file system roots
-        expExc.expect(BuildException.class);
 
         final File root1 = fileSystemRoots[0];
         final File root2 = fileSystemRoots[1];
         final File fileOnRoot1 = new File(root1, "abc/file1");
         final File fileOnRoot2 = new File(root2, "abc/file2");
-        fileset.getBaseDir(fileOnRoot1, fileOnRoot2);
-        fail("A BuildException was expected when trying to find a common base dir between '" + fileOnRoot1 + "' and '" + fileOnRoot2 + "'");
+        File base = fileset.getBaseDir(fileOnRoot1, fileOnRoot2);
+        assertNull(base);
+    }
+
+    @Test
+    public void getBaseDirNullValues() {
+        assertNull("Base directory was expected to be null", fileset.getBaseDir(null, new File("a")));
+        assertNull("Base directory was expected to be null", fileset.getBaseDir(new File("a"), null));
+    }
+
+    @Test
+    public void requireCommonBaseDirEmptyList() {
+        // we expect a BuildException when we try to find a (non-existent) common base dir
+        // across file system roots
+        expExc.expect(BuildException.class);
+        List<ArtifactDownloadReport> reports = Arrays.asList();
+        fileset.requireCommonBaseDir(reports);
+        fail("A BuildException was expected when trying to find a common base dir.");
+    }
+
+    @Test
+    public void requireCommonBaseDirNoCommon() {
+        final File[] fileSystemRoots = File.listRoots();
+        if (fileSystemRoots.length == 1) {
+            // single file system root isn't what we are interested in, in this test method
+            return;
+        }
+        // we expect a BuildException when we try to find a (non-existent) common base dir
+        // across file system roots
+        expExc.expect(BuildException.class);
+        List<ArtifactDownloadReport> reports = Arrays.asList(
+            artifactDownloadReport(new File(fileSystemRoots[0], "a/b/c/d")),
+            artifactDownloadReport(new File(fileSystemRoots[1], "a/b/e/f"))
+        );
+        fileset.requireCommonBaseDir(reports);
+        fail("A BuildException was expected when trying to find a common base dir.");
+    }
+
+    @Test
+    public void requireCommonBaseDirCommon() {
+        List<ArtifactDownloadReport> reports = Arrays.asList(
+            artifactDownloadReport(new File("a/b/c/d")),
+            artifactDownloadReport(new File("a/b/e/f"))
+        );
+        assertNotNull(fileset.requireCommonBaseDir(reports));
+    }
+    
+    private ArtifactDownloadReport artifactDownloadReport(File localFile) {
+        ArtifactDownloadReport report = new ArtifactDownloadReport(null);
+        report.setLocalFile(localFile);
+        return report;
     }
 }