powerhome/playbook

Playbook not compatible with Ruby versions 3+

web-kat opened this issue · 12 comments

Is your feature request related to a problem? Please describe.

Playbook is currently not compatible with applications using Ruby versions 3+.

Describe the solution you'd like

Playbook should be compatible with applications using Ruby versions 3+.

Describe alternatives you've considered

Downgrading our application to use Ruby version 2.7

Additional context

NitroID was started as a Rails 7 application on Ruby 3.1 and has had difficulty adopting Playbook.

@thestephenmarshall @jasperfurniss @jasoncypret This may be relevant for Create if we want to allow teams to use the latest versions of Rails and Ruby, but also for real-world applications like NitroID.

I wonder if a solution for this prior to Create is plausible.

@web-kat Can you by chance provide more detail about the errors your seeing? I just upgraded an app to ruby 3 using playbook and it installs fine, but I am getting an error regarding the props rb file. I want to make sure we're hunting down and fixing the problems you are facing.

@jasoncypret With Ruby 3.1, here is the initial error I saw.

/usr/local/bundle/ruby/3.1.0/gems/playbook_ui-10.26.0/lib/playbook/props/base.rb:10:in `initialize': wrong number of arguments (given 1, expected 0; required keywords: name, kit) (ArgumentError)
        from /usr/local/bundle/ruby/3.1.0/gems/playbook_ui-10.26.0/lib/playbook/props.rb:51:in `new'
        from /usr/local/bundle/ruby/3.1.0/gems/playbook_ui-10.26.0/lib/playbook/props.rb:51:in `prop'
        from /usr/local/bundle/ruby/3.1.0/gems/playbook_ui-10.26.0/lib/playbook/classnames.rb:6:in `included'
        from /usr/local/bundle/ruby/3.1.0/gems/playbook_ui-10.26.0/lib/playbook/kit_base.rb:27:in `include'
        from /usr/local/bundle/ruby/3.1.0/gems/playbook_ui-10.26.0/lib/playbook/kit_base.rb:27:in `<class:KitBase>'
        from /usr/local/bundle/ruby/3.1.0/gems/playbook_ui-10.26.0/lib/playbook/kit_base.rb:24:in `<module:Playbook>'
        from /usr/local/bundle/ruby/3.1.0/gems/playbook_ui-10.26.0/lib/playbook/kit_base.rb:23:in `<main>'
        from /usr/local/bundle/ruby/3.1.0/gems/bootsnap-1.11.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
        from /usr/local/bundle/ruby/3.1.0/gems/bootsnap-1.11.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
        from /usr/local/bundle/ruby/3.1.0/gems/playbook_ui-10.26.0/lib/playbook.rb:12:in `<main>'
        from /usr/local/bundle/ruby/3.1.0/gems/bootsnap-1.11.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
        from /usr/local/bundle/ruby/3.1.0/gems/bootsnap-1.11.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
        from /usr/local/bundle/ruby/3.1.0/gems/playbook_ui-10.26.0/lib/playbook_ui.rb:3:in `<main>'
        from /usr/local/bundle/ruby/3.1.0/gems/bootsnap-1.11.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
        from /usr/local/bundle/ruby/3.1.0/gems/bootsnap-1.11.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
        from /usr/local/rvm/gems/ruby-3.1.2/gems/bundler-2.3.12/lib/bundler/runtime.rb:60:in `block (2 levels) in require'
        from /usr/local/rvm/gems/ruby-3.1.2/gems/bundler-2.3.12/lib/bundler/runtime.rb:55:in `each'
        from /usr/local/rvm/gems/ruby-3.1.2/gems/bundler-2.3.12/lib/bundler/runtime.rb:55:in `block in require'
        from /usr/local/rvm/gems/ruby-3.1.2/gems/bundler-2.3.12/lib/bundler/runtime.rb:44:in `each'
        from /usr/local/rvm/gems/ruby-3.1.2/gems/bundler-2.3.12/lib/bundler/runtime.rb:44:in `require'
        from /usr/local/rvm/gems/ruby-3.1.2/gems/bundler-2.3.12/lib/bundler.rb:176:in `require'
        from /home/app/src/config/application.rb:14:in `<top (required)>'
        from /home/app/src/config/environment.rb:4:in `require_relative'
        from /home/app/src/config/environment.rb:4:in `<top (required)>'
        from config.ru:5:in `require_relative'
        from config.ru:5:in `block in <main>'
        from /usr/local/bundle/ruby/3.1.0/gems/rack-2.2.3/lib/rack/builder.rb:116:in `eval'
        from /usr/local/bundle/ruby/3.1.0/gems/rack-2.2.3/lib/rack/builder.rb:116:in `new_from_string'
        from /usr/local/bundle/ruby/3.1.0/gems/rack-2.2.3/lib/rack/builder.rb:105:in `load_file'
        from /usr/local/bundle/ruby/3.1.0/gems/rack-2.2.3/lib/rack/builder.rb:66:in `parse_file'
        from /usr/local/bundle/ruby/3.1.0/gems/puma-5.6.4/lib/puma/configuration.rb:348:in `load_rackup'
        from /usr/local/bundle/ruby/3.1.0/gems/puma-5.6.4/lib/puma/configuration.rb:270:in `app'
        from /usr/local/bundle/ruby/3.1.0/gems/puma-5.6.4/lib/puma/runner.rb:150:in `load_and_bind'
        from /usr/local/bundle/ruby/3.1.0/gems/puma-5.6.4/lib/puma/single.rb:44:in `run'
        from /usr/local/bundle/ruby/3.1.0/gems/puma-5.6.4/lib/puma/launcher.rb:182:in `run'
        from /usr/local/bundle/ruby/3.1.0/gems/puma-5.6.4/lib/puma/cli.rb:81:in `run'
        from /usr/local/bundle/ruby/3.1.0/gems/puma-5.6.4/bin/puma:10:in `<top (required)>'
        from /home/app/src/bin/puma:27:in `load'
        from /home/app/src/bin/puma:27:in `<main>'

I was able to get past this issue by monkey-patching props.rb:51 with self.props = props.merge(name => type.new(**options.merge(name: name, kit: self))) only to hit the same type of error again somewhere else.

Is that the same error you're seeing?

For more context, this issue seems the result of the way Ruby 3.1 handles hash literals and keyword args. I can reproduce this issue locally:

Ruby 2.7:

irb(main):001:1* def test_method(x:, y:)
irb(main):002:1*   puts x + y
irb(main):003:0> end
=> :test_method
irb(main):004:1* def parent_test_method(**options)
irb(main):005:1*   test_method(options.merge(x: 1, y: 2))
irb(main):006:0> end
=> :parent_test_method
irb(main):007:0> parent_test_method
3
=> nil

Ruby 3.1:

3.1.2 :057 > def test_method(x:, y:)
3.1.2 :058 >   puts x + y
3.1.2 :059 > end
 => :blah
3.1.2 :060 > def parent_test_method(**options)
3.1.2 :061 >   test_method(options.merge(x: 1, y: 2))
3.1.2 :062 > end
 => :parent_test_method
3.1.2 :063 > parent_test_method
(irb):57:in `test_method': wrong number of arguments (given 1, expected 0; required keywords: x, y) (ArgumentError)
	from (irb):61:in `parent_test_method'
	from (irb):63:in `<main>'
	from /usr/local/rvm/rubies/ruby-3.1.2/lib/ruby/gems/3.1.0/gems/irb-1.4.1/exe/irb:11:in `<top (required)>'
	from /usr/local/rvm/rubies/ruby-3.1.2/bin/irb:31:in `load'
	from /usr/local/rvm/rubies/ruby-3.1.2/bin/irb:31:in `<main>'

Yes that looks like the same one. We will get a test branch open to attempt a fix.

Indeed, the pairing that everyone will want to use at Create is Rails 7.0 with Ruby 3.1.

With the latest commits to our PR, Playbook is now fully compatible with applications using Ruby versions 3+: https://github.com/powerhome/playbook/pull/1942/commits

cc: @benlangfeld @wadewinningham @jasoncypret @stephenagreer @web-kat

Shout out to @xjunior who paired with me this afternoon and helped a lot!
In fact, as Carlos just mentioned to me, we should be able to fully support your ideal pairing @benlangfeld , because the tests are all running against ruby 3.1 and rails 7.

I'll spin up a new rails 7 app with Ruby 3.1+ and give it a go.

I went ahead and cut an alpha.

Actually, let me double-check that I cut that alpha correctly. I'm checking one particular step. Then I'll update you all again.

Here's the latest versions:
https://rubygems.org/gems/playbook_ui/versions/11.0.0.pre.alpha.2
https://www.npmjs.com/package/playbook-ui/v/11.0.0-alpha2

@stephenagreer - Would you mind trying these out in the starter app, and verifying that they work? Thanks!