无法从Build.scala访问项目的类/对象 [英] Can't get access to a project's classes / objects from Build.scala
问题描述
我想创建像Ruby rake这样的任务.我知道我可以通过sbt任务完成 http://www.scala-sbt .org/release/docs/Detailed-Topics/Tasks 但我不能使用项目中的任何类或对象.例如:
I'd like to create the task like Ruby rake. I know I can do by sbt tasks http://www.scala-sbt.org/release/docs/Detailed-Topics/Tasks But I can't use any class or object from my project. For example:
# 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
}
}
所以我无法访问model.User或项目中的任何其他类.我该怎么办?
So I can't get access to models.User or any other class in my project. What can I do about this?
推荐答案
Scala是强类型的,所有类型都必须在编译时解析.您的构建文件是先编译的-它不能依赖于它正在构建的项目的类型,因为要构建它正在构建的项目,它首先需要自己构建-看到循环依赖吗?
Scala is strongly typed, all types must be resolved at compile time. Your build file is first compiled - it can't depend on types from the project it's building since to build the project it is building it first needs to be built itself - see the circular dependency?
因此,您不能简单地从构建文件中调用项目中的Scala代码.
So you can't simply call Scala code in your project from your build file.
您可以做的是在项目中定义一个主类,并告诉SBT使用runMain
任务来调用它.这完成了首先编译项目,然后创建具有所有必要依赖项的类加载器,然后反射性地查找主类并调用它的所有魔术.请注意,大概您的代码需要一个正在运行的应用程序,因此最好在test
文件夹中执行此操作,并使用Play的伪造应用程序帮助程序,例如:
What you can do is define a main class in your project, and tell SBT to invoke that using the runMain
task. This does all the magic necessary to first compile your project, then create a classloader with all the necessary dependencies, then lookup your main class reflectively and invoke it. Note that presumably your code needs a running application, so you'll be best off to do this in the test
folder and use Play's fake application helper, eg:
package foo.bar
import play.api.test._
object MyMainClass extends App {
Helpers.running(FakeApplication()) {
val u = models.User.single(123)
...
}
}
现在从play
控制台中尝试以下操作:
Now from the play
console, try this:
test:runMain foo.bar.MyMainClass
如果可行,则可以通过将其添加到build.sbt
或在Build.scala
中建立设置来缩短它:
If that works, then you can shorten it by adding this to your build.sbt
or build settings in Build.scala
:
TaskKey[Unit]("do-something", "Do something") := {
(runMain in Test).toTask("foo.bar.MyMainClass").value
}
那么您应该只能够运行do-something
.
Then you should just be able to run do-something
.
这篇关于无法从Build.scala访问项目的类/对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!