From 4b9b586b72b54d38a31af4c1122dbb6db69d924c Mon Sep 17 00:00:00 2001 From: bronzdoc Date: Wed, 30 Sep 2020 12:24:54 -0600 Subject: [PATCH 1/7] Find the gemspec and build the gem in the correct context --- lib/rubygems/commands/build_command.rb | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/lib/rubygems/commands/build_command.rb b/lib/rubygems/commands/build_command.rb index 84faef2b82e4..5a92be84f66d 100644 --- a/lib/rubygems/commands/build_command.rb +++ b/lib/rubygems/commands/build_command.rb @@ -61,6 +61,14 @@ def usage # :nodoc: end def execute + if build_path = options[:build_path] + Dir.chdir(build_path) do + gem_name = get_one_optional_argument || find_gemspec + build_gem(gem_name) + end + return + end + gem_name = get_one_optional_argument || find_gemspec build_gem(gem_name) end @@ -83,16 +91,7 @@ def build_gem(gem_name) if File.exist?(gemspec) spec = Gem::Specification.load(gemspec) - - if options[:build_path] - Dir.chdir(File.dirname(gemspec)) do - spec = Gem::Specification.load(File.basename(gemspec)) - build_package(spec) - end - else - build_package(spec) - end - + build_package(spec) else alert_error "Gemspec file not found: #{gemspec}" terminate_interaction(1) From be9535b62da8299f9a45169a32fb043faef237d5 Mon Sep 17 00:00:00 2001 From: bronzdoc Date: Wed, 30 Sep 2020 12:25:52 -0600 Subject: [PATCH 2/7] Test when using the --C flag and no argument given --- .../test_gem_commands_build_command.rb | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/test/rubygems/test_gem_commands_build_command.rb b/test/rubygems/test_gem_commands_build_command.rb index 53916eb11b91..f19aa0639787 100644 --- a/test/rubygems/test_gem_commands_build_command.rb +++ b/test/rubygems/test_gem_commands_build_command.rb @@ -272,6 +272,47 @@ def test_execute_outside_dir assert_equal "this is a summary", spec.summary end + def test_execute_outside_dir_without_gem_name + gemspec_dir = File.join(@tempdir, 'build_command_gem') + gemspec_file = File.join(gemspec_dir, @gem.spec_name) + + readme_file = File.join gemspec_dir, 'README.md' + + FileUtils.mkdir_p(gemspec_dir) + + File.open readme_file, 'w' do |f| + f.write "My awesome gem" + end + + File.open(gemspec_file, "w") do |gs| + gs.write(@gem.to_ruby) + end + + @cmd.options[:build_path] = gemspec_dir + @cmd.options[:args] = [] + + use_ui @ui do + Dir.chdir(gemspec_dir) do + @cmd.execute + end + end + + output = @ui.output.split("\n") + assert_equal " Successfully built RubyGem", output.shift + assert_equal " Name: some_gem", output.shift + assert_equal " Version: 2", output.shift + assert_equal " File: some_gem-2.gem", output.shift + assert_equal [], output + + gem_file = File.join gemspec_dir, File.basename(@gem.cache_file) + assert File.exist?(gem_file) + + spec = Gem::Package.new(gem_file).spec + + assert_equal "some_gem", spec.name + assert_equal "this is a summary", spec.summary + end + def test_can_find_gemspecs_without_dot_gemspec gemspec_file = File.join(@tempdir, @gem.name) From 04090e9e4a23bd88a330b1a0b46521c1a67efa82 Mon Sep 17 00:00:00 2001 From: bronzdoc Date: Wed, 30 Sep 2020 12:26:58 -0600 Subject: [PATCH 3/7] Improve gemspec search --- lib/rubygems/commands/build_command.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/rubygems/commands/build_command.rb b/lib/rubygems/commands/build_command.rb index 5a92be84f66d..ac7134960b8f 100644 --- a/lib/rubygems/commands/build_command.rb +++ b/lib/rubygems/commands/build_command.rb @@ -87,7 +87,7 @@ def find_gemspec end def build_gem(gem_name) - gemspec = File.extname(gem_name) == ".gemspec" ? gem_name : "#{gem_name}.gemspec" + gemspec = Dir.glob(gem_name).sort.first || "#{gem_name}.gemspec" if File.exist?(gemspec) spec = Gem::Specification.load(gemspec) From 9402cf8e498b2225c9b46a9e9e63fcbe6b5574ac Mon Sep 17 00:00:00 2001 From: bronzdoc Date: Wed, 30 Sep 2020 13:37:19 -0600 Subject: [PATCH 4/7] Test gem build with a glob argument and outside dir --- .../test_gem_commands_build_command.rb | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/test/rubygems/test_gem_commands_build_command.rb b/test/rubygems/test_gem_commands_build_command.rb index f19aa0639787..b140f80a72cf 100644 --- a/test/rubygems/test_gem_commands_build_command.rb +++ b/test/rubygems/test_gem_commands_build_command.rb @@ -272,6 +272,44 @@ def test_execute_outside_dir assert_equal "this is a summary", spec.summary end + def test_execute_outside_dir_with_glob_argument + gemspec_dir = File.join @tempdir, 'build_command_gem' + gemspec_file = File.join gemspec_dir, @gem.spec_name + readme_file = File.join gemspec_dir, 'README.md' + + FileUtils.mkdir_p gemspec_dir + + File.open readme_file, 'w' do |f| + f.write "My awesome gem" + end + + File.open gemspec_file, 'w' do |gs| + gs.write @gem.to_ruby + end + + @cmd.options[:build_path] = gemspec_dir + @cmd.options[:args] = ["*.gemspec"] + + use_ui @ui do + @cmd.execute + end + + output = @ui.output.split "\n" + assert_equal " Successfully built RubyGem", output.shift + assert_equal " Name: some_gem", output.shift + assert_equal " Version: 2", output.shift + assert_equal " File: some_gem-2.gem", output.shift + assert_equal [], output + + gem_file = File.join gemspec_dir, File.basename(@gem.cache_file) + assert File.exist?(gem_file) + + spec = Gem::Package.new(gem_file).spec + + assert_equal "some_gem", spec.name + assert_equal "this is a summary", spec.summary + end + def test_execute_outside_dir_without_gem_name gemspec_dir = File.join(@tempdir, 'build_command_gem') gemspec_file = File.join(gemspec_dir, @gem.spec_name) From bdc72f08cfd23db6600682f40572d42fe4e48b9b Mon Sep 17 00:00:00 2001 From: bronzdoc Date: Wed, 30 Sep 2020 13:49:05 -0600 Subject: [PATCH 5/7] Test outside dir and no gemspec is present --- lib/rubygems/commands/build_command.rb | 3 ++ .../test_gem_commands_build_command.rb | 31 +++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/lib/rubygems/commands/build_command.rb b/lib/rubygems/commands/build_command.rb index ac7134960b8f..d8aeb49223b1 100644 --- a/lib/rubygems/commands/build_command.rb +++ b/lib/rubygems/commands/build_command.rb @@ -92,6 +92,9 @@ def build_gem(gem_name) if File.exist?(gemspec) spec = Gem::Specification.load(gemspec) build_package(spec) + elsif gemspec.scan(".gemspec").size > 1 + alert_error "No Gemspec in #{Dir.pwd}" + terminate_interaction(1) else alert_error "Gemspec file not found: #{gemspec}" terminate_interaction(1) diff --git a/test/rubygems/test_gem_commands_build_command.rb b/test/rubygems/test_gem_commands_build_command.rb index b140f80a72cf..167752eec2a1 100644 --- a/test/rubygems/test_gem_commands_build_command.rb +++ b/test/rubygems/test_gem_commands_build_command.rb @@ -310,6 +310,37 @@ def test_execute_outside_dir_with_glob_argument assert_equal "this is a summary", spec.summary end + def test_execute_outside_dir_no_gemspec_present + gemspec_dir = File.join @tempdir, 'build_command_gem' + gemspec_file = File.join @tempdir, @gem.spec_name + readme_file = File.join gemspec_dir, 'README.md' + + FileUtils.mkdir_p gemspec_dir + + File.open readme_file, 'w' do |f| + f.write "My awesome gem" + end + + File.open gemspec_file, 'w' do |gs| + gs.write @gem.to_ruby + end + + @cmd.options[:build_path] = gemspec_dir + @cmd.options[:args] = ["*.gemspec"] + + use_ui @ui do + assert_raises Gem::MockGemUi::TermError do + @cmd.execute + end + end + + assert_equal "", @ui.output + assert_equal "ERROR: No Gemspec in #{gemspec_dir}\n", @ui.error + + gem_file = File.join gemspec_dir, File.basename(@gem.cache_file) + refute File.exist?(gem_file) + end + def test_execute_outside_dir_without_gem_name gemspec_dir = File.join(@tempdir, 'build_command_gem') gemspec_file = File.join(gemspec_dir, @gem.spec_name) From 67c5ae4a6f4701e296f5fb217e96d23a29dff586 Mon Sep 17 00:00:00 2001 From: bronzdoc Date: Sat, 31 Oct 2020 09:07:27 -0600 Subject: [PATCH 6/7] Refactor and improve error message --- lib/rubygems/commands/build_command.rb | 51 ++++++++++++------- .../test_gem_commands_build_command.rb | 4 +- 2 files changed, 35 insertions(+), 20 deletions(-) diff --git a/lib/rubygems/commands/build_command.rb b/lib/rubygems/commands/build_command.rb index d8aeb49223b1..fff5f7c76fab 100644 --- a/lib/rubygems/commands/build_command.rb +++ b/lib/rubygems/commands/build_command.rb @@ -62,21 +62,17 @@ def usage # :nodoc: def execute if build_path = options[:build_path] - Dir.chdir(build_path) do - gem_name = get_one_optional_argument || find_gemspec - build_gem(gem_name) - end + Dir.chdir(build_path) { build_gem } return end - gem_name = get_one_optional_argument || find_gemspec - build_gem(gem_name) + build_gem end private - def find_gemspec - gemspecs = Dir.glob("*.gemspec").sort + def find_gemspec(glob = "*.gemspec") + gemspecs = Dir.glob(glob).sort if gemspecs.size > 1 alert_error "Multiple gemspecs found: #{gemspecs}, please specify one" @@ -86,22 +82,19 @@ def find_gemspec gemspecs.first end - def build_gem(gem_name) - gemspec = Dir.glob(gem_name).sort.first || "#{gem_name}.gemspec" + def build_gem + gemspec = resolve_gem_name - if File.exist?(gemspec) - spec = Gem::Specification.load(gemspec) - build_package(spec) - elsif gemspec.scan(".gemspec").size > 1 - alert_error "No Gemspec in #{Dir.pwd}" - terminate_interaction(1) + if gemspec + build_package(gemspec) else - alert_error "Gemspec file not found: #{gemspec}" + alert_error error_message terminate_interaction(1) end end - def build_package(spec) + def build_package(gemspec) + spec = Gem::Specification.load(gemspec) if spec Gem::Package.build( spec, @@ -114,4 +107,26 @@ def build_package(spec) terminate_interaction 1 end end + + def resolve_gem_name + return find_gemspec unless gem_name + + if File.exist?(gem_name) + gem_name + else + find_gemspec("#{gem_name}.gemspec") || find_gemspec(gem_name) + end + end + + def error_message + if gem_name + "Couldn't find a gemspec file matching '#{gem_name}' in #{Dir.pwd}" + else + "Couldn't find a gemspec file in #{Dir.pwd}" + end + end + + def gem_name + get_one_optional_argument + end end diff --git a/test/rubygems/test_gem_commands_build_command.rb b/test/rubygems/test_gem_commands_build_command.rb index 167752eec2a1..472a06e8f962 100644 --- a/test/rubygems/test_gem_commands_build_command.rb +++ b/test/rubygems/test_gem_commands_build_command.rb @@ -231,7 +231,7 @@ def test_execute_missing_file end assert_equal '', @ui.output - assert_equal "ERROR: Gemspec file not found: some_gem.gemspec\n", @ui.error + assert_equal "ERROR: Couldn't find a gemspec file matching 'some_gem' in #{@tempdir}\n", @ui.error end def test_execute_outside_dir @@ -335,7 +335,7 @@ def test_execute_outside_dir_no_gemspec_present end assert_equal "", @ui.output - assert_equal "ERROR: No Gemspec in #{gemspec_dir}\n", @ui.error + assert_equal "ERROR: Couldn't find a gemspec file matching '*.gemspec' in #{gemspec_dir}\n", @ui.error gem_file = File.join gemspec_dir, File.basename(@gem.cache_file) refute File.exist?(gem_file) From a46c11b5bc871115bab26f5f7954daa43271f0ae Mon Sep 17 00:00:00 2001 From: bronzdoc Date: Sat, 31 Oct 2020 09:12:57 -0600 Subject: [PATCH 7/7] Add tests for external gemspecs --- .../test_gem_commands_build_command.rb | 82 +++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/test/rubygems/test_gem_commands_build_command.rb b/test/rubygems/test_gem_commands_build_command.rb index 472a06e8f962..fe537780be4b 100644 --- a/test/rubygems/test_gem_commands_build_command.rb +++ b/test/rubygems/test_gem_commands_build_command.rb @@ -382,6 +382,88 @@ def test_execute_outside_dir_without_gem_name assert_equal "this is a summary", spec.summary end + def test_execute_outside_dir_with_external_gemspec + gemspec_dir = File.join @tempdir, 'gemspec_dir' + gemspec_file = File.join gemspec_dir, @gem.spec_name + + gemcode_dir = File.join @tempdir, 'build_command_gem' + readme_file = File.join gemcode_dir, 'README.md' + + FileUtils.mkdir_p gemspec_dir + FileUtils.mkdir_p gemcode_dir + + File.open readme_file, 'w' do |f| + f.write "My awesome gem in nested directory" + end + + File.open gemspec_file, 'w' do |gs| + gs.write @gem.to_ruby + end + + @cmd.options[:build_path] = gemcode_dir + @cmd.options[:args] = [gemspec_file] + + use_ui @ui do + @cmd.execute + end + + output = @ui.output.split "\n" + assert_equal " Successfully built RubyGem", output.shift + assert_equal " Name: some_gem", output.shift + assert_equal " Version: 2", output.shift + assert_equal " File: some_gem-2.gem", output.shift + assert_equal [], output + + gem_file = File.join gemcode_dir, File.basename(@gem.cache_file) + assert File.exist?(gem_file) + + spec = Gem::Package.new(gem_file).spec + + assert_equal "some_gem", spec.name + assert_equal "this is a summary", spec.summary + end + + def test_execute_outside_dir_with_external_relative_gemspec + gemspec_dir = File.join @tempdir, 'gemspec_dir' + gemspec_file = File.join gemspec_dir, @gem.spec_name + + gemcode_dir = File.join @tempdir, 'build_command_gem' + readme_file = File.join gemcode_dir, 'README.md' + + FileUtils.mkdir_p gemspec_dir + FileUtils.mkdir_p gemcode_dir + + File.open readme_file, 'w' do |f| + f.write "My awesome gem in nested directory" + end + + File.open gemspec_file, 'w' do |gs| + gs.write @gem.to_ruby + end + + @cmd.options[:build_path] = gemcode_dir + @cmd.options[:args] = [File.join("..", "gemspec_dir", @gem.spec_name)] + + use_ui @ui do + @cmd.execute + end + + output = @ui.output.split "\n" + assert_equal " Successfully built RubyGem", output.shift + assert_equal " Name: some_gem", output.shift + assert_equal " Version: 2", output.shift + assert_equal " File: some_gem-2.gem", output.shift + assert_equal [], output + + gem_file = File.join gemcode_dir, File.basename(@gem.cache_file) + assert File.exist?(gem_file) + + spec = Gem::Package.new(gem_file).spec + + assert_equal "some_gem", spec.name + assert_equal "this is a summary", spec.summary + end + def test_can_find_gemspecs_without_dot_gemspec gemspec_file = File.join(@tempdir, @gem.name)