Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rbenv short circuits commands #1374

Closed
rjhornsby opened this issue Dec 21, 2021 · 4 comments
Closed

rbenv short circuits commands #1374

rjhornsby opened this issue Dec 21, 2021 · 4 comments

Comments

@rjhornsby
Copy link

rbenv seems to be short-circuiting system commands (ie curl, clear, openssl) if they're present in one rbenv, but not another:

$ rbenv version
3.0.2 (set by /Users/rhornsby/.rbenv/version)
$ clear
rbenv: clear: command not found

The `clear' command exists in these Ruby versions:
  3.0.2c

for clarity - 3.0.2c here is the chef/cinc bundled ruby (comes with a bunch of extra gems and other things to try to ship a complete system-independent environment), while 3.0.2 is a "clean" ruby used for non-chef ruby projects.

In this example, clear is both in the 3.0.2c path, and at /usr/bin/clear, but rbenv short-circuits that because while it doesn't see clear in this ruby environment, it sees it in another one - which means this ruby environment is the "problem" if you will. The same thing happens for commands like curl and openssl. Why does chef's ruby include clear and curl commands? I assume curl is to make sure it's available, but clear I have no idea.

If I had to come up with a solution, I think probably rbenv should let or try to let the shell fall back to the rest of the PATH env entries, or check to see if the command is available on the PATH outside of rbenv and redirect to it if possible, rather than "this rbenv doesn't have the command, but another one does, so this is an error -> exit with 127"

@jasonkarns
Copy link
Member

I think this is essentially a dupe of #187 and #865

@rjhornsby
Copy link
Author

It does look like a dupe of #187, good catch. There's an outstanding PR #1110 that purports to address the nearly 10 year old #187. If #1110 fixes it, can we get that merged please?

Creating symlinks in ~/.rbenv/versions/3.0.2/bin to the affected system binaries work, but are brittle and subject to being deleted if the comments on #187 are anything to go by. It also relies on tracking which commands are present in one rbenv but not another, across all installed rubies.

@mislav
Copy link
Member

mislav commented Dec 27, 2021

Thanks for raising, @jasonkarns. Closing as duplicate.

The reason why this hasn't been fixed after such a long time of being a known issue is that the fix isn't clear-cut. Simply falling back to PATH if an executable wasn't found in the current Ruby version might be a good solution to your problem, but would fundamentally go against the strict separation of versions that rbenv enforces. What if the current Ruby version does not have the bundle executable, but system PATH has one? The solution would absolutely not be to fall back to /usr/bin/bundle, since that would activate a Ruby version other than the currently selected one. In that case, the current behavior of erroring out is beneficial to the user.

Why do any Ruby gems or tooling install executables like clear, curl, and openssl? This is the crux of the problem, and not how rbenv works. These Ruby executables would shadow system ones even if no Ruby version manager was used in the first place. The solution would be to prevent Ruby tooling from putting those in, or in rbenv's case, to make an rbenv plugin that cleans up or otherwise ignores those executables when generating shims during its "rehash" process.

@mislav mislav closed this as completed Dec 27, 2021
@rjhornsby
Copy link
Author

@mislav thanks for taking the time to explain. I genuinely appreciate the insight you provided. I tend to agree with you that overriding clear (?!) and even curl is a bit much. I assume the idea is for the chef-bundled ruby to be an all-in-one package, with versions of everything chef's ruby needs to run, regardless of what the system may or may not provide. Not sure I'm a fan of the consequences, but it tries to address dependency+compatibility issues with as little friction across distros and platforms as they could.

Symlinks in .rbenv/versions/... are sub-optimal mostly because they're targets for getting deleted by rehash, but they do work and they do get around the problem - restoring broken functionality - with minimal effort. A proper rbenv plugin to handle this probably makes more sense in the longer term.

$ ls -l ~/.rbenv/versions/3.0.2/bin | grep '^l'
lrwxr-xr-x  1 rhornsby  staff     14 Dec 21 12:11 clear -> /usr/bin/clear
lrwxr-xr-x  1 rhornsby  staff     13 Dec 21 12:16 curl -> /usr/bin/curl
lrwxr-xr-x  1 rhornsby  staff     47 Dec 21 12:17 openssl -> /usr/local/Cellar/openssl@3/3.0.0_1/bin/openssl

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants