はじめに
Git、Subversion、Mercurialと個別のバージョン管理システムの話が一通り終わったので、今度からは共通の話をします。今回は「Android Studioのプロジェクト管理ファイルってバージョン管理したほうがいいの?」です。
中途半端に長くなったので前・中・後編の3回に分けて説明します。前編の今回は能書きばかりで肝心な話題は次回以降に持ち越しです。
その前に
今回のシリーズでよく登場するパスのシンボルについて再掲しておきます。より細かい内容が知りたい方は、Android Studioのプロジェクト構成は第5回を、Android Studioの設定ディレクトリは第2回を、それぞれ参照しておいてください。
表1 文中に登場するシンボルの意味
シンボル | 意味 |
<PROJCET_HOME> | Android Studioのプロジェクトのトップディレクトリ |
<MODULE_HOME> | プロジェクト内に作成したモジュールのトップディレクトリ |
<AS_CONFIG> | Android Studioの設定ディレクトリ |
<HOME> | 利用者のホームディレクトリ |
Android Studioのプロジェクト概要
Android StudioもいっぱしのIDEなので、独自のプロジェクト管理ファイルを持ちます。具体的には、<PROJCET_HOME>/.idea
ディレクトリにあるファイル群と、各種モジュール定義を行っている*.iml
ファイルです。これらはEclipseでいう.classpath
や.project
に相当します。
Android Studioのプロジェクトウィザードから作成した典型的なプロジェクトの構成は図1の通りです。初期のAndroid Studioと比べるとプロジェクト名やモジュール名は若干変わりましたが、それ以外の構造は変わっていません。
図1 Andoroid Studioのプロジェクト構成
※Android Studio v0.3.7の例です。
このうち明らかにバージョン管理の対象にしなくてよいのは、ビルド成果物を含む<PROJCET_HOME>/<MODULE_HOME>/build
ディレクトリ、Gradleのキャッシュディレクトリの<PROJCET_HOME>/.gradle
ディレクトリ、build.gradle
が参照するローカル設定の<PROJCET_HOME>/local.properties
ファイルの3つです。
それ以外はバージョン管理対象にしてよいファイルやディレクトリなのですが、Android Studioのプロジェクト管理ファイル群の扱いがハッキリしません。
一応、プロジェクトに付属している .gitignore
ファイルを参考にすると「<PROJCET_HOME>/.idea/workspace.xml
だけはバージョン管理しなくてよい」となりますが、果たして信じてよいのでしょうか……。
バージョン管理のポリシーあれこれ
プロジェクト管理ファイルの話に入る前に、そもそもこれらをバージョン管理する必要があるかどうかについて考えてみます。バックアップという観点では、プロジェクトに必要な情報なのでバージョン管理しておいたほうがよいですが、チーム開発という観点で見た場合、ホントウに全部管理しないとダメ?という疑問が出てきます。
バージョン管理のポリシーについても、その目的ごとに変わるので一概に「これが決定版」というものは出来ないでしょう。
ケース1. 個人で、かつ同じ環境で開発する場合
最も小さな構成のバージョン管理形態だと思います。要するにバージョン管理システムの役割は(履歴付きの)バックアップですね。
この場合、ビルド成果物以外はすべてバージョン管理対象にしても問題になることは無いでしょう。つまり、Android Studioが生成するプロジェクトに付いてきている .gitignore
のままで良いです。
図2 個人で、かつ同じ環境で開発する場合
ケース2. 個人だけど、異なる環境で開発する場合
バージョン管理システムを扱うのは自分一人だけれど、チェックアウトする環境が複数ある場合です。たとえば自宅と職場といった具合です。異なるPCにチェックアウトしたとしても、それらの環境差違が無いような構成にしている場合は、ケース1となんらかわりません。ここでいう環境差違とは、インストールしているAndroid StudioやAndroid SDKのバージョンやインストール先、チェックアウトしたプロジェクトのディレクトリがまったく同じということを指します。
このケースの本質的な状況は、どちらかというと「職場はWindowsだけれど自宅はMac」のように、外的要因で環境差違を解消できないような状況を指します。筆者の状況がまさにこれになります。
この時点からAndroid Studioの管理ファイルをどうバージョン管理システムに登録するか悩み始めます(「異なる環境で利用したいけれど、IDEのセットアップに手間をかけたくない」ために悩む)。要するにプロジェクト付属の.gitignore
のまま共有すると、作業環境によって設定ファイルの更新が頻発します。
図3 個人だけど、異なる環境で開発する場合
ケース3. チームで、皆がAndroid Studioを使って開発する場合
開発者が自分ひとりか、チームの複数人かの違いで、プラットフォーム(OS)やAndroid Studioバージョン、チェックアウト先をすべて統一するのであればケース1と条件は同じです。いわゆる「大規模開発」で良くやる手口なのですが、Android開発でもこのような手口は現実的なのでしょうか?
図4 チームで、皆がAndroid Studioを使って開発する場合
同一プラットフォームであっても、全員の環境をすべて統一するのはなかなか骨が折れる作業です。また ケース1 との決定的な違いは関係者が複数人居ることで、全員が同じくらいAndroid Studioに習熟しているとは限らないというのがポイントです。ただし、その解決策の提示は本連載の主旨とはズレるので、あえて触れません(習熟度が異なるため、環境差異を作らず全員統一環境にする、というのが答えと言えば答えです)。
この場合は「習熟度の異なる利用者が参加するので、セットアップはなるべく手間ヒマかからず、かつIDE(Android Studio)の機能を最大限活用したい」と考えるでしょう。
完全に作業環境を統一するのであればケース1と同じく、プロジェクト付属の .gitignore
のままで十分ですが、Android SDKのインストール場所やプロジェクトのチェックアウト先くらい、個人の自由にさせて欲しいとなると ケース2 と似たような悩みを抱えます(利用者が複数人いるので、ケース2とはちょっと変わった悩みを抱えます)。
ケース4. チームで、おのおのが好きな環境で開発する場合
個人的にはチーム開発であろうと開発者個人の好みは尊重されるべきだと思うので、この形が理想だと思っています。だけれども。Android Studioが作成するGradleベースのプロジェクトをAndroid Studio以外で開発するのは現実的なのだろうか?とも思っています。
Android Studioへのマイグレーション方法を持っているEclipseでさえ、Android Studioとプロジェクトを共用するのは困難です。現実的にありえるケースとしては、以下の3パターンくらいでしょう。
- テキストエディタで開発して、ビルドに
gradle
を利用する。
- NetBeansのNBAndroidプラグインを使って、Android Studioのプロジェクトをマウントする。
- EclipseベースのプロジェクトをGradleエクスポートして、Android Studioでも開発できるようにする(Android Studio→EclipseはNGだけど、その逆は可能)。
Eclipseとの共用はそれなりに価値がありそうですが、それ以外はあえてそれを選択する良さがわかりかねます。この他にIntelliJ IDEAのCommunity版やUltimate版との共用が可能ですが、それってバリエーションのウチに入らないな、とも思います。
図5 チームで、おのおのが好きな環境で開発する場合
この場合はケース2、ケース3の延長線で「手間ヒマかけず、Android Studioのプロジェクトを共有したい」と考えるか、または「ビルド関連の情報はGradle(build.gradle
)に集約されているので、IDE依存の管理ファイルを共有することはまかりならん」と考えるかも知れません。
前者の場合 ケース3と同じ悩みを抱え、後者の場合はバッサリと「Android Studioの設定ファイルは共有しない」と決めてしまいます(それがうまく行くのかは後述します)。
Eclipse ADTのプロジェクトをインポートする
Android Studio v0.4.0から追加された機能です。今までは、Eclipse ADTのプロジェクトをGradleプロジェクトにエクスポートして → それをAndroid Studioで開く、という流れでしたが、v0.4.0から直接Eclipse ADTのプロジェクトをAndroid Studioにインポートできるようになりました。
図6 インポートするEclipse ADTのプロジェクトの例
Android Studioのウェルカム画面にある「Import Project」を実行し、インポートしたいEclipse ADTのプロジェクトを指定します。
図7 Eclipse ADTのプロジェクトをインポートした例(クリックすると動きがわかります)
今までのやり方(Gradleエクスポート)は、Eclipse ADTのプロジェクトの構造をそのままにbuild.gradle
があわせる形でしたが、この方法はEclipse ADTのプロジェクト構造をGradleベースのプロジェクトに組み立て直します。そのため、インポート元のプロジェクトは弄らず、新たにインポートしたプロジェクトを作成します。第21回で紹介したインポートとは振る舞いが異なります。
今後はEclipse ADTのGradleエクスポートより、こちらのインポートを主流にしたいのでしょう。でも、これってEclipse ADTとAndroid Studioの併用を否定してますよね。
Android StudioとGradleベースのプロジェクトの特徴
Android Studioが作成するGradleベースのプロジェクトの最大の特徴は、
Android SDK(とJDK)さえあれば、どこでもビルドできること
です。
さらにAndroid Studioは、Gradleベースのプロジェクトを直接開く事ができるので、極論を言えばbuild.gradle
さえあれば、他のプロジェクト管理ファイルは一切必要ありません(とはいえ、gradle-wrapperはあった方がよいです)。先ほどの ケース4 のポリシーのひとつがこれにあたります。
Android Studioがプロジェクトとして認識できる必要最低限の状態に絞り込むと、<PROJCET_HOME>/.gitignore
はリスト1になります。
リスト1 Android Studioのプロジェクトとして成り立つ最低限の<PROJCET_HOME>/.gitignore
/.gradle/
/local.properties
.DS_Store
/.idea/
*.iml
図11のようにAndroid Studioの管理ファイルを削除し、ビルドに必要な最低限の情報(ほぼbuild.gralde
のみ)をもつプロジェクトをAndroid Studioで開いてみます。
図11 Android Studio関連の設定を排除したプロジェクトの構造
ウェルカム画面から「Open Project」を実行し、「Open Project」ダイアログで該当プロジェクトを開きます。このファイルダイアログが「Android Studioのプロジェクト」と認識するのは「.idea
ディレクトリがあるか無いか」なので、.idea
ディレクトリを持たないプロジェクトは普通のディレクトリとして認識されます。
ただし、ビルドスクリプトbuild.gradle
をプロジェクト管理ファイルとして認識できるので、同ファイルを含むディレクトリはやはりプロジェクトディレクトリとして認識します(プロジェクトを示すアイコンが異なります)。
図12 build.gradleしかないディレクトリもプロジェクトと認識する
これから紹介する最初のやり方はひっかけなので注意して読んでください。
build.gradle
のみを持つプロジェクトディレクトリを選択すると、次に「Import Project from Gradle」ダイアログが表示されます。ちなみに、ウェルカム画面で「Open Project」の代わりに「Import Project...」を実行していても、結局この画面に辿り着きます(「Import Project...」の存在意義が……)。
図14 「Open Project」でbuild.gradleを含むディレクトリを選択する
図15 「Imprt Project from Gradle」ダイアログ(その1)
ここで注目すべきは「Use default gradle wrapper」が選択できなくなっている事です。ご丁寧に「このプロジェクトでは設定できません(not configured for the current project)」とかっこ書きが付いています。
できればこのオプションを選択したいのですが、このままでは叶いません。しかし、どうしたわけか「Open Project」ダイアログで「build.gradle
を含むディレクトリ」ではなくbuild.gradle
そのものを選択 すると、図16のように「Use default gradle wrapper」が選択された状態になります。この場合、ちゃっかり「推奨します(recommended)」とかっこ書きが付いているのが、ちょっとだけ癪に障ります。
図16 「Open Project」でbuild.gradleを選択する
図17 「Imprt Project from Gradle」ダイアログ(その2)
build.gradle
を指定したケースでプロジェクトを開くと、build.gradle
を元にAndroid Studioの管理ファイルを構築しはじめます。意外(?)なことに build.gradle
が用いるローカル設定ファイル(local.properties
)も再生成します。
図18 インポートに成功したGradleプロジェクト
要するに「New Project...」でやっていることを繰り返しているのでしょう。「New Project...」の場合は、プロジェクトウィザードの指示に基づいてbuild.gradle
とそれに沿ったプロジェクトのひな形を作り、Android Studioのプロジェクトとして開きます。今回の場合は、その後半の「Android Studioのプロジェクトとして開く」を再実行したことになります。
ある意味当たり前なことなのですが、<PROJECT_HOME>/*.iml
にできあがるモジュール名は、プロジェクトのディレクトリ名に依存します。今までの例では<PROJECT_HOME>
はMyApplication
という名前だったので<PROJECT_HOME>/MyApplication.iml
ができました。
仮に<PROJECT_HOME>
をMySampleApplication
にしたら、当然モジュール名も<PROJECT_HOME>/MySampleApplication.iml
になります。
図19 HOME>/*.imlはプロジェクトのディレクトリ名に依存している
ある意味、第30回や第32回で説明した内容に似ていますが、今回の例はAndroid Studio固有のプロジェクト管理ファイルを共有しない事を前提にしているので、なんら問題はありません(むしろ望んでやったことなのでしょう)。ただ、個々人の環境によってAndroid Studioの管理ファイル名が異なることを意識した上でこの手の操作をしておかないと、のちのちの諍い事の火種になるのでお気を付けて。
前編のまとめ
Android Studio固有の設定ファイルを共有せずともbuild.gradle
だけでプロジェクトとして開けることがわかりました。これはこれで完成形のひとつです。オープンソースで公開するなど、特定のIDEに依存している痕跡を残したく無い場合などは、このスタイルが適切でしょう。
その代わり、Android Studioの便利な機能(たとえばインスペクションやコードスタイルなど)の設定が共用されません。せっかく便利な機能が提供されているのなら、みんな同じ設定やルールを利用したいものです。そのための話を中編・後編で行います。