本を読む

読書やコンピュータなどに関するメモ

Shibuya.lisp Hackathon #1でJGit+Clojureをいじった

 Shibuya.lisp Hackathon #1に参加してきました。各言語ごとで島を作ってわいわい(またはもくもく)やる中、私はClojure島に参加してました。

やったこと

 Javaによるgitクライアント実装のJGitをClojureから使おうと試してました。

 野望としてはWebベースのgitリポジトリブラウザでも作れればと思っていたのですが、全然そこまでは行きませんでした。

準備

 leiningenで "lein new hoge" とかやってプロジェクトを作成。で、project.cljにJGitのリポジトリを追加。

  :repositories {"jgit-repository" "http://download.eclipse.org/jgit/maven"}

 dependenciesにもJGitを追加。

                 [org.eclipse.jgit/org.eclipse.jgit "0.9.3"]

 SLIMEを使う場合には、:dev-dependenciesでlein-swankも追加しておきます。

 あとはlein depsを実行してから、lein swank+SLIMEなりlein replなりでREPLを実行。

はまった過程

 結論だけ読みたい人はこのセクションを飛ばしてください。

 まず困ったのが、公式サイトにドキュメントがないっぽいし、jgitの.jarにもドキュメントがないこと。Clojure島の人に相談して、ソースをgit cloneしてjavadocでリファレンスを作りました。

 で、org.eclipse.jgit.api.Gitクラスのインスタンスでgitコマンドの操作をできるらしいということがわかり、まずは参照系としてgit log的なことをやってみようかと。

 ここからがハマりどころ。

  • org.eclipse.jgit.api.Gitのインスタンスを作りたい
    • コンストラクタの引数にorg.eclipse.jgit.lib.Repositoryのインスタンスをとるらしい
      • org.eclipse.jgit.lib.Repositoryのコンストラクタの引数にorg.eclipse.jgit.lib.BaseRepositoryBuilderのインスタンスをとるらしい
        • org.eclipse.jgit.lib.BaseRepositoryBuilderのコンストラクタの引数にjava.io.Fileのインスタンスをとるらしい
          • java.io.Fileのインスタンスを作った
        • org.eclipse.jgit.lib.BaseRepositoryBuilderのインスタンスを作った
      • org.eclipse.jgit.lib.Repositoryのnewがエラー(対応するコンストラクタがない)になる
      • Baseってついてるのはダメかなと思って、org.eclipse.jgit.lib.RepositoryBuilderにしても、やっぱりダメ

 しょうがないので、org.eclipse.jgit.lib.Repositoryのソースを見てみました。

 …"public abstract class" って宣言されてる…JavaDocなドキュメントを見返すと、確かにそこにも書かれてた orz

 org.eclipse.jgit.lib.Repositoryの継承クラスを調べると、org.eclipse.jgit.storage.file.FileRepositoryというのがありました。java.io.Fileをとるコンストラクタがあるので簡単そう。

 →成功。ここまででだいたい16時ぐらい。

使い方。

 まずimport。

user> (import '(org.eclipse.jgit.api Git))
org.eclipse.jgit.api.Git
user> (import '(org.eclipse.jgit.storage.file FileRepository))
org.eclipse.jgit.storage.file.FileRepository
user> (import '(java.io File))
java.io.File

 で、FileRepositoryクラスのオブジェクトをGitのnewに渡すと、Gitクラスのオブジェクトができました。".git"ディレクトリを指定するのに注意。

user> (Git. (FileRepository. (File. "/path/to/repo/.git")))
#<Git org.eclipse.jgit.api.Git@1e852be>

 Clojureらしく->を使うと、こうかな。

user> (-> "/path/to/repo/.git" File. FileRepository. Git.)
#<Git org.eclipse.jgit.api.Git@3f4a21>

 とりあえずdefしておきます。

user> (def git (-> "/path/to/repo/.git" File. FileRepository. Git.))
#'user/git

 git log相当の操作をしてみます。".."を使ってメソッドチェーン。

user> (.. git log call)
#<RevWalk org.eclipse.jgit.revwalk.RevWalk@601f3f>

 戻り値はシーケンスのようです。ためしにtakeで先頭の3要素を取ってみます。

user> (take 3 (.. git log call))
(#<RevCommit commit 7fe4cc728ae509ba48e48ae111cb32d6311bebc0 1271268189 ----sp> #<RevCommit commit 4d905b1b6cbc3709618c8706d5af910922adc49d 1270661391 ----sp> #<RevCommit commit a889cc92f2cbb97a138a282d700e02e26c9d600e 1270661330 ----sp>)

 それぞれのコミットはRevCommitのインスタンスのようです。HEAD、つまりシーケンスの最初の要素をとって、コミットメッセージを取得してみます。

user> (. (first (.. git log call)) getFullMessage)
"use Key in get-prop\n"

 文字列として取れました。

 ここまでで時間終了。

コメント

コメントの投稿

管理者にだけ表示を許可する

トラックバック

http://emasaka.blog65.fc2.com/tb.php/825-109c8a23

 | HOME | 

Categories

Recent Entries

Recent Comments

Recent Trackbacks

Appendix

emasaka

emasaka

フリーター。
連絡先はこのへん

Monthly


FC2Ad