文档

§调试你的构建

如果你在让 sbt 做你想做的事情时遇到困难,你可能需要使用 sbt 提供的一些内置实用程序来帮助你调试你的构建。

§调试依赖项

默认情况下,sbt 会生成所有依赖项的报告,包括依赖项树以显示哪些依赖项传递地引入了其他依赖项,以及冲突解决表以显示 sbt 如何决定在请求多个依赖项时选择哪个版本的依赖项。

这些报告生成到 xml 文件中,并附带一个 XSL 样式表,允许支持 XSL 的浏览器将 XML 报告转换为 HTML。支持此功能的浏览器包括 Firefox 和 Safari,但 Notably 不包括 Chrome。

这些报告可以在项目的 target/scala-2.12/resolution-cache/reports/ 目录中找到,每个项目范围都会生成一个,并命名为 organization-projectId_scalaVersion-scope.xml,例如,com.example-my-first-app_2.13-compile.xml。在 Firefox 中打开时,此报告看起来像这样

§调试设置

sbt 提供了一些有用的命令,可用于了解你的构建并找出问题所在。

§show 命令

show 命令显示任何 sbt 任务的返回值。例如,如果你不确定某个源文件是否正在编译,你可以运行 show sources 来查看 sbt 是否将其包含在源文件中

[my-first-app] $ show sources
[info] ArrayBuffer(my-first-app/app/controllers/Application.scala, 
  my-first-app/target/scala-2.13/twirl/main/views/html/index.template.scala,
  my-first-app/target/scala-2.13/twirl/main/views/html/main.template.scala,
  my-first-app/target/scala-2.13/src_managed/main/routes_reverseRouting.scala,
  my-first-app/target/scala-2.13/src_managed/main/routes_routing.scala,
  my-first-app/target/scala-2.13/src_managed/main/controllers/routes.java)

上面的输出已格式化以确保它整齐地显示在屏幕上,你可能需要将其复制到编辑器中才能理解它,如果你运行的任务返回一个很长的项目列表。

你也可以指定一个特定范围的任务,例如 Test/sourcesCompile/sources,或者针对特定项目,my-project/Compile/sources,在某些情况下,如果任务由另一个任务限定范围,你也可以指定该范围,例如,要查看将打包到项目 jar 文件中的所有内容,你需要显示 mappings 任务,限定范围为 packageBin 任务

[my-first-app] $ show Compile / packageBin / mappings
[info] List(
  (my-first-app/target/scala-2.13/classes/application.conf,application.conf),
  (my-first-app/target/scala-2.13/classes/controllers/Application.class,controllers/Application.class),
  ...

§inspect 命令

inspect 命令可以提供关于任务的详细信息,包括它依赖于什么,什么依赖于它,它在哪里定义等等。它可以像 show 命令一样使用。

[my-first-app] $ inspect managedSources
[info] Task: scala.collection.Seq[java.io.File]
[info] Description:
[info] 	Sources generated by the build.
[info] Provided by:
[info] 	{file:my-first-app/}root/compile:managedSources
[info] Defined at:
[info] 	(sbt.Defaults) Defaults.scala:185
[info] Dependencies:
[info] 	compile:sourceGenerators
[info] Reverse dependencies:
[info] 	compile:sources
...

这里我们检查了 managedSources 命令,它告诉我们这是一个生成文件序列的任务,它有一个描述 由构建生成的源代码。 你可以看到它依赖于 sourceGenerators 任务,而 sources 任务依赖于它。你还可以看到它在哪里定义,在本例中,它来自 sbt 的默认任务定义,第 185 行。

§inspect tree 命令

inspect tree 命令显示特定任务的整个任务依赖关系树。如果我们检查 unmanagedSources 任务的树,我们可以在这里看到它。

[my-first-app] $ inspect tree unmanagedSources
[info] compile:unmanagedSources = Task[scala.collection.Seq[java.io.File]]
[info]   +-*/*:sourcesInBase = true
[info]   +-*/*:unmanagedSources::includeFilter = sbt.SimpleFilter@3dc46f24
[info]   +-compile:unmanagedSourceDirectories = List(my-first-app/app, my-first-a..
[info]   | +-compile:javaSource = app
[info]   | | +-*:baseDirectory = my-first-app
[info]   | |   +-*:thisProject = Project(id root, base: my-first-app, configurations: List(compile,..
[info]   | |   
[info]   | +-compile:scalaSource = app
[info]   |   +-*:baseDirectory = my-first-app
[info]   |     +-*:thisProject = Project(id root, base: my-first-app, configurations: List(compile,..
[info]   |     
[info]   +-*:baseDirectory = my-first-app
[info]   +-*/*:excludeFilter = sbt.HiddenFileFilter$@49e479da

这显示了 sbt 用于发现项目中源代码的整个任务树,包括用于决定包含或排除哪些文件的过滤器。inspect tree 命令在你不确定构建的某些部分是如何构建的,并且你想找出它如何组合在一起以便你可以更深入地研究时特别有用。

§调试增量编译

人们在 Play 中遇到的一个常见问题是,他们发现 Play 在他们不希望它重新编译和重新加载时重新编译和重新加载。这通常是由源代码生成器或 IDE 意外更新 Play 类路径的元素引起的,从而强制重新加载。要调试此类问题,我们可以查看编译任务的调试日志。当 sbt 运行任务时,它会捕获所有日志输出,无论它是否显示它,以便你以后可以检查它。可以使用 last 命令检查它。

所以,假设你 compile,并且需要重新编译一个文件。

[my-first-app] $ compile
[info] Compiling 1 Scala source to my-first-app/target/scala-2.13/classes...
[success] Total time: 1 s, completed 07/04/2015 1:28:43 PM

你可以通过运行 last compile 获取编译命令期间发生的事情的完整调试日志。这将转储大量输出,但我们只对第一部分感兴趣,如这里所示。

[my-first-app] $ last compile
[debug]
[debug] Initial source changes:
[debug] 	removed:Set()
[debug] 	added: Set()
[debug] 	modified: Set(my-first-app/app/controllers/Application.scala)
[debug] Removed products: Set()
[debug] External API changes: API Changes: Set()
[debug] Modified binary dependencies: Set()
[debug] Initial directly invalidated sources: Set(my-first-app/app/controllers/Application.scala)
[debug]
[debug] Sources indirectly invalidated by:
[debug] 	product: Set()
[debug] 	binary dep: Set()
[debug] 	external source: Set()

这告诉我们,重新编译是因为 my-first-app/app/controllers/Application.scala 被修改了。

下一步:配置


发现此文档中的错误?此页面的源代码可以在这里找到。阅读文档指南后,请随时贡献拉取请求。有疑问或建议要分享?前往我们的社区论坛与社区开始对话。