查看 sbt 项目的依赖关系树的教程

sbt 是借助于 ivy 来管理项目依赖, 像 Maven 项目中可以用 dependency:tree 来显示依赖树, 那么对于 sbt 项目该如何查看项目依赖关系呢? 本文提及了三种方式来显示项目依赖, 它们是 Shell 脚本, 自定义 sbt 任务, 和 sbt-dependency-plugin 方式. 最后一个办法使得我们也能用 dependencyTree 显示出 Maven 的  dependency:tree 效果来, 还有更酷的的.

> dependencyTree
[info] default:test_2.10:0.1-SNAPSHOT [S]
[info]   +-ch.qos.logback:logback-classic:1.0.13
[info]     +-ch.qos.logback:logback-core:1.0.13
[info]     +-org.slf4j:slf4j-api:1.7.5
[info]
[success] Total time: 0 s, completed Apr 5, 2016 12:29:53 AM

下面是探索的全部过程.

通过 sbt 控制台的 tab  自动完成或用 help .*[Dd]ependenc.* 命令再进一步过滤出与依赖比较接近 sbt 控制台任务

dependencyClasspath  The classpath consisting of internal and external, managed and unmanaged dependencies.
externalDependencyClasspath  The classpath consisting of library dependencies, both managed and unmanaged.
internalDependencyClasspath  The internal (inter-project) classpath.
projectDependencies  Inter-project dependencies.
excludeDependencies  Declares managed dependency exclusions.
dependencyCacheDirectory  The base directory for cached dependencies.
allDependencies  Inter-project and library dependencies.
libraryDependencies  Declares managed dependencies.
dependencyOverrides  Declares managed dependency overrides.
trackInternalDependencies  The level of tracking for the internal (inter-project) dependency.
dependencyPositions  Source positions where the dependencies are defined.

来深入, 我们建立一个简单的项目, 文件目录如下

test
├── build.sbt
└── lib
    └── guava-18.0.jar

build.sbt 文件的内容是

libraryDependencies ++= Seq(
  "ch.qos.logback" % "logback-classic" % "1.0.13"
)

我们来看看 sbt 的  dependencyClasspath, externalDependencyClasspath, 和 internalDependencyClasspath 的输出

> show dependencyClasspath
[info] List(Attributed(/Users/uqiu/test/lib/guava-18.0.jar), Attributed(/Users/uqiu/.sbt/boot/scala-2.10.6/lib/scala-library.jar), Attributed(/Users/uqiu/.ivy2/cache/ch.qos.logback/logback-classic/jars/logback-classic-1.0.13.jar), Attributed(/Users/uqiu/.ivy2/cache/ch.qos.logback/logback-core/jars/logback-core-1.0.13.jar), Attributed(/Users/uqiu/.ivy2/cache/org.slf4j/slf4j-api/jars/slf4j-api-1.7.5.jar))
[success] Total time: 0 s, completed Apr 4, 2016 11:54:57 PM
> show externalDependencyClasspath
[info] List(Attributed(/Users/uqiu/test/lib/guava-18.0.jar), Attributed(/Users/uqiu/.sbt/boot/scala-2.10.6/lib/scala-library.jar), Attributed(/Users/uqiu/.ivy2/cache/ch.qos.logback/logback-classic/jars/logback-classic-1.0.13.jar), Attributed(/Users/uqiu/.ivy2/cache/ch.qos.logback/logback-core/jars/logback-core-1.0.13.jar), Attributed(/Users/uqiu/.ivy2/cache/org.slf4j/slf4j-api/jars/slf4j-api-1.7.5.jar))
[success] Total time: 0 s, completed Apr 4, 2016 11:55:03 PM
> show internalDependencyClasspath
[info] List()
[success] Total time: 0 s, completed Apr 4, 2016 11:55:10 PM
这里我们没有定义子项目, 所以 internalDependencyClasspath 为空, dependencyClasspath 和  externalDependencyClasspath 是一样的.

一般来说我们关心的是 externalDependencyClasspath 的内容, 上面显示的是 List[Attribute[String]] 类型的内容, 为了可读性, 可以用 Shell 脚本或自定义 sbt 任务来格式化显示它.

Shell 脚本显示, 在项目目录下创建 dependencies.sh, 内容如下:

#!/bin/bash

echo "Direct dependencies"
sbt 'show all-dependencies' | gawk 'match($0, /List\((.*)\)/, a) {print a[1]}' | tr -d ' ' | tr ',' '\n' | sort -t ':' | \
  tr ':' '\t' | expand -t 30

echo -e "\nAll dependencies, including transitive dependencies"
sbt 'show managed-classpath' | tr -d ' ' | tr ',' '\n' | gawk 'match($0, /Attributed\((.*)\)/, a) {print a[1]}' | \
  tr -d '()' | sed "s^$HOME/.ivy2/cache/^^g" | sed "s^/jars^^" | \
  gawk -F / '{print $1, $3}' | sort | tr ' ' '\t' | expand -t 30
Mac 下虽安装 gawk, 可用命令  brew install gawk 安装, 并用 chmod +x dependencies.sh 加上可执行属性, 完整命令如下:

brew install gawk
chmod +x dependencies.sh
./dependencies.sh
显示结果大致如下:

Direct dependencies
ch.qos.logback                logback-classic               1.0.13
optional(default)
optional(default)
org.scala-lang                scala-compiler                2.10.6                        scala-tool->default
org.scala-lang                scala-library                 2.10.6
org.scala-lang                scala-library                 2.10.6                        scala-tool->default

All dependencies, including transitive dependencies
                              uqiu
ch.qos.logback                logback-classic-1.0.13.jar
ch.qos.logback                logback-core-1.0.13.jar
org.slf4j                     slf4j-api-1.7.5.jar
自定义 sbt 任务, 在 build.sbt 中加入如下内容:

本文原始链接 http://unmi.cc/show-sbt-dependency-tree/, 来自 隔叶黄莺 Unmi Blog
lazy val versionReport = TaskKey[String]("version-report")

// Add this setting to your project.
versionReport <<= (externalDependencyClasspath in Compile, streams) map {
   (cp: Seq[Attributed[File]], streams) =>
     val report = cp.map {
       attributed =>
         attributed.get(Keys.moduleID.key) match {
           case Some(moduleId) => "%40s %20s %10s %10s".format(
             moduleId.organization,
             moduleId.name,
             moduleId.revision,
             moduleId.configurations.getOrElse("")
           )
           case None           =>
             // unmanaged JAR, just
             attributed.data.getAbsolutePath
         }
     }.mkString("\n")
     streams.log.info(report)
     report
  }
重新运行 sbt 或 reload 之后执行 versionReport 任务, 输出如下:

> versionReport
[info] /Users/uqiu/test/lib/guava-18.0.jar
[info]                           org.scala-lang        scala-library     2.10.6
[info]                           ch.qos.logback      logback-classic     1.0.13
[info]                           ch.qos.logback         logback-core     1.0.13
[info]                                org.slf4j            slf4j-api      1.7.5
这能让我们看到所有的依赖, 但并未显示成树状关系图, 还没有达到本文标题所称的目标, 所以终极办法也是最简单的办法就是不重新发明轮子, 使用现有的插件 https://github.com/jrudolph/sbt-dependency-graph.

sbt 插件显示依赖树

可以在 ~/.sbt/0.13/plugins/plugins.sbt 或项目中新建 project/plugins.sbt 中加入行

addSbtPlugin("net.virtual-void" % "sbt-dependency-graph" % "0.8.2")
这时在 sbt 的控制台下就增加了好多任务,

dependencyTree: Shows an ASCII tree representation of the project's dependencies
dependencyBrowseGraph: Opens a browser window with a visualization of the dependency graph (courtesy of graphlib-dot + dagre-d3).
dependencyGraph: Shows an ASCII graph of the project's dependencies on the sbt console
dependencyList: Shows a flat list of all transitive dependencies on the sbt console (sorted by organization and name)
whatDependsOn <organization> <module> <revision>: Find out what depends on an artifact. Shows a reverse dependency tree for the selected module.
dependencyLicenseInfo: show dependencies grouped by declared license
dependencyStats: Shows a table with each module a row with (transitive) Jar sizes and number of dependencies
dependencyGraphMl: Generates a .graphml file with the project's dependencies to target/dependencies-<config>.graphml. Use e.g. yEd to format the graph to your needs.
dependencyDot: Generates a .dot file with the project's dependencies to target/dependencies-<config>.dot. Use graphviz to render it to your preferred graphic format.
ivyReport: let's ivy generate the resolution report for you project. Use show ivyReport for the filename of the generated report
我比较感兴趣的是 dependencyTree(显示像  Maven 的  dependency:tree 那样) 和 dependencyBrowseGraph(打开浏览器显示一个依赖关系图)

> dependencyTree
[info] default:test_2.10:0.1-SNAPSHOT [S]
[info]   +-ch.qos.logback:logback-classic:1.0.13
[info]     +-ch.qos.logback:logback-core:1.0.13
[info]     +-org.slf4j:slf4j-api:1.7.5
[info]
[success] Total time: 0 s, completed Apr 5, 2016 12:29:53 AM
或者执行 dependencyBrowseGraph 后打开一个浏览器

还有 dependencyGraph 任务输出为文本图形, dependencyDot 能生成 dot 文件, 等等.

用 sbt-dependency-graph 插件的办法是最强大也是最简单, 而且如果在 ~/.sbt/0.13/plugins/plugins.sbt 加载该插件更可谓是一劳永逸的做法.

时间: 2024-09-23 16:49:53

查看 sbt 项目的依赖关系树的教程的相关文章

linux下查看动态链接库依赖关系的命令 x86: ldd *.so arm: arm-linux-readelf -d *.so 实际例子: 以项目中用到的库librtsp.so分析: lijun@ubuntu:~/workspace$ arm-hisiv100nptl-

linux下查看动态链接库依赖关系的命令 x86:ldd    *.so arm:arm-linux-readelf    -d    *.so 实际例子:以项目中用到的库librtsp.so分析:lijun@ubuntu:~/workspace$ arm-hisiv100nptl-linux-ld -d librtsp.so arm-hisiv100nptl-linux-ld: warning: liblog.so, needed by librtsp.so, not found (try u

maven项目本地仓库有jar包,但是pom.xml却提示依赖关系报错!这是怎么处理

问题描述 maven项目本地仓库有jar包,但是pom.xml却提示依赖关系报错!这是怎么处理 解决方案 贴出具体描述来,这样看不出来

使用Composer管理PHP依赖关系

Composer 是PHP中用来管理依赖(dependency)关系的工具.你可以在自己的项目中声明所依赖的外部工具库(libraries),Composer会帮你安装这些依赖的库文件. 系统需求: Composer 需要PHP5.3.2+ 以上的环境来运行.有几个敏感的PHP设置和编译标志也是必需的,但安装程序会发出警告当存在任何不兼容的情况.比如PHP的扩展的要求是,安装或重新编译php without –disable-phar Composer 是兼容多平台的,其运行适用于Windows

对DLL的依赖关系

问题描述 在VisualStudio2013里创建了两个项目:1.LibB:项目类型"ClassLibrary",生成LibB.dll文件2.ExeA:项目类型"ConsoleApplication",生成ExeA.exe文件.ExeA.exe执行的时候需要引用LibB.dll里的类和函数,所以在VS里用AddReference添加了对LibB.dll的引用.ExeA.exe的编译和运行明明是依赖于LibB.dll的,可是用dumpbin或者dependencywa

C/C++源代码的Include依赖关系图

前一篇博文中我曾仔细介绍过如何查看C/C++代码的依赖项关系图,在这篇文章中我将会介绍如何使用Visualization and Modeling Feature Pack 工具包,查看C/C++源代码的Include关系图,这个功能是针对C/C++编程语言本身的特性而新加入的.在这里我依然会使用工程Hilo 作为案例,展示如何以图形化的方式显示工程中源代码文件与头文件之间Include关系. 首先,在Visual Studio下打开工程Hilo,在菜单栏中选择菜单"体系结构->生成依赖关

UML学习:类图class的依赖关系

依赖关系的概念与符号 依赖表示一个类以某种形式依赖于其他类.当两个类处于依赖关系中时,其中一个类的改变可能会影响另一个类. 符号: 依赖关系在代码中的表现 在程序代码中,依赖关系意味着一个类的对象出现在另一个类的操作中.常见的有两种情况:一个类将另一个类的对象作为自己某个操作的参数(形参),或者是操作的局部变量. 程序演示:code/train class train { public string number; public train(string num) { number = num;

轻松编程: 通过理顺软件的依赖关系提高应用程序灵活性

本文讨论: 紧密耦合体系结构的错误之处 测试和依赖关系灾难 依赖关系反转 依赖关系注入 本文使用了以下技术: .NET Framework 几乎所有人都认为追求松 散耦合设计不是明智之举.遗憾地是,我们所设计软件的紧密耦合程度通常都远远超过我们的预期.如何 了解设计是否耦合紧密?可使用静态分析工具(如 Ndepend)来分析依赖关系,但了解应用程序中耦合程 度最轻松的办法是尝试独立地实例化一个类. 从业务层中选取一个类(如 InvoiceService),然后将其代码复制到一个新的控制台项目中.

maven依赖关系中Scope的作用

原文:http://peak.iteye.com/blog/299225 maven依赖关系中Scope的作用 Dependency Scope 在POM 4中,<dependency>中还引入了<scope>,它主要管理依赖的部署.目前<scope>可以使用5个值:     * compile,缺省值,适用于所有阶段,会随着项目一起发布.     * provided,类似compile,期望JDK.容器或使用者会提供这个依赖.如servlet.jar.     *

在VS中通过建立依赖关系使文件结构更清晰

在一个Web应用中,当你添加一个Web页面的时候,VS实际上会为你创建三个文件:Xxx.aspx, Xxx.aspx.cs和Xxx.aspx.designer.cs,后面两个文件(依赖文件)依赖于第一个文件(主文件).依赖文件嵌套在主文件下,在结构上看起来非常的清晰.那么你是否可以把存在于同一个目录下的两个相关的文件也建立这种依赖关系呢? 目录 一.文件依赖达到的效果 二.文件依赖关系定义在Project文件中 三.通过VS插件建立两个文件之间的依赖关系   一.文件依赖达到的效果 对于项目文件