using "system" ruby fails as bazel is unable to access `@@rules_ruby~~ruby~ruby//:dist/bin/sudo`
Problem description
I set the following in my MODULE.bazel file
module(name = "myrepo", version = "0.0.0", repo_name = "myrepo")
bazel_dep(name = "rules_ruby", version = "0.10.0")
ruby = use_extension("@rules_ruby//ruby:extensions.bzl", "ruby")
ruby.toolchain(
name = "ruby",
version = "system",
)
use_repo(ruby, "ruby")
This yields 1002 targets!, and @ruby//:sudo is among them.
❯ bazel query @ruby//... | wc -l
Loading: 0 packages loaded
1002
❯ bazel query @ruby//...
@ruby//:AssetCacheLocatorUtil
<...SNIP...>
@ruby//:rmic
@ruby//:rmid
@ruby//:rmiregistry
@ruby//:rpcgen
@ruby//:rs
@ruby//:rsync
@ruby//:ruby
@ruby//:ruby_file
@ruby//:rview
@ruby//:rvim
<...SNIP...>
@ruby//:scp
@ruby//:screen
@ruby//:script
@ruby//:sdef
@ruby//:sdiff
@ruby//:sdp
@ruby//:sdx
@ruby//:security
@ruby//:sed
@ruby//:seeksize.d
<...SNIP...>
@ruby//:strip
@ruby//:su
@ruby//:sudo
@ruby//:sum
<...SNIP...>
However, we are unable to run the ruby target
❯ bazel run @ruby//:ruby -- --help
Starting local Bazel server and connecting to it...
INFO: Analyzed target @@rules_ruby~~ruby~ruby//:ruby (68 packages loaded, 1479 targets configured).
ERROR: /Volumes/BazelOut/_bazel_bassam/49638b6383ca98bc7c45c8f9c0c8e8c7/external/rules_ruby~~ruby~ruby/BUILD:14:10: @@rules_ruby~~ruby~ruby//:ruby: error reading file '@@rules_ruby~~ruby~ruby//:dist/bin/sudo': /Volumes/BazelOut/_bazel_bassam/49638b6383ca98bc7c45c8f9c0c8e8c7/external/rules_ruby~~ruby~ruby/dist/bin/sudo (Permission denied)
ERROR: /Volumes/BazelOut/_bazel_bassam/49638b6383ca98bc7c45c8f9c0c8e8c7/external/rules_ruby~~ruby~ruby/BUILD:14:10: 1 input file(s) are in error
Target @@rules_ruby~~ruby~ruby//:ruby failed to build
INFO: Elapsed time: 2.741s, Critical Path: 0.10s
INFO: 4 processes: 4 internal.
ERROR: Build did NOT complete successfully
ERROR: Build failed. Not running target
Looking at the source code, it appears the rules are symlinking the parent directory returned by which ruby
https://github.com/bazel-contrib/rules_ruby/blob/main/ruby/private/download.bzl#L232-L236
Instead of symlinking the directory where ruby is located, can the repository rule symlink only the required binaries, or maybe exclude sudo and other critical utilities from being created?
Host Information
-
Mac OS Sonoma 14.5
-
Chip: Apple M1 Pro
-
Ruby Locationa:
❯ which ruby /usr/bin/ruby ❯ which -a ruby /usr/bin/ruby
To be honest, I would like to avoid building special cases code for handling system-installed Ruby. The main reason is that it breaks Bazel's hermeticity so issues like that will be popping up. That's why system is only recommended if you know what you are doing - a much better option would be to let Bazel install Ruby for you. For advanced use cases when system is preferred, I would expect the user to install Ruby via rbenv/rvm, not to use the Ruby shipped by OS.
On the other hand, I could probably rework this to get path using RbConfig.ruby:
ruby -e "puts RbConfig.ruby"
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/bin/ruby