在开发过程中,通常有两个截然不同的阶段:“脏开发”,开发人员致力于解决方案,测试各种概念,并引入临时代码结构,以及“清理”阶段,在提交最终版本或之前完善代码拉取请求。在肮脏的开发过程中,冗余或死代码、未使用的导入、缺少显式类型等缺陷是很常见的。在这种情况下,即使在开发过程中有警告,也有利于代码编译。
如何配置 SBT 以针对编码的不同阶段使用各种
scalacOptions
?
假设对于“肮脏的开发”阶段,我想使用空的 scalacOptions,但是在进行最终清理时,它们可能看起来像:
val scalaCompilerOptions = Seq(
"-Xfatal-warnings",
"-Xlint:-missing-interpolator,_",
"-Xlint:adapted-args",
"-Xlint:constant",
"-Xlint:-byname-implicit",
"-Ywarn-unused:imports",
"-Ywarn-unused:patvars",
"-Ywarn-unused:privates",
"-Ywarn-unused:locals",
"-Ywarn-unused:explicits",
"-Ywarn-unused:params",
"-Ywarn-unused:implicits",
"-Ywarn-value-discard",
"-Ywarn-dead-code",
"-deprecation",
"-feature",
"-unchecked",
...
)
理想情况下,当进入
test:compile
任务时,它会使用空的scalacOptions
,但是当使用test
(或package
或distTgz
)时,它会应用限制选项。
sbt.version=1.7.2
在 sbt 中,您可以创建具有不同配置的不同子模块。
应用程序
// the application
lazy val app = project
.in(file("."))
.settings(
name := "my-app",
libraryDependencies += (
dependency1,
dependency2,
// ...
dependencyN,
)
)
然后是具有不同配置的不同子模块
lazy val testPackage = project
// we put the results in a build folder
.in(file("build/test"))
.settings(
scalacOptions in Compile := Seq(
// options for test
),
// override the resource directory
resourceDirectory in Compile := (resourceDirectory in (app, Compile)).value,
mappings in Universal += {
((resourceDirectory in Compile).value / "test.conf") -> "conf/application.conf"
}
)
.dependsOn(app)
// bascially identical despite the configuration differences
lazy val stagePackage = project
.in(file("build/stage"))
.settings(
scalacOptions in Compile := Seq(
// options for stage
),
resourceDirectory in Compile := (resourceDirectory in (app, Compile)).value,
mappings in Universal += {
((resourceDirectory in Compile).value / "stage.conf") -> "conf/application.conf"
}
)
.dependsOn(app)
lazy val prodPackage = project
.in(file("build/prod"))
.settings(
scalacOptions in Compile := Seq(
// options for prod
),
resourceDirectory in Compile := (resourceDirectory in (app, Compile)).value,
mappings in Universal += {
((resourceDirectory in Compile).value / "prod.conf") -> "conf/application.conf"
}
)
.dependsOn(app)
插件
sbt-native-packager
有一个很好的例子如何做。
一种方法(不是唯一的方法)是进行自己的设置,然后让
scalacOptions
依赖于该设置。然后您可以随时使用set
更改设置。
例如,在 Scala 2 编译器 (https://github.com/scala/scala) 的 sbt 构建中,我们希望在本地开发期间禁用致命警告,但在 CI 中启用。
所以我们的
build.sbt
有:
val fatalWarnings = settingKey[Boolean](
"whether or not warnings should be fatal in the build")
Global / fatalWarnings := insideCI.value
// then in whatever context is appropriate in your build,
Compile / scalacOptions ++= {
if (fatalWarnings.value) Seq("-Werror")
else Nil
}
然后在本地当我们想临时启用致命警告时,
set Global / fatalWarnings := true
.
这对我来说似乎比加斯顿的建议更轻量级的解决方案。