Eclipse+Subversive環境での、複数プロジェクトの扱い

やー、凹んだorz

何が起きたのか

Sabotter 0.0.2リリースの為に、タグ打ったんですよ。
そしたら、その一操作でCodeReposに12回ものコミットが入ったんですよorz
で、IRCで話題沸騰。

一般的な話

Sabotterは、12個の「Eclipseプロジェクト」に分かれています。もう少し詳しく言うと、7つのコンポーネントと、5つのフィーチャープロジェクト*1。そして、その7つのコンポーネントはそれぞれ依存関係があります。

Sabotterの様な複数コンポーネントのプロジェクト群は、repository/trunk 内に、複数のディレクトリを作って、それぞれコミットすると思います。で、チェックアウト時には trunk ディレクトリを指定して、内部のプロジェクトをごっそりチェックアウトしますね。これが一般的な使い方。

  • /repository/
    • trunk/
      • ComponentAProject/
        • .project
      • ComponentBProject/
        • .project
      • ComponentCProject/
        • .project
    • branches/
    • tags/

Eclipseだと何がどうなるのか

Eclipseというのは、起動時に「ワークスペース」という、プロジェクトを配置するディレクトリを指定します。今日のテーマであるEclipseのイケてない仕様の一つに、Eclipseワークスペースディレクトリの直下のディレクトリしか、Eclipseプロジェクトとして扱わない。というか、直下のディレクトリを全てプロジェクトとして扱う。というものがあります。(デフォルトでは。参照 http://d.hatena.ne.jp/taichitaichi/20080711/1215759933

そしてもう一つ。Eclipseはプロジェクトディレクトリ直下の .project ファイル(等)を利用して、このプロジェクトのメタデータを管理(Javaプロジェクトなのか、EclipsePluginプロジェクトなのか、Mavenで管理されているのか否か、等)しています。これらのファイルは、プロジェクト直下でなければ役割を果たしません。

  • /path/to/workspace/
    • ComponentAProject/
      • .project
    • ComponentBProject/
      • .project
    • ComponentCProject/
      • .project

のような状況ですね。

しかし、Eclipse環境だと、trunkディレクトリを指定してチェックアウトを行うと、「trunk」という名前のプロジェクトが1つだけ出来上がり、内部にディレクトリが複数できあがります。

  • /path/to/workspace/
    • trunk/
      • ComponentAProject/
        • .project
      • ComponentBProject/
        • .project
      • ComponentCProject/
        • .project

こうなった場合、まずEclipseは、trunk直下に .project が無い為、適当な .project ファイルを勝手に作成します。(そんな事されても意味ないんですけど…)

次に。trunk/ComponentAProject/ ディレクトリ内には .project ファイルがある訳ですが、これは「プロジェクトディレクトリ直下」では無いので、ガン無視されます。

EclipseJavaプロジェクトなのかどうかさえ判断しないまま(つまりコンパイルも行わず)、ただの「Windowsエクスプローラの様なもの」の挙動をします。IDE使う意味がまったくない状態w

ではどうしようか。というと。trunkをチェックアウトするのではなく、ComponentA〜CProjectを個別にチェックアウトします。そうすると、プロジェクト間の関連性は消えてしまいますが、Eclipseに適した形でチェックアウトすることができます。

これが原因で事件が起きました…

これら12個のコンポーネントは、互いに依存性がある為、現在の状況をまとめてタグ打ちする必要があります。通常であれば、trunkディレクトリを tags/v0.0.2 なんかにコピーする事によって、タグ打ちをします。が、前述の通り、Eclipse上にはtrankディレクトリがありません。そこで俺がやった操作は…。

「該当12プロジェクトを選択状態にして、コンテキストメニューから Team>タグ を選ぶ」

そうすると、通常は1回で済むところが、12回バラバラにコミット(コピー?)が行われてしまいます。うおーー。

ではどうすれば良かったのか。

結論を言えば、Repositoryエクスプローラ*2から、trunkを選択して、New>タグ ですね。

なるほど。別にローカルコピーをコミットしてタグを打つ訳ではないのだから、こちらから操作するのもアリなんだ。これで、やっとアトミックにタグを打つことができます。次からそうします。CodeReposの方々、お騒がせしました><

というのが事の顛末。

しかし、まだ問題は残っていた!

タグ打ちは問題なくなりました。しかし。

コミットする時どうしよう。

前述の通り、各コンポーネントは依存関係にあります。例えば一番コアなコンポーネントのクラス名を変えたとします。そうすると、その下流にあるコンポーネントは全て影響を受け、発信変更状態になります。

これをアトミックにコミットすることができない! やっぱり12回コミットする事になってしまうのか…。

また、依存関係はないものの、新バージョンリリース時には、各プロジェクトのMANIFEST.MF内に記述してあるバージョン表記を変更しなければいけません*3。これはアトミックである必要はありませんが、出来ればアトミックにコミットしたいですよね。

コミットはタグ打ちとは違って、ローカルコピーが必須になるので、SVNリポジトリビューから作業を行うことはできません。

という問題が、未だ解決できていません。どなたかお知恵を…。

*1:EclipsePlugin作者じゃないと意味不明ですが…。

*2:正確には、SVNレポジトリビュー

*3:EclipsePluginを作た経験が無い方には分からないと思いますが、全部個別に記述しなければいけないんです。