将多个 sbt 任务合并为一个
Posted
技术标签:
【中文标题】将多个 sbt 任务合并为一个【英文标题】:Combine several sbt tasks into one 【发布时间】:2015-03-14 11:54:37 【问题描述】:我对创建 Scala 任务的 Scala/SBT 文档有些困惑。目前我可以从命令行运行以下命令:
sbt ";set target := file(\"$PWD/package/deb-upstart\"); set serverLoading in Debian := com.typesafe.sbt.packager.archetypes.ServerLoader.Upstart; debian:packageBin; set target := file(\"$PWD/package/deb-systemv\"); set serverLoading in Debian := com.typesafe.sbt.packager.archtypes.ServerLoader.SystemV; debian:packageBin; set target := file(\"$PWD/package/rpm-systemd\"); rpm:packageBin"
这会将我的目标每次重置到不同的目录(deb-upstart、deb-systemv 和 rpm-systemd),并为每个设置运行一个 sbt-native-package 任务。 (是的,我意识到我正在编译它三个不同的时间;但是 sbt-native-packager 似乎没有工件目录的设置)
这在 bash 提示符下工作正常,但我一直试图将相同的目标放入 jenkins(用 $WORKSPACE 替换 $PWD),但我似乎无法正确转义引号。我认为通过 build.sbt 或 project/Build.scala 来运行所有这三个任务的任务可能更容易,每次都更改目标变量(并用完整路径替换 $PWD 或 $TARGET的基本目录)。
我尝试了以下方法:
lazy val packageAll = taskKey[Unit]("Creates deb-upstart, deb-systenv and rpm-systemd packages")
packageAll :=
target := baseDirectory.value / "package" / "deb-upstart"
serverLoading in Debian := com.typesafe.sbt.packager.archetypes.ServerLoader.Upstart
(packageBin in Debian).value
target := baseDirectory.value / "package" / "deb-systemv"
serverLoading in Debian := com.typesafe.sbt.packager.archetypes.ServerLoader.SystemV
(packageBin in Debian).value
target := baseDirectory.value / "package" / "rpm-systemd"
(packageBin in Rpm).value
但问题是 .value 会导致任务在我的任务运行之前得到评估,因此他们没有获得新的目标设置(如另一个问题所述:How can I call another task from my SBT task?)
【问题讨论】:
我不确定,但您是否尝试将每个自定义packageBin
步骤提取到自定义任务中,然后将它们与 packageAll
聚合?如果只更改一次输出目录,也可以使用target in Rpm
或target in Debian
设置。
@Muki 我希望我可以只是 target in [Setting]
但如果你仔细看,你会发现我为 Debian 更改了两次目标,一次用于 Upstart ServerLoader,一次用于 SystemV ServerLoader。我将如何将每个 packageBin 提取到自定义任务中?
【参考方案1】:
所以,我为您解决了这个问题 :) 正如您已经提到的,将多个任务合并到一个任务中,其中一些任务依赖于相同的设置,不会按预期工作。
相反,我们执行以下操作
-
为我们的每个自定义步骤创建一个任务,例如为新贵包装 debian
定义按顺序执行这些命令的别名
定义任务
lazy val packageDebianUpstart = taskKey[File]("creates deb-upstart package")
lazy val packageDebianSystemV = taskKey[File]("creates deb-systenv package")
lazy val packageRpmSystemD = taskKey[File]("creates rpm-systenv package")
示例任务实现
实现非常简单,每个都相同 任务。
// don't forget this
import com.typesafe.sbt.packager.archetypes._
packageDebianUpstart :=
// define where you want to put your stuff
val output = baseDirectory.value / "package" / "deb-upstart"
// run task
val debianFile = (packageBin in Debian).value
// place it where you want
IO.move(debianFile, output)
output
定义别名
现在将这些任务组合成一个别名
addCommandAlias("packageAll", "; clean " +
"; set serverLoading in Debian := com.typesafe.sbt.packager.archetypes.ServerLoader.SystemV" +
"; packageDebianSystemV " +
"; clean " +
"; set serverLoading in Debian := com.typesafe.sbt.packager.archetypes.ServerLoader.Upstart" +
"; packageDebianUpstart " +
"; packageRpmSystemD")
可以看完整代码here。
更新
在别名里面设置SystemLoader好像是对的 解决这个问题的方法。不幸的是,清洁是必要的 每个构建都使用相同的输出格式。
【讨论】:
此解决方案不起作用。它将包重命名为 deb-upstart 而不是将其放在目录中(我尝试在val output
之后添加 scalax.file.Path(output).createDirectory()
,但它仍然重命名包而不是将它们放在自己的目录中)。此外,如果您运行dpkg-deb -c deb-systemv
,您会发现它实际上是新贵版本。 .value
在您的自定义任务之前运行这些任务。唯一的方法是使用命令。我一直在努力研究一个;如果我能弄清楚,可能会发出拉取请求。
我更新了示例。 sbt 似乎没有正确处理任务内部的设置,或者以其他方式完成。通过别名从外部设置它是可行的。该目录是为我正确创建的,它会按照描述移动文件。 IO.move(package, outputfolder)
.以上是关于将多个 sbt 任务合并为一个的主要内容,如果未能解决你的问题,请参考以下文章
scala:如何在SBT设置中定义多个相关任务之间的执行顺序?