SyntaxHighlighter

ラベル Subversion の投稿を表示しています。 すべての投稿を表示
ラベル Subversion の投稿を表示しています。 すべての投稿を表示

2012年6月3日日曜日

Add Subversion Links の Redmine 2.0 対応

Add Subversion Links プラグインを Redmine 2.0 対応したので、そのときのメモです。

Add Subversion Links プラグイン

Add Subversion Links プラグインは、Redmine のプラグインです。

このプラグインを入れておくと、 Redmine のチケット画面やリポジトリ画面に、 Subversion リポジトリ本体へのリンクが勝手に追加されます。

詳しくは GitHub の説明ページを見てください。

Redmine 2.0 対応

Redmine 2.0 では、ベースとなる Rails のバージョンが 3.2 に上がりました。
その結果、多くのプラグインの互換性がなくなったので、 Redmine 2.0 にバージョンアップしていない人も多いと思います。

Add Subversion Links の場合も、動かなくなっていました。

一つめの原因は、 Rails 3 で導入された html_safe に関するものでした。
Rails 3 では、「エスケープされていない String」と「エスケープ済みの SafeBuffer」を区別して扱うことで、エスケープ漏れや、多重のエスケープを回避しています。

Add Subversion Links では、 Subversion リポジトリへのリンクを生成する部分で、一部、エスケープしていない文字が入っており、結果として正しい表示になっていませんでした。
(エスケープしていない文字は、単なる空白だったので、最初は何が起こったかよく分かりませんでした。)

もう一つは、 image_path メソッドが削除されたことでした。

原因はよく調べていませんが、プラグインが持つ image assets の場所を返すメソッド image_path がなくなっていました。

Add Subversion Links では、一部、 JavaScript で動的にリンクを生成している箇所があり、そのリンク画像生成のために image_path を使っていたので、エラーになっていました。
結局、こちらは image_tag というタグ自体を生成するメソッドは残っていたので、こちらを使うように処理を変更することで対応しました。

Add Subversion Links プラグインの仕組み

Redmine 2.0 対応とは関係ないですが、このプラグインの仕組みを少しだけ書いておきます。

Redmine プラグインの作り方は、他にたくさんの優れたページがあるので、ここでは書きません。

ここでは、 Add Subversion Links プラグインを作る上での話について少し書きます。

メソッドの上書き

プラグインを入れると、下記のような Subversion のアイコンが現れ、リポジトリ本体へのリンクが追加されます。

example

これは、 application.js 内の link_to_revision メソッドを上書きして、アイコンを追加してやるだけで簡単に実現できました。

JavaScript による書き換え

面倒だったのは、下記の Name 列のような、個々のファイルへのリンクでした。

example2

こちらの方は、 link_to_revision のような、専用のメソッドがあるわけではないので、プラグインからメソッドを上書きして機能を変更するということが、簡単にはできなさそうでした。

というわけで、方針を変えて、 JavaScript で load 時に動的に追加してやることにしました。

しかし、この Name 列の内容は、 Ajax で動的に追加されるものであるため、 load 時にリンクを作るだけでは、後から Ajax で追加された要素に対してリンクを生成することができませんでした。

そこで、面倒だったのですが、 Ajax で Name 列の要素が生成されたときに呼ばれるコールバック関数 (prototype.js の Ajax.UpdateronSuccess 属性に渡す関数) をフックしてやり、そのフック関数の中で Subversion リポジトリ本体へのリンクを生成してやりました。

コードとしては以下のようになっており、 onSuccess で呼ばれる scmEntryLoaded を Rails の alias_method_chain のように上書きしてやることで、リンクを生成する処理を追加しています。
また、 Ajax.Updater による要素の追加は、 onSuccess直後に行われるので、実際にリンクを追加する addRepositoryLinkInRepositoryPage は、 setTimeout を使って遅らせています。

これで、めでたく Redmine 2.0 に対応できました。
JavaScript の部分以外はテストも書いたので、少しは (面倒であまり楽しくない) メンテナンスも楽になるはずです。

2012年5月5日土曜日

Subversion Ajax View

Subversion リポジトリを Ajax で見易く表示できるようにしてみました。

概要

以下が動作サンプルです。
ローカルに設置した mruby のソースを見ているところです。

Subversion リポジトリを公開しているサーバー側に設置するスクリプトです。
以下のような特徴があります。

  • サーバーサイドに置きますが、PHP, Ruby on Rails などのスクリプト環境を必要としません。 pure JavaScript で書かれています。
    そのため、ファイルを差し替えるなどすれば、 VisualSVN Server を Windows 上で動作させているような場合でも、見た目だけ容易に変更できると思います。
  • Ajax を活用しているので、静的なページ遷移を発生させずにスムーズなアクセスが可能です。
  • ログもブラウザ上で見ることができます。
  • 古いリビジョンも見ることができます。
  • 現在のところ、差分表示はできません。
    将来、対応するかは未定です。
  • Internet Explorer には対応していません。
    静的な従来の表示がされるだけです。今後、対応するかも未定です。

背景

最近は Subversion よりも、分散型の git や mercurial などが人気ですが、特に企業などではまだまだ Subversion を利用しているところも多いと思います。
特に、開発者ではない人達も閲覧する場合、ブランチが単なるディレクトリである、といったような Subversion の単純化された概念は受け入れられやすいように思います。

そのため、より Subversion を利用しやすくなればよいと思い、こんな拡張機能を作ってみました。

設置方法

詳しくは GitHub の README.md を見てください。
設置してみたいのによく分からないという方は、コメント欄などでお聞きください。

  1. ソースをダウンロードしてください。
    ダウンロードページから subversion_ajax_view.zip をダウンロードし、 Subversion リポジトリのあるサーバーの公開されたディレクトリに展開します。
    ここでは、例として /var/www/svn_ajaxview_dir に展開し、http://server/svn_ajaxview としてそのディレクトリにブラウザからアクセスできるとします。
  2. svn_ajaxview 以外の場所に置くときは、/var/www/svn_ajaxview_dir/svnindex.xsl を開き、中の link, script 要素の href, src の該当部分である二箇所を適宜修正してください。
    この時点で、ブラウザから http://server/svn_ajaxview/svnindex.xslhttp://server/svn_ajaxview/ajaxview/ajaxview.js にアクセスできるかを確認してみてください。
    アクセスできなければ、httpd.conf の Alias 設定などが正しいかを確認してください。
  3. httpd.conf 内の Location ブロック内に SVNIndexXSLT /svn_ajaxview/svnindex.xsl を追記してください。
  4. その後、Apache を再起動してください。

技術的な話

以上はどうでもよい話で、これからが書きたかったことです。
長くなりますが、覚え書きのために書いておきます。

目的

このプログラムを書いた目的は以下の通りです。

  • JavaScript について勉強する。
  • jQuery を使ってみたい。
  • pushState を使ってみたい。

そのため、 Subversion をブラウザ上で綺麗に表示することが目的ではありません。
そういうことであれば、WebSVN などを使うとよいと思います。(PHP を入っていなければ面倒ですが。)

Subversion と WebDAV

Subversion リポジトリを Apache 経由で公開する場合、通常は WebDAV という技術を用いて、つまり WebDAV プロトコルを用いてサーバーとクライアント間でやりとりが行われます。

WebDAV とは HTTP を拡張したプロトコルで、通常の HTTP 1.1 で定義されたメソッドに加え、いくつかのメソッドが定義されています。
HTTP 1.1 では、よく使われる GET, POST 以外にも OPTIONS などのメソッドが RFC では定義されていますが、WebDAV ではその他にも PROPFIND などが定義されています。

Subversion のサーバーとクライアントでは、これらのメソッドを用いて通信が行われています。

XMLHttpRequest で使えるメソッド

Ajax の中核となっているオブジェクトとして、 XMLHttpRequest があります。
これは、 JavaScript 経由でサーバーと通信できるようにするための仕組みです。

この XMLHttpRequest は、 WebDAV のメソッドも発行できるようになっています
Internet Explorer は知りませんが、少なくとも Firefox, Chrome, Safari では可能です。
確かに W3C の open メソッドの説明HTTP 1.1 の RFC を見る限りでは、 extension-method として他のメソッドを受け付けるようになっています。

ということは、 Subversion クライアントが WebDAV 通信をしている以上、 Subversion クライアントが行えることは、すべて Ajax で行えることになります。
(もちろん、ローカルストレージが必要なチェックアウトなどは別です。)

と思ったので、既に存在するかどうかは別にして、「pure JavaScript で Subversion クライアントを作ってみたい」というのがそもそもの動機でした。

今回はビューワを作りましたが、意味があるかは別として、その気になればコミットも可能だろうと思います。

pushState

せっかく Ajax を活用してみたので、 pushState を活用して、 URL も動的に追従するようにさせてみました。

その他

  • Chrome では XML の解析時に getElementsByTagName で名前空間を無視して要素を参照できるようですが、 Firefox ではきちんと getElementsByTagNameNS で名前空間を指定しないと無理でした。
  • あまりきちんとエラー処理していません。
  • Subversion の通信の手順の詳細な仕様がよく分からなかったので、Subversion のソースと Wireshark のパケット解析に基づいて実装しました。
    なので、何かおかしな挙動があるかもしれません。
  • もともとは Chrome の拡張機能として作成していました。
    いずれこちらも整理して公開するかもしれません。
  • Subversion リポジトリにブラウザからアクセスしたときの見た目を変更する方法は、 Subversion Book の "Customizing the look" に載っていました。
  • バグがありましたら、教えていただけると嬉しいです。(対応できるかは未定です。)

というわけで、あまり役には立たないような気もしますが、せっかく作ったので公開してみました。