2008年7月2日水曜日

ivy.xmlのconfの使い方

confの基本

Ivyで一番難しいのはconfの使いこなし方だと思う。confは、たとえばコンパイル時と実行時でライブラリのセットを切り替えたい場合などに使う。

configurationsを書かなければデフォルトのconfである"default"が1つ作られる。明示的に書く場合

<configurations>
    <conf name="compile" />
    <conf name="runtime" />
</configurations>

などと書き、コンパイル時とランタイム時に分けることができる。しかし、ただconfigutationsを書いただけでは意味がない。依存性ごとにどのconfに紐付くのかを指定する必要がある。

<depandencies>
    <dependency org="javaee" name="javaee-api" rev="5" conf="compile"/>
    <dependency org="commons-betwixt" name="commons-betwixt" rev="0.8" conf="compile;runtime"/>
</dependencies>

上のように書くと、javaee-apiはコンパイル時だけに必要でbetwixtはコンパイル時、実行時に含まれることになる。

build.xmlのretrieveタスクでパターンを設定するとconf別のライブラリディレクトリが出来上がる。

<ivy:retrieve pattern="${ivy.lib.dir}/[conf]/[artifact].[ext]" sync="true"/>

confのマッピング

でも残念なことに上記のような書き方でantするとjavaee-apiのところで警告が出てその先の依存性が解決できない。 なぜかと言うと自分のプロジェクトに複数のconfがあるように依存相手のプロジェクトにも複数のconfがあるから。上記javaee-apiのconfはこちらのcompile設定に結びつくのと同時に相手のcompile設定にも結びついてしまう。これを実行したときのivysettings.xmlはJava.Netリポジトリのpomを読まない設定なのでローカルリポジトリに自動的にjavaee-api用のivy.xmlができる。このivy.xmlには"default"設定1つだけが定義されているのでcompile設定では依存性が解決できない。

ではどうするかというと

<dependency org="javaee" name="javaee-api" rev="5" conf="compile->default"/>

のように "自分のconf名->相手のconf名" と言う形でconfのマッピングをしてやる。

Mavenのscopeのように標準的な名前があればいいのだけどIvyのconfはそれぞれのプロジェクトで勝手に名前がつけられるので、依存先のivy.xmlを見ないとconfの設定が書けない。でも大抵はMaven2のリポジトリを使うことになるのでpomから生成されたお決まりのconfパターンになる。こういうときはconfigurations要素のdefaultconfmapping属性にマッピングを書いておくことでいちいちdependencyにconfマッピングを書かなくても済む。

マッピングいろいろ

調査中なので以下嘘かも。
詳しくはIvyドキュメントのdependencyのリファレンスに書いてある。

複数のconfを複数のconfにマッピング。A, B, Cのどのconfでもx, y両方が含まれる。
"A,B,C->x,y"

複数のマッピングを書くとき。
"A->x;B->y"

ワイルドカード指定もできる。confがAのとき、依存先のすべてのconfを含む。
"A->*"

confのマッピングを書かなかった場合、すべてのconfに依存先のすべてのconfが含まれる。
"*->*"

除外の指定。A, B以外すべてのときxにマッピング。
"*, !A, !B -> x"

Aのときはx, それ以外のときはyにマッピング。
"A->x;%->y"

フォールバック。Aのときxにマッピングするが、xがなかったら*にマッピング。
"A->x(*)"