Skip to content

Commit 4fe882e

Browse files
deivid-rodriguezhsbt
authored andcommitted
[rubygems/rubygems] Let gem exec raise an error in ambiguous cases
When `gem exec foo` is run, and "foo" is a gem that has multiple executables, none of them named "foo", raise an error explaining the situation and telling user to be more specific. Currently the first command in the executables array is run, but this may come as surprising sometimes, so better raise an error. ruby/rubygems@acda5d8f6e
1 parent ee7cfb1 commit 4fe882e

File tree

2 files changed

+20
-8
lines changed

2 files changed

+20
-8
lines changed

lib/rubygems/commands/exec_command.rb

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ def load!
195195
argv = ARGV.clone
196196
ARGV.replace options[:args]
197197

198-
exe = executable = options[:executable]
198+
executable = options[:executable]
199199

200200
contains_executable = Gem.loaded_specs.values.select do |spec|
201201
spec.executables.include?(executable)
@@ -206,13 +206,22 @@ def load!
206206
end
207207

208208
if contains_executable.empty?
209-
if (spec = Gem.loaded_specs[executable]) && (exe = spec.executable)
210-
contains_executable << spec
211-
else
209+
spec = Gem.loaded_specs[executable]
210+
211+
if spec.nil? || spec.executables.empty?
212212
alert_error "Failed to load executable `#{executable}`," \
213213
" are you sure the gem `#{options[:gem_name]}` contains it?"
214214
terminate_interaction 1
215215
end
216+
217+
if spec.executables.size > 1
218+
alert_error "Ambiguous which executable from gem `#{executable}` should be run: " \
219+
"the options are #{spec.executables}, specify one via COMMAND, and use `-g` and `-v` to specify gem and version"
220+
terminate_interaction 1
221+
end
222+
223+
contains_executable << spec
224+
executable = spec.executable
216225
end
217226

218227
if contains_executable.size > 1
@@ -223,8 +232,8 @@ def load!
223232
end
224233

225234
old_exe = $0
226-
$0 = exe
227-
load Gem.activate_bin_path(contains_executable.first.name, exe, ">= 0.a")
235+
$0 = executable
236+
load Gem.activate_bin_path(contains_executable.first.name, executable, ">= 0.a")
228237
ensure
229238
$0 = old_exe if old_exe
230239
ARGV.replace argv

test/rubygems/test_gem_commands_exec_command.rb

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -370,8 +370,11 @@ def test_gem_with_multiple_executables_no_match
370370
util_clear_gems
371371

372372
use_ui @ui do
373-
@cmd.invoke "a:2"
374-
assert_equal "a-2 foo\n", @ui.output
373+
e = assert_raise Gem::MockGemUi::TermError do
374+
@cmd.invoke "a:2"
375+
end
376+
assert_equal 1, e.exit_code
377+
assert_equal "ERROR: Ambiguous which executable from gem `a` should be run: the options are [\"foo\", \"bar\"], specify one via COMMAND, and use `-g` and `-v` to specify gem and version\n", @ui.error
375378
end
376379
end
377380

0 commit comments

Comments
 (0)