Solaris 環境における Node.js 複数バージョン管理 (nodebrew)


やはり、この問題は避けては通れないようです。

* Node.js Version Manager
 * nodebrew: [hokaccha/nodebrew](https://github.com/hokaccha/nodebrew)
 * nvm: [creationix/nvm](https://github.com/creationix/nvm)

Node.js の version manager としては、nvm, nodebrew などがあるみたいですけど binary は nodejs.org 
から持ってくるので Solaris では動作しないものがインストールされることになったり。


## **nvm と nodebrew どっち使う？**

どちらも source code から build する機能を持っているけど、nvm は v1.0 以降の version から build することをサポートしていない。  

```sh
$ nvm install -s v5.5.0
Installing node v1.0 and greater from source is not currently supported
```

nodebrew は version 関係無く source から build してインストールできるけど、Solaris 環境では v0.12.x 系だとちょっと手を入れてあげないとダメだし、configure オプションも指定が必要。

configure のオプションを個別に渡せる仕組みが欲しい・・・なぁと Issues を見ていたら、[Add options parser #14](https://github.com/hokaccha/nodebrew/issues/14) とかあったので、こんな感じで実行してあげると configure に渡っているっぽい。

```sh
$ nodebrew install v5.5.0 '--dest-cpu=x64 --dest-os=solaris --with-dtrace'
```

これで v4.x/v5.x 系はいけるけど、v0.12.x 系はどうしようかなぁと調べているうちに、nodebrew に手を入れていた。今日から nodebrew 使えます。
というわけで、nodebrew を選択してみました。

## **Oracle Solaris でのオレ的変更点** 

Solaris で nodebrew を動かす際に、いくつかのオプションに制限を入れました。
install は source code からの build になります。

* install-binary オプションはサポートしません。
  nodejs.org で配布されている SunOS binary は illumos kernel を利用した distribution でのみ動作するため
* io.js はサポートしない
* gmake を使うように

修正は、[Add Oracle Solaris 11 support #51](https://github.com/hokaccha/nodebrew/pull/51) として PR しておきました。

また、v0.12.x のインストールには、下記のような patch が必要ですが、これをどう nodebrew の中で自動的に適用するか悩む。

```sh
$ gdiff -cd common.gypi.orig common.gypi
*** common.gypi.orig    2016-01-01 16:26:36.151123040 +0900
--- common.gypi 2016-01-01 16:32:44.235974848 +0900
***************
*** 198,203 ****
--- 198,204 ----
              'ldflags': [ '-m64' ],
            }],
            [ 'OS=="solaris"', {
+             'defines': ['_GLIBCXX_USE_C99_MATH'],
              'cflags': [ '-pthreads' ],
              'ldflags': [ '-pthreads' ],
              'cflags!': [ '-pthread' ],
```

悩んだ。
差分を取得する際、diff の `-d できるだけがんばって、小さい差分を見つける。` オプションをつけ、下記のように最小限の diff を作成。

```sh
$ gdiff -d common.gypi.orig common.gypi
200a201
>             'defines': ['_GLIBCXX_USE_C99_MATH'],
```

そして、これを、openssl コマンドで base64 encode にすれば 1 行の文字列として、この差分を扱えるので、

```sh
$ gdiff -d common.gypi.orig common.gypi  | openssl enc -e -base64 -A
MjAwYTIwMQo+IAkgICAgJ2RlZmluZXMnOiBbJ19HTElCQ1hYX1VTRV9DOTlfTUFUSCddLAo=
```

Base64 エンコードされた差分を openssl コマンドでデコードして、GNU patch に流し込む。
ただし、差分は最小限の情報(適用するファイル名などの情報は含まれていない)しか持っていないため、差分を適用するファイル名は指定する必要がある。

patch 適用を oneliner 化して nodebrew の中に仕込んでいます。
v0 で始まる node.js をインストールするときは、この patch 適用が発動します.

```sh
echo "MjAwYTIwMQo+IAkgICAgJ2RlZmluZXMnOiBbJ19HTElCQ1hYX1VTRV9DOTlfTUFUSCddLAo=" | openssl enc -d -base64 -A| gpatch common.gypi
```


## **nodebrew のインストール**

現時点では、ファイルの置き換えで対応することになります。

とりあえず、本家 nodebrew のインストール手順を実行。
$HOME/.nodebrew/current/bin を PATH に追加。

```sh
$ wget -qO- git.io/nodebrew | perl - setup                                                             
Fetching nodebrew...
Installed nodebrew in $HOME/.nodebrew

========================================
Export a path to nodebrew:

export PATH=$HOME/.nodebrew/current/bin:$PATH
========================================
```

その後、$HOME/.nodebrew/ へ移動し、nodebrew を修正版(<https://raw.githubusercontent.com/satokaz/nodebrew/for_solaris11/nodebrew>)に入れ替えます。(<https://git.io/vzoad> は、<https://git.io> で短縮 URL 化したもの) 

```sh
$ cd $HOME/.nodebrew/
$ wget -O nodebrew https://git.io/vzoad 
```

これで、nodebrwe を Solaris でも利用できるようになりました。

## **適当に何かインストールしてみる**

source code から build するので、こちらの[前提条件](http://qiita.com/satokaz/items/b7345834ee8950e42e90#前提条件)を確認してください。
インストール直後は何も設定されていないので、not installed と　current: none となっています。

```sh
$ nodebrew ls       
not installed

current: none
```

試しに nodejs v5.5.0 をインストール。
node-v5.5.0 の tar ball を download するとこからはじめるので、少し時間がかかります。

```sh
$ nodebrew install v5.5.0
```

プロンプトが返ってくれば、インストール完了。
nodebrew ls で v5.5.0 が選択できることが確認できます。

```sh
$ nodebrew ls
nodebrew ls
v5.5.0

current: none
```

インストールされた node v5.5.0 を利用するために nodebrew use を実行。

```sh
$ nodebrew use v5.5.0
use v5.5.0
```

current: v5.5.0 となり、node v5.5.0 を利用することができるようになりました。

```sh
$ nodebrew ls
v5.5.0

current: v5.5.0

$ node -v
v5.5.0

$ npm -v
3.3.12
```

v0.12.9 も同様の手順でいけます。
こんな感じで利用可能な node version が追加されてゆくので、必要なバージョンを適宜切り替えて利用することが可能になります。

```sh
$ nodebrew ls
v0.12.9
v5.5.0

current: v5.5.0
```

# **その他**

[以前書いた Node.js ネタ](http://qiita.com/satokaz/items/b7345834ee8950e42e90)で Solaris 11.3 で selenium-webdriver を動かしてみてくれた方が。
ネタからネタに繋がるとうれしいですね。

* [Solaris 11.3(x86)でSelenium WebDriverを動かしてみた](http://www.slideshare.net/hirofumitouhei/solaris-113x86selenium-webdriver)