git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@713016 13f79535-47bb-0310-9956-ffa450edef68master
@@ -519,6 +519,9 @@ Other changes: | |||||
* <import> has a new attribute "as" that can be used to control the | * <import> has a new attribute "as" that can be used to control the | ||||
prefix prepended to the imported target's names. | prefix prepended to the imported target's names. | ||||
* a new task <include> provides an alternative to <import> that | |||||
should be preferred when you don't want to override any targets. | |||||
Changes from Ant 1.7.0 TO Ant 1.7.1 | Changes from Ant 1.7.0 TO Ant 1.7.1 | ||||
============================================= | ============================================= | ||||
@@ -27,6 +27,14 @@ | |||||
<p> | <p> | ||||
Imports another build file into the current project. | Imports another build file into the current project. | ||||
</p> | </p> | ||||
<p> | |||||
<b>Note</b> this task heavily relies on the ProjectHelper | |||||
implementation and doesn't really perform any work of its own. If | |||||
you have configured Ant to use a ProjectHelper other than Ant's | |||||
default, this task may or may not work. | |||||
</p> | |||||
<p> | <p> | ||||
On execution it will read another Ant file into | On execution it will read another Ant file into | ||||
the same Project. This means that it basically works like the | the same Project. This means that it basically works like the | ||||
@@ -83,7 +91,7 @@ property of the main buildfile.</p> | |||||
<p>Note that "builddocs" is not the filename, but the name attribute | <p>Note that "builddocs" is not the filename, but the name attribute | ||||
present in the imported project tag.</p> | present in the imported project tag.</p> | ||||
<p> | <p> | ||||
If import file does not have a name attribute, the ant.file.projectname | |||||
If the imported file does not have a name attribute, the ant.file.projectname | |||||
property will not be set. | property will not be set. | ||||
</p> | </p> | ||||
@@ -182,6 +190,89 @@ directory.</p> | |||||
<p>Imports the project defined by the property deploy-platform</p> | <p>Imports the project defined by the property deploy-platform</p> | ||||
<h3>How is <import> different | |||||
from <a href="include.html"><include></a>?</h3> | |||||
<p>When using import the imported targets are available by up to two | |||||
names. Their "normal" name without any prefix and potentially with | |||||
a prefixed name (the value of the as attribute or the imported | |||||
project's name attribute, if any).</p> | |||||
<p>When using include the included targets are only available in the | |||||
prefixed form.</p> | |||||
<p>When using import, the imported target's depends attribute | |||||
remains unchanged, i.e. it uses "normal" names and allows you to | |||||
override targets in the dependency list.</p> | |||||
<p>When using include, the included target's depends attribute is | |||||
rewritten so that prefixed names are used. This allows writers of | |||||
the included file to control which target is invoked as part of the | |||||
dependencies.</p> | |||||
<p>It is possible to include the same file more than once by using | |||||
different prefixes, it is not possible to import the same file more | |||||
than once.</p> | |||||
<p>Use import if you intend to override a target, otherwise use include.</p> | |||||
<p><i>nested.xml</i> shall be:</p> | |||||
<pre> | |||||
<project> | |||||
<target name="setUp"> | |||||
<property name="prop" value="in nested"/> | |||||
</target> | |||||
<target name="echo" depends="setUp"> | |||||
<echo>prop has the value ${prop}</echo> | |||||
</target> | |||||
</project> | |||||
</pre> | |||||
<p>When using import like in</p> | |||||
<pre> | |||||
<project> | |||||
<target name="setUp"> | |||||
<property name="prop" value="in importing"/> | |||||
</target> | |||||
<import file="nested.xml" as="nested"/> | |||||
</project> | |||||
</pre> | |||||
<p>Running the target <i>nested.echo</i> will emit: | |||||
<pre> | |||||
setUp: | |||||
nested.echo: | |||||
[echo] prop has the value in importing | |||||
</pre> | |||||
<p>When using include like in</p> | |||||
<pre> | |||||
<project> | |||||
<target name="setUp"> | |||||
<property name="prop" value="in importing"/> | |||||
</target> | |||||
<include file="nested.xml" as="nested"/> | |||||
</project> | |||||
</pre> | |||||
<p>Running the target <i>nested.echo</i> will emit: | |||||
<pre> | |||||
nested.setUp: | |||||
nested.echo: | |||||
[echo] prop has the value in nested | |||||
</pre> | |||||
<p>and there won't be any target named "echo" on the including build file.</p> | |||||
</body> | </body> | ||||
</html> | </html> |
@@ -0,0 +1,274 @@ | |||||
<!-- | |||||
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. | |||||
--> | |||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> | |||||
<html> | |||||
<head> | |||||
<meta http-equiv="Content-Language" content="en-us"> | |||||
<link rel="stylesheet" type="text/css" href="../stylesheets/style.css"> | |||||
<title>Include Task</title> | |||||
</head> | |||||
<body> | |||||
<h2><a name="include">Include</a></h2> | |||||
<h3>Description</h3> | |||||
<p> | |||||
Include another build file into the current project. | |||||
</p> | |||||
<p> | |||||
<b>Note</b> this task heavily relies on the ProjectHelper | |||||
implementation and doesn't really perform any work of its own. If | |||||
you have configured Ant to use a ProjectHelper other than Ant's | |||||
default, this task may or may not work. | |||||
</p> | |||||
<p> | |||||
On execution it will read another Ant file into the same Project | |||||
rewriting the included target names and depends lists. This is | |||||
different | |||||
from <a href="http://ant.apache.org/faq.html#xml-entity-include">Entity | |||||
Includes as explained in the Ant FAQ</a> in so far as the target | |||||
names get prefixed by the included project's name or the as | |||||
attribute and do not appear as if the file was contained in the | |||||
including file. | |||||
</p> | |||||
<p> | |||||
The include task may only be used as a top-level task. This means that | |||||
it may not be used in a target. | |||||
</p> | |||||
<p> | |||||
There are two further functional aspects that pertain to this task and | |||||
that are not possible with entity includes: | |||||
<ul> | |||||
<li>target rewriting</li> | |||||
<li>special properties</li> | |||||
</ul> | |||||
</p> | |||||
<h4>Target rewriting</h4> | |||||
<p>Any target in the included file will be renamed | |||||
to <i>prefix.name</i> where <i>name</i> is the original target's | |||||
name and <i>prefix</i> is either the value of the <i>as</i> | |||||
attribute or the <i>name</i> attribute of the <i>project</i> tag of | |||||
the included file.</p> | |||||
<p>The depends attribute of all included targets is rewritten so that | |||||
all target names are prefixed as well. This makes the included file | |||||
self-contained.</p> | |||||
<h4>Special Properties</h4> | |||||
<p>Included files are treated as they are present in the main | |||||
buildfile. This makes it easy to understand, but it makes it impossible | |||||
for them to reference files and resources relative to their path. | |||||
Because of this, for every included file, Ant adds a property that | |||||
contains the path to the included buildfile. With this path, the | |||||
included buildfile can keep resources and be able to reference them | |||||
relative to its position.</p> | |||||
<p>So if I include for example a <i>docsbuild.xml</i> file named <b>builddocs</b>, | |||||
I can get its path as <b>ant.file.builddocs</b>, similarly to the <b>ant.file</b> | |||||
property of the main buildfile.</p> | |||||
<p>Note that "builddocs" is not the filename, but the name attribute | |||||
present in the included project tag.</p> | |||||
<p> | |||||
If the included file does not have a name attribute, the ant.file.projectname | |||||
property will not be set. | |||||
</p> | |||||
<h4>Resolving files against the included file</h4> | |||||
<p>Suppose your main build file called <code>including.xml</code> | |||||
includes a build file <code>included.xml</code>, located anywhere on | |||||
the file system, and <code>included.xml</code> reads a set of | |||||
properties from <code>included.properties</code>:</p> | |||||
<pre><!-- including.xml --> | |||||
<project name="including" basedir="." default="..."> | |||||
<include file="${path_to_included}/included.xml"/> | |||||
</project> | |||||
<!-- included.xml --> | |||||
<project name="included" basedir="." default="..."> | |||||
<property file="included.properties"/> | |||||
</project> | |||||
</pre> | |||||
<p>This snippet however will resolve <code>included.properties</code> | |||||
against the basedir of <code>including.xml</code>, because the basedir | |||||
of <code>included.xml</code> is ignored by Ant. The right way to use | |||||
<code>included.properties</code> is:</p> | |||||
<pre> | |||||
<!-- included.xml --> | |||||
<project name="included" basedir="." default="..."> | |||||
<dirname property="included.basedir" file="${ant.file.included}"/> | |||||
<property file="${included.basedir}/included.properties"/> | |||||
</project> | |||||
</pre> | |||||
<p>As explained above <code>${ant.file.included}</code> stores the | |||||
path of the build script, that defines the project called | |||||
<code>included</code>, (in short it stores the path to | |||||
<code>included.xml</code>) and <a | |||||
href="dirname.html"><code><dirname></code></a> takes its | |||||
directory. This technique also allows <code>included.xml</code> to be | |||||
used as a standalone file (without being included in other | |||||
project).</p> | |||||
<h3>Parameters</h3> | |||||
<table border="1" cellpadding="2" cellspacing="0"> | |||||
<tbody> | |||||
<tr> | |||||
<td valign="top"><b>Attribute</b></td> | |||||
<td valign="top"><b>Description</b></td> | |||||
<td align="center" valign="top"><b>Required</b></td> | |||||
</tr> | |||||
<tr> | |||||
<td valign="top"> | |||||
file | |||||
</td> | |||||
<td valign="top"> | |||||
The file to include. If this is a relative file name, the file name will be resolved | |||||
relative to the <i>including</i> file. <b>Note</b>, this is unlike most other | |||||
ant file attributes, where relative files are resolved relative to ${basedir}. | |||||
</td> | |||||
<td valign="top" align="center">Yes</td> | |||||
</tr> | |||||
<tr> | |||||
<td valign="top"> | |||||
optional | |||||
</td> | |||||
<td valign="top"> | |||||
If true, do not stop the build if the file does not exist, | |||||
default is false. | |||||
</td> | |||||
<td valign="top" align="center">No</td> | |||||
</tr> | |||||
<tr> | |||||
<td valign="top"> | |||||
as | |||||
</td> | |||||
<td valign="top"> | |||||
Specifies the prefix prepended to the target names. If | |||||
ommitted, the name attribute of the project tag of the | |||||
imported file will be used. | |||||
</td> | |||||
<td valign="top" align="center">Yes, if the included file's | |||||
project tag doesn't specify a name attribute.</td> | |||||
</tr> | |||||
</tbody> | |||||
</table> | |||||
<h3>Examples</h3> | |||||
<pre> <include file="../common-targets.xml"/> | |||||
</pre> | |||||
<p>Includes targets from the common-targets.xml file that is in a parent | |||||
directory.</p> | |||||
<pre> <include file="${deploy-platform}.xml"/> | |||||
</pre> | |||||
<p>Includes the project defined by the property deploy-platform</p> | |||||
<h3>How is <a href="import.html"><import></a> different | |||||
from <include>?</h3> | |||||
<p>When using import the imported targets are available by up to two | |||||
names. Their "normal" name without any prefix and potentially with | |||||
a prefixed name (the value of the as attribute or the imported | |||||
project's name attribute, if any).</p> | |||||
<p>When using include the included targets are only available in the | |||||
prefixed form.</p> | |||||
<p>When using import, the imported target's depends attribute | |||||
remains unchanged, i.e. it uses "normal" names and allows you to | |||||
override targets in the dependency list.</p> | |||||
<p>When using include, the included target's depends attribute is | |||||
rewritten so that prefixed names are used. This allows writers of | |||||
the included file to control which target is invoked as part of the | |||||
dependencies.</p> | |||||
<p>It is possible to include the same file more than once by using | |||||
different prefixes, it is not possible to import the same file more | |||||
than once.</p> | |||||
<p>Use import if you intend to override a target, otherwise use include.</p> | |||||
<p><i>nested.xml</i> shall be:</p> | |||||
<pre> | |||||
<project> | |||||
<target name="setUp"> | |||||
<property name="prop" value="in nested"/> | |||||
</target> | |||||
<target name="echo" depends="setUp"> | |||||
<echo>prop has the value ${prop}</echo> | |||||
</target> | |||||
</project> | |||||
</pre> | |||||
<p>When using import like in</p> | |||||
<pre> | |||||
<project> | |||||
<target name="setUp"> | |||||
<property name="prop" value="in importing"/> | |||||
</target> | |||||
<import file="nested.xml" as="nested"/> | |||||
</project> | |||||
</pre> | |||||
<p>Running the target <i>nested.echo</i> will emit: | |||||
<pre> | |||||
setUp: | |||||
nested.echo: | |||||
[echo] prop has the value in importing | |||||
</pre> | |||||
<p>When using include like in</p> | |||||
<pre> | |||||
<project> | |||||
<target name="setUp"> | |||||
<property name="prop" value="in importing"/> | |||||
</target> | |||||
<include file="nested.xml" as="nested"/> | |||||
</project> | |||||
</pre> | |||||
<p>Running the target <i>nested.echo</i> will emit: | |||||
<pre> | |||||
nested.setUp: | |||||
nested.echo: | |||||
[echo] prop has the value in nested | |||||
</pre> | |||||
<p>and there won't be any target named "echo" on the including build file.</p> | |||||
</body> | |||||
</html> |
@@ -77,6 +77,7 @@ | |||||
<a href="CoreTasks/unpack.html">GUnzip</a><br/> | <a href="CoreTasks/unpack.html">GUnzip</a><br/> | ||||
<a href="CoreTasks/pack.html">GZip</a><br/> | <a href="CoreTasks/pack.html">GZip</a><br/> | ||||
<a href="CoreTasks/import.html">Import</a><br/> | <a href="CoreTasks/import.html">Import</a><br/> | ||||
<a href="CoreTasks/include.html">Include</a><br/> | |||||
<a href="CoreTasks/input.html">Input</a><br/> | <a href="CoreTasks/input.html">Input</a><br/> | ||||
<a href="CoreTasks/jar.html">Jar</a><br/> | <a href="CoreTasks/jar.html">Jar</a><br/> | ||||
<a href="CoreTasks/java.html">Java</a><br/> | <a href="CoreTasks/java.html">Java</a><br/> | ||||
@@ -843,6 +843,11 @@ documentation.</p> | |||||
in it with targets of your own.</p></td> | in it with targets of your own.</p></td> | ||||
</tr> | </tr> | ||||
<tr valign="top"> | |||||
<td nowrap><a href="CoreTasks/include.html">Include</a></td> | |||||
<td><p>Include another build file.</p></td> | |||||
</tr> | |||||
<tr valign="top"> | <tr valign="top"> | ||||
<td nowrap><a href="OptionalTasks/javacc.html">JavaCC</a></td> | <td nowrap><a href="OptionalTasks/javacc.html">JavaCC</a></td> | ||||
<td><p>Invokes the | <td><p>Invokes the | ||||
@@ -128,7 +128,7 @@ public class ProjectHelper { | |||||
* | * | ||||
* @return the configured prefix or null | * @return the configured prefix or null | ||||
* | * | ||||
* @since ant 1.8.0 | |||||
* @since Ant 1.8.0 | |||||
*/ | */ | ||||
public static String getCurrentTargetPrefix() { | public static String getCurrentTargetPrefix() { | ||||
return (String) targetPrefix.get(); | return (String) targetPrefix.get(); | ||||
@@ -137,12 +137,47 @@ public class ProjectHelper { | |||||
/** | /** | ||||
* Sets the prefix to prepend to imported target names. | * Sets the prefix to prepend to imported target names. | ||||
* | * | ||||
* @since ant 1.8.0 | |||||
* @since Ant 1.8.0 | |||||
*/ | */ | ||||
public static void setCurrentTargetPrefix(String prefix) { | public static void setCurrentTargetPrefix(String prefix) { | ||||
targetPrefix.set(prefix); | targetPrefix.set(prefix); | ||||
} | } | ||||
private final static ThreadLocal inIncludeMode = new ThreadLocal() { | |||||
protected Object initialValue() { | |||||
return Boolean.FALSE; | |||||
} | |||||
}; | |||||
/** | |||||
* Whether the current file should be read in include as opposed | |||||
* to import mode. | |||||
* | |||||
* <p>In include mode included targets are only known by their | |||||
* prefixed names and their depends lists get rewritten so that | |||||
* all dependencies get the prefix as well.</p> | |||||
* | |||||
* <p>In import mode imported targets are known by an adorned as | |||||
* well as a prefixed name and the unadorned target may be | |||||
* overwritten in the importing build file. The depends list of | |||||
* the imported targets is not modified at all.</p> | |||||
* | |||||
* @since Ant 1.8.0 | |||||
*/ | |||||
public static boolean isInIncludeMode() { | |||||
return inIncludeMode.get() == Boolean.TRUE; | |||||
} | |||||
/** | |||||
* Sets whether the current file should be read in include as | |||||
* opposed to import mode. | |||||
* | |||||
* @since Ant 1.8.0 | |||||
*/ | |||||
public static void setInIncludeMode(boolean includeMode) { | |||||
inIncludeMode.set(includeMode ? Boolean.TRUE : Boolean.FALSE); | |||||
} | |||||
// -------------------- Parse method -------------------- | // -------------------- Parse method -------------------- | ||||
/** | /** | ||||
* Parses the project file, configuring the project as it goes. | * Parses the project file, configuring the project as it goes. | ||||
@@ -125,19 +125,31 @@ public class Target implements TaskContainer { | |||||
* depends on. Must not be <code>null</code>. | * depends on. Must not be <code>null</code>. | ||||
*/ | */ | ||||
public void setDepends(String depS) { | public void setDepends(String depS) { | ||||
if (depS.length() > 0) { | |||||
for (Iterator iter = parseDepends(depS, getName()).iterator(); | |||||
iter.hasNext(); ) { | |||||
addDependency((String) iter.next()); | |||||
} | |||||
} | |||||
public static List/*<String>*/ parseDepends(String depends, | |||||
String targetName) { | |||||
ArrayList list = new ArrayList(); | |||||
if (depends.length() > 0) { | |||||
StringTokenizer tok = | StringTokenizer tok = | ||||
new StringTokenizer(depS, ",", true); | |||||
new StringTokenizer(depends, ",", true); | |||||
while (tok.hasMoreTokens()) { | while (tok.hasMoreTokens()) { | ||||
String token = tok.nextToken().trim(); | String token = tok.nextToken().trim(); | ||||
// Make sure the dependency is not empty string | // Make sure the dependency is not empty string | ||||
if ("".equals(token) || ",".equals(token)) { | if ("".equals(token) || ",".equals(token)) { | ||||
throw new BuildException("Syntax Error: depends " + "attribute of target \"" | |||||
+ getName() + "\" has an empty string as dependency."); | |||||
throw new BuildException("Syntax Error: depends " | |||||
+ "attribute of target \"" | |||||
+ targetName | |||||
+ "\" has an empty string as " | |||||
+ "dependency."); | |||||
} | } | ||||
addDependency(token); | |||||
list.add(token); | |||||
// Make sure that depends attribute does not | // Make sure that depends attribute does not | ||||
// end in a , | // end in a , | ||||
@@ -145,12 +157,15 @@ public class Target implements TaskContainer { | |||||
token = tok.nextToken(); | token = tok.nextToken(); | ||||
if (!tok.hasMoreTokens() || !",".equals(token)) { | if (!tok.hasMoreTokens() || !",".equals(token)) { | ||||
throw new BuildException("Syntax Error: Depend " | throw new BuildException("Syntax Error: Depend " | ||||
+ "attribute for target \"" + getName() | |||||
+ "\" ends with a , character"); | |||||
+ "attribute for target \"" | |||||
+ targetName | |||||
+ "\" ends with a \",\" " | |||||
+ "character"); | |||||
} | } | ||||
} | } | ||||
} | } | ||||
} | } | ||||
return list; | |||||
} | } | ||||
/** | /** | ||||
@@ -45,6 +45,7 @@ import java.io.UnsupportedEncodingException; | |||||
import java.net.URL; | import java.net.URL; | ||||
import java.util.HashMap; | import java.util.HashMap; | ||||
import java.util.Hashtable; | import java.util.Hashtable; | ||||
import java.util.Iterator; | |||||
import java.util.Map; | import java.util.Map; | ||||
import java.util.Stack; | import java.util.Stack; | ||||
@@ -845,9 +846,25 @@ public class ProjectHelper2 extends ProjectHelper { | |||||
context.getLocator()); | context.getLocator()); | ||||
} | } | ||||
String prefix = null; | |||||
boolean isInIncludeMode = | |||||
context.isIgnoringProjectTag() && isInIncludeMode(); | |||||
if (isInIncludeMode) { | |||||
prefix = getTargetPrefix(context); | |||||
if (prefix == null) { | |||||
throw new BuildException("can't include build file " | |||||
+ context.getBuildFile() | |||||
+ ", no as attribute has been given" | |||||
+ " and the project tag doesn't" | |||||
+ " specify a name attribute"); | |||||
} | |||||
name = prefix + "." + name; | |||||
} | |||||
// Check if this target is in the current build file | // Check if this target is in the current build file | ||||
if (context.getCurrentTargets().get(name) != null) { | if (context.getCurrentTargets().get(name) != null) { | ||||
throw new BuildException("Duplicate target '" + name + "'", target.getLocation()); | |||||
throw new BuildException("Duplicate target '" + name + "'", | |||||
target.getLocation()); | |||||
} | } | ||||
Hashtable projectTargets = project.getTargets(); | Hashtable projectTargets = project.getTargets(); | ||||
boolean usedTarget = false; | boolean usedTarget = false; | ||||
@@ -862,12 +879,19 @@ public class ProjectHelper2 extends ProjectHelper { | |||||
usedTarget = true; | usedTarget = true; | ||||
} | } | ||||
if (depends.length() > 0) { | if (depends.length() > 0) { | ||||
target.setDepends(depends); | |||||
if (!isInIncludeMode) { | |||||
target.setDepends(depends); | |||||
} else { | |||||
for (Iterator iter = | |||||
Target.parseDepends(depends, name).iterator(); | |||||
iter.hasNext(); ) { | |||||
target.addDependency(prefix + "." + iter.next()); | |||||
} | |||||
} | |||||
} | } | ||||
String prefix = null; | |||||
if (context.isIgnoringProjectTag() | |||||
if (!isInIncludeMode && context.isIgnoringProjectTag() | |||||
&& (prefix = getTargetPrefix(context)) != null) { | && (prefix = getTargetPrefix(context)) != null) { | ||||
// In an impored file (and not completely | |||||
// In an imported file (and not completely | |||||
// ignoring the project tag or having a preconfigured prefix) | // ignoring the project tag or having a preconfigured prefix) | ||||
String newName = prefix + "." + name; | String newName = prefix + "." + name; | ||||
Target newTarget = usedTarget ? new Target(target) : target; | Target newTarget = usedTarget ? new Target(target) : target; | ||||
@@ -145,7 +145,7 @@ public class ImportTask extends Task { | |||||
} | } | ||||
} | } | ||||
if (importStack.contains(importedFile)) { | |||||
if (!isInIncludeMode() && importStack.contains(importedFile)) { | |||||
getProject().log( | getProject().log( | ||||
"Skipped already imported file:\n " | "Skipped already imported file:\n " | ||||
+ importedFile + "\n", Project.MSG_VERBOSE); | + importedFile + "\n", Project.MSG_VERBOSE); | ||||
@@ -155,14 +155,36 @@ public class ImportTask extends Task { | |||||
// nested invokations are possible like an imported file | // nested invokations are possible like an imported file | ||||
// importing another one | // importing another one | ||||
String oldPrefix = ProjectHelper.getCurrentTargetPrefix(); | String oldPrefix = ProjectHelper.getCurrentTargetPrefix(); | ||||
boolean oldIncludeMode = ProjectHelper.isInIncludeMode(); | |||||
try { | try { | ||||
ProjectHelper.setCurrentTargetPrefix(targetPrefix); | ProjectHelper.setCurrentTargetPrefix(targetPrefix); | ||||
ProjectHelper.setInIncludeMode(isInIncludeMode()); | |||||
helper.parse(getProject(), importedFile); | helper.parse(getProject(), importedFile); | ||||
} catch (BuildException ex) { | } catch (BuildException ex) { | ||||
throw ProjectHelper.addLocationToBuildException( | throw ProjectHelper.addLocationToBuildException( | ||||
ex, getLocation()); | ex, getLocation()); | ||||
} finally { | } finally { | ||||
ProjectHelper.setCurrentTargetPrefix(oldPrefix); | ProjectHelper.setCurrentTargetPrefix(oldPrefix); | ||||
ProjectHelper.setInIncludeMode(oldIncludeMode); | |||||
} | } | ||||
} | } | ||||
/** | |||||
* Whether the task is in include (as opposed to import) mode. | |||||
* | |||||
* <p>In include mode included targets are only known by their | |||||
* prefixed names and their depends lists get rewritten so that | |||||
* all dependencies get the prefix as well.</p> | |||||
* | |||||
* <p>In import mode imported targets are known by an adorned as | |||||
* well as a prefixed name and the unadorned target may be | |||||
* overwritten in the importing build file. The depends list of | |||||
* the imported targets is not modified at all.</p> | |||||
* | |||||
* @since Ant 1.8.0 | |||||
*/ | |||||
protected final boolean isInIncludeMode() { | |||||
return "include".equals(getTaskType()); | |||||
} | |||||
} | } |
@@ -56,6 +56,7 @@ get=org.apache.tools.ant.taskdefs.Get | |||||
gunzip=org.apache.tools.ant.taskdefs.GUnzip | gunzip=org.apache.tools.ant.taskdefs.GUnzip | ||||
gzip=org.apache.tools.ant.taskdefs.GZip | gzip=org.apache.tools.ant.taskdefs.GZip | ||||
import=org.apache.tools.ant.taskdefs.ImportTask | import=org.apache.tools.ant.taskdefs.ImportTask | ||||
include=org.apache.tools.ant.taskdefs.ImportTask | |||||
input=org.apache.tools.ant.taskdefs.Input | input=org.apache.tools.ant.taskdefs.Input | ||||
jar=org.apache.tools.ant.taskdefs.Jar | jar=org.apache.tools.ant.taskdefs.Jar | ||||
java=org.apache.tools.ant.taskdefs.Java | java=org.apache.tools.ant.taskdefs.Java | ||||
@@ -28,4 +28,22 @@ | |||||
<target name="testExplicitPrefix" depends="c.b"> | <target name="testExplicitPrefix" depends="c.b"> | ||||
<au:assertEquals expected="baz" actual="${foo}"/> | <au:assertEquals expected="baz" actual="${foo}"/> | ||||
</target> | </target> | ||||
<target name="testNoExplicitPrefixUsedWithoutPrefix" depends="a"> | |||||
<au:assertEquals expected="bar" actual="${foo}"/> | |||||
</target> | |||||
<target name="testExplicitPrefixUsedWithoutPrefix" depends="b"> | |||||
<au:assertEquals expected="baz" actual="${foo}"/> | |||||
</target> | |||||
<import file="importtests/override.xml"/> | |||||
<target name="setProperty"> | |||||
<property name="prop" value="in including/importing"/> | |||||
</target> | |||||
<target name="testOverride" depends="override.dummy"> | |||||
<au:assertEquals expected="in including/importing" actual="${prop}"/> | |||||
</target> | |||||
</project> | </project> |
@@ -0,0 +1,25 @@ | |||||
<?xml version="1.0"?> | |||||
<!-- | |||||
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. | |||||
--> | |||||
<project name="override"> | |||||
<target name="setProperty"> | |||||
<property name="prop" value="in included/imported"/> | |||||
</target> | |||||
<target name="dummy" depends="setProperty"/> | |||||
</project> | |||||
@@ -0,0 +1,41 @@ | |||||
<?xml version="1.0"?> | |||||
<!-- | |||||
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. | |||||
--> | |||||
<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit"> | |||||
<import file="../antunit-base.xml" /> | |||||
<include file="importtests/a.xml"/> | |||||
<include file="importtests/b.xml" as="c"/> | |||||
<target name="testNoExplicitPrefix" depends="a.a"> | |||||
<au:assertEquals expected="bar" actual="${foo}"/> | |||||
</target> | |||||
<target name="testExplicitPrefix" depends="c.b"> | |||||
<au:assertEquals expected="baz" actual="${foo}"/> | |||||
</target> | |||||
<include file="importtests/override.xml"/> | |||||
<target name="setProperty"> | |||||
<property name="prop" value="in including/importing"/> | |||||
</target> | |||||
<target name="testNoOverride" depends="override.dummy"> | |||||
<au:assertEquals expected="in included/imported" actual="${prop}"/> | |||||
</target> | |||||
</project> |