Browse Source

very experimental WiX task

git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@276334 13f79535-47bb-0310-9956-ffa450edef68
master
Stefan Bodewig 21 years ago
parent
commit
41b4662f9a
4 changed files with 484 additions and 0 deletions
  1. +2
    -0
      proposal/sandbox/dotnet/docs/index.html
  2. +177
    -0
      proposal/sandbox/dotnet/docs/wix.html
  3. +301
    -0
      proposal/sandbox/dotnet/src/main/org/apache/tools/ant/taskdefs/optional/dotnet/WixTask.java
  4. +4
    -0
      proposal/sandbox/dotnet/src/main/org/apache/tools/ant/taskdefs/optional/dotnet/antlib.xml

+ 2
- 0
proposal/sandbox/dotnet/docs/index.html View File

@@ -111,6 +111,8 @@

<li><a href="msbuild.html">msbuild</a> - execute the MSBuild build
tool, untested.</li>

<li><a href="wix.html">wix</a> - execute the WiX toolset, untested.</li>
</ul>

<hr/>


+ 177
- 0
proposal/sandbox/dotnet/docs/wix.html View File

@@ -0,0 +1,177 @@
<html>
<head>
<meta http-equiv="Content-Language" content="en-us"></meta>
<title>Wix Task</title>
</head>

<body>
<h2>Wix</h2>

<h3>Description</h3>

<p>Runs the candle, light or both from the <a
href="http://sourceforge.net/projects/wix">Wix</a> toolset.</p>

<h3>Parameters</h3>
<table border="1" cellpadding="2" cellspacing="0">
<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">source</td>
<td valign="top">The single source file to process.</td>
<td align="center">Either this or at least one nested
&lt;sources&gt; set.</td>
</tr>
<tr>
<td valign="top">target</td>
<td valign="top">The expected target file.</td>
<td align="center">Yes, unless you run candle without light.</td>
</tr>
<tr>
<td valign="top">mode</td>
<td valign="top">Which part of the toolset to run, one of
&quot;candle&quot;, &quot;light&quot; or
&quot;both&quot;.</td>
<td align="center">No, default is &quot;both&quot;.</td>
</tr>
<tr>
<td valign="top">vm</td>
<td valign="top">Same as <a
href="dotnetexec.html">dotnetexec</a>'s vm attribute.
Specify the framework to use.</td>
<td align="center">No.</td>
</tr>
</table>

<h3>Parameters specified as nested elements</h3>

<h4>sources</h4>

<p>Specify source files that shall be passed on the command line.
This is a <a
href="http://ant.apache.org/manual/CoreTypes/fileset.html">fileset</a>.</p>

<h4>moresources</h4>

<p>Specify source files that shall not be passed on the command
line. This is a <a
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 &quot;normal&quot; sources are
newer than the expected target, the task won't do anything.</p>


<h3>Examples</h3>

<p>Create <code>product.wixobj</code> from <code>product.wxs</code>:</p>

<pre>
&lt;wix mode="candle" source="product.wxs"/&gt;
</pre>

<p>The same but using a nested sources element:</p>

<pre>
&lt;wix mode="candle"&gt;
&lt;sources dir="."&gt;
&lt;include name="product.wxs"/&gt;
&lt;/sources&gt;
&lt;/wix&gt;
</pre>

<p>Create <code>product.msi</code> from <code>product.wixobj</code>:</p>

<pre>
&lt;wix mode="light" source="product.wixobj" target="product.msi"/&gt;
</pre>

<p>Combine the examples into a single step:</p>

<pre>
&lt;wix source="product.wxs" target="product.msi"/&gt;
</pre>

<p>Note that the task wouldn't do anything if
<code>product.wxs</code> was older than
<code>product.wixobj</code> and <code>product.wixobj</code> was
older than <code>product.msi</code>.</p>

<p>Compile multiple <code>.wxs</code> files at once:</p>

<pre>
&lt;wix mode="candle"&gt;
&lt;sources dir="."&gt;
&lt;include name="*.wxs"/&gt;
&lt;/sources&gt;
&lt;/wix&gt;
</pre>

<p>Compile multiple <code>.wxs</code> files at once, specify some
include files in addition to that:</p>

<pre>
&lt;wix mode="candle"&gt;
&lt;sources dir="."&gt;
&lt;include name="*.wxs"/&gt;
&lt;/sources&gt;
&lt;moresources dir="."&gt;
&lt;include name="*.wxi"/&gt;
&lt;/moresources&gt;
&lt;/wix&gt;
</pre>

<p>Link multiple <code>.wixobj</code> files at once:</p>

<pre>
&lt;wix mode="light" target="product.msi"&gt;
&lt;sources dir="."&gt;
&lt;include name="*.wixobj"/&gt;
&lt;/sources&gt;
&lt;/wix&gt;
</pre>

<p>Link multiple <code>.wixobj</code> files at once and specify
that the files in directory &quot;source&quot; will become part of
the package:</p>

<pre>
&lt;wix mode="light" target="product.msi"&gt;
&lt;sources dir="."&gt;
&lt;include name="*.wixobj"/&gt;
&lt;/sources&gt;
&lt;moresources dir="source"/&gt;
&lt;/wix&gt;
</pre>

<pre>Combine multiple <code>.wxs</code> files and include files
into a single package and specify that the package will contain
files from the source directory:</pre>

<pre>
&lt;wix target="product.msi"&gt;
&lt;sources dir="."&gt;
&lt;include name="*.wxs"/&gt;
&lt;/sources&gt;
&lt;moresources dir="."&gt;
&lt;include name="*.wxi"/&gt;
&lt;/moresources&gt;
&lt;moresources dir="source"/&gt;
&lt;/wix&gt;
</pre>

<p>Again, if the intermediate <code>.wixobj</code> files are newer
that the corresponding <code>.wxs</code> files (and all include
files) the candle step will be skipped. If
<code>product.msi</code> is newer than all files, the task won't
do anything.</p>

<hr/>
<p align="center">Copyright &copy; 2004 The Apache Software Foundation. All rights Reserved.</p>
</body>
</html>

+ 301
- 0
proposal/sandbox/dotnet/src/main/org/apache/tools/ant/taskdefs/optional/dotnet/WixTask.java View File

@@ -0,0 +1,301 @@
/*
* Copyright 2004 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.
* 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.
*
*/

package org.apache.tools.ant.taskdefs.optional.dotnet;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.types.EnumeratedAttribute;
import org.apache.tools.ant.types.FileSet;

import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
* Task to run the WiX utility to create MSI files from an XML description.
*
* @see http://sf.net/projects/wix
*/
public class WixTask extends Task {

/**
* The vm attribute - if given.
*/
private String vm;

/**
* The source files.
*/
private ArrayList sources = new ArrayList();

/**
* Additional source files (include files in the case of candle,
* or media/files/whatever in the case of light).
*/
private ArrayList moreSources = new ArrayList();

/**
* A single source file.
*/
private File source;

/**
* The target file.
*/
private File target;

/**
* What to do.
*/
private Mode mode;

public WixTask() {
super();
}

/**
* Set the name of the executable for the virtual machine.
*
* @param value the name of the executable for the virtual machine
*/
public void setVm(String value) {
this.vm = value;
}

/**
* The main source file.
*
* <p><code>candle</code> may include more files than this one,
* the main source is the one passed on the command line.</p>
*
* @param File object of the main source file.
*/
public void setSource(File f) {
source = f;
}

/**
* A set of source files.
*/
public void addSources(FileSet fs) {
sources.add(fs);
}

/**
* A set of additional source files (include files in the case of
* candle, or media/files/whatever in the case of light).
*
* <p>Unlike the files specified as sources, these will not be
* passed on the command line, they only help Ant to determine
* whether the target is out-of-date.</p>
*/
public void addMoreSources(FileSet fs) {
moreSources.add(fs);
}

public void execute() {
if (source == null && sources.size() == 0) {
throw new BuildException("You must specify at least one source"
+ " file.");
}
String m = Mode.BOTH;
if (mode != null) {
m = mode.getValue();
}

if (target == null && !m.equals(Mode.CANDLE)) {
throw new BuildException("You must specify the target if you want"
+ " to run light.");
}

List lightSources = new ArrayList();
if (!m.equals(Mode.LIGHT)) {
doCandle(lightSources);
} else {
if (source != null) {
lightSources.add(source);
}
if (sources.size() > 0) {
lightSources.addAll(grabFiles(sources));
}
}
List moreLightSources = new ArrayList();
if (moreSources.size() > 0) {
moreLightSources = grabFiles(moreSources);
}
if (!m.equals(Mode.CANDLE)) {
doLight(lightSources, moreLightSources);
}
}

/**
* 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.
*/
private void doCandle(List lightSources) {
List s = new ArrayList();
if (source != null) {
s.add(source);
}
if (sources != null) {
s.addAll(grabFiles(sources));
}
List ms = new ArrayList();
if (moreSources != null) {
ms.addAll(grabFiles(moreSources));
}
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);
}
if (isOutOfDate(t, thisSource, ms)) {
toProcess.add(thisSource);
lightSources.add(t);
}
}
if (toProcess.size() != 0) {
runCandle(toProcess);
}
}

/**
* Invoke light on all sources that are newer than their targets.
*/
private void doLight(List lightSources, List moreLightSources) {
List tmp = new ArrayList(lightSources);
tmp.addAll(moreLightSources);
if (isOutOfDate(target, tmp)) {
runLight(lightSources);
}
}

/**
* Run candle passing all files in list on the command line.
*/
private void runCandle(List s) {
run("candle.exe", s, null);
}

/**
* Run light passing all files in list on the command line.
*/
private void runLight(List s) {
run("light.exe", s, target);
}

/**
* Runs the specified command passing list on the command line an
* potentially adding an /out parameter.
*/
private void run(String executable, List s, File target) {
DotNetExecTask exec = new DotNetExecTask();
if (vm != null) {
exec.setVm(vm);
}
exec.setProject(getProject());
exec.setExecutable(executable);
exec.setTaskName(getTaskName());
Iterator iter = s.iterator();
while (iter.hasNext()) {
File f = (File) iter.next();
exec.createArg().setValue(f.getAbsolutePath());
}
if (target != null) {
exec.createArg().setValue("/out");
exec.createArg().setValue(target.getAbsolutePath());
}
exec.execute();
}

/**
* Is t older than s or any of the files in list?
*/
private boolean isOutOfDate(File t, File s, List 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) {
Iterator iter = l.iterator();
while (iter.hasNext()) {
File f = (File) iter.next();
if (t.lastModified() < f.lastModified()) {
return true;
}
}
return false;
}

/**
* Turn the fileset collection into a list of Files.
*/
private List grabFiles(List s) {
List r = new ArrayList();
Iterator iter = s.iterator();
while (iter.hasNext()) {
FileSet fs = (FileSet) iter.next();
DirectoryScanner ds = fs.getDirectoryScanner(getProject());
String[] f = ds.getIncludedFiles();
File base = fs.getDir(getProject());
for (int i = 0; i < f.length; i++) {
r.add(new File(base, f[i]));
}
}
return r;
}

/**
* Generates the name of a candle target from the source file.
*
* <p>Simply chops of the extension and adds .wixobj.</p>
*/
private File getTarget(File s) {
String name = s.getAbsolutePath();
int dot = name.lastIndexOf(".");
if (dot > -1) {
return new File(name.substring(0, dot) + ".wixobj");
} else {
return new File(name + ".wixobj");
}
}

public static class Mode extends EnumeratedAttribute {
private final static String CANDLE = "candle";
private final static String LIGHT = "light";
private final static String BOTH = "both";

public Mode() {
super();
}

public String[] getValues() {
return new String[] {CANDLE, LIGHT, BOTH,};
}
}
}

+ 4
- 0
proposal/sandbox/dotnet/src/main/org/apache/tools/ant/taskdefs/optional/dotnet/antlib.xml View File

@@ -27,4 +27,8 @@
name="nant"
classname="org.apache.tools.ant.taskdefs.optional.dotnet.NAntTask"
/>
<taskdef
name="wix"
classname="org.apache.tools.ant.taskdefs.optional.dotnet.WixTask"
/>
</antlib>

Loading…
Cancel
Save