posh-gvmでWindowsでもGroovyを楽しむことができます
サラリーマン時代からPowerShellと並んで自動化や効率化に利用してきたスクリプト環境が3つあります。
ひとつはrubyです。 JRubyもCRubyも大変お世話になりました。 1.8から1.9、そして2.0とバージョンが上がっていき、つかっていたgemが使えなくなったりとmakeができない環境下では辛い思いをしたのも良い思い出です。
ふたつめはPythonです。 LinuxでもWindowsでもSolarisでも大変お世話になりました。 各OSでバージョンがバラバラで、同じコードがPCからサーバーへデプロイすると動作しないとか、良い思い出です。
みっつめがGroovyです。 Javaランタイムで動作してくれるおかげでどのOSでも大変お世話になりました。 これに関しては全く困ったことがありません。
そういうわけで、SurfaceにもGroovyを入れておこうと思うのは人間のサガというものでしょう。
と思っていたらsdkmanという不思議な名前のツールに生まれ変わっていてビックリしました…
sdkman the Software Development Kit Manager
http://sdkman.io/
どちらにしてもjarだけあればGroovyは動作するので、もうなんでもいいのかもしれませんが。
Windowsでは? わたしはzipでダウンロードしてきて、自分の好きなところへ展開してパスを通してつかっていました。 だって、gvmはbashなんかが動作しないと使うことができないからです。
Written in bash and only requires curl and unzip to be present on your system. Even works with ZSH too.
msys?Cygwin? いやいや、もういいでしょう。 MinGWか!いや、それももういいです。
Windowsには以下のコマンドを正常に実行完了するための標準的な環境がありません。
$ curl -s http://get.sdkman.io | bash
Installation - sdkman
http://sdkman.io/install.html
sdkman installs smoothly on Mac OSX, Linux, Cygwin, Solaris and FreeBSD.
Windowsの場合は「posh-gvm」というのがあります。
flofreud/posh-gvm
https://github.com/flofreud/posh-gvm
こちらはgvm時代に開発されたPowerShellでのgvmクローンです。
Posh-GVM is a clone of the GVM CLI. In most aspects its an 1:1 copy of the BASH based version.
ちょっと前まではsdkmanのプロジェクトページにもここへのリンクがあったような気がしたのですが、見当たらなくなってしまいました…
動作にはPowerShell 3.0以上が必要になります。
NuGetにインスパイアされたというPsGetをつかってインストールする
Githubリポジトリからクローンしてきてインストールする
Githubのreadme.mdに書いてある通りなんですが、次のようにします。
とりあえずダウンロードしてモジュールパスに配置する
適切な実行ポリシーのPowerShellコンソールから以下のようにすれば上記の内容が実行できます。
(new-object Net.WebClient).DownloadString('https://raw.githubusercontent.com/flofreud/posh-gvm/master/GetPoshGvm.ps1') | iex
後はモジュールとして読み込めばOKです。profile.ps1なんかに記述しておくと、PowerShellでgvmしたいときに都度インポートしなくて便利ですね。
sdkmanよりもちょっとコードが長いですよね。 それはそうです。
sdkmanは「curl」コマンドを利用しているのに対して、PowerShellでは「Net.WebClient」をオブジェクト化した上でスクリプトを文字列としてダウンロードしているのですから。
また、sdkmanはbashだけでダウンロードして配置していますが、PowerShellの場合はそれだけではダメです。 というのも、モジュールとしてインポートされないと「gvm」というコマンドのように利用することができないからです。
なおインストールのときには外部スクリプトを実行することになるので、実行ポリシーを「RemoteSigned」にはしておいたほうがいいでしょう。
posh-gvmのインストールを眺めてPowerShellを学習してみる
posh-gvmのインストールを眺めて、学ぶことができるところは学ぼうかなと思います。
まず最初に文字列としてダウンロードしている「GetPoshGvm.ps1」から見ていきましょう。
GetPoshGvm.ps1
https://github.com/flofreud/posh-gvm/blob/master/GetPoshGvm.ps1
最初に実行されるのは一番最後の行の「Install-Posh-Gvm」です。 これは関数を呼び出しています。
この関数が行っていることは非常にシンプルで、以下のとおりです。
一時フォルダにGUIDをファイル名としたダウンロード先フォルダを作る
Githubからmasterリポジトリのzipアーカイブを一時フォルダへダウンロードする
まず1番目のモジュールパスを探す、ですがこれも関数になっていて「Find-Module-Location」として定義されています。
$moduleDescriptor = Get-Module posh-gvm
これによって既にモジュールとして読み込まれているなら、その読み込み元フォルダを返します。 もし読み込まれてない場合はユーザーのドキュメントフォルダ配下の「WindowsPowerShell¥Modules」フォルダがPowerShellのモジュールパスに含まれているか確認します。
$modulePaths = @($Env:PSModulePath -split ';') # set module path to posh default $targetModulePath = Join-Path -Path ([Environment]::GetFolderPath('MyDocuments')) -ChildPath WindowsPowerShell\Modules # if its not use select the first defined if ( $modulePaths -inotcontains $targetModulePath ) { $targetModulePath = $modulePaths | Select-Object -Index 0 }
もしも含まれていない場合はモジュールパスの最初のパス(ユーザー用のモジュールパスの次の優先度のもの)を利用し、そうでなければユーザー用のモジュールパスを使います。
ということで、大抵はユーザーのモジュールパスが返されると思います。
$tempDir = [guid]::NewGuid().ToString()
3番目も.Netの力を借りて、デフォルトのプロキシ認証情報をつかってダウンロードしています。
$client = (New-Object Net.WebClient) $client.Proxy.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials $client.DownloadFile($poshGvmZipUrl, $poshGvmZip)
4番目はunzip.exeがインストールされていない環境を見越しての対処ですね。 よくやる操作だと思います。
COMで「Shell.Application」を呼び出して、これの「CopyHere」メソッドを利用してzip内のエントリをファイルにしています。
$shell = New-Object -com shell.application $shell.namespace($tempDir).copyhere($shell.namespace($poshGvmZip).items(), 0x14)
ここで、CopyHereの二つ目の引数は「0x14」となっています。 これはオプションが2つ足しこまれていて、「0x04」の「進捗ダイアログを表示しない」と「0x10」の「上書き確認をしない」になっています。
5番目はサブフォルダまでモジュールパスへコピーということになります。
なお、途中でエラーになってもダウンロード先の一時フォルダは強制的に削除されるようになっていますね。
ということで、最後に手動でImport-Moduleすればめでたく「gvm」として機能するようになります。
ものすごく簡単な原理です。 読み込まれたモジュールのソース「posh-gvm.psm1」を見てみるとすぐにお分かりでしょう。
Export-ModuleMember 'gvm'
つまり、モジュールの中では「gvm」という関数だけが公開されているのです。 だから「gvm」とPowerShellコンソールから呼び出すとオプションは全て関数gvmへのパラメータとして扱われます。
関数gvmは「Commands.ps1」に定義されています。 興味のある方はどうぞ。
Groovyを導入すると、という話で始めたのに気づくとPowerShellオンリーなエントリーになってしまいました。 WindowsでもJavaランタイムがあれば動作するGroovyも楽しいので使いましょう。
わたしも全く使いこなせていないGroovyなので、もっと勉強したいと思います。