Browse Source

Try to get the dependency analysis right this time while preserving BC.

PR: 29977


git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@276715 13f79535-47bb-0310-9956-ffa450edef68
master
Matthew Jason Benson 21 years ago
parent
commit
c692a67a30
7 changed files with 75 additions and 30 deletions
  1. +7
    -0
      src/etc/testcases/taskdefs/ant.xml
  2. +7
    -0
      src/etc/testcases/taskdefs/calltarget.xml
  3. +48
    -17
      src/main/org/apache/tools/ant/Project.java
  4. +3
    -8
      src/main/org/apache/tools/ant/Target.java
  5. +2
    -5
      src/main/org/apache/tools/ant/taskdefs/Ant.java
  6. +4
    -0
      src/testcases/org/apache/tools/ant/taskdefs/AntTest.java
  7. +4
    -0
      src/testcases/org/apache/tools/ant/taskdefs/CallTargetTest.java

+ 7
- 0
src/etc/testcases/taskdefs/ant.xml View File

@@ -206,6 +206,13 @@
</ant>
</target>

<target name="multiple-targets-2">
<ant antfile="ant.xml">
<target name="tb" />
<target name="da" />
</ant>
</target>

<target name="ta"><echo>ta</echo></target>
<target name="tb" depends="da,dc"><echo>tb</echo></target>
<target name="tc" depends="db,dc"><echo>tc</echo></target>


+ 7
- 0
src/etc/testcases/taskdefs/calltarget.xml View File

@@ -65,6 +65,13 @@
</antcall>
</target>

<target name="multiple-targets-2">
<ant antfile="ant.xml">
<target name="tb" />
<target name="da" />
</ant>
</target>

<target name="ta"><echo>ta</echo></target>
<target name="tb" depends="da,dc"><echo>tb</echo></target>
<target name="tc" depends="db,dc"><echo>tc</echo></target>


+ 48
- 17
src/main/org/apache/tools/ant/Project.java View File

@@ -1181,14 +1181,11 @@ public class Project {
throw new BuildException(msg);
}

// Sort the dependency tree, and run everything from the
// beginning until we hit our targetName.
// Sort and run the dependency tree.
// Sorting checks if all the targets (and dependencies)
// exist, and if there is any cycle in the dependency
// graph.
Vector sortedTargets = topoSort(targetName, targets);
sortedTargets.setSize(sortedTargets.indexOf(targets.get(targetName)) + 1);
executeSortedTargets(sortedTargets);
executeSortedTargets(topoSort(targetName, targets, false));
}

/**
@@ -1557,38 +1554,65 @@ public class Project {
}

/**
* Topologically sorts a set of targets.
* Topologically sorts a set of targets. Equivalent to calling
* <CODE>topoSort(new String[] {root}, targets, true)</CODE>.
*
* @param root The name of the root target. The sort is created in such
* a way that the sequence of Targets up to the root
* target is the minimum possible such sequence.
* Must not be <code>null</code>.
* @param targets A map of names to targets (String to Target).
* @param targets A Hashtable mapping names to Targets.
* Must not be <code>null</code>.
* @return a vector of Target objects in sorted order.
* @return a Vector of ALL Target objects in sorted order.
* @exception BuildException if there is a cyclic dependency among the
* targets, or if a named target does not exist.
*/
public final Vector topoSort(String root, Hashtable targets)
throws BuildException {
return topoSort(new String[] {root}, targets);
return topoSort(new String[] {root}, targets, true);
}

/**
* Topologically sorts a set of targets. Equivalent to calling
* <CODE>topoSort(new String[] {root}, targets, returnAll)</CODE>.
*
* @param root The name of the root target. The sort is created in such
* a way that the sequence of Targets up to the root
* target is the minimum possible such sequence.
* Must not be <code>null</code>.
* @param targets A Hashtable mapping names to Targets.
* Must not be <code>null</code>.
* @param returnAll <CODE>boolean</CODE> indicating whether to return all
* targets, or the execution sequence only.
* @return a Vector of Target objects in sorted order.
* @exception BuildException if there is a cyclic dependency among the
* targets, or if a named target does not exist.
* @since Ant 1.6.3
*/
public final Vector topoSort(String root, Hashtable targets,
boolean returnAll) throws BuildException {
return topoSort(new String[] {root}, targets, returnAll);
}

/**
* Topologically sorts a set of targets.
*
* @param root <CODE>String[]</CODE> containing the names of the root targets.
* The sort is created in such a way that the sequence of Targets
* up to the root target is the minimum possible such sequence.
* The sort is created in such a way that the ordered sequence of
* Targets is the minimum possible such sequence to the specified
* root targets.
* Must not be <code>null</code>.
* @param targets A map of names to targets (String to Target).
* Must not be <code>null</code>.
* @return a vector of Target objects in sorted order.
* @param returnAll <CODE>boolean</CODE> indicating whether to return all
* targets, or the execution sequence only.
* @return a Vector of Target objects in sorted order.
* @exception BuildException if there is a cyclic dependency among the
* targets, or if a named target does not exist.
* @since Ant 1.6.3
*/
public final Vector topoSort(String[] root, Hashtable targets)
throws BuildException {
public final Vector topoSort(String[] root, Hashtable targets,
boolean returnAll) throws BuildException {
Vector ret = new Vector();
Hashtable state = new Hashtable();
Stack visiting = new Stack();
@@ -1602,7 +1626,13 @@ public class Project {
// build Target.

for (int i = 0; i < root.length; i++) {
tsort(root[i], targets, state, visiting, ret);
String st = (String)(state.get(root[i]));
if (st == null) {
tsort(root[i], targets, state, visiting, ret);
} else if (st == VISITING) {
throw new RuntimeException("Unexpected node in visiting state: "
+ root[i]);
}
}
StringBuffer buf = new StringBuffer("Build sequence for target(s)");

@@ -1612,17 +1642,18 @@ public class Project {
buf.append(" is " + ret);
log(buf.toString(), MSG_VERBOSE);

Vector complete = (returnAll) ? ret : new Vector(ret);
for (Enumeration en = targets.keys(); en.hasMoreElements();) {
String curTarget = (String) en.nextElement();
String st = (String) state.get(curTarget);
if (st == null) {
tsort(curTarget, targets, state, visiting, ret);
tsort(curTarget, targets, state, visiting, complete);
} else if (st == VISITING) {
throw new RuntimeException("Unexpected node in visiting state: "
+ curTarget);
}
}
log("Complete build sequence is " + ret, MSG_VERBOSE);
log("Complete build sequence is " + complete, MSG_VERBOSE);
return ret;
}



+ 3
- 8
src/main/org/apache/tools/ant/Target.java View File

@@ -219,14 +219,9 @@ public class Target implements TaskContainer {
* @since Ant 1.6
*/
public boolean dependsOn(String other) {
if (getProject() != null) {
List l = getProject().topoSort(getName(),
getProject().getTargets());
int myIdx = l.indexOf(this);
int otherIdx = l.indexOf(getProject().getTargets().get(other));
return myIdx >= otherIdx;
}
return false;
Project p = getProject();
Hashtable t = (p == null) ? null : p.getTargets();
return (p != null && p.topoSort(getName(), t, false).contains(t.get(other)));
}

/**


+ 2
- 5
src/main/org/apache/tools/ant/taskdefs/Ant.java View File

@@ -397,12 +397,9 @@ public class Ant extends Task {
String[] nameArray =
(String[])(locals.toArray(new String[locals.size()]));

Hashtable targets = newProject.getTargets();
Vector sortedTargets = newProject.topoSort(nameArray, targets);
newProject.executeSortedTargets(newProject.topoSort(
nameArray, newProject.getTargets(), false));

sortedTargets.setSize(sortedTargets.indexOf(targets.get(
locals.lastElement())) + 1);
newProject.executeSortedTargets(sortedTargets);
} catch (BuildException ex) {
t = ProjectHelper
.addLocationToBuildException(ex, getLocation());


+ 4
- 0
src/testcases/org/apache/tools/ant/taskdefs/AntTest.java View File

@@ -303,6 +303,10 @@ public class AntTest extends BuildFileTest {
expectLog("multiple-targets", "tadadctbdbtc");
}

public void testMultipleTargets2() {
expectLog("multiple-targets-2", "dadctb");
}

private class BasedirChecker implements BuildListener {
private String[] expectedBasedirs;
private int calls = 0;


+ 4
- 0
src/testcases/org/apache/tools/ant/taskdefs/CallTargetTest.java View File

@@ -63,6 +63,10 @@ public class CallTargetTest extends BuildFileTest {
expectLog("multiple-targets", "tadadctbdbtc");
}

public void testMultipleTargets2() {
expectLog("multiple-targets-2", "dadctb");
}

public void tearDown() {
project.executeTarget("cleanup");
}


Loading…
Cancel
Save