Stefan Bodewig wrote:
Be that as it may, the current behaviour is a bit silly -
i.e. inconsistent.
big +1
But we should discuss it here instead of in bugzilla - nobody's going
to follow it there. I know that I don't.
No problem.
The bug is : http://issues.apache.org/bugzilla/show_bug.cgi?id=28444 The example given is:
<project name="A"> <target name="x"/> </project>
<project name="B"> <import file="A.xml"/> <target name="x" depends="A.x"/> </project>
<project name="C"> <import file="A.xml"/> <import file="B.xml"/> </project>
Succeeds: ant -f A.xml x ant -f B.xml x
Fails: ant -f C.xml x
BUILD FAILED
Target `A.x' does not exist in this project. It is used from target `B.x'.
My comment is:
I never liked the target renaming stuff - it seems a bit strange. Be that as it may, the current behaviour is a bit silly - i.e. inconsistent. The target gets renamed if there another target of the same name, but not otherwise - how can one write a proper reusable import file using the rename feature in this case?
The fix will have a small overhead - the target object needs to be cloned and given a a new name, whereas the current code just renames the target object.
The changes to ant for this is: Index: src/main/org/apache/tools/ant/Target.java =================================================================== RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/Target.java,v retrieving revision 1.58 diff -u -3 -p -r1.58 Target.java --- src/main/org/apache/tools/ant/Target.java 10 Mar 2005 12:50:57 -0000 1.58 +++ src/main/org/apache/tools/ant/Target.java 12 May 2005 14:41:25 -0000 @@ -52,12 +52,28 @@ public class Target implements TaskConta /** Description of this target, if any. */ private String description = null;
- /** Sole constructor. */ + /** Default constructor. */ public Target() { //empty }
/** + * Cloning constructor. + * @param other the Target to clone. + */ + public Target(Target other) { + this.name = other.name; + this.ifCondition = other.ifCondition; + this.unlessCondition = other.unlessCondition; + this.dependencies = other.dependencies; + this.location = other.location; + this.project = other.project; + this.description = other.description; + // The children are added to after this cloning + this.children = other.children; + } + + /** * Sets the project this target belongs to. * * @param project The project this target belongs to. Index: src/main/org/apache/tools/ant/helper/ProjectHelper2.java =================================================================== RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/helper/ProjectHelper2.java,v retrieving revision 1.54 diff -u -3 -p -r1.54 ProjectHelper2.java --- src/main/org/apache/tools/ant/helper/ProjectHelper2.java 26 Apr 2005 11:55:18 -0000 1.54 +++ src/main/org/apache/tools/ant/helper/ProjectHelper2.java 12 May 2005 14:41:26 -0000 @@ -815,38 +815,39 @@ public class ProjectHelper2 extends Proj + "a name attribute", context.getLocator()); }
- Hashtable currentTargets = project.getTargets(); + // Check if this target is in the current build file + if (context.getCurrentTargets().get(name) != null) { + throw new BuildException( + "Duplicate target '" + name + "'", target.getLocation()); + }
- // If the name has already been defined ( import for example ) - if (currentTargets.containsKey(name)) { - if (context.getCurrentTargets().get(name) != null) { - throw new BuildException( - "Duplicate target '" + name + "'", target.getLocation()); - } - // Alter the name. - if (context.getCurrentProjectName() != null) { - String newName = context.getCurrentProjectName() - + "." + name; - project.log("Already defined in main or a previous import, " - + "define " + name + " as " + newName, - Project.MSG_VERBOSE); - name = newName; - } else { - project.log("Already defined in main or a previous import, " - + "ignore " + name, Project.MSG_VERBOSE); - name = null; - } + if (depends.length() > 0) { + target.setDepends(depends); }
- if (name != null) { + Hashtable projectTargets = project.getTargets(); + boolean usedTarget = false; + // If the name has not already been defined define it + if (projectTargets.containsKey(name)) { + project.log("Already defined in main or a previous import, " + + "ignore " + name, Project.MSG_VERBOSE); + } else { target.setName(name); context.getCurrentTargets().put(name, target); project.addOrReplaceTarget(name, target); + usedTarget = true; }
- // take care of dependencies - if (depends.length() > 0) { - target.setDepends(depends); + if (context.isIgnoringProjectTag() && context.getCurrentProjectName() != null + && context.getCurrentProjectName().length() != 0) { + // In an impored file (and not completely + // ignoring the project tag) + String newName = context.getCurrentProjectName() + + "." + name; + Target newTarget = usedTarget ? new Target(target) : target; + newTarget.setName(newName); + context.getCurrentTargets().put(newName, newTarget); + project.addOrReplaceTarget(newName, newTarget); } }
Cheers, Peter
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]