Skip to content

Commit

Permalink
Merge pull request #5737 from rubygems/fix-rubygems-upgrade-writing-o…
Browse files Browse the repository at this point in the history
…utside-of-destdir

Fix `ruby setup.rb` with `--destdir` writing outside of `--destdir`
  • Loading branch information
deivid-rodriguez committed Jul 20, 2022
2 parents a0884e0 + 5ed2753 commit 16db218
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 28 deletions.
8 changes: 4 additions & 4 deletions lib/rubygems/commands/setup_command.rb
Original file line number Diff line number Diff line change
Expand Up @@ -361,17 +361,17 @@ def fake_spec.full_gem_path

def install_default_bundler_gem(bin_dir)
current_default_spec = Gem::Specification.default_stubs.find {|s| s.name == "bundler" }
specs_dir = if current_default_spec
specs_dir = if current_default_spec && default_dir == Gem.default_dir
Gem::Specification.remove_spec current_default_spec
loaded_from = current_default_spec.loaded_from
File.delete(loaded_from)
File.dirname(loaded_from)
else
File.join(default_dir, "specifications", "default")
target_specs_dir = File.join(default_dir, "specifications", "default")
mkdir_p target_specs_dir, :mode => 0755
target_specs_dir
end

mkdir_p specs_dir, :mode => 0755

bundler_spec = Dir.chdir("bundler") { Gem::Specification.load("bundler.gemspec") }
default_spec_path = File.join(specs_dir, "#{bundler_spec.full_name}.gemspec")
Gem.write_binary(default_spec_path, bundler_spec.to_ruby)
Expand Down
64 changes: 40 additions & 24 deletions test/rubygems/test_gem_commands_setup_command.rb
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def setup
spec_fetcher do |fetcher|
fetcher.download "bundler", "1.15.4"

fetcher.gem "bundler", BUNDLER_VERS
fetcher.gem "bundler", bundler_version

fetcher.gem "bundler-audit", "1.0.0"
end
Expand Down Expand Up @@ -164,10 +164,8 @@ def test_destdir_flag_does_not_try_to_write_to_the_default_gem_home
@cmd.options[:destdir] = destdir
@cmd.execute

spec = Gem::Specification.load("bundler/bundler.gemspec")

spec.executables.each do |e|
assert_path_exist File.join destdir, @gemhome.gsub(/^[a-zA-Z]:/, ''), 'gems', spec.full_name, spec.bindir, e
bundler_spec.executables.each do |e|
assert_path_exist prepend_destdir(destdir, File.join(@gemhome, 'gems', bundler_spec.full_name, bundler_spec.bindir, e))
end
end

Expand Down Expand Up @@ -199,7 +197,6 @@ def test_install_default_bundler_gem
bin_dir = File.join(@gemhome, 'bin')
@cmd.install_default_bundler_gem bin_dir

bundler_spec = Gem::Specification.load("bundler/bundler.gemspec")
default_spec_path = File.join(Gem.default_specifications_dir, "#{bundler_spec.full_name}.gemspec")
spec = Gem::Specification.load(default_spec_path)

Expand All @@ -211,19 +208,17 @@ def test_install_default_bundler_gem
assert_path_exist File.join bin_dir, e
end

default_dir = Gem.default_specifications_dir

# expect to remove other versions of bundler gemspecs on default specification directory.
assert_path_not_exist File.join(default_dir, "bundler-1.15.4.gemspec")
assert_path_exist File.join(default_dir, "bundler-#{BUNDLER_VERS}.gemspec")
assert_path_not_exist previous_bundler_specification_path
assert_path_exist new_bundler_specification_path

# expect to not remove bundler-* gemspecs.
assert_path_exist File.join(Gem.dir, "specifications", "bundler-audit-1.0.0.gemspec")

# expect to remove normal gem that was same version. because it's promoted default gems.
assert_path_not_exist File.join(Gem.dir, "specifications", "bundler-#{BUNDLER_VERS}.gemspec")
assert_path_not_exist File.join(Gem.dir, "specifications", "bundler-#{bundler_version}.gemspec")

assert_path_exist "#{Gem.dir}/gems/bundler-#{BUNDLER_VERS}"
assert_path_exist "#{Gem.dir}/gems/bundler-#{bundler_version}"
assert_path_exist "#{Gem.dir}/gems/bundler-1.15.4"
assert_path_exist "#{Gem.dir}/gems/bundler-audit-1.0.0"
end
Expand All @@ -239,11 +234,9 @@ def test_install_default_bundler_gem_with_default_gems_not_installed_at_default_

@cmd.install_default_bundler_gem bin_dir

default_dir = Gem.default_specifications_dir

# expect to remove other versions of bundler gemspecs on default specification directory.
assert_path_not_exist File.join(default_dir, "bundler-1.15.4.gemspec")
assert_path_exist File.join(default_dir, "bundler-#{BUNDLER_VERS}.gemspec")
assert_path_not_exist previous_bundler_specification_path
assert_path_exist new_bundler_specification_path
end

def test_install_default_bundler_gem_with_force_flag
Expand All @@ -262,7 +255,6 @@ def test_install_default_bundler_gem_with_force_flag

@cmd.install_default_bundler_gem bin_dir

bundler_spec = Gem::Specification.load("bundler/bundler.gemspec")
default_spec_path = File.join(Gem.default_specifications_dir, "#{bundler_spec.full_name}.gemspec")
spec = Gem::Specification.load(default_spec_path)

Expand All @@ -287,10 +279,16 @@ def test_install_default_bundler_gem_with_destdir_flag

@cmd.install_default_bundler_gem bin_dir

spec = Gem::Specification.load("bundler/bundler.gemspec")
# leaves other versions of bundler gemspecs on default specification directory.
assert_path_exist previous_bundler_specification_path
assert_path_not_exist new_bundler_specification_path

spec.executables.each do |e|
assert_path_exist File.join destdir, @gemhome.gsub(/^[a-zA-Z]:/, ''), 'gems', spec.full_name, spec.bindir, e
# installs the updated bundler gemspec to destdir
assert_path_not_exist prepend_destdir(destdir, previous_bundler_specification_path)
assert_path_exist prepend_destdir(destdir, new_bundler_specification_path)

bundler_spec.executables.each do |e|
assert_path_exist prepend_destdir(destdir, File.join(@gemhome, 'gems', bundler_spec.full_name, bundler_spec.bindir, e))
end
ensure
FileUtils.chmod "+w", @gemhome
Expand All @@ -307,10 +305,8 @@ def test_install_default_bundler_gem_with_destdir_and_prefix_flags

@cmd.install_default_bundler_gem bin_dir

spec = Gem::Specification.load("bundler/bundler.gemspec")

spec.executables.each do |e|
assert_path_exist File.join destdir, 'gems', spec.full_name, spec.bindir, e
bundler_spec.executables.each do |e|
assert_path_exist File.join destdir, 'gems', bundler_spec.full_name, bundler_spec.bindir, e
end
end

Expand Down Expand Up @@ -462,4 +458,24 @@ def default_bundle_bin_path
def default_bundler_bin_path
File.join RbConfig::CONFIG['bindir'], 'bundler'
end

def previous_bundler_specification_path
File.join(Gem.default_specifications_dir, "bundler-1.15.4.gemspec")
end

def new_bundler_specification_path
File.join(Gem.default_specifications_dir, "bundler-#{bundler_version}.gemspec")
end

def bundler_spec
Gem::Specification.load("bundler/bundler.gemspec")
end

def bundler_version
bundler_spec.version
end

def prepend_destdir(destdir, path)
File.join(destdir, path.gsub(/^[a-zA-Z]:/, ''))
end
end unless Gem.java_platform?

0 comments on commit 16db218

Please sign in to comment.