IntelliJ/PHPStormの拡張Pluginの作成 (Git, kintone連携)

こんにちは、Garoon 開発チームの杉山です。

いきなりですが、みなさんは IDE を使ってますでしょうか。サイボウズ内では Javer な方々は IntelliJ を使っていたり、僕は PHPer なので PHPStorm を使っていたりします。

どの IDE にも把握しきれないほど多くの便利な機能が備わっていますが、せっかくなら、自分たちの開発スタイルに合わせてカスタマイズしていきたいものです。

今回は Garoon チームで行っている振り返りから上がった問題を改善する IntelliJ 系の IDE のプラグインを作成しました。

プラグインを PHPStorm でも動くようにしたり、ライブラリを読み込ませたりするのに少しつまづいたところがあるので、その手順をまとめておきたいと思います。

何を作ったか

Garoon チームでは開発タスクや不具合を kintone アプリで管理しています。ソースコードは GitHub で管理しているのですが、Git の運用ルールもあり、ブランチ名はレコード番号に、コミットコメントにもタスク・不具合のレコード番号を付けるようにしています。

この運用によって、各コードがいつ、どんなタスクで追加されたものなのかが調査しやすくなりました。

しかし、現状ではコミットメッセージを毎回手動で入力する必要があり、レコード番号を書き間違えてしまう問題も頻発していました。そもそも、タスク番号を手動で入力するのは面倒です。ブランチ名とコミットメッセージにつけるタスク番号が同じなら、それくらいは自動でつくようにして、ついでにそのタスクの情報も kintone からとってくるようにしました。

完成イメージはこんな感じです。 f:id:cybozuinsideout:20160119120731j:plain 画像は PHPStorm でコミットするときに出てくるパネルです。赤丸の Garoon のアイコンを押すとコミットメッセージが変化して、kintone からタスクのタイトルを取ってきて吹き出しで表示するようにしました。

作成方法

1. IntelliJ IDEA のインストール

PHPStorm のプラグインを作るときに、初めに襲い掛かるハードルは IntelliJ を使わないといけないことだと思っています。言語は当然 Java になるので、Java 初心者な私にはいささかきついところもありました。

ちなみにこの記事の手順で、JetBrains から出ている IDE であれば、どれでも使えるプラグインの作成が可能です。

Ultimate Edition (有料版) を使いたいところでしたが、Community Edition (無償版) で我慢しました。プラグイン作成はほぼ問題なく行えました。

2. Project を作成する

  • [File] -> [New] -> [Project] とクリック
  • 左のリストから [IntelliJ Platform Plugin] を選択する
  • プロジェクト名を入れて [Finish] を押す

f:id:cybozuinsideout:20160119133617p:plain

3. plugin.XMLを編集する

プラグインの基本情報は、"resources\META-INF\plugin.xml"に記述します。主にプラグインのインストール画面に表示される情報や、ライブラリの依存関係を記述します。

また、IntelliJ 以外の IDE(PHPStormとかRubyMineとか)でも動作するプラグインを作成する場合は、ファイル中ほどにある

<depends>com.intellij.modules.lang</depends>

を有効にする必要があります。

4. アクションを作成する

プラグイン内ではアクションと呼ばれる動作単位を記述していきます。アクションは次の手順で作成します。

  • srcフォルダを右クリック
  • [New] -> [Action]
  • Action ID, Class Name, Name を入力
  • Groupsを選択
  • [OK]ボタンを押す f:id:cybozuinsideout:20160119160137p:plain

Action ID とクラス名は基本的には同じもので大丈夫そうです。Name はプラグイン使用時に見えることがあるものなので、簡単な説明文とかを入れてもいいかもしれません。

アクション作成時に重要なのは手順4の Groups の選択です。対応する Groups さえ見つけられれば、各ツールバーやメニューの中にアクションを作成できます。グループを選択するとそのグループに属しているアクションの一覧が表示されるので、それを見ながらお好みのグループを探すとよいと思います。

今回作ったプラグインは VCS(Version Control System) のコミットメッセージに関するものだったので、"Vcs.MessageActionGroup"グループにしました。

上記の手順で actionPerformed メソッドを持つクラスが作成されます。イベント発火時に actionPerformed メソッドが実行されます。

また、plugin.xml を見てみると、

<action id="SetTaskName" class="SetTaskName" text="Set Task Name." >
      <add-to-group group-id="Vcs.MessageActionGroup" anchor="first"/>
</action>

と、アクションに関する記述が追加されます。

アイコンを表示するには、画像を用意して action タグ に icon 属性を足せばオッケーです。

<action id="SetTaskName" class="SetTaskName" text="Set Task Name." icon="garoon.png" >
      <add-to-group group-id="Vcs.MessageActionGroup" anchor="first"/>
</action>

5. 動かしてみる

実装では IntelliJ IDEA's Open API を使っていきます。詳しい Reference はまだ乏しいので、使いかたを調べるのには公開されているプラグインのコードを見に行ったほうが早かったりします。

とりあえず動くかどうかを確認するためにこんなコードを書きました。

public void actionPerformed(AnActionEvent e) {
    BalloonBuilder balloonBuilder = JBPopupFactory.getInstance().createHtmlTextBalloonBuilder("Hello World!!", MessageType.INFO, null);
    final Balloon balloon = balloonBuilder.createBalloon();
    balloon.show(new RelativePoint( new Point(0, 0)), Balloon.Position.above);
}

"Hello World!!"って Balloon が表示されるだけのコードです。

デバッグには設定が必要ですが、

  • [Run] -> [Edit Configurations...]
  • プラスマークからPluginを追加
  • "Use classpath of module" を設定

で大丈夫です。これ以降[Run]なり[Debug]なりを押すと新しく IntelliJ が起動して実装したプラグインを試すことができます。

これで[VCS] -> [Commit Changes...]と行くとパネルの真ん中あたりに Garoon のアイコンが表示されて、クリックするとメッセージが表示されるようになりました! f:id:cybozuinsideout:20160119181914p:plain

ブレークポイントとかも設定できるのでデバッグはわりと楽でした。

残念なのは、PHPStorm を利用してデバッグできないこと。IntelliJ も PHPStorm も動作はほとんど同じなので問題ないといえばないのですが、PHPStorm に特化した拡張プラグインの作成は少し難しそうです。

ライブラリの追加

今回は Git の情報を取得する必要があります。調べてみると、git4idea というライブラリが使えそうなのでインクルードします。
git4idea.jar は(IntelliJのInstallディレクトリ)/plugin/git4idea/lib/ に存在します。

  • [File] -> [Project Structure]
  • [Modules] -> [Dependencies]
  • プラスマークから、 git4idea.jar を選択、追加
  • Scope を"Provided"に変更する
  • plugin.xml に<depends>Git4Idea</depends>を追加する

今いるブランチ名をとってくるのはこんな感じでできました。

Project project = e.getProject();
if (project == null)
    return;
VirtualFile virtualFile = project.getBaseDir();

GitRepositoryManager gitRepositoryManager = GitUtil.getRepositoryManager(project); 
GitRepository gitRepository = gitRepositoryManager.getRepositoryForFile(virtualFile);
if (gitRepository == null)
    return;
GitBranch gitBranch = gitRepository.getCurrentBranch();
if (gitBranch == null)
    return;

String branchName = gitBranch.getName()

また kintone と連携するのには kintone API SDK(β) for Java を使いました。
この SDK のインクルード手順は、

  • 上記サイトからプログラムをダウンロード
  • GitHub の Readme の Build .jar file に従って jar ファイルを作成
  • [File] -> [Project Structure]
  • [Modules] -> [Dependencies]
  • プラスマークから、作成した jar ファイルを選択、追加
  • Scope を"Compile"に変更する

とすれば大丈夫です。 git4idea の時とは Scope が違うのではまりました。詳細は IntelliJ IDEA のヘルプページをご覧ください。

kintone API SDK では、レコードのタイトルが欲しいだけなので、API トークンを使いました。実際のコードはこんな感じです。

Connection connection = new Connection("domain", apitoken);
try {
    String response = connection.request("GET", "record.json?app="+appId+"&id="+recordNumber, "");
  //以下JSONの処理
} catch (DBException error) {
    //以下エラー処理    
}

6. PHPStorm で動かす

デバッグである程度動作の確認ができたら、PHPStorm でも動作を確認しましょう。PHPStorm で確認するには、一度 jar ファイル(またはzipファイル)をビルドする必要があります。
[Build] -> [Prepare Plugin Module "Hello Plugin" For Deployment]("Hello Plugin"にはプロジェクト名が入ります。)を押せばビルドができます。

生成されたら

  • PHPStorm を開く
  • [File] -> [Settings...]
  • [Plugins]を選択
  • 画面中央にある[Install plugin from disk...]をクリック
  • ビルドした jar ファイルを選択
  • PHPStorm を再起動

とするとプラグインが動くようになります!

社内でほかの人に配布するときも jar ファイルを渡すだけでいいので簡単です。

まとめ

プログラマーが最もお世話になる製品 IDE。自分たちのプロジェクトに合わせて、少しでも使いにくい点や改善できる点があったら、自前でプラグインを作るチャンスです。

公式ページのコンテンツも足りてない部分もありますが、最近は更新が活発です。

みなさまもぜひプラグイン開発でよりよい開発ライフをお送りください!(^-^)/~~