Skip to content

Commit

Permalink
WindowsPlugin: support multiple wxs sources (#1176) (#1177)
Browse files Browse the repository at this point in the history
* Implement building from multiple WiX sources

* Add a test for custom WiX sources in WindowsPlugin

* Fix code formatting

* Remove unnecessary overwrite flag

* Fix for SBT 0.13
  • Loading branch information
nigredo-tori authored and muuki88 committed Nov 29, 2018
1 parent 01ac7a8 commit fe0c8f9
Show file tree
Hide file tree
Showing 8 changed files with 105 additions and 13 deletions.
4 changes: 3 additions & 1 deletion src/main/scala/com/typesafe/sbt/packager/windows/Keys.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ trait WindowsKeys {
TaskKey[xml.Node]("wix-product-xml", "The WIX XML configuration for a product (nested in Wix/Product elements).")
val wixConfig =
TaskKey[xml.Node]("wix-xml", "The WIX XML configuration for this package.")
val wixFile = TaskKey[File]("wix-file", "The WIX XML file to package with.")
@deprecated("Use wixFiles task instead", "1.3.15")
val wixFile = TaskKey[File]("wix-file", "The generated WIX XML file.")
val wixFiles = TaskKey[Seq[File]]("wix-files", "WIX XML sources (*.wxs) to package with")
val candleOptions = SettingKey[Seq[String]]("candle-options", "Options to pass to the candle.exe program.")
val lightOptions = SettingKey[Seq[String]]("light-options", "Options to pass to the light.exe program.")
val wixMajorVersion =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,27 +96,45 @@ object WindowsPlugin extends AutoPlugin {
val wixConfigFile = (target in Windows).value / ((name in Windows).value + ".wxs")
IO.write(wixConfigFile, config.toString)
wixConfigFile
}
},
wixFiles := Seq(wixFile.value)
) ++ inConfig(Windows)(Seq(packageBin := {
val wixFileValue = wixFile.value
val wsxSources = wixFiles.value
val msi = target.value / (name.value + ".msi")
// First we have to move everything (including the wix file) to our target directory.
val wix = target.value / (name.value + ".wix")
if (wixFileValue.getAbsolutePath != wix.getAbsolutePath) IO.copyFile(wixFileValue, wix)

// First we have to move everything (including the WIX scripts)
// to our target directory.
val targetFlat: Path.FileMap = Path.flat(target.value)
val wsxFiles = wsxSources.map(targetFlat(_).get)
val wsxCopyPairs = wsxSources.zip(wsxFiles).filter {
case (src, dest) => src.getAbsolutePath != dest.getAbsolutePath
}
IO.copy(wsxCopyPairs)
IO.copy(for ((f, to) <- mappings.value) yield (f, target.value / to))

// Now compile WIX
val wixdir = Option(System.getenv("WIX")) getOrElse sys.error(
"WIX environment not found. Please ensure WIX is installed on this computer."
)
val candleCmd = Seq(wixdir + "\\bin\\candle.exe", wix.getAbsolutePath) ++ candleOptions.value
val candleCmd = (wixdir + "\\bin\\candle.exe") +:
wsxFiles.map(_.getAbsolutePath) ++:
candleOptions.value
val wixobjFiles = wsxFiles.map { wsx =>
wsx.getParentFile / (wsx.base + ".wixobj")
}

streams.value.log.debug(candleCmd mkString " ")
sys.process.Process(candleCmd, Some(target.value)) ! streams.value.log match {
case 0 => ()
case exitCode => sys.error(s"Unable to run WIX compilation to wixobj. Exited with ${exitCode}")
}

// Now create MSI
val wixobj = target.value / (name.value + ".wixobj")
val lightCmd = Seq(wixdir + "\\bin\\light.exe", wixobj.getAbsolutePath) ++ lightOptions.value
val lightCmd = List(wixdir + "\\bin\\light.exe", "-out", msi.getAbsolutePath) ++ wixobjFiles.map(
_.getAbsolutePath
) ++
lightOptions.value

streams.value.log.debug(lightCmd mkString " ")
sys.process.Process(lightCmd, Some(target.value)) ! streams.value.log match {
case 0 => ()
Expand Down
14 changes: 14 additions & 0 deletions src/sbt-test/windows/custom-wix/build.sbt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
enablePlugins(WindowsPlugin)

name := "custom-wix"
version := "0.1.0"

// make sure we don't somehow use the generated script
wixFile in Windows := {
sys.error("wixFile shouldn't have been called")
}

wixFiles := List(
sourceDirectory.value / "wix" / "main.wsx",
sourceDirectory.value / "wix" / "ui.wsx"
)
1 change: 1 addition & 0 deletions src/sbt-test/windows/custom-wix/project/plugins.sbt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % sys.props("project.version"))
47 changes: 47 additions & 0 deletions src/sbt-test/windows/custom-wix/src/wix/main.wsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">

<!-- Use * to generate product ID on every build -->
<Product
Id="*"
Name="Custom WiX build"
Language="1033"
Version="1.0.0.0"
Manufacturer="sbt-native-packager"
UpgradeCode="424a691a-627d-47c2-b5b7-39fed4fe69e9">

<Package
Compressed="yes"
InstallScope="perMachine"
Manufacturer="software architects"
Description="Demo installer for learning WiX basics."
Comments="(c) 2012 software architects" />

<Media Id="1" Cabinet="custom.cab" EmbedCab="yes" />

<!--Directory structure-->
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="CustomDir" Name="Custom WiX build" />
</Directory>
</Directory>

<!--Components-->
<DirectoryRef Id="CustomDir">
<Component Id="CustomComponent" Guid="37de77f3-e716-486b-a859-600ba4edc466">
<CreateFolder/>
</Component>
</DirectoryRef>

<!--Features-->
<Feature
Id="CustomFeature"
Title="Custom WiX feature"
Level="1">

<ComponentRef Id="CustomComponent" />
</Feature>

<UIRef Id="CustomUI"/>
</Product>
</Wix>
7 changes: 7 additions & 0 deletions src/sbt-test/windows/custom-wix/src/wix/ui.wsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<!-- No actual UI - just something to reference -->
<UI Id="CustomUI" />
</Fragment>
</Wix>
3 changes: 3 additions & 0 deletions src/sbt-test/windows/custom-wix/test
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Run the windows packaging.
> windows:packageBin
$ exists target/windows/custom-wix.msi
8 changes: 4 additions & 4 deletions src/sphinx/formats/windows.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ it's important to understand how WIX works. http://wix.tramontana.co.hu/ is an
to how to create packages using wix.

However, the native-packager provides a simple layer on top of wix that *may* be enough for most projects.
If it is not enough, just override ``wixConfig`` or ``wixFile`` settings. Let's look at the layer above direct
If it is not enough, just override ``wixConfig`` or ``wixFiles`` tasks. Let's look at the layer above direct
xml configuration.

.. note:: The windows plugin depends on the :ref:`universal-plugin`.
Expand Down Expand Up @@ -109,10 +109,10 @@ Settings
inline XML to use for wix configuration. This is everything nested inside the ``<Product>`` element.

``wixConfig``
inline XML to use for wix configuration. This is used if the ``wixFile`` setting is not specified.
inline XML to use for wix configuration. This is used if the ``wixFiles`` task is not specified.

``wixFile``
The file containing WIX xml that defines the build.
``wixFiles``
WIX xml source files (``wxs``) that define the build.

``mappings in packageMsi in Windows``
A list of file->location pairs. This list is used to move files into a location where WIX can pick up the files and generate a ``cab`` or embedded ``cab`` for the ``msi``.
Expand Down

0 comments on commit fe0c8f9

Please sign in to comment.