SyntaxHighlighter

2012年11月27日火曜日

AutoIt を Ruby から使い、それを ocra で EXE 化する

AutoIt を Ruby から使い、それを ocra で EXE 化する

ピンポイントな内容で、あまり他の人の役に立つか分かりませんが、ちょっと調べたので書いておきます。

今回の目的は、「AutoIt を呼び出す Ruby スクリプトを ocra で EXE 化し、制限ユーザーでも実行できるようにする」です。

実現方法

予備知識として、ocra による EXE 化はできる前提です。

準備

  1. RubyInstaller から Ruby 1.9.3 をダウンロードし、インストールしておきます。また、bin ディレクトリにパスを通しておきます。
  2. 以下のコマンドで ocra をインストールしておきます。
  3. 続いて AutoIt から AutoIt をダウンロードし、インストールしておきます。
  4. AutoItX/AutoItX3.dll を Ruby の bin ディレクトリ以下にコピーしておきます。
  5. 以下の内容を記述した ruby.exe.manifest を Ruby の bin ディレクトリ以下に作成します。

これで事前準備は完了です。

EXE の生成

以下のような sample.rb を考えます。

これは電卓を起動し、3 + 4 を実行するスクリプトです。電卓のウィンドウを表す文字列は、OS によっては異なるかもしれません。

これをそのまま EXE 化して EXE ファイルを別の実機に持っていっても、AutoItX3.dll が無いので実行できません。AutoItX3.dll も別の実機にコピーし、前もって 「regsvr32 AutoItX3.dll」を実行しておけば可能ですが、これには管理者権限が必要です。

これを回避するために、以下のようなコマンドで EXE 化します。

このようにして生成された EXE ファイルは、制限ユーザーであってもそのまま実行でき、AutoItX3.dll を呼び出すことができます。

説明と補足

以下は、原理の説明などです。

AutoIt

AutoIt とは、Windows の GUI を自動操作することができるツールのことです。

Windows 上で GUI を含んだツールのテストをしたり、GUI プログラムの定型処理を自動化したりするには、それなりに面倒なことが多いのですが、この AutoIt を使うと、割と楽に自動化できます。
同様なことは、.NET からだと Windows 標準の UI Automation などでも可能です。

この AutoIt には、COM インターフェースも用意されており、 COM オブジェクトにアクセスできる言語からは、自由に機能を利用することができます。
実体は AutoItX3.dll で、AutoItX3.Control という ProgID でアクセスできます。

もちろん Ruby からも WIN32OLE を利用することで、呼び出すことができます。
上に書いたように、例えば Windows の電卓 (calc.exe) を起動し、3+4 を計算させる場合は、以下のようになります。

ただし、このスクリプトを実行できるようにするためには、AutoItX3.dll をあらかじめ Windows に登録する必要があります。
インストーラでインストールした場合は登録されているはずですが、自己解凍形式でインストールした場合は、以下のコマンドを管理者権限で実行し、AutoItX3.dll を Windows に登録しておかなければなりません。

EXE 化して実行するときの問題点

上記の Ruby スクリプトを ocra で EXE 化した場合、その EXE を実行する Windows マシンにも AutoItX3.dll がインストール済みでなければなりません。これは多少面倒ですし、管理者権限も必要になってしまいます。
今回の本題は、そのあたりをどうするかについてです。

基本的には、ocra で EXE 化する際に AutoItX3.dll も EXE に含めてしまい、かつスクリプトの内部から制限ユーザーでも呼び出せるようにするということになります。

マニフェストファイル

大きな流れとしては、AutoItX3.dll を EXE の中に組込み、かつマニフェストファイルを作成することで、その DLL ファイルを COM としてアクセスできるようにしてやる、ということになります。

マニフェストファイルとは、EXE ファイルのメタ情報のようなもので、ロードすべき DLL を指定したり、UAC 昇格が必要であることを指定したりする XML ファイルです。

このファイルを用いて、AutoItX3.dll の中に AutoItX3.Control という ProgID の COM オブジェクトがあることを明示し、ruby.exe からアクセスできるようにしてやります。
このマニフェストファイルは、実行する EXE に .manifest をつけた名前にします。

ocra では、ruby.exe やその他の DLL を Temp ディレクトリに展開し、その後 ruby.exe を実行します。
そのため、Temp ディレクトリに展開される際に、マニフェストファイルも展開されるようにすれば、ruby.exe が実行される際にマニフェストファイルで COM 用 DLL を指定することができます。

そのため、以下のようなコマンドで EXE ファイルを作成すれば、AutoItX3.dllruby.exe.manifestruby.exe と同じディレクトリに展開されるようになります。

これで、制限ユーザーであっても、AutoItX3.dll がインストールされていない状況であっても、Ruby スクリプトから AutoIt の COM インターフェースにアクセスできる EXE ができあがります。

ポイント

--dll を使っているところがポイントです。

前提として、ocra で EXE 化されたスクリプトは、まず一時フォルダに ruby.exe 本体やスクリプトや DLL などを展開し、さらに展開した ruby プログラムを実行する、という二段構成になっています。
細かく書くと、EXE を実行すると、ruby.exe 本体が置かれる bin ディレクトリ、ライブラリが置かれる lib ディレクトリ、ユーザーのソースコードが置かれる src ディレクトリの三つをそれぞれ展開し、その後 src 以下のソースコードを bin ディレクトリ以下の ruby.exe によって実行する、という流れになります。

EXE 作成時に --dll オプションを使って指定されたファイルは、EXE 実行時に bin ディレクトリ以下に展開されることになります。
そのため、上の例では、EXE 実行時には以下のような配置になります。

/
bin
ruby.exe
AutoItX3.dll
ruby.exe.manifest
lib
require されたライブラリが配置される。
src
sample.rb

上のように ruby.exe.manifest ファイルを配置することで、展開された ruby.exe が実行される際に、ruby.exe.manifest を読み込ませることができ、結果として AutoItX の COM インターフェースにアクセスできるようになります。

ちなみに、ocraruby として一つのバイナリにまとめてある Ruby の中にも、同様の仕組みで AutoItX3.dll を組み込んであります。

というわけで、何回か仕事で使うツールの内容が続きましたが、忙しかった時期も過ぎつつあり、そろそろこの週末ぐらいからは mruby を触れそうです。

2012年11月4日日曜日

ocraruby - Ruby を一つの EXE にまとめて、簡単に持ち運べるようにしておく

ocraruby - Ruby を一つの EXE にまとめて、簡単に持ち運べるようにしておく

体調を崩していることもあり、なかなか仕事以外で Ruby に触れる機会がないですが、これも業務で使うために家で作ったので公開しておきます。

単一のバイナリのみで、任意の Ruby スクリプトを実行したい

いろいろな Windows PC 上で作業する必要があったり、ちょっと Windows サーバーのメンテナンスをする必要がある場合などにあると便利なので、 ocra を使って単一のバイナリのみで任意の Ruby スクリプトを実行できるようにしたものを作っておきました。
任意とは言っても、gem などの外部ライブラリを必要とするものは動作しません。
あくまで、 Ruby の標準添付ライブラリのみを使用しているスクリプトが動作するということです。

とりあえず Windows で Ruby を触ってみたいというような、 Windows で Ruby を初めて使う方にもよいかもしれません。
サポートはできないですが。

ダウンロード

バイナリのダウンロードは GitHub のダウンロードページからお願いします。
この記事を書いている時点では、Ruby 1.9.3p286 を元にしたものがダウンロードできます。

ocraruby.exe
私が独断で選んだよく使う標準添付ライブラリが入っています。ネットワーク関係が入っていないのは、これらを入れるとサイズが大きくなるからです。
ocrarubyfull.exe
すべての標準添付ライブラリが入っています。
ocrarubylite.exe
標準添付ライブラリなし

仕組み

特に何のひねりがあるわけでもなく、引数で渡されたファイルを load するようなスクリプトを ocra で EXE 化しているだけです。

一応、 ARGV$0 の設定はしてあるので、下記のようなスクリプトも期待通りに動作します。

注意

注意点としては、 ocra を使っているので、 Ruby 本体を Temp ディレクトリに展開する分だけ時間がかかってしまうということです。

ocrarubyfull.exe などでは、5秒以上かかるかもしれません。
これは展開に時間がかかっているのであり、 Ruby は遅いんだな、と勘違いしないでください

来月になればきっと体調も戻り、時間もできると思うので、また色々やりたいことをやろうと思います。

oruby は既にそういう名前のものがあったので ocraruby にしておきました。

ocra による Ruby の EXE 化

ocra による Ruby の EXE 化

近頃はずっと仕事が忙しく、mruby を見たり遊んだりもまったくできないので、業務で使わせていただいている ocra について、主に社内用にメモしておきます。

JsMruby やその他のリクエストに対応できていなくてごめんなさい。

以前にも書きましたが、Ruby 1.8 のときに愛用させていただいていた Exerb は、現在主流の Ruby 1.9 には対応していないようです。
そのため、現在は Ruby 1.9 に対応している ocra を使わせていただいています。
今回はその ocra についてのメモです。
もっと詳細は、 GitHub の ocra のページを参照してください。

Ruby の EXE 化

ocra では、Ruby のスクリプトを Ruby 本体やライブラリとともに、一つの EXE にまとめてくれます。
実行する際は、できた EXE ファイルを、実行したい PC に置くだけで実行することができます。

EXE 化する際には、一度 ocra がそのスクリプトを実行し、スクリプトファイル中で require などで読み込まれたファイルやライブラリを、圧縮して一つのファイルにまとめてくれます。

逆に実行時には、スクリプトファイルや Ruby 本体やライブラリを Temp ディレクトリに展開してから実行されます。

ちなみに、Exerb では require を専用のものに置き換え、ファイルが require されたときに、EXE ファイル本体内に格納されているスクリプトファイルを実行するようになっています。

ocra で定義される定数や環境変数

ocra のように、コンパイル時に一度スクリプトを実行してみるようなものでは、以下の三つの状態をスクリプト内で区別したいときがよくあると思います。

  1. 通常の Ruby で実行されている
  2. ocra でコンパイルされている間に、 require をチェックするために実行されている
  3. ocra で EXE 化された後に、その EXE ファイル経由で実行されている

ocra では、この条件を簡単に見切るために以下の定数や環境変数を参照できます。

定数 Ocra
ocra でコンパイル中のみ定義されています。 EXE ファイル実行中は定義されていません。
そのため、例えば以下のように書けば、コンパイル中のみコードを実行させることができます。
環境変数 OCRA_EXECUTABLE
ocra によって生成された EXE ファイルを実行しているときのみ、実行中の EXE ファイルのフルパスが "\" 区切りで設定されます。
そのため、例えば以下のように書けば、 EXE ファイル実行中のみコードを実行することができます。

各環境での動作

ここでは以下のようなスクリプトを実行し、それらの値やカレントディレクトリなどの環境をまとめておきます。

通常の実行時

このスクリプトを C:/work/test/test.rb として c:/work/test で実行すると、以下のようになります。

EXE 化する時

ocra で EXE 化する場合、ocra によってスクリプトが実行され、その際に require で読み込まれたファイルやライブラリがチェックされます。
この require されるファイルチェックの場合には、以下のようになります。

このように、EXE 化する時には Ocra という定数が定義されます。
通常のスクリプトは、EXE 化する際には本処理を実行したくないことが多いので、たいていは以下のように書くことになると思います。

EXE 実行時

できた test.exe を実行すると、以下のようになります。

このように、EXE 実行時には OCRA_EXECUTABLE という環境変数が、 EXE ファイルのフルパスとして定義されます。

また、上で書いたように ocra はスクリプトファイルなどを Temp ディレクトリに展開した状態で実行しますが、 __FILE__$0 を見ると、確かに Temp ディレクトリの中に展開されていることが分かります。

EXE ファイルへの他のファイルの同梱

ocra は require で読み込んだファイルを自動で検出して EXE ファイルに含めてくれますが、明示的にスクリプトファイルやその他のファイルを含めることもできます。

やり方は簡単で、 EXE を作るときに ocra.bat に渡す引数に加えてやればよいだけです。

こうすると、 EXE 実行時には、 7za.exesample.rb と同じディレクトリに展開されます。
つまり、 sample.rb 内であれば File.dirname(__FILE__) + "/7za.exe" でパスを得ることができるので、別の EXE を同梱して Ruby スクリプト実行時に参照することも可能です。

2012年9月17日月曜日

JsMruby - mruby NPAPI plugin

JsMruby - mruby NPAPI plugin

mruby を Firefox, Google Chrome で動作するようにしました。

mruby

mruby on EFI Shell でも書いたように、 mruby は、Ruby の作者であるまつもとさんが開発されている「組込み向け軽量 Ruby」の実装です。

前回は、単に EFI Shell 上で動くようにコンパイルしただけでしたが、今回は Firefox, Chrome 上から mruby スクリプトを実行でき、 JavaScript の関数も呼べるようにしてみました。

JsMruby - mruby NPAPI plugin

Firefox, Chrome 上で動作する mruby の NPAPI plugin を作ってみました。

サンプル

このプラグインを Firefox, Chrome にインストールしていると、以下のような書き方ができます。

ちょっと長いですが、全文を載せます。

この HTML ファイルを開き、 Draw ボタンをクリックすると、 canvas に正方形が描かれます。

もう少し長いサンプルとしては、マンデルブロ集合を描くサンプルを参照してみてください。
このサンプルでは Draw を押してから 3 秒ぐらい待ってから描画されます。

このように、割とシームレスに JavaScript のメソッドが呼べ、これまで JavaScript で書かねばならなかったものを mruby で書けるようになります。

概要

現在のところ、以下のようなことができます。上のサンプルを参照しながら読んでみてください。
ただし、これらは今後の実装次第で変わっていくだろうと思います。

JavaScript から mruby スクリプトの実行

object タグで NPAPI プラグインを読み込みます。

このオブジェクトに対して、load メソッドで mruby スクリプトをパースし、実行できます。

その後は、 send メソッドで、 mruby スクリプト内で定義したメソッドを直接実行することができます。

mruby から JavaScript スクリプトの実行

逆に mruby スクリプト側からは、 JsObj.get() メソッドで JavaScript のオブジェクトを取得できます。

現在の実装では、 Array, String, Integer, Double などに関しては、 mruby の該当するオブジェクトに変換されます。
また、 DOM オブジェクトなどの場合は、 DOM オブジェクトそのものをラップした JsObj クラスのインスタンスが返され、そのインスタンスに対しては、通常の DOM オブジェクトに対するメソッドを呼び出すことができます。(createElement などを呼べます)
function の場合は、 mruby の Proc オブジェクトのようなものが返されます。(ただし call メソッドでしか呼び出せません)

制限

現在のものは、あくまでアルファ版なのでクラッシュしたりうまく動かなかったりするだろうと思います。

特に、例外まわりやガベージコレクションまわりについては、それほどきちんと考えて書いていないので、不具合が多く眠っているだろうと思います。

ダウンロードとインストール

いずれも GitHub のページからダウンロードできます。

まだ Windows 向けにしか作成していないので、 Mac などでは動きません。

Firefox
jsmruby_0_0_1.xpi をダウンロードし、そのファイルを Firefox に Drag & Drop するとインストールできます。
このアドオンは、単に JsMruby の NPAPI プラグインを含んでいるだけのものです。
余談ですが、 NPAPI プラグインを含むアドオンを作成する場合は、 install.rdf 内に <em:unpack>true</em:unpack> の一行を書く必要があります。
Chrome
jsmruby_0_0_1.zip をダウンロードし、そのファイルをローカルで展開します。
Chrome の「ツール」-「拡張機能」を開いて「デベロッパーモード」にチェックを入れ、「パッケージ化されていない拡張機能を読み込む」から展開したディレクトリを指定して読み込みます。

ソースコードは GitHub の JsMruby のページで見られます。
まだ整理できていないですが、そのうち整理します。
また、 Mozilla のサンプルソースを使っている関係上、一部のファイルのみ NPL ですが、それ以外のファイルに関しては MIT ライセンスとする予定です。

ブラウザ上の Ruby

既に本家の Ruby では、 Ruby 2.0 にて Chrome の NaCl に対応することが表明されています。
似たようなのを作っておいて書くのも何ですが、私はこちらにとても期待しています。

また、 mruby についても既に試されている方がいらっしゃいます。

私はまだそれほど NaCl や PPAPI については勉強していないのと、 Chrome よりも Firefox が好きなので Firefox で動かしたい、という動機があったので、この NPAPI 版のプラグインを作ってみました。
というか、 masuidrive さんの MobiRuby の講演を聞いて、「いいなぁ」と思って自分も何か作りたくなったというのが本音です。

EFI Shell 版の方は、使いたい人はあまりいないと思いますが、 Windows 8 リリースまでにはまとめようかと思っています。

暇を見つけて Mac 版や、ドキュメントの作成などをします。たぶん。

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月21日月曜日

mruby on EFI Shell

mruby on EFI Shell

mruby を 32bit, 64bit の EFI Shell 上で動かしてみました。

mruby

mruby は、Ruby の作者であるまつもとさんが開発されている「組込み向け軽量 Ruby」の実装です。

詳しくは ITPro の紹介記事などをご覧ください。

今回は、この mruby を EFI Shell 上で動かしてみました。

EFI と EFI Shell

EFI

EFI もしくは UEFI とは、BIOS の置き換えのために Intel などが中心となって策定したファームウェアの仕様です。

最近の PC はほぼ UEFI 対応していますが、だからといって、すべてのもので EFI Shell が立ち上げられるとは限りません。
また、UEFI Boot 自体も、まだそれほど一般的ではないかもしれません。
ベンダによっては、UEFI なのに、UEFI Native Boot ではなく Legacy Boot させている (つまり CSM Boot させている) ところも多いようです。

ただし、Windows 8 が出てくるころには、状況も変わってくると思います。

EFI Shell

詳しく書くときりがないので EFI の詳細については省略しますが、その仕様の中で、EFI Shell という DOS や bash のようなシェル環境が定義されており、実際にいくつかの UEFI Boot 対応 PC では、Firmware 内に組込まれています。

BIOS Setup 画面で Launch EFI Shell のような項目があれば、それが該当します。
また、EFI Shell バイナリを USB メモリなどから起動させることで起動することもできます。

で、今回、この EFI Shell 上で動くように mruby をコンパイルしてみました。

動作例とダウンロード

ダウンロードは GitHub から可能です。
展開して得られるバイナリのうち、mruby.efi は 32bit 用、mruby64.efi は 64bit 用です。

VMware Player 上で動かすと、以下のようになります。
図は [ 10, 2, 4, 1 ].sort.each{ |i| p i } を引数で直接指定して実行したところです。
ファイルを渡してももちろん動作します。

作業記録とソースコード

以下は、作業記録です。

ソースコード

EFI Shell アプリケーションを作るので、EDK と mruby の二つが必要です。

EDK は edk2_for_mruby として、 mruby は mruby_efi_shell として、どちらも GitHub 上に置いてあります。

まず、edk2_for_mruby をダウンロードして展開し、続いて AppPkg/Applications/mruby に mruby_efi_shell を展開します。
やったことがなかったので、サブモジュールなどの設定はまだしていません。

ビルド環境

少し古いですが、現在の Mac や Let's note を使い始める前に使っていた Ubuntu 9.10 (Karmic Koala) でビルドしました。
ただし、これはすでにサポート期限が切れているので、これから始める人は、12.X をインストールした方がよいでしょう。
(余談ですが、私の実機では、 12.X をインストールすると、画面の Refresh Rate がおかしくなったので、面倒になってインストールをやめました。)

また、32bit, 64bit いずれの mruby.efi をビルドする場合でも、32bit の Ubuntu で可能です。
ただし、64bit 版を試すには、VMware Player で 64bit の EFI をエミュレートできる必要があります。
よく分かっていませんが、64bit CPU を搭載している必要があるだろうと思います。また、 Intel-VT などが有効になっている必要があるかもしれません。

あとは、EDK の How to build を見ながら設定していきます。
Unix-like systems でのビルド方法にも、必要なライブラリ (build-essential など) が書かれているので、入れていなかったらインストールします。

ソースの変更

ビルドするために、いくつか変更を加えました。

詳しくは GitHub の履歴を見ていただければいいですが、悩んだのは EDK 側のバグでした。

EFI Application で C の標準ライブラリを使えるようにするためのラッパが用意されているのですが、その中の一つである StdLib/LibC/Main/Main.cmain 関数の宣言が間違っていました。

正確には、それを呼び出しているサンプルである AppPkg/Applications/Main/Main.c との整合性がとれておらず、呼び出し規約が異なったものになっていました。

そのため、偶然、32bit 環境では動作するのに、64bit では動作せず、かなり悩むはめになりました。

それ以外は、y.tab.c のように動的に生成されるものをいくつかあらかじめ作っておくなどをしました。

なお、EDK 側に関数が定義されていないものがあり、現状は math モジュールは除いてあります
今後、必要なら EDK 側に実装するなどして、対応しようと思います。

テスト環境

テスト環境には VirtualBoxVMware Player を用いました。

VirtualBox では、「システム」の「EFI を有効化」にチェックをすることで、Bootable Device がなければ、32bit の EFI Shell が自動で立ち上がります。

VMware Player では、*.vmx ファイルに、以下の行を加えることで EFI Boot させることができます。
efi は小文字にする必要があります。

firmware = "efi"

これで、 Bootable Device がなければ、EFI Shell が自動で立ち上がるはずです。
なお、私の環境では Network の部分でハングしていたので、 Network デバイスを削除しておきました。

以上で 32bit, 64bit ともにテストができるはずです。

今後

今後は、EFI の機能を簡単に呼べるようなライブラリを作っておこうと思います。

少なくとも、Boot Service, Runtime Service ぐらいは Ruby の関数として提供しようと思います。

可能なら、すでに EDK に入っている Python のように、mruby を EDK に含めてもらいたいです。

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" に載っていました。
  • バグがありましたら、教えていただけると嬉しいです。(対応できるかは未定です。)

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