From efb6ce9e1cd3454fef9fc11648a5f3ba76dd657d Mon Sep 17 00:00:00 2001 From: Ilya Savitsky Date: Mon, 15 Jun 2026 22:09:30 +0100 Subject: [PATCH] init: pin Ruby interpreter in shell wrappers Use `RbConfig.ruby` to embed the absolute path of the current Ruby interpreter in the generated shell wrappers. This ensures the wrapper works in environments where Ruby is not on `$PATH` (such as NixOS). --- spec/init_spec.md | 16 +++++++++++----- try.rb | 8 +++++--- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/spec/init_spec.md b/spec/init_spec.md index 6e61448..4fb3c54 100644 --- a/spec/init_spec.md +++ b/spec/init_spec.md @@ -24,7 +24,7 @@ Supported shells: ```bash try() { local out - out=$('/path/to/try' exec --path '/default/tries/path' "$@" 2>/dev/tty) + out=$('/path/to/ruby' '/path/to/try' exec --path '/default/tries/path' "$@" 2>/dev/tty) if [ $? -eq 0 ]; then eval "$out" else @@ -35,6 +35,9 @@ try() { Key elements: - Function name: `try` +- Pins the Ruby interpreter that was used to run `init` (via `RbConfig.ruby`), so the + function works even when Ruby is not on `$PATH` (e.g. NixOS, where Ruby only exists + inside the `try` package's wrapper) - Captures `try exec` output to local variable - Redirects stderr to `/dev/tty` (TUI renders to stderr) - Exit code 0: Evaluates the output (executes cd, git clone, etc.) @@ -44,7 +47,7 @@ Key elements: ```fish function try - set -l out (/path/to/try exec --path '/default/tries/path' $argv 2>/dev/tty | string collect) + set -l out ('/path/to/ruby' '/path/to/try' exec --path '/default/tries/path' $argv 2>/dev/tty | string collect) if test $pipestatus[1] -eq 0 eval $out else @@ -56,10 +59,13 @@ end ## Path Embedding The init output must embed: -1. The full path to the `try` binary (resolved at init time) -2. The default tries path (typically `~/src/tries`) +1. The absolute path to the Ruby interpreter that ran `init` (`RbConfig.ruby`), + resolved at init time so the function does not depend on Ruby being in `$PATH` +2. The full path to the `try` script (resolved at init time) +3. The default tries path (typically `~/src/tries`) -This ensures the wrapper always calls the correct binary regardless of `$PATH` changes. +This ensures the wrapper always calls the correct binary and interpreter regardless +of `$PATH` changes. ## Installation Instructions diff --git a/try.rb b/try.rb index d966f80..f4a7b50 100755 --- a/try.rb +++ b/try.rb @@ -1263,12 +1263,14 @@ def shell_rc_file(shell) end def init_snippet(shell, script_path, explicit_path, default_path) + require 'rbconfig' + ruby_bin = RbConfig.ruby case shell when 'fish' fish_path_arg = explicit_path ? " --path '#{explicit_path}'" : " --path (if set -q TRY_PATH; echo \"$TRY_PATH\"; else; echo '#{default_path}'; end)" <<~FISH function try - set -l out (/usr/bin/env ruby '#{script_path}' exec#{fish_path_arg} $argv 2>/dev/tty | string collect) + set -l out ('#{ruby_bin}' '#{script_path}' exec#{fish_path_arg} $argv 2>/dev/tty | string collect) if test $pipestatus[1] -eq 0 eval $out else @@ -1286,7 +1288,7 @@ def init_snippet(shell, script_path, explicit_path, default_path) function try { $tryPath = #{ps_path_expr} $tempErr = [System.IO.Path]::GetTempFileName() - $out = & ruby '#{script_path}' exec --path $tryPath @args 2>$tempErr + $out = & '#{ruby_bin}' '#{script_path}' exec --path $tryPath @args 2>$tempErr if ($LASTEXITCODE -eq 0) { $out | Invoke-Expression } else { @@ -1301,7 +1303,7 @@ def init_snippet(shell, script_path, explicit_path, default_path) <<~SH try() { local out - out=$(/usr/bin/env ruby '#{script_path}' exec#{path_arg} "$@" 2>/dev/tty) + out=$('#{ruby_bin}' '#{script_path}' exec#{path_arg} "$@" 2>/dev/tty) if [ $? -eq 0 ]; then eval "$out" else