開発時ビルドのバージョン番号の付け方に対するMavenとIvyの思想の違いについて

Apache Ivyの紹介と基本的な使い方 - 達人プログラマーを目指してに関連して説明させていただきます。
Mavenに慣れている人がIvyを使うときに必ずつまづくポイントとして、開発中の中間ビルド時のバージョン番号の付け方に対する両者の思想の違いがあります。Mavenの場合は、規約により開発中のバージョンには「-SNAPSHOT」という接尾辞をつけ、次のリリースを行うまでは同じバージョン番号のまま既存のビルド結果を上書きしながら使い続けることが前提となっています。
一方、もともとIvyの思想では、バージョン番号はビルド内容と1対1に対応しているべきという考え方があります。ビルド結果の中身が違うのであれば、バージョン番号も異なるべきという考え方です。ですから、中間ビルド(Ivyの用語では結合ビルドと呼ばれている)のバージョン番号にタイムスタンプを付けるとか、インクリメンタルなビルド番号を付けるなどの設定が簡単にできるようになっています。実際、タグを使うことで、次に来るべき番号を自動的に計算する機能があります。なお、バージョン番号の付け方の思想については、以下にベストプラクティスとして説明されています。
Best practices | Apache Ivy™ Documentation
マルチプロジェクトのアプリケーションで、この方式でバージョン番号をビルドごとに変更する場合に、ivy.xmlにて依存関係にある兄弟のプロジェクトのバージョン番号に固定の番号を記述してしまうと管理が大変になります。兄弟のモジュールのバージョンがすべて同一と言い切れるならプロパティーファイルなどでバージョンを一元管理しておき、${プロパティ名}の記法で参照すればよいですが、一般にはモジュールごとの番号がそろっている保障はありません。
Ivyではこの問題に対処するために「動的レビジョン番号」という機能があります。たとえば、以下のように依存している対象のバージョンを"latest.integration"のように指定することで、その時点で最新のビルドに依存していると解釈してくれます。

<dependency org="foo" name="bar" rev="latest.integration"/>

さらに、Ivy2.0からはrevision constraintという仕掛けが設けられています。上記のような動的レビジョンの記述をレポジトリー上に直接パブリッシュする代わりに、パブリッシュ時(厳密にはdeliver時)にivy.xmlの依存定義を以下のように自動変換するようになっています。

<dependency org="foo" name="bar" rev="その時点の実際の静的レビジョン" revConstraint="latest.integration" />

こうすることで、レポジトリー上にパブリッシュ済みのアーティファクトについてはレビジョン番号を固定してビルド時の再現性を高くすることができるようになっています。ただし、revConstraint属性にもともとの動的レビジョンの情報を残しておくことで、必要に応じて動的な解決も可能になります。revConstraintの方を使うにはタグを明示的に使って、resolveMode属性をdynamicに指定するか、ivysettings.xmlでデフォルトのresolveModeをdynamicにします。(開発中は全プロジェクトのビルドの代わりにモジュール単位での差分ビルドを行うことが多いのでdynamicモードが重宝します。)
このように、Ivyではビルドごとにレビジョン番号を設定することが推奨されているのですが、Maven風のSNAPSHOT的なやり方をまねることもできます。このような場合にIvyでは忘れずにchanging revisionの設定を行います。特定のレビジョン番号のパターンをchanging revisionであると宣言することで、レポジトリーのキャッシュ動作を抑制する必要があるのです。(デフォルトではIvyはビジョン番号が同一で中身が異なるということのない前提で、レポジトリーのダウンロード結果をキャッシュしてしまうからです。これはトラブルの元になります。)このためには、ivysettings.xmlでレポジトリーに対するレゾルバーを宣言する部分で以下のようにcheckModified属性とchangingPattern属性を合わせて指定します。

<filesystem name="local" checkmodified="true" changingPattern=".*SNAPSHOT">
  <ivy pattern="${ivy.local.default.root}/${ivy.local.default.ivy.pattern}" />
  <artifact pattern="${ivy.local.default.root}/${ivy.local.default.artifact.pattern}" />
</filesystem>

この点については以下が参考になります。
Main Concepts | Apache Ivy™ Documentation
Ivy is Useful
いずれにしてもかなり複雑ですね。この点はIvyで最初にはまるポイントの1つだと思います。私は最初はIvyのマニュアルのベストプラクティスに従って、ビルドごとに番号を振り出す方式を使っていたのですが、動的レビジョンの解決などかなり複雑ですし、レポジトリーのサイズがビルドごとに増大してディスク容量が足りなくなるなどの問題もありました。ただし、SNAPSHOT方式にすると以上に説明したようにIvy固有のキャッシュの問題でトラブルが発生したりします。なかなか悩ましいところです。