Open jfirebaugh opened 3 years ago
I found this upstream issue with symlinked directories, which was fixed, but it seems Ruby still has issues when require
and require_relative
are mixed with symlinked files.
mkdir a
echo "require_relative 'b'" > a/a.rb
echo "p 'b loaded'" > a/b.rb
mkdir b
ln -s ../a/a.rb b
ln -s ../a/b.rb b
echo "$: << File.expand_path('../b', __FILE__); require 'b'; require 'a'" > c.rb
ruby c.rb
This results in "b loaded" being printed twice.
I opened a new upstream issue: https://bugs.ruby-lang.org/issues/17885.
Great thanks for reporting it.
I agree this is a Ruby issue, not the rules. In general I've been avoiding require_relative
in my open source gems because of similar issues with resolution caching.
Does it make sense to keep this open, or can we close this issue?
Do you think there's any possibility of working around the issue within rules_ruby? As it stands, at least one rather essential gem in the Ruby ecosystem uses require_relative
extensively (rack), and there doesn't seem to be much momentum around getting the upstream issue resolved. It seems like the status quo would limit the adoption of rules_ruby and it might be worth avoiding filesystem structures that trigger the issue. (I ask this not knowing much about the internal constraints of rules_ruby, so I'm also prepared to accept that it isn't feasible or would be too much work.)
So the result is that it breaks anything that relies on rack?
Any chance you could submit a new example under the examples/rack
that would fail as you describe?
Looking for additional core maintainers: https://github.com/bazelruby/rules_ruby/discussions/146
Minimal reproduction: repro.zip
If you run
bazel run :main
in this workspace, you will get output which includes the following:I debugged a bit by placing a
puts caller
insiderack.rb
. It gets required via two call stacks:main.rb:1
, resolved as<outputBase>/execroot/__main__/bazel-out/darwin-fastbuild/bin/main.runfiles/bundle/lib/ruby/2.6.0/gems/rack-2.2.3/lib/rack.rb
require_relative
inrack/session/abstract/id.rb
, resolved as<outputBase>/external/bundle/lib/ruby/2.6.0/gems/rack-2.2.3/lib/rack.rb:20
It appears that
require_relative
is resolving the require relative to the resolved symlink location in bazel'sexternal
directory, rather than the runfiles location where the direct require was resolved to.