Can't get access to a project's classes / objects from Build.scala

倖福魔咒の 提交于 2019-12-12 18:32:58

问题


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
    }

}

So I can't get access to models.User or any other class in my project. What can I do about this?


回答1:


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?

So you can't simply call Scala code in your project from your build file.

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)
    ...
  }
}

Now from the play console, try this:

test:runMain foo.bar.MyMainClass

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
}

Then you should just be able to run do-something.




回答2:


Build.scala defines how to build the project. In the build definition you are trying to use something that should be built based on that definition.

General answer is that models has to be built before (a separate module) and added as a dependency for the build project (not for the "real" project).

But the whole idea that you need something from the project to actually build the project sounds suspicious. Perhaps somebody can come up with a better answer if you explain why and what exactly are you trying to achieve.



来源:https://stackoverflow.com/questions/22447100/cant-get-access-to-a-projects-classes-objects-from-build-scala

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!