git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@275705 13f79535-47bb-0310-9956-ffa450edef68master
@@ -27,4 +27,31 @@ | |||
<property name="foo" value="bar"/> | |||
</msbuild> | |||
</target> | |||
<target name="nested-file"> | |||
<property name="foo" value="bar"/> | |||
<msbuild | |||
xmlns="antlib:org.apache.tools.ant.taskdefs.optional.dotnet" | |||
> | |||
<build> | |||
<Project DefaultTargets="echo"> | |||
<Target Name="echo"> | |||
<Task Name="Echo" Message="foo is ${foo}"/> | |||
</Target> | |||
</Project> | |||
</build> | |||
</msbuild> | |||
</target> | |||
<target name="nested-task"> | |||
<property name="foo" value="bar"/> | |||
<msbuild | |||
xmlns="antlib:org.apache.tools.ant.taskdefs.optional.dotnet" | |||
> | |||
<build> | |||
<Task Name="Echo" Message="foo is ${foo}"/> | |||
</build> | |||
</msbuild> | |||
</target> | |||
</project> |
@@ -27,4 +27,30 @@ | |||
<property name="foo" value="bar"/> | |||
</nant> | |||
</target> | |||
<target name="nested-file"> | |||
<property name="foo" value="bar"/> | |||
<nant | |||
xmlns="antlib:org.apache.tools.ant.taskdefs.optional.dotnet" | |||
> | |||
<build> | |||
<project basedir="." default="echo"> | |||
<target name="echo"> | |||
<echo message="foo is ${foo}"/> | |||
</target> | |||
</project> | |||
</build> | |||
</nant> | |||
</target> | |||
<target name="nested-task"> | |||
<property name="foo" value="bar"/> | |||
<nant | |||
xmlns="antlib:org.apache.tools.ant.taskdefs.optional.dotnet" | |||
> | |||
<build> | |||
<echo message="foo is ${foo}"/> | |||
</build> | |||
</nant> | |||
</target> | |||
</project> |
@@ -54,9 +54,18 @@ | |||
package org.apache.tools.ant.taskdefs.optional.dotnet; | |||
import org.apache.tools.ant.BuildException; | |||
import org.apache.tools.ant.Task; | |||
import org.apache.tools.ant.util.DOMElementWriter; | |||
import org.apache.tools.ant.util.FileUtils; | |||
import org.apache.tools.ant.util.XMLFragment; | |||
import org.w3c.dom.DocumentFragment; | |||
import org.w3c.dom.Element; | |||
import java.io.File; | |||
import java.io.FileOutputStream; | |||
import java.io.IOException; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
@@ -80,6 +89,11 @@ public abstract class AbstractBuildTask extends Task { | |||
*/ | |||
private List properties = new ArrayList(1); | |||
/** | |||
* Nested build file fragment. | |||
*/ | |||
private XMLFragment buildSnippet; | |||
/** | |||
* Empty constructor. | |||
*/ | |||
@@ -93,6 +107,18 @@ public abstract class AbstractBuildTask extends Task { | |||
buildFile = f; | |||
} | |||
/** | |||
* Adds a build file fragment. | |||
*/ | |||
public void addBuild(XMLFragment f) { | |||
if (buildSnippet == null) { | |||
buildSnippet = f; | |||
} else { | |||
throw new BuildException("You must not specify more than one " | |||
+ "build element"); | |||
} | |||
} | |||
/** | |||
* A target. | |||
*/ | |||
@@ -180,10 +206,25 @@ public abstract class AbstractBuildTask extends Task { | |||
*/ | |||
protected abstract String[] getPropertyArguments(List properties); | |||
/** | |||
* Turn the DoucmentFragment into a DOM tree suitable as a build | |||
* file when serialized. | |||
* | |||
* <p>Must throw a BuildException if the snippet can not be turned | |||
* into a build file.</p> | |||
*/ | |||
protected abstract Element makeTree(DocumentFragment f); | |||
/** | |||
* Perform the build. | |||
*/ | |||
public void execute() { | |||
if (buildFile != null && buildSnippet != null) { | |||
throw new BuildException("You must not specify the build file" | |||
+ " attribute and a nested build at the" | |||
+ " same time"); | |||
} | |||
DotNetExecTask exec = new DotNetExecTask(); | |||
exec.setProject(getProject()); | |||
exec.setExecutable(getExecutable()); | |||
@@ -196,10 +237,48 @@ public abstract class AbstractBuildTask extends Task { | |||
for (int i = 0; i < args.length; i++) { | |||
exec.createArg().setValue(args[i]); | |||
} | |||
args = getBuildfileArguments(buildFile); | |||
File generatedFile = null; | |||
if (buildSnippet != null) { | |||
try { | |||
generatedFile = getBuildFile(); | |||
} catch (IOException e) { | |||
throw new BuildException(e); | |||
} | |||
args = getBuildfileArguments(generatedFile); | |||
} else { | |||
args = getBuildfileArguments(buildFile); | |||
} | |||
for (int i = 0; i < args.length; i++) { | |||
exec.createArg().setValue(args[i]); | |||
} | |||
exec.execute(); | |||
try { | |||
exec.execute(); | |||
} finally { | |||
if (generatedFile != null) { | |||
generatedFile.delete(); | |||
} | |||
} | |||
} | |||
private File getBuildFile() throws IOException { | |||
File f = null; | |||
if (buildSnippet != null) { | |||
Element e = makeTree(buildSnippet.getFragment()); | |||
f = FileUtils.newFileUtils().createTempFile("build", ".xml", null); | |||
f.deleteOnExit(); | |||
FileOutputStream out = null; | |||
try { | |||
out = new FileOutputStream(f); | |||
(new DOMElementWriter()).write(e, out); | |||
} finally { | |||
if (out != null) { | |||
out.close(); | |||
} | |||
} | |||
} | |||
return f; | |||
} | |||
} |
@@ -59,11 +59,18 @@ import java.util.Iterator; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
import org.w3c.dom.DocumentFragment; | |||
import org.w3c.dom.Element; | |||
import org.w3c.dom.Node; | |||
import org.w3c.dom.NodeList; | |||
/** | |||
* Runs a MSBuild build process. | |||
*/ | |||
public class MSBuildTask extends AbstractBuildTask { | |||
private static final String TARGET = "generated-by-ant"; | |||
public MSBuildTask() { | |||
super(); | |||
} | |||
@@ -119,4 +126,32 @@ public class MSBuildTask extends AbstractBuildTask { | |||
return new String[0]; | |||
} | |||
} | |||
/** | |||
* Turn the DocumentFragment into a DOM tree suitable as a build | |||
* file when serialized. | |||
* | |||
* <p>If we have exactly one <Project> child, return that. | |||
* Otherwise if we have only <Task> children, wrap them into a | |||
* <Target> which in turn gets wrapped into a <Project>. | |||
* Otherwise, fail.</p> | |||
*/ | |||
protected Element makeTree(DocumentFragment f) { | |||
NodeList nl = f.getChildNodes(); | |||
if (nl.getLength() == 1 | |||
&& nl.item(0).getNodeType() == Node.ELEMENT_NODE | |||
&& nl.item(0).getNodeName().equals("Project")) { | |||
return (Element) nl.item(0); | |||
} else { | |||
Element p = f.getOwnerDocument().createElement("Project"); | |||
p.setAttribute("DefaultTargets", TARGET); | |||
Element t = f.getOwnerDocument().createElement("Target"); | |||
t.setAttribute("Name", TARGET); | |||
p.appendChild(t); | |||
t.appendChild(f); | |||
return p; | |||
} | |||
} | |||
} |
@@ -59,6 +59,11 @@ import java.util.Iterator; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
import org.w3c.dom.DocumentFragment; | |||
import org.w3c.dom.Element; | |||
import org.w3c.dom.Node; | |||
import org.w3c.dom.NodeList; | |||
/** | |||
* Runs a NAnt build process. | |||
*/ | |||
@@ -102,4 +107,25 @@ public class NAntTask extends AbstractBuildTask { | |||
} | |||
return (String[]) al.toArray(new String[al.size()]); | |||
} | |||
/** | |||
* Turn the DocumentFragment into a DOM tree suitable as a build | |||
* file when serialized. | |||
* | |||
* <p>If we have exactly one <project> child, return that. | |||
* Otherwise assume that this is a valid build file snippet that | |||
* just needs an empty project wrapped around it.</p> | |||
*/ | |||
protected Element makeTree(DocumentFragment f) { | |||
NodeList nl = f.getChildNodes(); | |||
if (nl.getLength() == 1 | |||
&& nl.item(0).getNodeType() == Node.ELEMENT_NODE | |||
&& nl.item(0).getNodeName().equals("project")) { | |||
return (Element) nl.item(0); | |||
} else { | |||
Element e = f.getOwnerDocument().createElement("project"); | |||
e.appendChild(f); | |||
return e; | |||
} | |||
} | |||
} |
@@ -86,4 +86,16 @@ public class MSBuildTaskTest extends BuildFileTest { | |||
expectLogContaining("echo", "foo is bar"); | |||
} | |||
} | |||
public void testNestedFile() throws Exception { | |||
if (getProject().getProperty("msbuild.found") != null) { | |||
expectLogContaining("nested-file", "foo is bar"); | |||
} | |||
} | |||
public void testNestedTask() throws Exception { | |||
if (getProject().getProperty("msbuild.found") != null) { | |||
expectLogContaining("nested-task", "foo is bar"); | |||
} | |||
} | |||
} |
@@ -86,4 +86,16 @@ public class NAntTaskTest extends BuildFileTest { | |||
expectLogContaining("echo", "foo is bar"); | |||
} | |||
} | |||
public void testNestedFile() throws Exception { | |||
if (getProject().getProperty("nant.found") != null) { | |||
expectLogContaining("nested-file", "foo is bar"); | |||
} | |||
} | |||
public void testNestedTask() throws Exception { | |||
if (getProject().getProperty("nant.found") != null) { | |||
expectLogContaining("nested-task", "foo is bar"); | |||
} | |||
} | |||
} |