make WiX task work
git-svn-id: https://svn.apache.org/repos/asf/ant/antlibs/dotnet/trunk@411883 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/CONTRIBUTORS b/CONTRIBUTORS
index cca76fb..c852f07 100644
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
@@ -1 +1,2 @@
Brian Watson
+Stefan Bodewig
diff --git a/README b/README
index 70bc73d..606ee20 100644
--- a/README
+++ b/README
@@ -1,10 +1,5 @@
-dotnet sandbox README
-=====================
-
-Author:
--------
-
-Stefan Bodewig, but feel free to go ahead and modify to your liking.
+dotnet README
+=============
Goal:
-----
@@ -34,5 +29,3 @@
* A <nunit> task.
-Those tasks should end up in an antlib of their own in order to be
-distributable independent of Ant.
diff --git a/docs/index.html b/docs/index.html
index 66272d8..4bddc6c 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -127,7 +127,8 @@
<li><a href="msbuild.html">msbuild</a> - execute the MSBuild build
tool of Microsoft's .NET framework 2.0.</li>
- <li><a href="wix.html">wix</a> - execute the WiX toolset, untested.</li>
+ <li><a href="wix.html">wix</a> - execute candle and/or light of
+ the WiX toolset.</li>
<li><a href="nunit.html">nunit</a> - execute the
nunit-console.exe <a href="http://www.nunit.org/">NUnit</a>
@@ -135,6 +136,6 @@
</ul>
<hr/>
- <p align="center">Copyright © 2003-2005 The Apache Software Foundation. All rights Reserved.</p>
+ <p align="center">Copyright © 2003-2006 The Apache Software Foundation. All rights Reserved.</p>
</body>
</html>
diff --git a/docs/wix.html b/docs/wix.html
index a79ff99..b007385 100644
--- a/docs/wix.html
+++ b/docs/wix.html
@@ -9,8 +9,9 @@
<h3>Description</h3>
- <p>Runs the candle, light or both from the <a
- href="http://sourceforge.net/projects/wix">Wix</a> toolset.</p>
+ <p>Runs candle or light from the <a
+ href="http://sourceforge.net/projects/wix">Wix</a> toolset - or
+ both of them in sequence.</p>
<h3>Parameters</h3>
<table border="1" cellpadding="2" cellspacing="0">
@@ -44,6 +45,19 @@
Specify the framework to use.</td>
<td align="center">No.</td>
</tr>
+ <tr>
+ <td valign="top">wixHome</td>
+ <td valign="top">Installation directory of WiX.</td>
+ <td align="center">No - Ant will assume WiX is on your PATH
+ otherwise.</td>
+ </tr>
+ <tr>
+ <td valign="top">wixobjDestDir</td>
+ <td valign="top">Directory that shall hold the .wixobj files
+ generated by candle.</td>
+ <td align="center">No - Ant will candle have its way and use
+ the current working directory if omitted.</td>
+ </tr>
</table>
<h3>Parameters specified as nested elements</h3>
@@ -61,11 +75,19 @@
href="http://ant.apache.org/manual/CoreTypes/fileset.html">fileset</a>.</p>
<p>Typically this would list include files when running candle or
- the files that vecome part of the MSI file when running light.
- The files in this set are only used for timestamp comparisons. If
- neither these files nor the given "normal" sources are
- newer than the expected target, the task won't do anything.</p>
+ the files that become part of the MSI file when running light.</p>
+ <p>The files in this set are only used for timestamp comparisons.
+ If neither these files nor the given "normal" sources
+ are newer than the expected target, the task won't do
+ anything.</p>
+
+ <h4>candleParameters</h4>
+
+ <p>Specifies preprocessor parameters for candle</p>
+
+ <p><code>candleParameters</code> has two required attributes.
+ name and value that specify name and value of a parameter.</p>
<h3>Examples</h3>
@@ -172,6 +194,6 @@
do anything.</p>
<hr/>
- <p align="center">Copyright © 2004 The Apache Software Foundation. All rights Reserved.</p>
+ <p align="center">Copyright © 2004,2006 The Apache Software Foundation. All rights Reserved.</p>
</body>
</html>
\ No newline at end of file
diff --git a/src/main/org/apache/ant/dotnet/WixTask.java b/src/main/org/apache/ant/dotnet/WixTask.java
index b7895aa..c6cc2be 100644
--- a/src/main/org/apache/ant/dotnet/WixTask.java
+++ b/src/main/org/apache/ant/dotnet/WixTask.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2004-2005 The Apache Software Foundation
+ * Copyright 2004-2006 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,8 +25,12 @@
import java.io.File;
import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
+import java.util.Set;
/**
* Task to run the WiX utility to create MSI files from an XML description.
@@ -66,6 +70,21 @@
*/
private Mode mode;
+ /**
+ * Where is WiX installed?
+ */
+ private File wixHome = null;
+
+ /**
+ * Where to place the generated .wixobj files.
+ */
+ private File wixobjDestDir = null;
+
+ /**
+ * list of parameters for the preprocessor.
+ */
+ private ArrayList parameters = new ArrayList();
+
public WixTask() {
super();
}
@@ -92,6 +111,15 @@
}
/**
+ * The main target file.
+ *
+ * @param File object of the main target file.
+ */
+ public void setTarget(File f) {
+ target = f;
+ }
+
+ /**
* A set of source files.
*/
public void addSources(FileSet fs) {
@@ -110,11 +138,51 @@
moreSources.add(fs);
}
+ /**
+ * Sets the installation directory of WiX.
+ *
+ * <p>If omitted, Ant will assume that WiX's executables can be
+ * found on the PATH.</p>
+ */
+ public void setWixHome(File f) {
+ wixHome = f;
+ }
+
+ /**
+ * Whether to run candle, light or both.
+ */
+ public void setMode(Mode m) {
+ mode = m;
+ }
+
+ /**
+ * Sets the destination directory for wixobj files generated by candle.
+ *
+ * <p>Let's candle decide and assumes they'll be created in the
+ * current working directory.</p>
+ */
+ public void setWixobjDestDir(File f) {
+ wixobjDestDir = f;
+ }
+
+ /**
+ * A parameter to pass to candle.exe.
+ */
+ public final void addCandleParameter(AbstractBuildTask.Property t) {
+ parameters.add(t);
+ }
+
public void execute() {
if (source == null && sources.size() == 0) {
throw new BuildException("You must specify at least one source"
+ " file.");
}
+
+ if (source != null && !source.exists()) {
+ throw new BuildException("Source file " + source
+ + " doesn't exist.");
+ }
+
String m = Mode.BOTH;
if (mode != null) {
m = mode.getValue();
@@ -125,10 +193,11 @@
+ " to run light.");
}
- List lightSources = new ArrayList();
+ Collection lightSources = null;
if (!m.equals(Mode.LIGHT)) {
- doCandle(lightSources);
+ lightSources = doCandle();
} else {
+ lightSources = new HashSet();
if (source != null) {
lightSources.add(source);
}
@@ -136,11 +205,12 @@
lightSources.addAll(grabFiles(sources));
}
}
- List moreLightSources = new ArrayList();
- if (moreSources.size() > 0) {
- moreLightSources = grabFiles(moreSources);
- }
+
if (!m.equals(Mode.CANDLE)) {
+ Collection moreLightSources = Collections.EMPTY_SET;
+ if (moreSources.size() > 0) {
+ moreLightSources = grabFiles(moreSources);
+ }
doLight(lightSources, moreLightSources);
}
}
@@ -148,44 +218,45 @@
/**
* Invoke candle on all sources that are newer than their targets.
*
- * @param lightSources list that will be filled with File objects
- * pointing to the generated object files.
+ * @return a set of File objects pointing to the generated files.
*/
- private void doCandle(List lightSources) {
- List s = new ArrayList();
+ private Collection doCandle() {
+ Set s = new HashSet();
if (source != null) {
s.add(source);
}
if (sources != null) {
s.addAll(grabFiles(sources));
}
- List ms = new ArrayList();
+ Set ms = new HashSet();
if (moreSources != null) {
ms.addAll(grabFiles(moreSources));
}
+
+ Set toProcess = new HashSet();
+ Set generatedTargets = new HashSet();
Iterator iter = s.iterator();
- List toProcess = new ArrayList();
while (iter.hasNext()) {
File thisSource = (File) iter.next();
- File t = target;
- if (t == null) {
- t = getTarget(thisSource);
- }
+ File t = getTarget(thisSource);
+ generatedTargets.add(t);
if (isOutOfDate(t, thisSource, ms)) {
toProcess.add(thisSource);
- lightSources.add(t);
}
}
if (toProcess.size() != 0) {
runCandle(toProcess);
+ return generatedTargets;
}
+ return Collections.EMPTY_SET;
}
/**
* Invoke light on all sources that are newer than their targets.
*/
- private void doLight(List lightSources, List moreLightSources) {
- List tmp = new ArrayList(lightSources);
+ private void doLight(Collection lightSources,
+ Collection moreLightSources) {
+ Set tmp = new HashSet(lightSources);
tmp.addAll(moreLightSources);
if (isOutOfDate(target, tmp)) {
runLight(lightSources);
@@ -193,26 +264,45 @@
}
/**
- * Run candle passing all files in list on the command line.
+ * Run candle passing all files of the collection on the command line.
*/
- private void runCandle(List s) {
- run("candle.exe", s, null);
+ private void runCandle(Collection s) {
+ run(wixExecutable("candle.exe"), s, null, wixobjDestDir, parameters);
}
/**
- * Run light passing all files in list on the command line.
+ * Run light passing all files of the collection on the command line.
*/
- private void runLight(List s) {
- run("light.exe", s, target);
+ private void runLight(Collection s) {
+ run(wixExecutable("light.exe"), s, target, null, Collections.EMPTY_LIST);
}
/**
- * Runs the specified command passing list on the command line an
- * potentially adding an /out parameter.
+ * returns an absolute path for the given executable if wixHome
+ * has been specified, the given name otherwise.
*/
- private void run(String executable, List s, File target) {
+ private String wixExecutable(String name) {
+ return wixHome == null ? name
+ : new File(wixHome, name).getAbsolutePath();
+ }
+
+ /**
+ * Runs the specified command passing all files of the collection
+ * on the command line - potentially adding an /out parameter.
+ */
+ private void run(String executable, Collection s, File target,
+ File runInDir, Collection params) {
DotNetExecTask exec = DotNetExecTask.getTask(this, vm,
executable, null);
+ if (runInDir != null) {
+ exec.setDir(runInDir);
+ }
+
+ exec.setFailonerror(true);
+ exec.setTaskType("wix");
+
+ exec.createArg().setValue("/nologo");
+
Iterator iter = s.iterator();
while (iter.hasNext()) {
File f = (File) iter.next();
@@ -223,20 +313,27 @@
exec.createArg().setValue(target.getAbsolutePath());
}
+ iter = params.iterator();
+ while (iter.hasNext()) {
+ AbstractBuildTask.Property p =
+ (AbstractBuildTask.Property) iter.next();
+ exec.createArg().setValue("-d" + p.getName() + "=" + p.getValue());
+ }
+
exec.execute();
}
/**
* Is t older than s or any of the files in list?
*/
- private boolean isOutOfDate(File t, File s, List l) {
+ private boolean isOutOfDate(File t, File s, Collection l) {
return t.lastModified() < s.lastModified() || isOutOfDate(t, l);
}
/**
* Is t older than any of the files in list?
*/
- private boolean isOutOfDate(File t, List l) {
+ private boolean isOutOfDate(File t, Collection l) {
Iterator iter = l.iterator();
while (iter.hasNext()) {
File f = (File) iter.next();
@@ -250,8 +347,8 @@
/**
* Turn the fileset collection into a list of Files.
*/
- private List grabFiles(List s) {
- List r = new ArrayList();
+ private Collection grabFiles(Collection s) {
+ Set r = new HashSet();
Iterator iter = s.iterator();
while (iter.hasNext()) {
FileSet fs = (FileSet) iter.next();
@@ -268,16 +365,20 @@
/**
* Generates the name of a candle target from the source file.
*
- * <p>Simply chops of the extension and adds .wixobj.</p>
+ * <p>Simply chops of the extension, adds .wixobj and calculates
+ * the absolute path based on wixobjDestDir.</p>
*/
private File getTarget(File s) {
- String name = s.getAbsolutePath();
+ String name = s.getName();
int dot = name.lastIndexOf(".");
if (dot > -1) {
- return new File(name.substring(0, dot) + ".wixobj");
+ name = name.substring(0, dot) + ".wixobj";
} else {
- return new File(name + ".wixobj");
+ name = name + ".wixobj";
}
+
+ return wixobjDestDir == null
+ ? new File(name) : new File(wixobjDestDir, name);
}
public static class Mode extends EnumeratedAttribute {