Intellij IDEAのRubyプラグインの有効化に失敗していたんですが、pikが原因でした→pikのconfig.yamlが原因でした

Intellij IDEAのRubyプラグインの有効化に失敗していたんですが、pikが原因でした なんて記事があがっていたけど、怒りにまかせてファイル消して対応したとか書いてあってモヤモヤしたので調べてみました。

動作環境

エラー再現

  • 既にインストール済だったRuby pluginをIntelliJ IDEAからアンインストール
  • pikをインストールし、ruby-1.9.2-p136をインストール
  • 再度Ruby pluginをインストール
  • IntelliJ IDEAの再起動

f:id:tenten0213:20140331192154j:plain

エラーが出ました。参照元の記事と、Rubyのバージョンが違うだけでエラー内容はほとんど同様です。エラー内容のテキストは記事の一番下にでも貼り付けておきます。

原因

どうやらpik関連のYAMLを読み込んだ際にエラーが発生しているようです。 %HOME%/.pik/にconfig.ymlといういかにもっぽい設定ファイルがあるので覗いてみると、以下のような内容になっていました。

--- 
"[ruby-]1.9.2[-p136]": 
  :path: !ruby/object:Pathname 
    path: C:/Users/tis302655/.pik/rubies/ruby-1.9.2-p136/bin
  :version: |
    ruby 1.9.2p136 (2010-12-25) [i386-mingw32]

--- {}

エラーに出ている箇所が見事にありますね。

but found another document
 in 'reader', line 8, column 1:
    --- {}

まさにこのファイルのようです。 YAMLは「---」で区切ると1ファイルに複数のYAMLドキュメントを含めることができます。1ドキュメントだけ取得するはずが、別のドキュメントまで取得できてしまったからエラーになったようです。

対応

ということで、config.ymlの不要部分を削除し、以下のようにしてから

--- 
"[ruby-]1.9.2[-p136]": 
  :path: !ruby/object:Pathname 
    path: C:/Users/tis302655/.pik/rubies/ruby-1.9.2-p136/bin
  :version: |
    ruby 1.9.2p136 (2010-12-25) [i386-mingw32]

IntelliJ IDEAを再起動することで正常にプラグインを読み込むことが出来ました。

エラー内容はちゃんと読んで対応しなければいけませんね。

エラーの内容

Plugin 'org.jetbrains.plugins.ruby' failed to initialize and will be disabled.  Please restart IntelliJ IDEA.

expected a single document in the stream
 in 'reader', line 2, column 1:
    "[ruby-]1.9.2[-p136]": 
    ^
but found another document
 in 'reader', line 8, column 1:
    --- {}
    ^

    at org.yaml.snakeyaml.composer.Composer.getSingleNode(Composer.java:110)
    at org.yaml.snakeyaml.constructor.BaseConstructor.getSingleData(BaseConstructor.java:120)
    at org.yaml.snakeyaml.Yaml.loadFromReader(Yaml.java:481)
    at org.yaml.snakeyaml.Yaml.load(Yaml.java:412)
    at org.jetbrains.plugins.ruby.ruby.RubyUtil.loadYaml(RubyUtil.java:106)
    at org.jetbrains.plugins.ruby.version.management.pik.PikSdkRefresher.parseConfig(PikSdkRefresher.java:133)
    at org.jetbrains.plugins.ruby.version.management.pik.PikSdkRefresher.getSdkInfos(PikSdkRefresher.java:60)
    at org.jetbrains.plugins.ruby.version.management.SdkRefresherBase.refreshSDKs(SdkRefresherBase.java:59)
    at org.jetbrains.plugins.ruby.version.management.SdkVersionManagerUtil.updateSDKs(SdkVersionManagerUtil.java:14)
    at org.jetbrains.plugins.ruby.version.management.ProjectSdkRefresher.initComponent(ProjectSdkRefresher.java:23)
    at com.intellij.openapi.components.impl.ComponentManagerImpl$ComponentConfigComponentAdapter$1.getComponentInstance(ComponentManagerImpl.java:548)
    at com.intellij.openapi.components.impl.ComponentManagerImpl$ComponentConfigComponentAdapter.getComponentInstance(ComponentManagerImpl.java:590)
    at com.intellij.util.pico.DefaultPicoContainer.getLocalInstance(DefaultPicoContainer.java:225)
    at com.intellij.util.pico.DefaultPicoContainer.getInstance(DefaultPicoContainer.java:212)
    at com.intellij.util.pico.DefaultPicoContainer.getComponentInstance(DefaultPicoContainer.java:199)
    at org.picocontainer.alternatives.AbstractDelegatingMutablePicoContainer.getComponentInstance(AbstractDelegatingMutablePicoContainer.java:75)
    at com.intellij.openapi.components.impl.ComponentManagerImpl.createComponent(ComponentManagerImpl.java:121)
    at com.intellij.openapi.components.impl.ComponentManagerImpl.a(ComponentManagerImpl.java:112)
    at com.intellij.openapi.components.impl.ComponentManagerImpl.init(ComponentManagerImpl.java:89)
    at com.intellij.openapi.project.impl.ProjectImpl.init(ProjectImpl.java:296)
    at com.intellij.openapi.project.impl.ProjectManagerImpl.a(ProjectManagerImpl.java:281)
    at com.intellij.openapi.project.impl.ProjectManagerImpl.access$300(ProjectManagerImpl.java:83)
    at com.intellij.openapi.project.impl.ProjectManagerImpl$9.compute(ProjectManagerImpl.java:569)
    at com.intellij.openapi.project.impl.ProjectManagerImpl$9.compute(ProjectManagerImpl.java:565)
    at com.intellij.openapi.progress.impl.ProgressManagerImpl$4.run(ProgressManagerImpl.java:240)
    at com.intellij.openapi.progress.impl.ProgressManagerImpl$TaskRunnable.run(ProgressManagerImpl.java:464)
    at com.intellij.openapi.progress.impl.ProgressManagerImpl$6.run(ProgressManagerImpl.java:274)
    at com.intellij.openapi.progress.impl.ProgressManagerImpl$2.run(ProgressManagerImpl.java:178)
    at com.intellij.openapi.progress.ProgressManager.executeProcessUnderProgress(ProgressManager.java:209)
    at com.intellij.openapi.progress.impl.ProgressManagerImpl.executeProcessUnderProgress(ProgressManagerImpl.java:212)
    at com.intellij.openapi.progress.impl.ProgressManagerImpl.runProcess(ProgressManagerImpl.java:171)
    at com.intellij.openapi.application.impl.ApplicationImpl$10$1.run(ApplicationImpl.java:645)
    at com.intellij.openapi.application.impl.ApplicationImpl$8.run(ApplicationImpl.java:419)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
    at java.util.concurrent.FutureTask.run(FutureTask.java:262)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:724)
    at com.intellij.openapi.application.impl.ApplicationImpl$1$1.run(ApplicationImpl.java:149)

追記

関連するissueがあがっていました。

対応としては同様にコードを修正してるっぽいです。

これ以上調べないでいいかなって思っていたのですが、後輩にpikも調べろやって感じの対応をされたので、pikのコードも見てみました。

おそらく…以下の49行目でglobalにインストールされたRubyに関するドキュメントを吐こうとしているものの、@global = {} の状態のまま書き込んでるから --- {} になってるんじゃないかと。

https://github.com/vertiginous/pik/blob/22a028c84a44088aa813bc8da1d0ae1a7a6597be/lib/pik/config_file.rb#L49

一応irbで簡単に試してみました。 @global = {} のままだと確かに --- {} になります。

irb(main):001:0> require 'yaml'
=> true
irb(main):002:0> @global = {}
=> {}
irb(main):003:0> YAML.dump(@global)
=> "--- {}\n"

rubyのバージョンも疑ってみましたが、1.8,1.9,2.0もほぼ同様の出力になったのでバージョン差異は問題ではなさそうです。(1.8は"--- {}\n\n"でしたが)

あとは、Ruby plugin側のコード変更でエラーが出るようになったことが考えられますが、調べるのが面倒なのでここらへんでおしまいにします。

また後輩に調べろやって言われないといいな。。。