自作のScalaライブラリをpublishLocalしながら手元でリリース前に最終確認する - $shibayu36->blog; で、手元で自作ライブラリの最終確認をするにはpublishLocalすれば良いことを書いた。この時にsbtが依存管理に使っているivyについてもついでに調べたので、調べたことについてメモしておく。コードをちゃんと追いかけているわけではないので、もし間違っていたら教えてください。
ivyとは
ivyとは依存管理のライブラリ。sbtも依存管理にはivyを使っているようだ。
ただし、sbtはivyにパッチを当てて使っていそうに見えたので、これは注意かもしれない。
なぜローカルのivyレポジトリを参照してくれるのか
これはデフォルトでsbtが参照先に~/.ivy2/localがresolverを追加しているからっぽい。Resolverについては https://www.scala-sbt.org/1.x/docs/Resolvers.html あたりを参照。sbtでshow fullResolversすると、何がresolverに追加されているか分かる。
sbt:joda-time-fake> show fullResolvers [info] * Raw(ProjectResolver(inter-project, mapped: )) [info] * FileRepository(local, Patterns(ivyPatterns=Vector(${ivy.home}/local/[organisation]/[module]/(scala_[scalaVersion]/)(sbt_[sbtVersion]/)([branch]/)[revision]/[type]s/[artifact](-[classifier]).[ext]), artifactPatterns=Vector(${ivy.home}/local/[organisation]/[module]/(scala_[scalaVersion]/)(sbt_[sbtVersion]/)([branch]/)[revision]/[type]s/[artifact](-[classifier]).[ext]), isMavenCompatible=false, descriptorOptional=false, skipConsistencyCheck=false), FileConfiguration(true, None)) [info] * public: https://repo1.maven.org/maven2/
このFileRepositoryの部分がローカルのivyレポジトリを参照するための設定。ivyPatternsあたりを見ると${ivy.home}/local/[organisation]/[module]/(scala_[scalaVersion]/)(sbt_[sbtVersion]/)([branch]/)[revision]/[type]s/[artifact](-[classifier]).[ext]
と書いてある。実際のjarファイルが置いてある場所の~/.ivy2/local/com.github.shibayu36/joda-time-fake_2.11/0.0.3-SNAPSHOT/jars/joda-time-fake_2.11.jar
とくらべてみると
- com.github.shibayu36が[organisation]にマッチ
- joda-time-fake_2.11が[module]にマッチ
- (scala_[scalaVersion])はマッチしないけど括弧で包まれているので問題ない
- (sbt_[sbtVersion]/)も同様にマッチしない
- ([branch]/)も同様にマッチしない
- 0.0.3-SNAPSHOTが[revision]にマッチ
- [type]sがjarsにマッチ
- joda-time-fake_2.11.jarが[artifact](-[classifier]).[ext]にマッチ
ということで、ちゃんと使われるということなのかな?このPatternについてはhttps://ant.apache.org/ivy/history/latest-milestone/concept.html#patterns あたりも参考になった。
ivyのキャッシュについて
ivyは毎回アーティファクトをダウンロードに使わないためにキャッシュしているようなので、このあたりについても調べた。sbt利用上のIvyに関するハマりポイント - たけぞう瀕死ブログが参考になった。
まずキャッシュのディレクトリは~/.ivy2/cache/
以下にある。先程のjoda-time-fakeのキャッシュを見てみると、以下のようになっている。
$ tree ~/.ivy2/cache/com.github.shibayu36/joda-time-fake_2.11/ /Users/shibayu36/.ivy2/cache/com.github.shibayu36/joda-time-fake_2.11/ ├── ivy-0.0.1-SNAPSHOT.xml ├── ivy-0.0.1.xml ├── ivy-0.0.2.xml ├── ivy-0.0.2.xml.original ├── ivy-0.0.3-SNAPSHOT.xml ├── ivydata-0.0.1-SNAPSHOT.properties ├── ivydata-0.0.1.properties ├── ivydata-0.0.2.properties ├── ivydata-0.0.3-SNAPSHOT.properties └── jars └── joda-time-fake_2.11-0.0.2.jar
まずリモートレポジトリからfetchしてきたものに関しては、jars以下にjarファイル自体をキャッシュしているようだ。なのでjars以下にjoda-time-fake_2.11-0.0.2.jar
が存在している。またivydata-0.0.2.propertiesというファイルを眺めてみると
ivydata-0.0.2.properties
#ivy cached data file for com.github.shibayu36#joda-time-fake_2.11;0.0.2 #Sun Mar 25 08:46:10 JST 2018 artifact\:ivy\#ivy\#xml\#742964223.is-local=false artifact\:joda-time-fake_2.11\#jar\#jar\#1850426835.is-local=false artifact\:ivy\#ivy\#xml\#742964223.location=https\://repo1.maven.org/maven2/com/github/shibayu36/joda-time-fake_2.11/0.0.2/joda-time-fake_2.11-0.0.2.pom artifact\:joda-time-fake_2.11\#jar\#jar\#1850426835.location=https\://repo1.maven.org/maven2/com/github/shibayu36/joda-time-fake_2.11/0.0.2/joda-time-fake_2.11-0.0.2.jar artifact\:joda-time-fake_2.11\#pom.original\#pom\#-791977799.is-local=false artifact\:joda-time-fake_2.11\#jar\#jar\#1850426835.exists=true artifact\:joda-time-fake_2.11\#pom.original\#pom\#-791977799.location=https\://repo1.maven.org/maven2/com/github/shibayu36/joda-time-fake_2.11/0.0.2/joda-time-fake_2.11-0.0.2.pom artifact\:ivy\#ivy\#xml\#742964223.exists=true artifact\:joda-time-fake_2.11\#pom.original\#pom\#-791977799.exists=true
となっており、
- localじゃない
- オリジナルはhttps://repo1.maven.org/maven2/ から取ってきている
みたいなことが書いてある。なるほど。
続いてpublishLocalしたレポジトリから取ってきた、0.0.3-SNAPSHOTのほうを見てみると
ivydata-0.0.3-SNAPSHOT.properties
#ivy cached data file for com.github.shibayu36#joda-time-fake_2.11;0.0.3-SNAPSHOT #Sun Mar 25 10:06:08 JST 2018 artifact\:joda-time-fake_2.11\#jar\#jar\#679424103.is-local=true artifact\:ivy\#ivy.original\#xml\#1006386850.exists=true artifact\:joda-time-fake_2.11\#jar\#jar\#679424103.location=/Users/shibayu36/.ivy2/local/com.github.shibayu36/joda-time-fake_2.11/0.0.3-SNAPSHOT/jars/joda-time-fake_2.11.jar artifact\:joda-time-fake_2.11\#doc\#jar\#-517561348.exists=true artifact\:joda-time-fake_2.11\#doc\#jar\#-517561348.is-local=true artifact\:joda-time-fake_2.11\#doc\#jar\#-517561348.location=/Users/shibayu36/.ivy2/local/com.github.shibayu36/joda-time-fake_2.11/0.0.3-SNAPSHOT/docs/joda-time-fake_2.11-javadoc.jar artifact\:ivy\#ivy.original\#xml\#1006386850.location=/Users/shibayu36/.ivy2/local/com.github.shibayu36/joda-time-fake_2.11/0.0.3-SNAPSHOT/ivys/ivy.xml artifact\:ivy\#ivy\#xml\#-428038509.exists=true artifact\:ivy\#ivy\#xml\#-428038509.location=/Users/shibayu36/.ivy2/local/com.github.shibayu36/joda-time-fake_2.11/0.0.3-SNAPSHOT/ivys/ivy.xml artifact\:ivy\#ivy.original\#xml\#1006386850.is-local=true artifact\:joda-time-fake_2.11\#src\#jar\#-1768464466.is-local=true artifact\:joda-time-fake_2.11\#src\#jar\#-1768464466.location=/Users/shibayu36/.ivy2/local/com.github.shibayu36/joda-time-fake_2.11/0.0.3-SNAPSHOT/srcs/joda-time-fake_2.11-sources.jar artifact\:ivy\#ivy\#xml\#-428038509.is-local=true artifact\:joda-time-fake_2.11\#src\#jar\#-1768464466.exists=true artifact\:joda-time-fake_2.11\#jar\#jar\#679424103.exists=true
となっており、
- localである
- ローカルのivyレポジトリのjarファイルへの参照も書いてある
artifact\:joda-time-fake_2.11\#jar\#jar\#679424103.location=/Users/shibayu36/.ivy2/local/com.github.shibayu36/joda-time-fake_2.11/0.0.3-SNAPSHOT/jars/joda-time-fake_2.11.jar
あたり?
となっていた。なるほど〜。
これらの調査から、sbt利用上のIvyに関するハマりポイント - たけぞう瀕死ブログに書かれていた、
Ivyはローカルリポジトリに格納されているライブラリに対してはjarファイルを絶対パスで参照するメタファイルのみキャッシュします。上記ではライブラリは一度キャッシュされたら更新チェックは行われないと書きましたが、ローカルリポジトリのjarファイルについてはjarファイルそのものがキャッシュされているわけではなく、参照がキャッシュされているだけなのでpublish-localするだけで変更が反映されるということになります。
をなんとなくであるが理解することが出来たように思う。
キャッシュ周り、このあたり理解できてないとむっちゃハマりそうだな〜。
まとめ
今回はsbtが依存管理に使っているivyのローカルレポジトリやキャッシュについて調べて、その内容をメモした。自分で適当にライブラリを作ってみると、こういう感じで依存管理やビルドツールについても詳しくなれるので便利。
参考
- http://ant.apache.org/ivy/
- https://www.scala-sbt.org/1.x/docs/ja/Library-Dependencies.html
- https://github.com/sbt/sbt/blob/1.1.x/project/Dependencies.scala#L27..L27
- https://github.com/sbt/librarymanagement
- https://github.com/sbt/ivy
- https://www.scala-sbt.org/1.x/docs/Resolvers.html
- https://ant.apache.org/ivy/history/latest-milestone/concept.html#patterns
- sbt利用上のIvyに関するハマりポイント - たけぞう瀕死ブログ