Hudson CLIの内部構造
id:masanobuimaiさんがHudson CLIの仕組みを調べてくださったので、ここで仕組みをちょっと解説しようかな、と。
CLIは、まずHudsonに2つのHTTPリクエストをします。片方はサーバからCLIにバイト列を送るために使い、もう片方はCLIからサーバにバイト列を送るために使います。(なのでCLIはサーバ上では2つもスレッドを消費するのですが、それはそれ。)
この双方向バイトストリームの上にリモーティングインフラ(hudson.remoting.*)を載せて、これで分散処理環境が出来上がります。ここまで出来たらCLIはコマンドの引数を全部サーバに渡します。この時、stdin/stdout/stderrもサーバに渡します。
なので、見てのとおり、CLI側にはコマンドの知識は何も埋め込まれていません。
Channel channel = ...; CliEntryPoint cli = (CliEntryPoint)channel.waitForRemoteProperty(CliEntryPoint.class.getName()); r = cli.main(args, Locale.getDefault(), new RemoteInputStream(System.in), new RemoteOutputStream(System.out), new RemoteOutputStream(System.err)); ... System.exit(r);
このcliオブジェクトはサーバへのstubなので「cli.main」はサーバ側で実行されます。サーバ側からは折り返しCLI側へクロージャを送って実行することも出来るので、当然ローカルからリモートへのファイルコピーや、あるいはもっと複雑なことも出来ます。
これらの送られてきたクロージャを実行することで、CLIは万能CLIとなるわけです。
Groovyshではリモーティングの事を考えていない既存のコードをリモート対応させないといけないのでトリッキーですが、例えばloadコマンドの実装を交換してCLI側からファイルをロードする、といった程度であれば非常に簡単に出来ます。