下面是一个具有自定义设置和值的 sbt 0.13.1
项目:
% pwd
/Users/tisue/myproj
% ls
build.sbt
% cat build.sbt
val foo = settingKey[String]("This is a custom setting")
foo := "bar"
% sbt
[info] Set current project to myproj (in build file:/Users/tisue/myproj/)
> show foo
[info] bar
目前为止,一切都好。但是现在:
> set foo := "qux"
<set>:1: error: not found: value foo
foo := "qux"
^
[error] Type error in expression
这不应该行吗?
我部分理解这里出了什么问题; set
计算一个 Scala 表达式,并且该表达式显然是在val foo
不在范围内的上下文中编译的。
但我希望,当从.sbt
文件编译foo := ...
时,确保foo
在范围内的魔法,在 shell 中编译相同的东西时也会生效。
自版本 0.13.6 (2014-09-12) 起,这不再是限制 (#1059/#1456)
原始答案 - 适用于使用 sbt 0.13.0 - 0.13.5 的任何项目
事实证明,0.13.0 更改清楚地表明这是预期行为:
所有定义都是在设置之前编译的,但最佳做法可能是将定义放在一起。目前,定义的可见性仅限于定义它的 .sbt 文件。它们目前在
consoleProject
或set
命令中也不可见。在project/中使用Scala文件,以便在所有.sbt文件中查看。
这样,您应该能够在project/Build.scala
中定义设置后共享该设置,如下所示:
import sbt._
import Keys._
object HelloBuild extends Build {
lazy val foo = settingKey[String]("This is a custom setting")
foo := "Build.scala"
}
build.sbt
scalaVersion := "2.10.4-RC1"
foo := "build.sbt"
然后,在 sbt 外壳中:
[sbt-0-13-1]> foo
[info] build.sbt
[sbt-0-13-1]> set foo := "shell"
[info] Defining *:foo
[info] The new value will be used by no settings or tasks.
[info] Reapplying settings...
[info] Set current project to sbt-0-13-1 (in build file:/Users/jacek/sandbox/so/sbt-0.13.1/)
[sbt-0-13-1]> foo
[info] shell