Bug #16680
closedSymlink folder in $LOAD_PATH does not work with autoload
Description
The following is a full reproducible process. I will use a gem named 'looksee' to reproduce this.
-
Do
gem install looksee
-
Go to
gem
folder and copylib
content into/tmp/test_looksee
so that we have a folder like this:╰─ $ tree /tmp/test_looksee /tmp/test_looksee └── lib ├── looksee │ ├── adapter │ │ ├── base.rb │ │ └── rubinius.rb │ ├── adapter.rb │ ├── clean.rb │ ├── columnizer.rb │ ├── core_ext.rb │ ├── editor.rb │ ├── help.rb │ ├── inspector.rb │ ├── lookup_path.rb │ ├── mri.so │ └── version.rb └── looksee.rb
-
Create a new symlink to this folder.
╰─ $ln -s /tmp/test_looksee /tmp/test_looksee1 ╰─ $ ls -alhd /tmp/test_looksee* drwxr-xr-x 3 zw963 zw963 60 2020-03-08 01:39 /tmp/test_looksee/ lrwxrwxrwx 1 zw963 zw963 13 2020-03-08 02:08 /tmp/test_looksee1 -> test_looksee//
-
Run the following command to reproduce this issue.
╰─ $ ruby -I/tmp/test_looksee1/lib/ -rlooksee -e 'puts 100' Traceback (most recent call last): 10: from /home/zw963/others/.rvm/rubies/ruby-2.7.0/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:72:in `require' 9: from /home/zw963/others/.rvm/rubies/ruby-2.7.0/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:72:in `require' 8: from /tmp/test_looksee1/lib/looksee.rb:1:in `<top (required)>' 7: from /home/zw963/others/.rvm/rubies/ruby-2.7.0/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:72:in `require' 6: from /home/zw963/others/.rvm/rubies/ruby-2.7.0/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:72:in `require' 5: from /tmp/test_looksee1/lib/looksee/clean.rb:4:in `<top (required)>' 4: from /tmp/test_looksee1/lib/looksee/clean.rb:171:in `<module:Looksee>' 3: from /home/zw963/others/.rvm/rubies/ruby-2.7.0/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:72:in `require' 2: from /home/zw963/others/.rvm/rubies/ruby-2.7.0/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:72:in `require' 1: from /tmp/test_looksee1/lib/looksee/adapter.rb:1:in `<top (required)>'
/tmp/test_looksee1/lib/looksee/adapter.rb:2:in `module:Looksee': uninitialized constant Looksee::Adapter (NameError)
```
You may want to ask why use symlinks folder in $LOAD_PATH
. I think this is a quite common case; many ruby developers have a local gem not managed by Rubygems
or Bundler
. They just use $LOAD_PATH
to require
/load
it, and it is hard to ensure everyone's folder is not a symlink.
I think this is a breaking change. All those codes worked quite well before 2.7 because old codes always
follow symlinks. The following is an example from ruby 2.6.3, which works.
╰─ $ ruby -I/tmp/test_looksee1/lib/ -rlooksee -e 'puts 100'
Traceback (most recent call last):
8: from /home/zw963/others/.rvm/rubies/ruby-2.6.3/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'
7: from /home/zw963/others/.rvm/rubies/ruby-2.6.3/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'
6: from /tmp/test_looksee/lib/looksee.rb:1:in `<top (required)>'
5: from /home/zw963/others/.rvm/rubies/ruby-2.6.3/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'
4: from /home/zw963/others/.rvm/rubies/ruby-2.6.3/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'
3: from /tmp/test_looksee/lib/looksee/clean.rb:4:in `<top (required)>'
2: from /tmp/test_looksee/lib/looksee/clean.rb:171:in `<module:Looksee>'
1: from /home/zw963/others/.rvm/rubies/ruby-2.6.3/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'
/home/zw963/others/.rvm/rubies/ruby-2.6.3/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require': incompatible library version - /tmp/test_looksee/lib/looksee/mri.so (LoadError)
As we can seen, those breaking codes come from autoload :Adapter, 'looksee/adapter'
. I suspect
maybe this is caused by nested autoload. But this is only a guess, please check. Thank you.
Files