patorashのブログ

方向性はまだない

RailsにPR送ったらマージされた

Railsに含まれているgem web-consoleに自分のPRが取り込まれた🎉

github.com

感動を残しておくためにブログに書いとく。

事の始まり

先日、Rails 6.0.0 rc1でrails newして、ごにょごにょと進めていたら、ログに以下のメッセージが出ていた。

Cannot render console from Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255

今はWindowsからHyper-V上のUbuntuに接続して開発しているため、web-consoleがホスト側のIPを許可していないってことだった。早速ググって、設定を追加しようとした。

qiita.com

おー、これだこれだ…と思い、追加。

config.web_console.whitelisted_ips = '0.0.0.0/0'

そして、再度アクセスすると、まだログが出るじゃないですか。どういうことですか、これは…。

ソースコードを読みに行く

すると、最新のweb-consoleのコードでは、config.web_console.whitelisted_ipsではなく、config.web_console.permissionsを利用するようになっていた。

Railsアプリ側でwhitelisted_ipspermissionsに変更すれば、エラーログも消えて問題なくなった。

config.web_console.permissions = '0.0.0.0/0'

しかし、互換性を保つため、config.web_console.whitelisted_ipsも利用できるように見えていたんですよ、一見は。

initializer "web_console.permissions" do
  if permissions = config.web_console.permissions || config.web_console.whitelisted_ips
    Request.permissions = Permissions.new(permissions)
  end
end

しかし、上のほうでconfig.web_console.permissions = %w( 127.0.0.1 ::1 )って初期化されているため、config.web_console.permissionsnilになることは絶対になく、config.web_console.whitelisted_ipsが使われることはないことになっていた。これ今までのコードで設定していた人たちがRails6にアップデートしたら急にweb-consoleが使えなくなる地雷じゃない?というかバグじゃない?と思い、PRを作ってみることに。

Pull Request作成

ひとまず、上記のところの順番を逆にするだけのPRを作って送った。最初にconfig.web_console.whitelisted_ipsを評価してしまえばそれでいいからだ。

initializer "web_console.permissions" do
  if permissions = config.web_console.whitelisted_ips || config.web_console.permissions
    Request.permissions = Permissions.new(permissions)
  end
end

そしたら、「テストを追加してくれ」と言われたので、やろうとしたのだけれど、うまくいかなかった。railtieのテストでRailsの初期化をもう一度やる仕組みが定義されていたのだが、それに則るとconfig.web_console.permissionsが設定されていなくてnilになっており、もしwhitelisted_ipsに値を入れても評価されるかどうかのテストがあったとしてもパスしていただろう。つまりテストもバグってた。

どーしたもんかなー…と思い悩んでいたのだけれど、コードとテスト見ると、ループバックアドレス127.0.0.1のこと)はデフォルトで常に許可されるように定義されていたため、「あれ?これってconfig.web_console.permissions = %w( 127.0.0.1 ::1 )の初期値の定義いらないよな?🤔」と思い、初期値の行の削除とpermissionsの定義を行うメソッドを必ず実行するように修正した。

# config.web_console.permissions = %w( 127.0.0.1 ::1 ) は削除済み
initializer "web_console.permissions" do
  permissions = config.web_console.permissions || config.web_console.whitelisted_ips
  Request.permissions = Permissions.new(permissions) # ifが不要だったので外した
end

whitelisted_ipsを使ってもpermissionsが設定されることを確認するテストを追加して、コードを引用しながら拙い英語で頑張ってみたところ、マージされた!!😂Rails6には間に合う模様。嬉しい!!

感想

やってみるもんです。