【问题标题】:Get full classpath without compilation in SBT无需在 SBT 中编译即可获得完整的类路径
【发布时间】:2021-05-05 19:51:01
【问题描述】:

我需要一段使用 SBT 的代码,可能是内部代码,它在不调用编译的情况下获取 SBT 项目的完整类路径。通常我会使用“Runtime / fullClasspath”,但这需要先编译项目。有没有办法在不触发编译的情况下获得 fullClasspath?我认为 build.sbt 单独决定了类路径,编译(理论上)不是必需的。

我在 SBT gitter 频道上询问过,那里也提到使用dependencyClasspath。 dependencyClasspath 不需要编译根项目,但它确实需要编译所有依赖项。所以这对我来说还没有解决。我正在寻找运行根项目所需的完整类路径,而无需编译其组成部分。

我对解决此问题的任何方法都感兴趣,所以如果有任何牵强的解决方法,也欢迎。

我现在拥有的一个例子:

Global / printMainClasspath := {
    val paths = (rootProject / fullClasspath).value
    val joinedPaths = paths
        .map(_.data)
        .mkString(pathSeparator)
    println(joinedPaths)
}

这部分工作,它创建一个打印完整类路径的任务“printMainClasspath”。但是如果我在 sbt shell 中调用它,它会先编译代码。我希望在不调用项目的完整编译的情况下打印类路径。理想情况下,只编译所有组成项目的所有 build.sbt。有什么办法吗?

【问题讨论】:

  • 为什么不编译?
  • 我们希望类路径可用于我们项目的某些外部组件。所以我们定期将类路径导出到文件中。由于导出类路径会编译代码,因此如果代码包含错误,则不会导出类路径。如果我们可以从该循环中删除编译,则可以在后台定期且安静地导出类路径。 (假设:即使我们在 src/ 中的 scala 文件包含错误,类路径也已定义/格式正确)
  • 真的像X/Y
  • 可能,我们的方法也用于解决 sbt 的缓慢问题,特别是 sbt 的启动时间。也欢迎含糊的想法/想法

标签: scala sbt classpath


【解决方案1】:
val dryClasspath = taskKey[Seq[File]]("dryClasspath")

dryClasspath := {
  val data = settingsData.value
  val thisProj = thisProjectRef.value
  val allProjects = thisProj +: buildDependencies.value.classpathTransitiveRefs(thisProj)
  val classDirs = allProjects.flatMap(p => (p / Runtime / classDirectory).get(data))
  val externalJars = (Runtime / externalDependencyClasspath).value.map(_.data)
  classDirs ++ externalJars
}

【讨论】:

  • 这似乎对我有用,谢谢!您认为此代码在 sbt 版本升级时中断的可能性有多大?
  • 所有这些 API 都是公开的,所以我敢打赌应该没问题。我已经用了几年了,到目前为止它很稳定。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-10-02
  • 2014-07-22
  • 1970-01-01
  • 2011-03-27
  • 1970-01-01
  • 2017-03-24
  • 1970-01-01
相关资源
最近更新 更多