palkan / anyway_config

Configuration library for Ruby gems and applications
MIT License
778 stars 52 forks source link

NameError in Anyway::Config After Upgrading to 2.6.0 on Ruby 3.2.2 and Rails 7.1.2 #143

Closed bbraga closed 10 months ago

bbraga commented 10 months ago

Issue Description

After upgrading anyway_config from version 2.5.4 to 2.6.0 due to an indirect project dependency, I encountered a NameError when running bundle exec rails c.

Expected Behavior

The upgrade should have been seamless without introducing any breaking changes or bugs.

Actual Behavior

The following error was thrown:

bundle exec rails c
/Users/user/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/anyway_config-2.6.0/lib/anyway/config.rb:157:in `block in on_load': undefined local variable or method `it' for Anyway::Config:Class (NameError)

          load_callbacks.push(*names.map { NamedCallback.new(it) })
                                                             ^^
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/anyway_config-2.6.0/lib/anyway/config.rb:157:in `map'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/anyway_config-2.6.0/lib/anyway/config.rb:157:in `on_load'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/anyway_config-2.6.0/lib/anyway/config.rb:316:in `<class:Config>'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/anyway_config-2.6.0/lib/anyway/config.rb:22:in `<module:Anyway>'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/anyway_config-2.6.0/lib/anyway/config.rb:6:in `<top (required)>'
        from <internal:/Users/user/.rbenv/versions/3.2.2/lib/ruby/site_ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:38:in `require'
        from <internal:/Users/user/.rbenv/versions/3.2.2/lib/ruby/site_ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:38:in `require'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/zeitwerk-2.6.12/lib/zeitwerk/kernel.rb:38:in `require'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/anyway_config-2.6.0/lib/anyway_config.rb:20:in `<top (required)>'
        from <internal:/Users/user/.rbenv/versions/3.2.2/lib/ruby/site_ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:38:in `require'
        from <internal:/Users/user/.rbenv/versions/3.2.2/lib/ruby/site_ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:38:in `require'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/zeitwerk-2.6.12/lib/zeitwerk/kernel.rb:38:in `require'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/anycable-core-1.4.3/lib/anycable/config.rb:3:in `<top (required)>'
        from <internal:/Users/user/.rbenv/versions/3.2.2/lib/ruby/site_ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:38:in `require'
        from <internal:/Users/user/.rbenv/versions/3.2.2/lib/ruby/site_ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:38:in `require'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/zeitwerk-2.6.12/lib/zeitwerk/kernel.rb:38:in `require'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/anycable-core-1.4.3/lib/anycable.rb:4:in `<top (required)>'
        from <internal:/Users/user/.rbenv/versions/3.2.2/lib/ruby/site_ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:38:in `require'
        from <internal:/Users/user/.rbenv/versions/3.2.2/lib/ruby/site_ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:38:in `require'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/zeitwerk-2.6.12/lib/zeitwerk/kernel.rb:38:in `require'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/anycable-rails-core-1.4.3/lib/anycable/rails.rb:3:in `<top (required)>'
        from <internal:/Users/user/.rbenv/versions/3.2.2/lib/ruby/site_ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:38:in `require'
        from <internal:/Users/user/.rbenv/versions/3.2.2/lib/ruby/site_ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:38:in `require'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/zeitwerk-2.6.12/lib/zeitwerk/kernel.rb:38:in `require'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/anycable-rails-core-1.4.3/lib/anycable-rails.rb:3:in `<top (required)>'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/zeitwerk-2.6.12/lib/zeitwerk/kernel.rb:38:in `require'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/zeitwerk-2.6.12/lib/zeitwerk/kernel.rb:38:in `require'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/site_ruby/3.2.0/bundler/runtime.rb:60:in `block (2 levels) in require'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/site_ruby/3.2.0/bundler/runtime.rb:55:in `each'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/site_ruby/3.2.0/bundler/runtime.rb:55:in `block in require'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/site_ruby/3.2.0/bundler/runtime.rb:44:in `each'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/site_ruby/3.2.0/bundler/runtime.rb:44:in `require'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/site_ruby/3.2.0/bundler.rb:187:in `require'
        from /Users/user/work/bleak_server/config/application.rb:33:in `<top (required)>'
        from <internal:/Users/user/.rbenv/versions/3.2.2/lib/ruby/site_ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:38:in `require'
        from <internal:/Users/user/.rbenv/versions/3.2.2/lib/ruby/site_ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:38:in `require'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/railties-7.1.2/lib/rails/command/actions.rb:15:in `require_application!'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/railties-7.1.2/lib/rails/command/environment_argument.rb:31:in `require_application!'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/railties-7.1.2/lib/rails/command/actions.rb:19:in `boot_application!'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/railties-7.1.2/lib/rails/commands/console/console_command.rb:105:in `perform'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/thor-1.3.0/lib/thor/command.rb:28:in `run'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/thor-1.3.0/lib/thor/invocation.rb:127:in `invoke_command'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/railties-7.1.2/lib/rails/command/base.rb:178:in `invoke_command'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/thor-1.3.0/lib/thor.rb:527:in `dispatch'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/railties-7.1.2/lib/rails/command/base.rb:73:in `perform'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/railties-7.1.2/lib/rails/command.rb:71:in `block in invoke'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/railties-7.1.2/lib/rails/command.rb:149:in `with_argv'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/railties-7.1.2/lib/rails/command.rb:69:in `invoke'
        from /Users/user/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/railties-7.1.2/lib/rails/commands.rb:18:in `<top (required)>'
        from <internal:/Users/user/.rbenv/versions/3.2.2/lib/ruby/site_ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:38:in `require'
        from <internal:/Users/user/.rbenv/versions/3.2.2/lib/ruby/site_ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:38:in `require'
        from bin/rails:4:in `<main>'

Temporary Workaround

I temporarily reverted to version 2.5.4 using the Gemfile:

gem 'anyway_config', '2.5.4'

Additional Context

N/A

Environment Details

palkan commented 10 months ago

Thanks for the report!

I cannot reproduce in my env (which is the same), so it will require some investigation.

Which dependency loads anyway_config? Probably, it's not doing this the right way.

One thing that should help is adding anyway_config to the Gemfile (or adding require "anyway_config" right before Bundler.require(...)). If that doesn't help then continue with the following debug instructions.

It would be helpful to see the output of the following commands:

ls -al "$(bundle info anyway_config --path)/lib"
ls -al "$(bundle info anyway_config --path)/lib/.rbnext"

Also, adding the following before the line that fails would be useful, too:

puts $LOAD_PATH.grep(/anyway_config/)
bbraga commented 10 months ago

I suspect the issue might be related to the anycable-rails gem. Below are some excerpts from my Gemfile and Gemfile.lock. Notably, anyway_config is a direct dependency of anycable-core.

Gemfile:

# ...
# GRPC system in Ruby (https://github.com/google/grpc/tree/master/src/ruby)
gem 'grpc', platforms: ['ruby']
# Protocol Buffers (https://developers.google.com/protocol-buffers)
gem 'google-protobuf', platforms: ['ruby']
# Rails adapter for AnyCable (http://github.com/anycable/anycable-rails)
gem 'anycable-rails', '~> 1.0', platforms: ['ruby']

Gemfile.lock:

(...)
anycable (1.4.3)
  anycable-core (= 1.4.3)
  google-protobuf (~> 3.23)
  grpc (~> 1.53)
anycable-core (1.4.3)
  anyway_config (~> 2.2)
  google-protobuf (>= 3.13)
anycable-rails (1.4.3)
  anycable
  anycable-rails-core (= 1.4.3)
anycable-rails-core (1.4.3)
  actioncable (>= 6.0)
  anycable-core (~> 1.4)
  globalid
anyway_config (2.6.0)
  ruby-next-core (>= 0.15)
(...)

After updating to anyway_config 2.6.0, I ran the following commands:

ls -al "$(bundle info anyway_config --path)/lib"
ls -al "$(bundle info anyway_config --path)/lib/.rbnext"

Output:

total 16
drwxr-xr-x   8 user  staff   256 Dec 19 11:21 .
drwxr-xr-x   7 user  staff   224 Dec 19 11:21 ..
drwxr-xr-x   8 user  staff   256 Dec 19 11:21 .rbnext
drwxr-xr-x  23 user  staff   736 Dec 19 11:21 anyway
-rw-r--r--   1 user  staff    55 Dec 19 11:21 anyway.rb
-rw-r--r--   1 user  staff  1224 Dec 19 11:21 anyway_config.rb
drwxr-xr-x   3 user  staff    96 Dec 19 11:21 generators
drwxr-xr-x   3 user  staff    96 Dec 19 11:21 rails

.rbnext directory contents:

total 0
drwxr-xr-x  8 user  staff  256 Dec 19 11:21 .
drwxr-xr-x  8 user  staff  256 Dec 19 11:21 ..
drwxr-xr-x  3 user  staff   96 Dec 19 11:21 2.6
drwxr-xr-x  3 user  staff   96 Dec 19 11:21 2.7
drwxr-xr-x  3 user  staff   96 Dec 19 11:21 3.0
drwxr-xr-x  3 user  staff   96 Dec 19 11:21 3.1
drwxr-xr-x  3 user  staff   96 Dec 19 11:21 3.2
drwxr-xr-x  3 user  staff   96 Dec 19 11:21 3.4

Finally, here's the $LOAD_PATH:

rails c
LOADPATH: ["/Users/user/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/anyway_config-2.6.0/lib"]

However, I encountered the following error:

/Users/user/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/anyway_config-2.6.0/lib/anyway/config.rb:158:in `block in on_load': undefined local variable or method `it' for Anyway::Config:Class (NameError)

  load_callbacks.push(*names.map { NamedCallback.new(it) })

 ^^
(from /Users/user/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/anyway_config-2.6.0/lib/anyway/config.rb:158)
...

This error occurs during the Rails console startup process.

palkan commented 10 months ago

What's your ruby-next version? Try bundle update ruby-next-core (it must update it to 1.0.x); I think, the reason is that older Ruby Next doesn't know about Ruby 3.4 and doesn't add it to the LOAD_PATH (we should see two paths for anyway_config).

palkan commented 10 months ago

Or upgrade to just released 2.6.1 (which was just released).