2013年2月5日火曜日

GitHub上のコードを補完候補にするEZ Completionを作った

このエントリーをはてなブックマークに追加
Qiita 2-day Hackathonに参加しました。
 そこで、「EZ Completion」というプロダクトを作りました。


EZ Completionは、GitHub全体を巨大な知識データベースとして捉え、開発者が作成しているプログラムと類似したプログラムがGitHub上にある場合には、補完候補として提示します。
具体的には、プログラム上に定義された関数を監視し、似たような関数が実装されているソースコードをGitHub上から取ってきます。

要は、巨人の肩の上に立ち、車輪の再発明はやめようというコンセプトです。これにより、開発者全体で類似コードを作成する必要がなくなり、開発者はプロジェクト固有部分の開発に集中することができます。

仕組みはこんな感じ
1. 自分のプロジェクトに関係ありそうな特定のキーワードからGitHubのリポジトリをクローリングし、ローカルにリポジトリをダウンロード
2. ローカルにダウンロードしたファイルに定義されている関数の情報を抽出し、検索用インデックスを作成
3. 自分が作成しているプログラムの関数情報を読み取り、インデックスと照合
4. 似ている関数がインデックス内に見つかった場合には、その関数が定義されているファイルをリコメンド
5. ユーザは、リコメンドされたファイルの関数定義箇所にジャンプし、気に入ったらコピペ!

実装例はこんな感じ
1-2. create_index.py

ここでは、実装例としてZip形式でダウンロードし、Pythonの関数定義を読み取っている。インデックスはJSON形式で出力している。GitHubのAPIはPyGithubというライブラリを使ってます。ただ、インデックスを予め用意するのは面倒なので、サーバに作っておくか、そもそもGitHubでAPIを用意して頂きたい!


3. main.py

main.pyは引数として自分のプログラムの関数定義を渡すと、インデックス内から似た関数定義を取得し、出力する。この時、"authenticate"という単語を渡しても"getAuthenticate"や"get_authentication_url"等も出力するようにしている。ここでは、レーベンシュタイン距離によりファジー検索を実装している。ただ、そこまで精度は良くなくて、改善のためには、N-gramとの併用や、オントロジー&セマンティックみたいな技術が必要かな。

4-5. .vimrc

main.pyの実行のためのフロント部分には、Vimスクリプトを使った。Unite.vimのsource機能を使ったので、バッファへの出力や関数定義部分へのジャンプなどが簡単に実装できた(Vimスクリプト自体には手こずったけど)。":Unite def"で実行します。
参考サイト

発表では、GitHubの創業者を前に英語でプレゼンしたんだけど、めっちゃんこ緊張してもーた。

ayakix/EZ_Completion · GitHub