Skip to content

Commit

Permalink
Fix "rbenv: command not found" error when running rbenv:install (#447)
Browse files Browse the repository at this point in the history
Recently, tomo's `rbenv:install` task has started failing with this
output:

```
Installing ruby 3.3.0 -- this may take several minutes
CFLAGS=-O3 rbenv install 3.3.0 --verbose
bash: line 1: rbenv: command not found
```

This is because rbenv was recently updated[^1] to to automatically add
the `rbenv init` script to the `.bashrc` file during installation.

However, rbenv adds it to the _bottom_ of the file after the early-exit
that skips most of the `.bashrc` when it is sourced in a non-interactive
shell (i.e. tomo via SSH).

That left rbenv in an installed but broken state; hence the error.

Fix by having `rbenv:install` detect this situation and prepend the
`rbenv init` script to the _top_ of the file, where it will get loaded
for non-interactive shells such as tomo's.

[^1]: rbenv/rbenv-installer#50
  • Loading branch information
mattbrictson authored May 25, 2024
1 parent b780936 commit dfb0ebb
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 1 deletion.
2 changes: 1 addition & 1 deletion lib/tomo/plugin/rbenv/tasks.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def run_installer

def modify_bashrc
existing_rc = remote.capture("cat", paths.bashrc, raise_on_error: false)
return if existing_rc.include?("rbenv init")
return if existing_rc.include?("rbenv init") && existing_rc.include?("$HOME/.rbenv/bin")

remote.write(text: <<~BASHRC + existing_rc, to: paths.bashrc)
if [ -d $HOME/.rbenv ]; then
Expand Down
72 changes: 72 additions & 0 deletions test/tomo/plugin/rbenv/tasks_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,78 @@ def test_install_is_skipped_if_version_is_already_installed
assert_includes(tester.stdout, "Ruby 3.2.0-rc1 is already installed")
end

def test_install_prepends_to_bashrc_if_rbenv_init_exists_but_path_is_not_set
tester = configure(
rbenv_ruby_version: "3.1.3",
release_path: "/tmp/tomo/20201027184921"
)
tester.mock_script_result("cat .bashrc", stdout: <<~STDOUT)
# ~/.bashrc: executed by bash(1) for non-login shells.
# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
# for examples
# If not running interactively, don't do anything
case $- in
*i*) ;;
*) return;;
esac
# Added by `rbenv init` on Sat May 25 00:47:06 UTC 2024
eval "$(~/.rbenv/bin/rbenv init - bash)"
STDOUT

tester.run_task("rbenv:install")
assert_match(/> .bashrc/, tester.executed_scripts[2])
assert_match(<<~EXPECTED.shellescape, tester.executed_scripts[2])
if [ -d $HOME/.rbenv ]; then
export PATH="$HOME/.rbenv/bin:$PATH"
eval "$(rbenv init -)"
fi
# ~/.bashrc: executed by bash(1) for non-login shells.
# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
# for examples
# If not running interactively, don't do anything
case $- in
*i*) ;;
*) return;;
esac
# Added by `rbenv init` on Sat May 25 00:47:06 UTC 2024
eval "$(~/.rbenv/bin/rbenv init - bash)"
EXPECTED
end

def test_install_does_not_prepend_to_bashrc_if_rbenv_path_and_init_are_already_present
tester = configure(
rbenv_ruby_version: "3.1.3",
release_path: "/tmp/tomo/20201027184921"
)
tester.mock_script_result("cat .bashrc", stdout: <<~STDOUT)
if [ -d $HOME/.rbenv ]; then
export PATH="$HOME/.rbenv/bin:$PATH"
eval "$(rbenv init -)"
fi
# ~/.bashrc: executed by bash(1) for non-login shells.
# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
# for examples
# If not running interactively, don't do anything
case $- in
*i*) ;;
*) return;;
esac
# Added by `rbenv init` on Sat May 25 00:47:06 UTC 2024
eval "$(~/.rbenv/bin/rbenv init - bash)"
STDOUT

tester.run_task("rbenv:install")
assert_empty(tester.executed_scripts.grep(/> .bashrc/))
end

private

def configure(settings={})
Expand Down

0 comments on commit dfb0ebb

Please sign in to comment.