问题
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