I got back to looking at HomeBrew today. Something I noticed last week, though, was that HomeBrew was always using the system ruby, even when I’m using rbenv to set a global ruby. I decided to take an hour or two out to figure out why that was happening.
Last week, I spent some time figuring out how HomeBrew does command loading. It’s pretty simple: there’s the brew command, which is a shell script, and mostly it sets some variables and dispatches to Library/brew.sh.
brew.sh sets up a whole bunch of the HomeBrew environment stuff, then it attempts to find a shell version of the command you’ve asked for. If a shell implementation can’t be found, it dispatches to this:
{ update-preinstall; exec "$HOMEBREW_RUBY_PATH" -W0 "$HOMEBREW_LIBRARY/brew.rb" "$@"; }
brew.rb attempt to find a ruby implementation of the command you’re looking for.
So, it looked like $HOMEBREW_RUBY_PATH is probably the thing that I need to research. How does it get set? In brew.sh, we can see the following code:
if [[ -z "$HOMEBREW_RUBY_PATH" ]] then if [[ -n "$HOMEBREW_OSX" ]] then HOMEBREW_RUBY_PATH="$(which ruby)" else HOMEBREW_RUBY_PATH="/System/Library/Frameworks/Ruby.framework/Versions/Current/usr/bin/ruby" if [[ -z "$HOMEBREW_RUBY_PATH" ]] then odie "No Ruby found, cannot proceed." fi fi fi
What’s super cool here is that we can see that on Max OS X, there’s an explicit requirement to use the system ruby. Rbenv and the like aren’t even _asked_ about what ruby they’re providing. As an aside, any budding hackers who’re interested may want to inject support for rbenv here.
What problem is this addressing? I suspect that the homebrew devs don’t want to have to support multiple versions of ruby on OS X. In fact, the commit that implements this reads:
Replace /usr/bin/ruby with full Framework path Rationale: some users insist on replacing the /usr/bin/ruby symlink to point to another ruby on their system, which may break homebrew. Use the full Framework path instead, which is less likely to be tampered with. This also reorganizes the brew --config checks to reflect the different path. Fixes Homebrew/homebrew#12009. Closes Homebrew/homebrew#12333.
To see why this was implemented, I checked the issues noted in the git log message.
https://github.com/Homebrew/legacy-homebrew/issues/12009
That all seems reasonable enough. I had wondered if this was an issue of trying to reduce maintenance overhead, and it appears that it was.