【问题标题】:Can't get access to a project's classes / objects from Build.scala无法从 Build.scala 访问项目的类/对象
【发布时间】:2014-03-17 04:39:37
【问题描述】:

我想创建像 Ruby rake 这样的任务。我知道我可以通过 sbt 任务来完成 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 或项目中的任何其他类。我该怎么办?

【问题讨论】:

    标签: scala playframework playframework-2.2


    【解决方案1】:

    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

    【讨论】:

    • 来自 Play 控制台的 'test:runMain foo.bar.MyMainClass' 看起来不太好,因为它与测试无关。其实看看这个kailuowang.blogspot.com/2013/05/…——它是通过反射完成的,非常优雅。
    【解决方案2】:

    Build.scala 定义了如何构建项目。在构建定义中,您尝试使用应该基于该定义构建的东西。

    一般答案是 models 必须在之前构建(一个单独的模块)并作为构建项目的依赖项添加(而不是“真实”项目)。

    但是,您需要从项目中获取一些东西来实际构建项目的想法听起来很可疑。如果你解释一下你为什么以及你想要达到什么目标,也许有人会想出一个更好的答案。

    【讨论】:

    • 这并不可疑,我只是希望能够在数据库中运行“sbt insertPredefinedUsers”。
    • added as a dependency for the build project (not for the "real" project) - 构建项目和“真实”项目有什么不同?
    • 1) 我认为在项目编译期间向数据库中插入与项目相关的内容是非常不寻常的。
    • 2) 在 SBT 中,结构是递归的。假设您在根目录中有一个项目。然后在 /project 子目录中,您有另一个项目,它定义了如何在根目录中构建“项目”。如果你愿意,你可以有一个 /project/project 定义如何构建项目来构建项目......我的想法是在 /project 目录中添加对构建项目的依赖。
    • 1) 它和编译有什么关系?
    猜你喜欢
    • 1970-01-01
    • 2012-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多