From 9afa25662edaae96d7845a3daeb812489e6d6c18 Mon Sep 17 00:00:00 2001 From: Dmitry Polienko Date: Wed, 28 Nov 2018 16:30:35 +0700 Subject: [PATCH 1/5] Implement building from multiple WiX sources --- .../typesafe/sbt/packager/windows/Keys.scala | 4 +- .../sbt/packager/windows/WindowsPlugin.scala | 38 +++++++++++++++---- src/sphinx/formats/windows.rst | 8 ++-- 3 files changed, 37 insertions(+), 13 deletions(-) diff --git a/src/main/scala/com/typesafe/sbt/packager/windows/Keys.scala b/src/main/scala/com/typesafe/sbt/packager/windows/Keys.scala index 9f276cfbe..5e2fa74b9 100644 --- a/src/main/scala/com/typesafe/sbt/packager/windows/Keys.scala +++ b/src/main/scala/com/typesafe/sbt/packager/windows/Keys.scala @@ -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 = diff --git a/src/main/scala/com/typesafe/sbt/packager/windows/WindowsPlugin.scala b/src/main/scala/com/typesafe/sbt/packager/windows/WindowsPlugin.scala index 21ab54bf3..853cad403 100644 --- a/src/main/scala/com/typesafe/sbt/packager/windows/WindowsPlugin.scala +++ b/src/main/scala/com/typesafe/sbt/packager/windows/WindowsPlugin.scala @@ -96,27 +96,49 @@ 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) + IO.copy( + wsxSources.zip(wsxFiles).filter { + case (src, dest) => src.getAbsolutePath != dest.getAbsolutePath + }, + CopyOptions().withOverwrite(true) + ) 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 => () diff --git a/src/sphinx/formats/windows.rst b/src/sphinx/formats/windows.rst index b30ce00e0..02bcd0c84 100644 --- a/src/sphinx/formats/windows.rst +++ b/src/sphinx/formats/windows.rst @@ -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`. @@ -109,10 +109,10 @@ Settings inline XML to use for wix configuration. This is everything nested inside the ```` 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``. From a305fc225d85c44b5d381b9ede64378b0c513c56 Mon Sep 17 00:00:00 2001 From: Dmitry Polienko Date: Wed, 28 Nov 2018 16:59:57 +0700 Subject: [PATCH 2/5] Add a test for custom WiX sources in WindowsPlugin --- src/sbt-test/windows/custom-wix/build.sbt | 14 ++++++ .../windows/custom-wix/project/plugins.sbt | 1 + .../windows/custom-wix/src/wix/main.wsx | 47 +++++++++++++++++++ .../windows/custom-wix/src/wix/ui.wsx | 7 +++ src/sbt-test/windows/custom-wix/test | 3 ++ 5 files changed, 72 insertions(+) create mode 100644 src/sbt-test/windows/custom-wix/build.sbt create mode 100644 src/sbt-test/windows/custom-wix/project/plugins.sbt create mode 100644 src/sbt-test/windows/custom-wix/src/wix/main.wsx create mode 100644 src/sbt-test/windows/custom-wix/src/wix/ui.wsx create mode 100644 src/sbt-test/windows/custom-wix/test diff --git a/src/sbt-test/windows/custom-wix/build.sbt b/src/sbt-test/windows/custom-wix/build.sbt new file mode 100644 index 000000000..6f6a54c79 --- /dev/null +++ b/src/sbt-test/windows/custom-wix/build.sbt @@ -0,0 +1,14 @@ +enablePlugins(WindowsPlugin) + +name := "custom-wix" +version := "0.1.0" + +// make sure we don't somehow use the generated script +Windows / wixFile := { + sys.error("wixFile shouldn't have been called") +} + +wixFiles := List( + sourceDirectory.value / "wix" / "main.wsx", + sourceDirectory.value / "wix" / "ui.wsx" +) diff --git a/src/sbt-test/windows/custom-wix/project/plugins.sbt b/src/sbt-test/windows/custom-wix/project/plugins.sbt new file mode 100644 index 000000000..b53de154c --- /dev/null +++ b/src/sbt-test/windows/custom-wix/project/plugins.sbt @@ -0,0 +1 @@ +addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % sys.props("project.version")) diff --git a/src/sbt-test/windows/custom-wix/src/wix/main.wsx b/src/sbt-test/windows/custom-wix/src/wix/main.wsx new file mode 100644 index 000000000..d0efaa29b --- /dev/null +++ b/src/sbt-test/windows/custom-wix/src/wix/main.wsx @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/sbt-test/windows/custom-wix/src/wix/ui.wsx b/src/sbt-test/windows/custom-wix/src/wix/ui.wsx new file mode 100644 index 000000000..dad5dd637 --- /dev/null +++ b/src/sbt-test/windows/custom-wix/src/wix/ui.wsx @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/sbt-test/windows/custom-wix/test b/src/sbt-test/windows/custom-wix/test new file mode 100644 index 000000000..edbc455c5 --- /dev/null +++ b/src/sbt-test/windows/custom-wix/test @@ -0,0 +1,3 @@ +# Run the windows packaging. +> windows:packageBin +$ exists target/windows/custom-wix.msi From b2a52b21077d015e0aa9e85b03d1687ba9b3b216 Mon Sep 17 00:00:00 2001 From: Dmitry Polienko Date: Wed, 28 Nov 2018 17:29:21 +0700 Subject: [PATCH 3/5] Fix code formatting --- .../sbt/packager/windows/WindowsPlugin.scala | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/src/main/scala/com/typesafe/sbt/packager/windows/WindowsPlugin.scala b/src/main/scala/com/typesafe/sbt/packager/windows/WindowsPlugin.scala index 853cad403..df7c8eeba 100644 --- a/src/main/scala/com/typesafe/sbt/packager/windows/WindowsPlugin.scala +++ b/src/main/scala/com/typesafe/sbt/packager/windows/WindowsPlugin.scala @@ -106,12 +106,9 @@ object WindowsPlugin extends AutoPlugin { // to our target directory. val targetFlat: Path.FileMap = Path.flat(target.value) val wsxFiles = wsxSources.map(targetFlat(_).get) - IO.copy( - wsxSources.zip(wsxFiles).filter { - case (src, dest) => src.getAbsolutePath != dest.getAbsolutePath - }, - CopyOptions().withOverwrite(true) - ) + IO.copy(wsxSources.zip(wsxFiles).filter { + case (src, dest) => src.getAbsolutePath != dest.getAbsolutePath + }, CopyOptions().withOverwrite(true)) IO.copy(for ((f, to) <- mappings.value) yield (f, target.value / to)) // Now compile WIX @@ -132,11 +129,9 @@ object WindowsPlugin extends AutoPlugin { } // Now create MSI - val lightCmd = List( - wixdir + "\\bin\\light.exe", - "-out", - msi.getAbsolutePath - ) ++ wixobjFiles.map(_.getAbsolutePath) ++ + val lightCmd = List(wixdir + "\\bin\\light.exe", "-out", msi.getAbsolutePath) ++ wixobjFiles.map( + _.getAbsolutePath + ) ++ lightOptions.value streams.value.log.debug(lightCmd mkString " ") From 3e5be47aa86204e2065007180fe30bdc4b93533d Mon Sep 17 00:00:00 2001 From: Dmitry Polienko Date: Wed, 28 Nov 2018 18:05:00 +0700 Subject: [PATCH 4/5] Remove unnecessary overwrite flag --- .../com/typesafe/sbt/packager/windows/WindowsPlugin.scala | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/scala/com/typesafe/sbt/packager/windows/WindowsPlugin.scala b/src/main/scala/com/typesafe/sbt/packager/windows/WindowsPlugin.scala index df7c8eeba..711b4c8ac 100644 --- a/src/main/scala/com/typesafe/sbt/packager/windows/WindowsPlugin.scala +++ b/src/main/scala/com/typesafe/sbt/packager/windows/WindowsPlugin.scala @@ -106,9 +106,10 @@ object WindowsPlugin extends AutoPlugin { // to our target directory. val targetFlat: Path.FileMap = Path.flat(target.value) val wsxFiles = wsxSources.map(targetFlat(_).get) - IO.copy(wsxSources.zip(wsxFiles).filter { + val wsxCopyPairs = wsxSources.zip(wsxFiles).filter { case (src, dest) => src.getAbsolutePath != dest.getAbsolutePath - }, CopyOptions().withOverwrite(true)) + } + IO.copy(wsxCopyPairs) IO.copy(for ((f, to) <- mappings.value) yield (f, target.value / to)) // Now compile WIX From 9b2d63b19051027d5bf8c73317380496109ff7df Mon Sep 17 00:00:00 2001 From: Dmitry Polienko Date: Wed, 28 Nov 2018 18:13:45 +0700 Subject: [PATCH 5/5] Fix for SBT 0.13 --- src/sbt-test/windows/custom-wix/build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sbt-test/windows/custom-wix/build.sbt b/src/sbt-test/windows/custom-wix/build.sbt index 6f6a54c79..a4ee3fc17 100644 --- a/src/sbt-test/windows/custom-wix/build.sbt +++ b/src/sbt-test/windows/custom-wix/build.sbt @@ -4,7 +4,7 @@ name := "custom-wix" version := "0.1.0" // make sure we don't somehow use the generated script -Windows / wixFile := { +wixFile in Windows := { sys.error("wixFile shouldn't have been called") }