无法从Build.scala访问项目的类/对象

时间:2014-03-17 04:39:38

标签: scala playframework playframework-2.2

我想像Ruby rake一样创建任务。我知道我可以通过sbt tasks来做http://www.scala-sbt.org/release/docs/Detailed-Topics/Tasks但是我不能使用我项目中的任何类或对象。例如:

# project/AppBuild.scala
object AppBuild extends Build {
  //............
    lazy val sampleTask = taskKey[Unit]("hello123", "A sample task.") := {
      val u = models.User.single(123) // Error! models is not accessible
    }

}

所以我无法访问models.User或我项目中的任何其他类。我该怎么办?

2 个答案:

答案 0 :(得分:2)

Scala是强类型的,所有类型都必须在编译时解析。您的构建文件首先被编译 - 它不依赖于它构建的项目中的类型,因为构建项目时它首先需要自己构建 - 请参阅循环依赖项?

因此,您无法从构建文件中调用项目中的Scala代码。

您可以做的是在项目中定义一个主类,并告诉SBT使用runMain任务调用它。这完成了首次编译项目所需的所有魔法,然后创建一个包含所有必需依赖项的类加载器,然后反复查找主类并调用它。请注意,大概您的代码需要一个正在运行的应用程序,因此您最好在test文件夹中执行此操作并使用Play的假应用程序帮助程序,例如:

package foo.bar

import play.api.test._
object MyMainClass extends App {
  Helpers.running(FakeApplication()) {
    val u = models.User.single(123)
    ...
  }
}

现在从play控制台试试这个:

test:runMain foo.bar.MyMainClass

如果可行,那么您可以将其添加到build.sbt中的Build.scala或版本设置中来缩短它:

TaskKey[Unit]("do-something", "Do something") := {
  (runMain in Test).toTask("foo.bar.MyMainClass").value
}

然后你应该能够运行do-something

答案 1 :(得分:1)

Build.scala定义了如何构建项目。在构建定义中,您尝试使用应根据该定义构建的内容。

一般的答案是models必须在之前构建(一个单独的模块),并作为构建项目的依赖项添加(不适用于"真正的"项目)。

但是你需要从项目中实际构建项目的整个想法听起来很可疑。如果你解释为什么以及你想要达到什么目的,也许有人可以提出更好的答案。