ant-notifications mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jlboud...@apache.org
Subject svn commit: r1404290 - in /ant/ivy/core/trunk: doc/toc.json doc/use/dependencytree.html src/java/org/apache/ivy/ant/IvyDependencyTree.java src/java/org/apache/ivy/ant/antlib.xml test/java/org/apache/ivy/ant/IvyDependencyTreeTest.java
Date Wed, 31 Oct 2012 18:42:43 GMT
Author: jlboudart
Date: Wed Oct 31 18:42:42 2012
New Revision: 1404290

URL: http://svn.apache.org/viewvc?rev=1404290&view=rev
Log:
Implement IvyDependencyTree task : display a dependency tree on the console

Added:
    ant/ivy/core/trunk/doc/use/dependencytree.html
    ant/ivy/core/trunk/src/java/org/apache/ivy/ant/IvyDependencyTree.java
    ant/ivy/core/trunk/test/java/org/apache/ivy/ant/IvyDependencyTreeTest.java
Modified:
    ant/ivy/core/trunk/doc/toc.json
    ant/ivy/core/trunk/src/java/org/apache/ivy/ant/antlib.xml

Modified: ant/ivy/core/trunk/doc/toc.json
URL: http://svn.apache.org/viewvc/ant/ivy/core/trunk/doc/toc.json?rev=1404290&r1=1404289&r2=1404290&view=diff
==============================================================================
--- ant/ivy/core/trunk/doc/toc.json (original)
+++ ant/ivy/core/trunk/doc/toc.json Wed Oct 31 18:42:42 2012
@@ -730,6 +730,13 @@
                             ]
                         },
                         {
+                          "id":"use/dependencytree",
+                          "title":"dependencytree",
+                          "children": [
+
+                            ]
+                        },
+                        {
                           "id":"use/findrevision",
                           "title":"findrevision",
                           "children": [
@@ -908,4 +915,4 @@
           ]
       }
     ]
-}
\ No newline at end of file
+}

Added: ant/ivy/core/trunk/doc/use/dependencytree.html
URL: http://svn.apache.org/viewvc/ant/ivy/core/trunk/doc/use/dependencytree.html?rev=1404290&view=auto
==============================================================================
--- ant/ivy/core/trunk/doc/use/dependencytree.html (added)
+++ ant/ivy/core/trunk/doc/use/dependencytree.html Wed Oct 31 18:42:42 2012
@@ -0,0 +1,72 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!--
+   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.    
+-->
+<html>
+<head>
+	<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=ISO-8859-1">
+	<script type="text/javascript">var xookiConfig = {level: 1};</script>	
+	<script type="text/javascript" src="../xooki/xooki.js"></script>
+</head>
+<body>
+	<textarea id="xooki-source">
+Display a dependency tree on the console.
+
+This is a [[ant:postresolvetask post resolve task]], with all the behaviour and attributes
common to all post resolve tasks.
+
+Please prefer the use of retrieve + standard ant path creation, which make your build more
independent from ivy (once artifacts are properly retrieved, ivy is not required any more).
+
+<h1>Attributes</h1>
+
+<table class="ant">
+<thead>
+    <tr><th class="ant-att">Attribute</th><th class="ant-desc">Description</th><th
class="ant-req">Required</th></tr>
+</thead>
+<tbody>
+    <tr><td>showEvicted</td><td>specify if evicted modules should
be printed</td>
+        <td>No. Defaults to false</td></tr>
+    <tr><td>conf</td><td>a comma separated list of the configurations
to take in consideration in the  dependency tree</td>
+        <td>No. Defaults to the configurations resolved by the last resolve call, or
* if no resolve was explicitly called</td></tr>
+    <tr><td>haltonfailure</td><td>true to halt the build on ivy failure,
false to continue</td><td>No. Defaults to true</td></tr>
+    <tr><td>validate</td><td>true to force ivy files validation against
ivy.xsd, false to force no validation</td>
+        <td>No. Defaults to default ivy value (as configured in configuration file)</td></tr>
+    <tr><td>settingsRef</td><td>A reference to the ivy settings that
must be used by this task <b>(since 2.0)</b></td><td>No, 'ivy.instance'
is taken by default.</td></tr>
+    <tr><td>overwrite</td><td>Overwrite the value of the property
if it already exist <b>(since 2.0)</b>.  Before 2.0, the properties were always
overwritten.</td><td>No, 'false' by default.</td></tr>
+</tbody>
+</table>
+
+<h1>Example</h1>
+Suppose we have two dependencies one called <i>mydep</i> in revision 2.0 and
one called <i>myotherdependency</i> in revision 2.2.
+<i>mydep</i> has a transitive dependency on <i>mytransitivedependency</i>
in revision 2.2.
+
+Then:
+<code type="xml">
+<dependencytree />
+</code>
+will display the following tree in the console:
+<code>
+Dependency tree for foobar
++- org#mydep;2.0
+   \- org#mytransitivedependency;2.2
+\- org#myotherdependency;2.2");
+</code>
+
+	</textarea>
+<script type="text/javascript">xooki.postProcess();</script>
+</body>
+</html>

Added: ant/ivy/core/trunk/src/java/org/apache/ivy/ant/IvyDependencyTree.java
URL: http://svn.apache.org/viewvc/ant/ivy/core/trunk/src/java/org/apache/ivy/ant/IvyDependencyTree.java?rev=1404290&view=auto
==============================================================================
--- ant/ivy/core/trunk/src/java/org/apache/ivy/ant/IvyDependencyTree.java (added)
+++ ant/ivy/core/trunk/src/java/org/apache/ivy/ant/IvyDependencyTree.java Wed Oct 31 18:42:42
2012
@@ -0,0 +1,132 @@
+/*
+ *  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.
+ *
+ */
+package org.apache.ivy.ant;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.ivy.core.module.id.ModuleRevisionId;
+import org.apache.ivy.core.report.ResolveReport;
+import org.apache.ivy.core.resolve.IvyNode;
+import org.apache.ivy.core.resolve.IvyNodeCallers.Caller;
+import org.apache.ivy.core.resolve.IvyNodeEviction.EvictionData;
+import org.apache.tools.ant.BuildException;
+
+public class IvyDependencyTree extends IvyPostResolveTask {
+
+    private Map/* <ModuleRevisionId, List<IvyNode>> */dependencies = new HashMap/*
+                                                                                 * <ModuleRevisionId,
+                                                                                 * List<IvyNode>>
+                                                                                 */();
+
+    private boolean showEvicted = false;
+
+    public void doExecute() throws BuildException {
+        prepareAndCheck();
+        ResolveReport report = getResolvedReport();
+        log("Dependency tree for " + report.getResolveId());
+        ModuleRevisionId mrid = report.getModuleDescriptor().getModuleRevisionId();
+        // make dependency tree easier to fetch informations
+        for (Iterator iterator = report.getDependencies().iterator(); iterator.hasNext();)
{
+            IvyNode dependency = (IvyNode) iterator.next();
+            populateDependencyTree(dependency, mrid, report);
+        }
+        printDependencies((List) dependencies.get(mrid), 0);
+    }
+
+    private void printDependencies(List/* <IvyNode> */dependencyList, int indent) {
+        for (Iterator iterator = dependencyList.iterator(); iterator.hasNext();) {
+            IvyNode dependency = (IvyNode) iterator.next();
+            boolean evicted = dependency.isEvicted(getConf());
+            if (evicted && !showEvicted) {
+                continue;
+            }
+            StringBuilder sb = new StringBuilder();
+            if (indent > 0) {
+                for (int i = 0; i < indent; i++) {
+                    if (i == indent - 1 && !iterator.hasNext() && !hasDependencies(dependency))
{
+                        sb.append("   ");
+                    } else {
+                        sb.append("|  ");
+                    }
+
+                }
+            }
+            if (iterator.hasNext()) {
+                sb.append("+- ");
+            } else {
+                sb.append("\\- ");
+            }
+            sb.append(dependency.getId().toString());
+            if (evicted && showEvicted) {
+                EvictionData evictedData = dependency.getEvictedData(getConf());
+                if (evictedData.isTransitivelyEvicted()) {
+                    sb.append(" transitively");
+                } else {
+                    sb.append(" evicted by ");
+                    sb.append(evictedData.getSelected());
+                    sb.append(" in ").append(evictedData.getParent());
+                    if (evictedData.getDetail() != null) {
+                        sb.append(" ").append(evictedData.getDetail());
+                    }
+                }
+            }
+            log(sb.toString());
+
+            printDependencies((List) dependencies.get(dependency.getId()), indent + 1);
+        }
+    }
+
+    private boolean hasDependencies(IvyNode dependency) {
+        List dependencyList = (List) dependencies.get(dependency.getId());
+        return dependencyList.size() > 0;
+    }
+
+    private void populateDependencyTree(IvyNode dependency, ModuleRevisionId currentMrid,
+            ResolveReport report) {
+        registerNodeIfNecessary(dependency.getId());
+        for (int i = 0; i < dependency.getAllCallers().length; i++) {
+            Caller caller = dependency.getAllCallers()[i];
+            addDependency(caller.getModuleRevisionId(), dependency);
+        }
+    }
+
+    private void registerNodeIfNecessary(ModuleRevisionId moduleRevisionId) {
+        if (!dependencies.containsKey(moduleRevisionId)) {
+            dependencies.put(moduleRevisionId, new ArrayList/* <IvyNode> */());
+        }
+    }
+
+    private void addDependency(ModuleRevisionId moduleRevisionId, IvyNode dependency) {
+        registerNodeIfNecessary(moduleRevisionId);
+        List/* <IvyNode> */list = (List) dependencies.get(moduleRevisionId);
+        list.add(dependency);
+    }
+
+    public boolean isShowEvicted() {
+        return showEvicted;
+    }
+
+    public void setShowEvicted(boolean showEvicted) {
+        this.showEvicted = showEvicted;
+    }
+
+}

Modified: ant/ivy/core/trunk/src/java/org/apache/ivy/ant/antlib.xml
URL: http://svn.apache.org/viewvc/ant/ivy/core/trunk/src/java/org/apache/ivy/ant/antlib.xml?rev=1404290&r1=1404289&r2=1404290&view=diff
==============================================================================
--- ant/ivy/core/trunk/src/java/org/apache/ivy/ant/antlib.xml (original)
+++ ant/ivy/core/trunk/src/java/org/apache/ivy/ant/antlib.xml Wed Oct 31 18:42:42 2012
@@ -47,4 +47,5 @@
     <taskdef name="buildobr" classname="org.apache.ivy.ant.BuildBundleRepoDescriptorTask"
/>
     <taskdef name="convertmanifest" classname="org.apache.ivy.ant.ConvertManifestTask"
/>
     <taskdef name="fixdeps" classname="org.apache.ivy.ant.FixDepsTask" />
+    <taskdef name="dependencytree" classname="org.apache.ivy.ant.IvyDependencyTree"/>
 </antlib>

Added: ant/ivy/core/trunk/test/java/org/apache/ivy/ant/IvyDependencyTreeTest.java
URL: http://svn.apache.org/viewvc/ant/ivy/core/trunk/test/java/org/apache/ivy/ant/IvyDependencyTreeTest.java?rev=1404290&view=auto
==============================================================================
--- ant/ivy/core/trunk/test/java/org/apache/ivy/ant/IvyDependencyTreeTest.java (added)
+++ ant/ivy/core/trunk/test/java/org/apache/ivy/ant/IvyDependencyTreeTest.java Wed Oct 31
18:42:42 2012
@@ -0,0 +1,223 @@
+/*
+ *  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.
+ *
+ */
+package org.apache.ivy.ant;
+
+import java.io.File;
+
+import junit.framework.TestCase;
+
+import org.apache.tools.ant.BuildEvent;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildListener;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.Delete;
+
+public class IvyDependencyTreeTest extends TestCase {
+    private File cache;
+
+    private IvyDependencyTree dependencyTree;
+
+    private AntTestListener antTestListener;
+
+    private Project project;
+
+    protected void setUp() throws Exception {
+        createCache();
+        project = AntTestHelper.newProject();
+        project.setProperty("ivy.settings.file", "test/repositories/ivysettings.xml");
+        antTestListener = new AntTestListener(Project.MSG_INFO);
+        project.addBuildListener(antTestListener);
+
+        dependencyTree = new IvyDependencyTree();
+        dependencyTree.setProject(project);
+        System.setProperty("ivy.cache.dir", cache.getAbsolutePath());
+    }
+
+    private void createCache() {
+        cache = new File("build/cache");
+        cache.mkdirs();
+    }
+
+    protected void tearDown() throws Exception {
+        cleanCache();
+    }
+
+    private void cleanCache() {
+        Delete del = new Delete();
+        del.setProject(new Project());
+        del.setDir(cache);
+        del.execute();
+    }
+
+    public void testSimple() throws Exception {
+        dependencyTree.setFile(new File("test/java/org/apache/ivy/ant/ivy-simple.xml"));
+        dependencyTree.execute();
+        assertLogContaining("Dependency tree for apache-resolve-simple");
+        assertLogContaining("\\- org1#mod1.2;2.0");
+    }
+
+    public void testWithResolveId() throws Exception {
+        IvyResolve resolve = new IvyResolve();
+        resolve.setProject(project);
+        resolve.setFile(new File("test/java/org/apache/ivy/ant/ivy-simple.xml"));
+        resolve.setResolveId("abc");
+        resolve.execute();
+
+        // resolve another ivy file
+        resolve = new IvyResolve();
+        resolve.setProject(project);
+        resolve.setFile(new File("test/java/org/apache/ivy/ant/ivy-latest.xml"));
+        resolve.execute();
+
+        dependencyTree.execute();
+        assertLogContaining("Dependency tree for apache-resolve-latest");
+        assertLogContaining("\\- org1#mod1.2;latest.integration");
+    }
+
+    public void testWithResolveIdWithoutResolve() throws Exception {
+        try {
+            dependencyTree.execute();
+            fail("Task should have failed because no resolve was performed!");
+        } catch (BuildException e) {
+            // this is expected!
+        }
+    }
+
+    public void testWithEvictedModule() throws Exception {
+        dependencyTree.setFile(new File("test/java/org/apache/ivy/ant/ivy-dyn-evicted.xml"));
+        dependencyTree.execute();
+        assertLogContaining("Dependency tree for apache-resolve-latest");
+        assertLogNotContaining("+- org1#mod1.2;1+");
+        assertLogContaining("+- org6#mod6.1;2.0");
+        assertLogContaining("   \\- org1#mod1.2;2.2");
+        assertLogContaining("\\- org1#mod1.2;2.2");
+    }
+
+    public void testShowEvictedModule() throws Exception {
+        dependencyTree.setFile(new File("test/java/org/apache/ivy/ant/ivy-dyn-evicted.xml"));
+        dependencyTree.setShowEvicted(true);
+        dependencyTree.execute();
+        assertLogContaining("Dependency tree for apache-resolve-latest");
+        assertLogContaining("+- org1#mod1.2;1+ evicted by [org1#mod1.2;2.2] in apache#resolve-latest;1.0");
+        assertLogContaining("+- org6#mod6.1;2.0");
+        assertLogContaining("   \\- org1#mod1.2;2.2");
+        assertLogContaining("\\- org1#mod1.2;2.2");
+    }
+
+    public void assertLogContaining(String substring) {
+        String realLog = antTestListener.getLog();
+        assertTrue("expecting log to contain \"" + substring + "\" log was \"" + realLog
+ "\"",
+            realLog.contains(substring));
+    }
+
+    public void assertLogNotContaining(String substring) {
+        String realLog = antTestListener.getLog();
+        assertFalse("expecting log to contain \"" + substring + "\" log was \"" + realLog
+ "\"",
+            realLog.contains(substring));
+    }
+
+    /**
+     * Our own personal build listener.
+     */
+    private class AntTestListener implements BuildListener {
+        private int logLevel;
+
+        private StringBuilder buildLog = new StringBuilder();
+
+        /**
+         * Constructs a test listener which will ignore log events above the given level.
+         */
+        public AntTestListener(int logLevel) {
+            this.logLevel = logLevel;
+        }
+
+        /**
+         * Fired before any targets are started.
+         */
+        public void buildStarted(BuildEvent event) {
+        }
+
+        /**
+         * Fired after the last target has finished. This event will still be thrown if an
error
+         * occurred during the build.
+         * 
+         * @see BuildEvent#getException()
+         */
+        public void buildFinished(BuildEvent event) {
+        }
+
+        /**
+         * Fired when a target is started.
+         * 
+         * @see BuildEvent#getTarget()
+         */
+        public void targetStarted(BuildEvent event) {
+            // System.out.println("targetStarted " + event.getTarget().getName());
+        }
+
+        /**
+         * Fired when a target has finished. This event will still be thrown if an error
occurred
+         * during the build.
+         * 
+         * @see BuildEvent#getException()
+         */
+        public void targetFinished(BuildEvent event) {
+            // System.out.println("targetFinished " + event.getTarget().getName());
+        }
+
+        /**
+         * Fired when a task is started.
+         * 
+         * @see BuildEvent#getTask()
+         */
+        public void taskStarted(BuildEvent event) {
+            // System.out.println("taskStarted " + event.getTask().getTaskName());
+        }
+
+        /**
+         * Fired when a task has finished. This event will still be throw if an error occurred
+         * during the build.
+         * 
+         * @see BuildEvent#getException()
+         */
+        public void taskFinished(BuildEvent event) {
+            // System.out.println("taskFinished " + event.getTask().getTaskName());
+        }
+
+        /**
+         * Fired whenever a message is logged.
+         * 
+         * @see BuildEvent#getMessage()
+         * @see BuildEvent#getPriority()
+         */
+        public void messageLogged(BuildEvent event) {
+            if (event.getPriority() > logLevel) {
+                // ignore event
+                return;
+            }
+
+            buildLog.append(event.getMessage());
+        }
+
+        public String getLog() {
+            return buildLog.toString();
+        }
+
+    }
+
+}



Mime
View raw message