SVNにJavaからアクセス
先日Perlでリビジョンの推移を計測してみた。
今度は調子のって、誰が何ライン加筆・修正したかを計測しよう考えた。
SVNが持っている情報を最大限に引き出せば、
じゅうぶん求められる指標であることは間違いない。
でみ、SVNコマンドをチマチマと呼び出していたのでは限界がある気がする。
そこで、SVNのバイブル
Subversion実践入門:達人プログラマに学ぶバージョン管理(第2版)
- 作者: Mike Mason,でびあんぐる
- 出版社/メーカー: オーム社
- 発売日: 2007/04/21
- メディア: 単行本(ソフトカバー)
- 購入: 35人 クリック: 672回
- この商品を含むブログ (102件) を見る
そこでさっそく昼下がりの眠たい時間でトライしてみた。
それにしても日本語のブログでは、「JavaSVNってのがあるんだぜ」で終わってる記事が多過ぎるかと。
取り合えず簡単なサンプルコードぐらい書けよと声を大にして言いたい。
取り敢えずダウンロードはこちらから
http://svnkit.com/download.php
ダウンロードしたファイルの中から*.jarなファイルをEclipseのBulidPathに追加して。
後は、コードをカキカキしてみる。
Subversion 実践入門をタイプしなおしただけ
package main; import java.util.*; import org.tmatesoft.svn.core.*; import org.tmatesoft.svn.core.internal.io.dav.DAVRepositoryFactory; import org.tmatesoft.svn.core.io.SVNRepository; import org.tmatesoft.svn.core.io.SVNRepositoryFactory; public class JavaSVN { /** * * @param args * @throws SVNException */ public static void main(String[] args) throws SVNException { // TODO 自動生成されたメソッド・スタブ String repoUrl = "http://hostname/apple/"; SVNURL url = SVNURL.parseURIEncoded(repoUrl); DAVRepositoryFactory.setup(); SVNRepository repository = SVNRepositoryFactory.create(url); Map<String,String> dirProps = new HashMap<String,String>(); List<SVNDirEntry> dirEntries = new ArrayList<SVNDirEntry>(); repository.getDir("trunk/", -1, dirProps, dirEntries); for (SVNDirEntry dirEntry : dirEntries) { printEntry(dirEntry); } } private static void printEntry(SVNDirEntry entry) { if(entry.getKind() == SVNNodeKind.DIR) { System.out.println("Directory = " + entry.getName()); } else { System.out.println("File:" + entry.getName() + "size:" + entry.getSize() + "last modify by " + entry.getAuthor()); } } }
と打ち込んでみるとEclipseがエラーを出してる.
repository.getDir("/trunk", -1, dirProps, dirEntries);
JavaDocを見ると。
abstract long getDir(String path, long revision, SVNProperties properties, int entryFields, ISVNDirEntryHandler handler)
Fetches the contents and/or properties of a directory located at the specified path in a particular revision with the possibility to specify fields of the entry to fetch.
SVNProperties dirProps = new SVNProperties();
なるほどねーってコトで変更すると.今度は
Exception in thread "main" org.tmatesoft.svn.core.SVNAuthenticationException: svn: OPTIONS of '/apple/': 401 Authorization Required (http://hostname)
なるほど認証が通らない。こういう時はサンプルを見れば良いんじゃないかな?ってコトで.
http://svnkit.com/kb/examples/index.phpの
org.tmatesoft.svn.examples.repositoryのCommit.javaを見てみると、認証っぽい記述があったので真似て挿入してみる
package main; import java.util.*; import org.tmatesoft.svn.core.*; import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager; import org.tmatesoft.svn.core.internal.io.dav.DAVRepositoryFactory; import org.tmatesoft.svn.core.io.SVNRepository; import org.tmatesoft.svn.core.io.SVNRepositoryFactory; import org.tmatesoft.svn.core.wc.SVNWCUtil; public class JavaSVN { /** * * @param args * @throws SVNException */ public static void main(String[] args) throws SVNException { // TODO 自動生成されたメソッド・スタブ String repoUrl = "http://hostname/apple/"; SVNURL url = SVNURL.parseURIEncoded(repoUrl); DAVRepositoryFactory.setup(); SVNRepository repository = SVNRepositoryFactory.create(url); /* 認証機能を追加 */ String userName = "jobs"; String userPassword = "apple"; ISVNAuthenticationManager authManager = SVNWCUtil.createDefaultAuthenticationManager(userName, userPassword); repository.setAuthenticationManager(authManager); /* ここまで */ SVNProperties dirProps = new SVNProperties();//エラーのため修正 List<SVNDirEntry> dirEntries = new ArrayList<SVNDirEntry>(); repository.getDir("trunk/", -1, dirProps, dirEntries); for (SVNDirEntry dirEntry : dirEntries) { printEntry(dirEntry); } } private static void printEntry(SVNDirEntry entry) { if(entry.getKind() == SVNNodeKind.DIR) { System.out.println("Directory = " + entry.getName()); } else { System.out.println("File:" + entry.getName() + "size:" + entry.getSize() + "last modify by " + entry.getAuthor()); } } }
途中,Exception in thread "main" org.tmatesoft.svn.core.SVNException: svn: '/apple/!svn/bc/885/trunk' path not found: 404 Not Found (http://hostname)
というエラーに出くわして随分と悩んだ....
原因は
repository.getDir("trunk/", -1, dirProps, dirEntries);
を
repository.getDir("/trunk/", -1, dirProps, dirEntries);
としていたコト
実行結果
Directory = src
Directory = src-shared
Directory = src-client
Directory = conf
Directory = WebContent
Directory = build
File:.projectsize:1416last modify by jobs
Directory = .settings
取り敢えず昼から始めて1時間ぐらいでここまでたどり着いた。