From 08f6196bdac6b53df35caa5810839d28100d073c Mon Sep 17 00:00:00 2001 From: Gustavo Ribeiro Date: Thu, 22 Dec 2022 15:24:34 -0300 Subject: [PATCH] [rubygems/rubygems] add global flag (-C) to change execution directory https://github.com/rubygems/rubygems/commit/312fc36711 --- lib/rubygems/command.rb | 6 +++- lib/rubygems/command_manager.rb | 21 +++++++++--- test/rubygems/test_gem_command_manager.rb | 40 +++++++++++++++++++++++ 3 files changed, 62 insertions(+), 5 deletions(-) diff --git a/lib/rubygems/command.rb b/lib/rubygems/command.rb index badc21023a..f4688d793b 100644 --- a/lib/rubygems/command.rb +++ b/lib/rubygems/command.rb @@ -630,7 +630,11 @@ RubyGems is a package manager for Ruby. Usage: gem -h/--help gem -v/--version - gem command [arguments...] [options...] + gem [global options...] command [arguments...] [options...] + + Global options: + -C PATH run as if gem was started in + instead of the current working directory Examples: gem install rake diff --git a/lib/rubygems/command_manager.rb b/lib/rubygems/command_manager.rb index 8d31d85b44..1bdbd50530 100644 --- a/lib/rubygems/command_manager.rb +++ b/lib/rubygems/command_manager.rb @@ -175,14 +175,20 @@ class Gem::CommandManager when "-v", "--version" then say Gem::VERSION terminate_interaction 0 + when "-C" then + args.shift + start_point = args.shift + if Dir.exist?(start_point) + Dir.chdir(start_point) { invoke_command(args, build_args) } + else + alert_error clean_text("#{start_point} isn't a directory.") + terminate_interaction 1 + end when /^-/ then alert_error clean_text("Invalid option: #{args.first}. See 'gem --help'.") terminate_interaction 1 else - cmd_name = args.shift.downcase - cmd = find_command cmd_name - cmd.deprecation_warning if cmd.deprecated? - cmd.invoke_with_build_args args, build_args + invoke_command(args, build_args) end end @@ -237,4 +243,11 @@ class Gem::CommandManager ui.backtrace e end end + + def invoke_command(args, build_args) + cmd_name = args.shift.downcase + cmd = find_command cmd_name + cmd.deprecation_warning if cmd.deprecated? + cmd.invoke_with_build_args args, build_args + end end diff --git a/test/rubygems/test_gem_command_manager.rb b/test/rubygems/test_gem_command_manager.rb index 0b533329a9..6b34156187 100644 --- a/test/rubygems/test_gem_command_manager.rb +++ b/test/rubygems/test_gem_command_manager.rb @@ -126,6 +126,46 @@ class TestGemCommandManager < Gem::TestCase @command_manager.unregister_command :crash end + def test_process_args_with_c_flag + custom_start_point = File.join @tempdir, "nice_folder" + FileUtils.mkdir_p custom_start_point + + execution_path = nil + use_ui @ui do + @command_manager[:install].when_invoked do + execution_path = Dir.pwd + true + end + @command_manager.process_args %W[-C #{custom_start_point} install net-scp-4.0.0.gem --local] + end + + assert_equal custom_start_point, execution_path + end + + def test_process_args_with_c_flag_without_path + use_ui @ui do + assert_raise Gem::MockGemUi::TermError do + @command_manager.process_args %w[-C install net-scp-4.0.0.gem --local] + end + end + + assert_match(/install isn't a directory./i, @ui.error) + end + + def test_process_args_with_c_flag_path_not_found + custom_start_point = File.join @tempdir, "nice_folder" + FileUtils.mkdir_p custom_start_point + custom_start_point.tr!("_", "-") + + use_ui @ui do + assert_raise Gem::MockGemUi::TermError do + @command_manager.process_args %W[-C #{custom_start_point} install net-scp-4.0.0.gem --local] + end + end + + assert_match(/#{custom_start_point} isn't a directory./i, @ui.error) + end + def test_process_args_bad_arg use_ui @ui do assert_raise Gem::MockGemUi::TermError do