2017-02-11 PureScript IDE が psc-ide-server の起動に失敗するのを解決した
bouzuya/rally-cli の import があとすこしでできそうなのだけど、今日はそれではなく Visual Studio Code の PureScript IDE が psc-ide-server の起動に失敗する問題を解決したことを書く。
結論から書く。 PATH に Node.js が含まれておらず、 psc-ide-server の実行が失敗することが原因だった。 Terminal から Visual Studio Code を起動した場合は bash / zsh の設定ファイルで PATH に設定されるので問題ないのだけど、 Spotlight から Visual Studio Code を起動した場合は PATH に設定されないため問題が起きる。解決策としては /etc/profile に PATH の設定を含めるなどがある。
たどった経路を書いておく。
- Visual Studio Code の PureScript IDE (nwolverson/vscode-ide-purescript)
purescript.restartPscIdeコマンド https://github.com/nwolverson/vscode-ide-purescript/blob/v0.6.4/package.json#L52restartの呼び出し https://github.com/nwolverson/vscode-ide-purescript/blob/v0.6.4/src/IdePurescript/VSCode/Main.purs#L294restartの定義とstartPscIdeServerの呼び出し https://github.com/nwolverson/vscode-ide-purescript/blob/v0.6.4/src/IdePurescript/VSCode/Main.purs#L282startPscIdeServerの定義とstartServer'の呼び出し https://github.com/nwolverson/vscode-ide-purescript/blob/v0.6.4/src/IdePurescript/VSCode/Main.purs#L256startServer'の定義とP.startServer'(purescript-ide-purescript-coreパッケージ nwolverson/purescript-ide-purescript-core) の呼び出し https://github.com/nwolverson/vscode-ide-purescript/blob/v0.6.4/src/IdePurescript/VSCode/Main.purs#L109purescript-ide-purescript-coreのバージョンの確認 (^0.8.2) https://github.com/nwolverson/vscode-ide-purescript/blob/master/bower.json#L15P.startServer'の定義とfindBinsの呼び出し https://github.com/nwolverson/purescript-ide-purescript-core/blob/v0.8.2/src/IdePurescript/PscIdeServer.purs#L74findBinsの定義とfindBins'(purescript-psc-ideパッケージ kRITZCREEK/purescript-psc-ide) の呼び出し https://github.com/nwolverson/purescript-ide-purescript-core/blob/v0.8.2/src/IdePurescript/Exec.purs#L17purescript-psc-ideのバージョンの確認 (^7.0.0) https://github.com/nwolverson/purescript-ide-purescript-core/blob/v0.8.2/bower.json#L20findBins'の定義とgetVersionの呼び出し https://github.com/kRITZCREEK/purescript-psc-ide/blob/v7.0.0/src/PscIde/Server.purs#L111getVersionの定義 https://github.com/kRITZCREEK/purescript-psc-ide/blob/v7.0.0/src/PscIde/Server.purs#L117
もちろん、ここまで直線的ではなく、あちらこちらへいろいろな原因を疑いながら移動した。
findBins' は getVersion で psc-ide-server --version 相当を実行し、Executable を返す。Executable は data Executable = Executable String (Maybe String) で String が psc-ide-server のパスで、 Maybe String は psc-ide-server のバージョンだ。 getVersion に失敗した場合は Nothing が入る。
今回の状況では Node.js が見つからないため getVersion によって実行される psc-ide-server コマンドが失敗する。それが Executable "/path/to/psc-ide-server" Nothing という Maybe String を Nothing にした形で伝えられる。ちなみに正常なら Executable "/path/to/psc-ide-server" (Just "0.10.6") などという形で返される。「 Nothing のとき Executable じゃなくね?」と個人的には思うのだけど、そういう仕様なのだから仕方ない。
それを P.startServer' 内で処理するのだけど、ユーザーの目に触れない位置での log だけでバージョンの ERROR を通知するのみで、 実際の実行では強引に実行しようとしている。https://github.com/nwolverson/purescript-ide-purescript-core/blob/v0.8.2/src/IdePurescript/PscIdeServer.purs#L89-L110
startServer' の結果は StartError になるのだけど、画面に表示されるエラーメッセージは「ポート番号を確認しろ」というものとなる。ポート番号に問題はない。 https://github.com/nwolverson/purescript-ide-purescript-core/blob/v0.8.2/src/IdePurescript/PscIdeServer.purs#L110
P.startServer' がバージョンの確認に失敗する状況を甘く見ている。 Visual Studio Code における PATH は Terminal のものとも異なるので、画面表示のメッセージが弱いと、原因に気づきにくい。