copying scala.js linker artifacts after linking
There have been a few requests for a plugin to copy the scala.js linker artifacts to another location after the linker has run. While you could set the output path for the artifact to a different location, you may want to have the artifacts generated into the standard location then copy it to somewhere else to provide better compatibility with existing tooling.
Ad-hoc Approach
Here’s one way to add a copy process to a specific sub-project:
def copyTask(odir: String) = {
lazy val copyJSOutput = taskKey[Unit]("copy scala.js linker outputs to another location")
Seq(
copyJSOutput := {
println(s"Copying artifact ${scalaJSLinkedFile.in(Compile).value.path} to [${odir}]")
val src = file(scalaJSLinkedFile.in(Compile).value.path)
IO.copy(Seq(
(src, file(odir) / src.name),
(file(src.getCanonicalPath() + ".map"), file(odir) / (src.name + ".map"))
), CopyOptions(true, true, true))
},
fastOptJS / copyJSOutput := (copyJSOutput triggeredBy fastOptJS.in(Compile)).value,
fullOptJS / copyJSOutput := (copyJSOutput triggeredBy fullOptJS.in(Compile)).value
)
}
Notice that dev and prod linker tasks are modified. This does not show testing artifacts being changed.
Modify your project definition to use:
lazy val myproject = project.in(...)
.settings(copyTask("../node-server/src"))
Create a Plugin
You can also create a plugin in projects/CopyScalaJS.scala
package ttg
package scalajs
import sbt._
import Keys._
import org.scalajs.sbtplugin.ScalaJSPlugin
import org.scalajs.sbtplugin.ScalaJSPlugin.autoImport._
/**
* Copy JS linker artifacts to another location. Add to your project to enable.
*/
object CopyJSPlugin extends AutoPlugin {
override def requires = ScalaJSPlugin
final object autoImport {
val copyTarget = SettingKey[String]("copyTarget", "scala.js linker artifact copy target directory")
val copyJS = TaskKey[Unit]("copyJS", "Copy scala.js linker artifacts to another location after linking.")
}
import autoImport._
override lazy val projectSettings = Seq(
copyJS := copyJSTask.value,
fastOptJS / copyJS := (copyJS triggeredBy fastOptJS.in(Compile)).value,
fullOptJS / copyJS := (copyJS triggeredBy fullOptJS.in(Compile)).value
)
//define inline via `copyJS := {` or separately like this
private def copyJSTask = Def.task {
val odir = copyTarget.value
println(s"Copying artifact ${scalaJSLinkedFile.in(Compile).value.path} to [${odir}]")
val src = file(scalaJSLinkedFile.in(Compile).value.path)
IO.copy(Seq(
(src, file(odir) / src.name),
(file(src.getCanonicalPath() + ".map"), file(odir) / (src.name + ".map"))
), CopyOptions(true, true, true))
}
}
Enable like any other plugin:
lazy val myproject = ...
.enablePlugins(CopyJSPlugin)
.setting(copyTarget := "../somedir")
If you forget to set copyTarget
you will have a sbt static compilation error when trying to load the project file.
Comments
Post a Comment