CLOVER🍀

That was when it all began.

sbtで、プロジェクト内のライブラリ依存関係を調べる

Mavenのdependency:tree的な。

プラグインとかあるんだろうなーと思ってちょこっと調べたら、やっぱりありました。少し前から気付いてはいたのですが、先のInfinispan Queryを使う時に、初めて使ってみましたよ。

sbt-dependency-graph
https://github.com/jrudolph/sbt-dependency-graph

導入

プロジェクトルートディレクトリ配下に、build.sbtを使って設定する場合について載せます。その他の形式の設定については、上記サイトを参照してください…。

今回は、Seasar2(S2Container)とSpecs2にスケープゴートになっていただきます。

つまり、こんな依存関係を定義します、と。

libraryDependencies ++= Seq(
  "org.seasar.container" % "s2-framework" % "2.4.46",
  "org.specs2" %% "specs2" % "1.14" % "test"
)

これを踏まえて…まず、プロジェクトルートディレクトリ/project/plugins.sbtファイルを作成します。中身は、こんな感じです。

addSbtPlugin("net.virtual-void" % "sbt-dependency-graph" % "0.7.1")

そして、build.sbtには以下の1行を加えます。

net.virtualvoid.sbt.graph.Plugin.graphSettings

つまり、こんなbuild.sbtになります。

name := "sbt-dependenty"

version := "0.0.1"

scalaVersion := "2.10.1"

net.virtualvoid.sbt.graph.Plugin.graphSettings

resolvers += "The Seasar Foundation Maven2 Repository" at "http://maven.seasar.org/maven2"

libraryDependencies ++= Seq(
  "org.seasar.container" % "s2-framework" % "2.4.46",
  "org.specs2" %% "specs2" % "1.14" % "test"
)

使ってみる

ここまでの準備をして、sbtを起動するか、reloadするとsbt-dependency-graphプラグインを使ったコマンドが打てるようになっています。

例えば、

> dependency-tree
[info] sbt-dependenty:sbt-dependenty_2.10:0.0.1 [S]
[info]   +-org.seasar.container:s2-framework:2.4.46
[info]     +-aopalliance:aopalliance:1.0
[info]     +-commons-logging:commons-logging:1.1
[info]     +-jboss:javassist:3.4.ga
[info]     +-junit:junit:3.8.2
[info]     +-ognl:ognl:2.6.9-patch-20090427
[info]     
[success] Total time: 0 s, completed 2013/03/20 23:43:33

こんな感じです。

Specs2が入っていませんね。前に「test:」を付けて、スコープを指定すればよさそうです。

> test:dependency-tree
[info] sbt-dependenty:sbt-dependenty_2.10:0.0.1 [S]
[info]   +-org.seasar.container:s2-framework:2.4.46
[info]   | +-aopalliance:aopalliance:1.0
[info]   | +-commons-logging:commons-logging:1.1
[info]   | +-jboss:javassist:3.4.ga
[info]   | +-junit:junit:3.8.2
[info]   | +-ognl:ognl:2.6.9-patch-20090427
[info]   | 
[info]   +-org.specs2:specs2_2.10:1.14
[info]     +-org.specs2:specs2-scalaz-concurrent_2.10:7.0.0 [S]
[info]     | +-org.specs2:scalaz-effect_2.10:7.0.0 [S]
[info]     | | +-org.specs2:scalaz-core_2.10:7.0.0 [S]
[info]     | | 
[info]     | +-org.specs2:specs2-scalaz-core_2.10:7.0.0 [S]
[info]     | 
[info]     +-org.specs2:specs2-scalaz-core_2.10:7.0.0 [S]
[info]     
[success] Total time: 0 s, completed 2013/03/20 23:44:29

これ、どれがtestスコープかわからないんですけど…。このあたりは、MavenのDependency pluginの方が親切?

ところで、後ろについている[S]というのは

[info]     +-org.specs2:specs2-scalaz-concurrent_2.10:7.0.0 [S]

Scala Libraryに依存関係があるアーティファクトっぽいです。

> set filterScalaLibrary := false

と設定して、もう1度同じコマンドを実行すると

> test:dependency-tree
[info] sbt-dependenty:sbt-dependenty_2.10:0.0.1
[info]   +-org.scala-lang:scala-library:2.10.1
[info]   +-org.seasar.container:s2-framework:2.4.46
[info]   | +-aopalliance:aopalliance:1.0
[info]   | +-commons-logging:commons-logging:1.1
[info]   | +-jboss:javassist:3.4.ga
[info]   | +-junit:junit:3.8.2
[info]   | +-ognl:ognl:2.6.9-patch-20090427
[info]   | 
[info]   +-org.specs2:specs2_2.10:1.14
[info]     +-org.specs2:specs2-scalaz-concurrent_2.10:7.0.0
[info]     | +-org.scala-lang:scala-library:2.10.1
[info]     | +-org.specs2:scalaz-effect_2.10:7.0.0
[info]     | | +-org.scala-lang:scala-library:2.10.1
[info]     | | +-org.specs2:scalaz-core_2.10:7.0.0
[info]     | |   +-org.scala-lang:scala-library:2.10.1
[info]     | |   
[info]     | +-org.specs2:specs2-scalaz-core_2.10:7.0.0
[info]     |   +-org.scala-lang:scala-library:2.10.1
[info]     |   
[info]     +-org.specs2:specs2-scalaz-core_2.10:7.0.0
[info]       +-org.scala-lang:scala-library:2.10.1
[info]       
[success] Total time: 0 s, completed 2013/03/20 23:53:48

出力結果にScalaが現れるようになります。

他には、「dependency-graph」とか?

> dependency-graph
[info]                          +-----------------------+                         
[info]                          |sbt-dependenty_2.10 [S]|                         
[info]                          |    sbt-dependenty     |                         
[info]                          |         0.0.1         |                         
[info]                          +-----------------------+                         
[info]                                       |                                    
[info]                                       v                                    
[info]                            +--------------------+                          
[info]                            |    s2-framework    |                          
[info]                            |org.seasar.container|                          
[info]                            |       2.4.46       |                          
[info]                            +--------------------+                          
[info]                                 |  |  |  |  |                              
[info]     -----------------------------  |  |  |  -------------------------      
[info]     |            -------------------  |  ---------------            |      
[info]     |            |                    |                |            |      
[info]     v            v                    v                v            v      
[info]  +-----+ +---------------+ +--------------------+ +---------+ +-----------+
[info]  |junit| |commons-logging| |        ognl        | |javassist| |aopalliance|
[info]  |junit| |commons-logging| |        ognl        | |  jboss  | |aopalliance|
[info]  |3.8.2| |      1.1      | |2.6.9-patch-20090427| | 3.4.ga  | |    1.0    |
[info]  +-----+ +---------------+ +--------------------+ +---------+ +-----------+
[info] Note: The old tree layout is still available by using `dependency-tree`
[success] Total time: 0 s, completed 2013/03/20 23:55:04

以前は、このコマンドで「dependency-tree」と同じ結果が出ていたのかな?これはこれですごいなぁ、と。GraphMLでの出力もできるようですよ。

ちなみに、「dependency-graph」はそれなりに依存関係が多いプロジェクトを分析すると、警告が出るようになります。例えば、SAStrutsを足して

libraryDependencies ++= Seq(
  "org.seasar.sastruts" % "sa-struts" % "1.0.4-sp9",
  "org.seasar.container" % "s2-framework" % "2.4.46",
  "org.specs2" %% "specs2" % "1.14" % "test"
)

reload。

> reload

それから、「dependency-graph」を実行すると

> dependency-graph
[info] Updating {file:/xxxxx/sbt-dependency/}default-41550e...
[info] Resolving org.specs2#scalaz-core_2.10;7.0.0 ...
[info] Done updating.
[info] sbt-dependenty:sbt-dependenty_2.10:0.0.1 [S]
[info]   +-org.seasar.container:s2-framework:2.4.46
[info]   | +-aopalliance:aopalliance:1.0
[info]   | +-commons-logging:commons-logging:1.1
[info]   | | +-avalon-framework:avalon-framework:4.1.3
[info]   | | +-javax.servlet:servlet-api:2.3
[info]   | | +-log4j:log4j:1.2.12
[info]   | | +-logkit:logkit:1.0.1
[info]   | | 
[info]   | +-jboss:javassist:3.4.ga
[info]   | +-junit:junit:3.8.2 (evicted by: 4.4)
[info]   | +-ognl:ognl:2.6.9-patch-20090427
[info]   | 
[info]   +-org.seasar.sastruts:sa-struts:1.0.4-sp9
[info]     +-commons-fileupload:commons-fileupload:1.2
[info]     +-org.seasar.container:s2-tiger:2.4.44
[info]     | +-junit:junit:4.4
[info]     | +-org.easymock:easymock:2.4
[info]     | +-org.seasar.container:s2-extension:2.4.44
[info]     |   +-org.apache.poi:poi:3.0-FINAL
[info]     |   | +-commons-logging:commons-logging:1.1
[info]     |   |   +-avalon-framework:avalon-framework:4.1.3
[info]     |   |   +-javax.servlet:servlet-api:2.3
[info]     |   |   +-log4j:log4j:1.2.12
[info]     |   |   +-logkit:logkit:1.0.1
[info]     |   |   
[info]     |   +-org.seasar.container:s2-framework:2.4.44 (evicted by: 2.4.46)
[info]     |   
[info]     +-struts:struts:1.2.9
[info]       +-antlr:antlr:2.7.2
[info]       +-commons-beanutils:commons-beanutils:1.7.0
[info]       | +-commons-logging:commons-logging:1.0.3 (evicted by: 1.0.4)
[info]       | 
[info]       +-commons-digester:commons-digester:1.6
[info]       | +-commons-beanutils:commons-beanutils:1.6 (evicted by: 1.7.0)
[info]       | +-commons-collections:commons-collections:2.1
[info]       | +-commons-logging:commons-logging:1.0 (evicted by: 1.0.4)
[info]       | +-xml-apis:xml-apis:1.0.b2
[info]       | 
[info]       +-commons-fileupload:commons-fileupload:1.0 (evicted by: 1.2)
[info]       +-commons-logging:commons-logging:1.0.4 (evicted by: 1.1)
[info]       +-commons-validator:commons-validator:1.1.4
[info]       +-oro:oro:2.0.7
[info]       +-xalan:xalan:2.5.1
[info]       
[info] Note: The graph was estimated to be too big to display (> 15 nodes). Use `dependency-graph --force` to force graph display.
[success] Total time: 1 s, completed 2013/03/20 23:59:27

結果が「dependency-tree」と同じになってしまいます。

よくよく見ると、

[info] Note: The graph was estimated to be too big to display (> 15 nodes). Use `dependency-graph --force` to force graph display.

15ノード以上あるので、表示するには大きすぎるよと言っています。それでも出したければ、「--force」を使えということなので

> dependency-graph --force

…結果は、すごいことになるので載せません。

まあ便利なのですが、MavenのDependency pluginの方が今のところはわかりやすいかも?とはいえ、時々使いそうな気はしますけどね。