mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
7fd88da935
When bundler parallel installer installs gems concurrently, one can get confusing warnings like the following: ``` "[/home/runner/work/rubygems/rubygems/bundler/tmp/2/gems/system/specifications/zeitwerk-2.4.2.gemspec] isn't a Gem::Specification (NilClass instead). ``` I've got these warnings several times in the past, but I never managed to reproduce them, and never look deeply into the root cause, but this time a got a cause that reproduced quite frequently, so I looked into it. The problem is one thread reading a gemspec while another thread is writing it. The write of the gemspec was not protected, so `Gem::Specification.load` could end up seeing a truncated gemspec and thus throw this warning. The fix involve two changes: * Change the methods that write gemspecs to use `Gem.binary_write` which is protected by a lock. * Fix `Gem.binary_write` to create the file lock at file creation time, not when the file already exists after. The realworld user problem caused by this issue happens in bundler, but I'm fixing it in rubygems first, and then I'll backport to bundler whatever needs backporting to fix the issue on the bundler side. https://github.com/rubygems/rubygems/commit/a672e7555c
2311 lines
59 KiB
Ruby
2311 lines
59 KiB
Ruby
# frozen_string_literal: true
|
|
require_relative 'installer_test_case'
|
|
|
|
class TestGemInstaller < Gem::InstallerTestCase
|
|
def setup
|
|
super
|
|
common_installer_setup
|
|
|
|
@config = Gem.configuration
|
|
end
|
|
|
|
def teardown
|
|
common_installer_teardown
|
|
|
|
super
|
|
|
|
Gem.configuration = instance_variable_defined?(:@config) ? @config : nil
|
|
end
|
|
|
|
def test_app_script_text
|
|
installer = setup_base_installer
|
|
|
|
util_make_exec @spec, ''
|
|
|
|
expected = <<-EOF
|
|
#!#{Gem.ruby}
|
|
#
|
|
# This file was generated by RubyGems.
|
|
#
|
|
# The application 'a' is installed as part of a gem, and
|
|
# this file is here to facilitate running it.
|
|
#
|
|
|
|
require 'rubygems'
|
|
|
|
Gem.use_gemdeps
|
|
|
|
version = \">= 0.a\"
|
|
|
|
str = ARGV.first
|
|
if str
|
|
str = str.b[/\\A_(.*)_\\z/, 1]
|
|
if str and Gem::Version.correct?(str)
|
|
version = str
|
|
ARGV.shift
|
|
end
|
|
end
|
|
|
|
if Gem.respond_to?(:activate_bin_path)
|
|
load Gem.activate_bin_path('a', 'executable', version)
|
|
else
|
|
gem "a", version
|
|
load Gem.bin_path("a", "executable", version)
|
|
end
|
|
EOF
|
|
|
|
wrapper = installer.app_script_text 'executable'
|
|
assert_equal expected, wrapper
|
|
end
|
|
|
|
def test_check_executable_overwrite
|
|
installer = setup_base_installer
|
|
|
|
installer.generate_bin
|
|
|
|
@spec = Gem::Specification.new do |s|
|
|
s.files = ['lib/code.rb']
|
|
s.name = "a"
|
|
s.version = "3"
|
|
s.summary = "summary"
|
|
s.description = "desc"
|
|
s.require_path = 'lib'
|
|
end
|
|
|
|
util_make_exec
|
|
installer.gem_dir = @spec.gem_dir
|
|
installer.wrappers = true
|
|
installer.generate_bin
|
|
|
|
installed_exec = File.join util_inst_bindir, 'executable'
|
|
assert_path_exist installed_exec
|
|
|
|
wrapper = File.read installed_exec
|
|
assert_match %r{generated by RubyGems}, wrapper
|
|
end
|
|
|
|
def test_check_executable_overwrite_default_bin_dir
|
|
installer = setup_base_installer(false)
|
|
|
|
bindir(Gem.bindir) do
|
|
util_conflict_executable false
|
|
|
|
ui = Gem::MockGemUi.new "n\n"
|
|
use_ui ui do
|
|
e = assert_raise Gem::InstallError do
|
|
installer.generate_bin
|
|
end
|
|
|
|
conflicted = File.join @gemhome, 'bin', 'executable'
|
|
assert_match %r{\A"executable" from a conflicts with (?:#{Regexp.quote(conflicted)}|installed executable from conflict)\z},
|
|
e.message
|
|
end
|
|
end
|
|
end
|
|
|
|
def test_check_executable_overwrite_format_executable
|
|
installer = setup_base_installer
|
|
|
|
installer.generate_bin
|
|
|
|
@spec = Gem::Specification.new do |s|
|
|
s.files = ['lib/code.rb']
|
|
s.name = "a"
|
|
s.version = "3"
|
|
s.summary = "summary"
|
|
s.description = "desc"
|
|
s.require_path = 'lib'
|
|
end
|
|
|
|
File.open File.join(util_inst_bindir, 'executable'), 'w' do |io|
|
|
io.write <<-EXEC
|
|
#!/usr/local/bin/ruby
|
|
#
|
|
# This file was generated by RubyGems
|
|
|
|
gem 'other', version
|
|
EXEC
|
|
end
|
|
|
|
util_make_exec
|
|
Gem::Installer.exec_format = 'foo-%s-bar'
|
|
installer.gem_dir = @spec.gem_dir
|
|
installer.wrappers = true
|
|
installer.format_executable = true
|
|
|
|
installer.generate_bin # should not raise
|
|
|
|
installed_exec = File.join util_inst_bindir, 'foo-executable-bar'
|
|
assert_path_exist installed_exec
|
|
|
|
wrapper = File.read installed_exec
|
|
assert_match %r{generated by RubyGems}, wrapper
|
|
ensure
|
|
Gem::Installer.exec_format = nil
|
|
end
|
|
|
|
def test_check_executable_overwrite_other_gem
|
|
installer = setup_base_installer(false)
|
|
|
|
util_conflict_executable true
|
|
|
|
ui = Gem::MockGemUi.new "n\n"
|
|
|
|
use_ui ui do
|
|
e = assert_raise Gem::InstallError do
|
|
installer.generate_bin
|
|
end
|
|
|
|
assert_equal '"executable" from a conflicts with installed executable from conflict',
|
|
e.message
|
|
end
|
|
end
|
|
|
|
def test_check_executable_overwrite_other_gem_force
|
|
installer = setup_base_installer
|
|
|
|
util_conflict_executable true
|
|
installer.wrappers = true
|
|
installer.force = true
|
|
|
|
installer.generate_bin
|
|
|
|
installed_exec = File.join util_inst_bindir, 'executable'
|
|
assert_path_exist installed_exec
|
|
|
|
wrapper = File.read installed_exec
|
|
assert_match %r{generated by RubyGems}, wrapper
|
|
end
|
|
|
|
def test_check_executable_overwrite_other_non_gem
|
|
installer = setup_base_installer
|
|
|
|
util_conflict_executable false
|
|
installer.wrappers = true
|
|
|
|
installer.generate_bin
|
|
|
|
installed_exec = File.join util_inst_bindir, 'executable'
|
|
assert_path_exist installed_exec
|
|
|
|
wrapper = File.read installed_exec
|
|
assert_match %r{generated by RubyGems}, wrapper
|
|
end unless Gem.win_platform?
|
|
|
|
def test_check_that_user_bin_dir_is_in_path
|
|
installer = setup_base_installer
|
|
|
|
bin_dir = installer.bin_dir
|
|
|
|
if Gem.win_platform?
|
|
bin_dir = bin_dir.downcase
|
|
end
|
|
|
|
orig_PATH, ENV['PATH'] =
|
|
ENV['PATH'], [ENV['PATH'], bin_dir].join(File::PATH_SEPARATOR)
|
|
|
|
use_ui @ui do
|
|
installer.check_that_user_bin_dir_is_in_path
|
|
end
|
|
|
|
assert_empty @ui.error
|
|
|
|
return unless win_platform?
|
|
|
|
ENV['PATH'] = [orig_PATH, bin_dir.tr(File::SEPARATOR, File::ALT_SEPARATOR)].join(File::PATH_SEPARATOR)
|
|
|
|
use_ui @ui do
|
|
installer.check_that_user_bin_dir_is_in_path
|
|
end
|
|
|
|
assert_empty @ui.error
|
|
ensure
|
|
ENV['PATH'] = orig_PATH
|
|
end
|
|
|
|
def test_check_that_user_bin_dir_is_in_path_tilde
|
|
pend "Tilde is PATH is not supported under MS Windows" if win_platform?
|
|
|
|
orig_PATH, ENV['PATH'] =
|
|
ENV['PATH'], [ENV['PATH'], '~/bin'].join(File::PATH_SEPARATOR)
|
|
|
|
installer = setup_base_installer
|
|
installer.bin_dir.replace File.join @userhome, 'bin'
|
|
|
|
use_ui @ui do
|
|
installer.check_that_user_bin_dir_is_in_path
|
|
end
|
|
|
|
assert_empty @ui.error
|
|
ensure
|
|
ENV['PATH'] = orig_PATH unless win_platform?
|
|
end
|
|
|
|
def test_check_that_user_bin_dir_is_in_path_not_in_path
|
|
installer = setup_base_installer
|
|
|
|
use_ui @ui do
|
|
installer.check_that_user_bin_dir_is_in_path
|
|
end
|
|
|
|
expected = installer.bin_dir
|
|
|
|
if Gem.win_platform?
|
|
expected = expected.downcase
|
|
end
|
|
|
|
assert_match expected, @ui.error
|
|
end
|
|
|
|
def test_ensure_dependency
|
|
installer = setup_base_installer
|
|
|
|
util_spec 'a'
|
|
|
|
dep = Gem::Dependency.new 'a', '>= 2'
|
|
assert installer.ensure_dependency(@spec, dep)
|
|
|
|
dep = Gem::Dependency.new 'b', '> 2'
|
|
e = assert_raise Gem::InstallError do
|
|
installer.ensure_dependency @spec, dep
|
|
end
|
|
|
|
assert_equal 'a requires b (> 2)', e.message
|
|
end
|
|
|
|
def test_ensure_loadable_spec
|
|
a, a_gem = util_gem 'a', 2 do |s|
|
|
s.add_dependency 'garbage ~> 5'
|
|
end
|
|
|
|
installer = Gem::Installer.at a_gem
|
|
|
|
e = assert_raise Gem::InstallError do
|
|
installer.ensure_loadable_spec
|
|
end
|
|
|
|
assert_equal "The specification for #{a.full_name} is corrupt " +
|
|
"(SyntaxError)", e.message
|
|
end
|
|
|
|
def test_ensure_no_race_conditions_between_installing_and_loading_gemspecs
|
|
a, a_gem = util_gem 'a', 2
|
|
|
|
Gem::Installer.at(a_gem).install
|
|
|
|
t1 = Thread.new do
|
|
5.times do
|
|
Gem::Installer.at(a_gem).install
|
|
sleep 0.1
|
|
end
|
|
end
|
|
|
|
t2 = Thread.new do
|
|
_, err = capture_output do
|
|
20.times do
|
|
Gem::Specification.load(a.spec_file)
|
|
Gem::Specification.send(:clear_load_cache)
|
|
end
|
|
end
|
|
|
|
assert_empty err
|
|
end
|
|
|
|
t1.join
|
|
t2.join
|
|
end
|
|
|
|
def test_ensure_loadable_spec_security_policy
|
|
pend 'openssl is missing' unless Gem::HAVE_OPENSSL
|
|
|
|
_, a_gem = util_gem 'a', 2 do |s|
|
|
s.add_dependency 'garbage ~> 5'
|
|
end
|
|
|
|
policy = Gem::Security::HighSecurity
|
|
installer = Gem::Installer.at a_gem, :security_policy => policy
|
|
|
|
assert_raise Gem::Security::Exception do
|
|
installer.ensure_loadable_spec
|
|
end
|
|
end
|
|
|
|
def test_extract_files
|
|
installer = setup_base_installer
|
|
|
|
installer.extract_files
|
|
|
|
assert_path_exist File.join @spec.gem_dir, 'bin/executable'
|
|
end
|
|
|
|
def test_generate_bin_bindir
|
|
installer = setup_base_installer
|
|
|
|
installer.wrappers = true
|
|
|
|
@spec.executables = %w[executable]
|
|
@spec.bindir = 'bin'
|
|
|
|
exec_file = installer.formatted_program_filename 'executable'
|
|
exec_path = File.join @spec.gem_dir, exec_file
|
|
File.open exec_path, 'w' do |f|
|
|
f.puts '#!/usr/bin/ruby'
|
|
end
|
|
|
|
installer.gem_dir = @spec.gem_dir
|
|
|
|
installer.generate_bin
|
|
|
|
assert_directory_exists util_inst_bindir
|
|
installed_exec = File.join(util_inst_bindir, 'executable')
|
|
assert_path_exist installed_exec
|
|
assert_equal mask, File.stat(installed_exec).mode unless win_platform?
|
|
|
|
wrapper = File.read installed_exec
|
|
assert_match %r{generated by RubyGems}, wrapper
|
|
end
|
|
|
|
def test_generate_bin_bindir_with_user_install_warning
|
|
bin_dir = Gem.win_platform? ? File.expand_path(ENV["WINDIR"]).upcase :
|
|
"/usr/bin"
|
|
|
|
old_path = ENV["PATH"]
|
|
ENV["PATH"] = [ENV["PATH"], bin_dir].compact.join(File::PATH_SEPARATOR)
|
|
|
|
options = {
|
|
:bin_dir => bin_dir,
|
|
:install_dir => "/non/existent",
|
|
}
|
|
|
|
inst = Gem::Installer.at '', options
|
|
|
|
Gem::Installer.path_warning = false
|
|
|
|
use_ui @ui do
|
|
inst.check_that_user_bin_dir_is_in_path
|
|
end
|
|
|
|
assert_equal "", @ui.error
|
|
|
|
ensure
|
|
ENV["PATH"] = old_path
|
|
end
|
|
|
|
def test_generate_bin_script
|
|
installer = setup_base_installer
|
|
|
|
installer.wrappers = true
|
|
util_make_exec
|
|
installer.gem_dir = @spec.gem_dir
|
|
|
|
installer.generate_bin
|
|
assert_directory_exists util_inst_bindir
|
|
installed_exec = File.join util_inst_bindir, 'executable'
|
|
assert_path_exist installed_exec
|
|
assert_equal mask, File.stat(installed_exec).mode unless win_platform?
|
|
|
|
wrapper = File.read installed_exec
|
|
assert_match %r{generated by RubyGems}, wrapper
|
|
end
|
|
|
|
def test_generate_bin_script_format
|
|
installer = setup_base_installer
|
|
|
|
installer.format_executable = true
|
|
installer.wrappers = true
|
|
util_make_exec
|
|
installer.gem_dir = @spec.gem_dir
|
|
|
|
Gem::Installer.exec_format = 'foo-%s-bar'
|
|
installer.generate_bin
|
|
assert_directory_exists util_inst_bindir
|
|
installed_exec = File.join util_inst_bindir, 'foo-executable-bar'
|
|
assert_path_exist installed_exec
|
|
ensure
|
|
Gem::Installer.exec_format = nil
|
|
end
|
|
|
|
def test_generate_bin_script_format_disabled
|
|
installer = setup_base_installer
|
|
|
|
installer.wrappers = true
|
|
util_make_exec
|
|
installer.gem_dir = @spec.gem_dir
|
|
|
|
Gem::Installer.exec_format = 'foo-%s-bar'
|
|
installer.generate_bin
|
|
assert_directory_exists util_inst_bindir
|
|
installed_exec = File.join util_inst_bindir, 'executable'
|
|
assert_path_exist installed_exec
|
|
ensure
|
|
Gem::Installer.exec_format = nil
|
|
end
|
|
|
|
def test_generate_bin_script_install_dir
|
|
installer = setup_base_installer
|
|
|
|
installer.wrappers = true
|
|
|
|
gem_dir = File.join("#{@gemhome}2", "gems", @spec.full_name)
|
|
gem_bindir = File.join gem_dir, 'bin'
|
|
FileUtils.mkdir_p gem_bindir
|
|
File.open File.join(gem_bindir, 'executable'), 'w' do |f|
|
|
f.puts "#!/bin/ruby"
|
|
end
|
|
|
|
installer.gem_home = "#{@gemhome}2"
|
|
installer.gem_dir = gem_dir
|
|
installer.bin_dir = File.join "#{@gemhome}2", 'bin'
|
|
|
|
installer.generate_bin
|
|
|
|
installed_exec = File.join("#{@gemhome}2", "bin", 'executable')
|
|
assert_path_exist installed_exec
|
|
assert_equal mask, File.stat(installed_exec).mode unless win_platform?
|
|
|
|
wrapper = File.read installed_exec
|
|
assert_match %r{generated by RubyGems}, wrapper
|
|
end
|
|
|
|
def test_generate_bin_script_no_execs
|
|
installer = setup_base_installer
|
|
|
|
installer = util_execless
|
|
|
|
installer.wrappers = true
|
|
installer.generate_bin
|
|
|
|
assert_path_not_exist util_inst_bindir, 'bin dir was created when not needed'
|
|
end
|
|
|
|
def test_generate_bin_script_no_perms
|
|
installer = setup_base_installer
|
|
|
|
installer.wrappers = true
|
|
util_make_exec
|
|
|
|
Dir.mkdir util_inst_bindir
|
|
|
|
if win_platform?
|
|
pend('test_generate_bin_script_no_perms skipped on MS Windows')
|
|
elsif Process.uid.zero?
|
|
pend('test_generate_bin_script_no_perms skipped in root privilege')
|
|
else
|
|
FileUtils.chmod 0000, util_inst_bindir
|
|
|
|
assert_raise Gem::FilePermissionError do
|
|
installer.generate_bin
|
|
end
|
|
end
|
|
ensure
|
|
FileUtils.chmod 0755, util_inst_bindir unless ($DEBUG or win_platform?)
|
|
end
|
|
|
|
def test_generate_bin_script_no_shebang
|
|
installer = setup_base_installer
|
|
|
|
installer.wrappers = true
|
|
@spec.executables = %w[executable]
|
|
|
|
gem_dir = File.join @gemhome, 'gems', @spec.full_name
|
|
gem_bindir = File.join gem_dir, 'bin'
|
|
FileUtils.mkdir_p gem_bindir
|
|
File.open File.join(gem_bindir, 'executable'), 'w' do |f|
|
|
f.puts "blah blah blah"
|
|
end
|
|
|
|
installer.generate_bin
|
|
|
|
installed_exec = File.join @gemhome, 'bin', 'executable'
|
|
assert_path_exist installed_exec
|
|
assert_equal mask, File.stat(installed_exec).mode unless win_platform?
|
|
|
|
wrapper = File.read installed_exec
|
|
assert_match %r{generated by RubyGems}, wrapper
|
|
# HACK some gems don't have #! in their executables, restore 2008/06
|
|
#assert_no_match %r|generated by RubyGems|, wrapper
|
|
end
|
|
|
|
def test_generate_bin_script_wrappers
|
|
installer = setup_base_installer
|
|
|
|
installer.wrappers = true
|
|
util_make_exec
|
|
installer.gem_dir = @spec.gem_dir
|
|
installed_exec = File.join(util_inst_bindir, 'executable')
|
|
|
|
real_exec = File.join @spec.gem_dir, 'bin', 'executable'
|
|
|
|
# fake --no-wrappers for previous install
|
|
unless Gem.win_platform?
|
|
FileUtils.mkdir_p File.dirname(installed_exec)
|
|
FileUtils.ln_s real_exec, installed_exec
|
|
end
|
|
|
|
installer.generate_bin
|
|
assert_directory_exists util_inst_bindir
|
|
assert_path_exist installed_exec
|
|
assert_equal mask, File.stat(installed_exec).mode unless win_platform?
|
|
|
|
assert_match %r{generated by RubyGems}, File.read(installed_exec)
|
|
|
|
refute_match %r{generated by RubyGems}, File.read(real_exec),
|
|
'real executable overwritten'
|
|
end
|
|
|
|
def test_generate_bin_symlink
|
|
pend "Symlinks not supported or not enabled" unless symlink_supported?
|
|
|
|
installer = setup_base_installer
|
|
|
|
installer.wrappers = false
|
|
util_make_exec
|
|
installer.gem_dir = @spec.gem_dir
|
|
|
|
installer.generate_bin
|
|
assert_directory_exists util_inst_bindir
|
|
installed_exec = File.join util_inst_bindir, 'executable'
|
|
assert_equal true, File.symlink?(installed_exec)
|
|
assert_equal(File.join(@spec.gem_dir, 'bin', 'executable'),
|
|
File.readlink(installed_exec))
|
|
end
|
|
|
|
def test_generate_bin_symlink_no_execs
|
|
installer = setup_base_installer
|
|
|
|
installer = util_execless
|
|
|
|
installer.wrappers = false
|
|
installer.generate_bin
|
|
|
|
assert_path_not_exist util_inst_bindir
|
|
end
|
|
|
|
def test_generate_bin_symlink_no_perms
|
|
installer = setup_base_installer
|
|
|
|
installer.wrappers = false
|
|
util_make_exec
|
|
installer.gem_dir = @spec.gem_dir
|
|
|
|
Dir.mkdir util_inst_bindir
|
|
|
|
if win_platform?
|
|
pend('test_generate_bin_symlink_no_perms skipped on MS Windows')
|
|
elsif Process.uid.zero?
|
|
pend('test_user_install_disabled_read_only test skipped in root privilege')
|
|
else
|
|
FileUtils.chmod 0000, util_inst_bindir
|
|
|
|
assert_raise Gem::FilePermissionError do
|
|
installer.generate_bin
|
|
end
|
|
end
|
|
ensure
|
|
FileUtils.chmod 0755, util_inst_bindir unless ($DEBUG or win_platform?)
|
|
end
|
|
|
|
def test_generate_bin_symlink_update_newer
|
|
pend "Symlinks not supported or not enabled" unless symlink_supported?
|
|
|
|
installer = setup_base_installer
|
|
|
|
installer.wrappers = false
|
|
util_make_exec
|
|
installer.gem_dir = @spec.gem_dir
|
|
|
|
installer.generate_bin
|
|
installed_exec = File.join(util_inst_bindir, 'executable')
|
|
assert_equal(File.join(@spec.gem_dir, 'bin', 'executable'),
|
|
File.readlink(installed_exec))
|
|
|
|
@spec = Gem::Specification.new do |s|
|
|
s.files = ['lib/code.rb']
|
|
s.name = "a"
|
|
s.version = "3"
|
|
s.summary = "summary"
|
|
s.description = "desc"
|
|
s.require_path = 'lib'
|
|
end
|
|
|
|
util_make_exec
|
|
installer.gem_dir = @spec.gem_dir
|
|
installer.generate_bin
|
|
installed_exec = File.join(util_inst_bindir, 'executable')
|
|
assert_equal(@spec.bin_file('executable'),
|
|
File.readlink(installed_exec),
|
|
"Ensure symlink moved to latest version")
|
|
end
|
|
|
|
def test_generate_bin_symlink_update_older
|
|
pend "Symlinks not supported or not enabled" unless symlink_supported?
|
|
|
|
installer = setup_base_installer
|
|
|
|
installer.wrappers = false
|
|
util_make_exec
|
|
installer.gem_dir = @spec.gem_dir
|
|
|
|
installer.generate_bin
|
|
installed_exec = File.join(util_inst_bindir, 'executable')
|
|
assert_equal(File.join(@spec.gem_dir, 'bin', 'executable'),
|
|
File.readlink(installed_exec))
|
|
|
|
spec = Gem::Specification.new do |s|
|
|
s.files = ['lib/code.rb']
|
|
s.name = "a"
|
|
s.version = "1"
|
|
s.summary = "summary"
|
|
s.description = "desc"
|
|
s.require_path = 'lib'
|
|
end
|
|
|
|
util_make_exec
|
|
one = @spec.dup
|
|
one.version = 1
|
|
installer = Gem::Installer.for_spec spec
|
|
installer.gem_dir = one.gem_dir
|
|
|
|
installer.generate_bin
|
|
|
|
installed_exec = File.join util_inst_bindir, 'executable'
|
|
expected = File.join @spec.gem_dir, 'bin', 'executable'
|
|
assert_equal(expected,
|
|
File.readlink(installed_exec),
|
|
"Ensure symlink not moved")
|
|
end
|
|
|
|
def test_generate_bin_symlink_update_remove_wrapper
|
|
pend "Symlinks not supported or not enabled" unless symlink_supported?
|
|
|
|
installer = setup_base_installer
|
|
|
|
installer.wrappers = true
|
|
util_make_exec
|
|
installer.gem_dir = @spec.gem_dir
|
|
|
|
installer.generate_bin
|
|
|
|
installed_exec = File.join util_inst_bindir, 'executable'
|
|
assert_path_exist installed_exec
|
|
|
|
@spec = Gem::Specification.new do |s|
|
|
s.files = ['lib/code.rb']
|
|
s.name = "a"
|
|
s.version = "3"
|
|
s.summary = "summary"
|
|
s.description = "desc"
|
|
s.require_path = 'lib'
|
|
end
|
|
util_make_exec
|
|
|
|
util_installer @spec, @gemhome
|
|
installer.wrappers = false
|
|
installer.gem_dir = @spec.gem_dir
|
|
|
|
installer.generate_bin
|
|
|
|
installed_exec = File.join util_inst_bindir, 'executable'
|
|
assert_equal(@spec.bin_file('executable'),
|
|
File.readlink(installed_exec),
|
|
"Ensure symlink moved to latest version")
|
|
end
|
|
|
|
def test_generate_bin_symlink_win32
|
|
old_win_platform = Gem.win_platform?
|
|
Gem.win_platform = true
|
|
old_alt_separator = File::ALT_SEPARATOR
|
|
File.__send__(:remove_const, :ALT_SEPARATOR)
|
|
File.const_set(:ALT_SEPARATOR, '\\')
|
|
|
|
installer = setup_base_installer
|
|
|
|
installer.wrappers = false
|
|
util_make_exec
|
|
installer.gem_dir = @spec.gem_dir
|
|
|
|
use_ui @ui do
|
|
installer.generate_bin
|
|
end
|
|
|
|
assert_directory_exists util_inst_bindir
|
|
installed_exec = File.join(util_inst_bindir, 'executable')
|
|
assert_path_exist installed_exec
|
|
|
|
if symlink_supported?
|
|
assert File.symlink?(installed_exec)
|
|
return
|
|
end
|
|
|
|
assert_match(/Unable to use symlinks, installing wrapper/i,
|
|
@ui.error)
|
|
|
|
wrapper = File.read installed_exec
|
|
assert_match(/generated by RubyGems/, wrapper)
|
|
ensure
|
|
File.__send__(:remove_const, :ALT_SEPARATOR)
|
|
File.const_set(:ALT_SEPARATOR, old_alt_separator)
|
|
Gem.win_platform = old_win_platform
|
|
end
|
|
|
|
def test_generate_bin_uses_default_shebang
|
|
pend "Symlinks not supported or not enabled" unless symlink_supported?
|
|
|
|
installer = setup_base_installer
|
|
|
|
installer.wrappers = true
|
|
util_make_exec
|
|
|
|
installer.generate_bin
|
|
|
|
default_shebang = Gem.ruby
|
|
shebang_line = File.open("#{@gemhome}/bin/executable") {|f| f.readlines.first }
|
|
assert_match(/\A#!/, shebang_line)
|
|
assert_match(/#{default_shebang}/, shebang_line)
|
|
end
|
|
|
|
def test_generate_bin_with_dangling_symlink
|
|
gem_with_dangling_symlink = File.expand_path("packages/ascii_binder-0.1.10.1.gem", __dir__)
|
|
|
|
installer = Gem::Installer.at(
|
|
gem_with_dangling_symlink,
|
|
:user_install => false,
|
|
:force => true
|
|
)
|
|
|
|
build_rake_in do
|
|
use_ui @ui do
|
|
installer.install
|
|
end
|
|
end
|
|
|
|
assert_match %r{bin/ascii_binder` is dangling symlink pointing to `bin/asciibinder`}, @ui.error
|
|
assert_empty @ui.output
|
|
end
|
|
|
|
def test_generate_plugins
|
|
installer = util_setup_installer do |spec|
|
|
write_file File.join(@tempdir, 'lib', 'rubygems_plugin.rb') do |io|
|
|
io.write "puts __FILE__"
|
|
end
|
|
|
|
spec.files += %w[lib/rubygems_plugin.rb]
|
|
end
|
|
|
|
build_rake_in do
|
|
installer.install
|
|
end
|
|
|
|
plugin_path = File.join Gem.plugindir, 'a_plugin.rb'
|
|
|
|
FileUtils.rm plugin_path
|
|
|
|
installer.generate_plugins
|
|
|
|
assert File.exist?(plugin_path), 'plugin not written'
|
|
end
|
|
|
|
def test_generate_plugins_with_install_dir
|
|
spec = quick_gem 'a' do |s|
|
|
write_file File.join(@tempdir, 'lib', 'rubygems_plugin.rb') do |io|
|
|
io.write "puts __FILE__"
|
|
end
|
|
|
|
s.files += %w[lib/rubygems_plugin.rb]
|
|
end
|
|
|
|
util_build_gem spec
|
|
|
|
plugin_path = File.join "#{@gemhome}2", 'plugins', 'a_plugin.rb'
|
|
installer = util_installer spec, "#{@gemhome}2"
|
|
|
|
assert_equal spec, installer.install
|
|
|
|
assert File.exist?(plugin_path), 'plugin not written to install_dir'
|
|
end
|
|
|
|
def test_generate_plugins_with_user_install
|
|
spec = quick_gem 'a' do |s|
|
|
write_file File.join(@tempdir, 'lib', 'rubygems_plugin.rb') do |io|
|
|
io.write "puts __FILE__"
|
|
end
|
|
|
|
s.files += %w[lib/rubygems_plugin.rb]
|
|
end
|
|
|
|
util_build_gem spec
|
|
|
|
File.chmod(0555, Gem.plugindir)
|
|
system_path = File.join(Gem.plugindir, 'a_plugin.rb')
|
|
user_path = File.join(Gem.plugindir(Gem.user_dir), 'a_plugin.rb')
|
|
installer = util_installer spec, Gem.dir, :user
|
|
|
|
assert_equal spec, installer.install
|
|
|
|
assert !File.exist?(system_path), 'plugin incorrectly written to system plugins_dir'
|
|
assert File.exist?(user_path), 'plugin not written to user plugins_dir'
|
|
end
|
|
|
|
def test_generate_plugins_with_build_root
|
|
spec = quick_gem 'a' do |s|
|
|
write_file File.join(@tempdir, 'lib', 'rubygems_plugin.rb') do |io|
|
|
io.write "puts __FILE__"
|
|
end
|
|
|
|
s.files += %w[lib/rubygems_plugin.rb]
|
|
end
|
|
|
|
util_build_gem spec
|
|
|
|
File.chmod(0555, Gem.plugindir)
|
|
system_path = File.join(Gem.plugindir, 'a_plugin.rb')
|
|
|
|
build_root = File.join(@tempdir, 'build_root')
|
|
build_root_path = File.join(build_root, Gem.plugindir.gsub(/^[a-zA-Z]:/, ''), 'a_plugin.rb')
|
|
|
|
installer = Gem::Installer.at spec.cache_file, :build_root => build_root
|
|
|
|
assert_equal spec, installer.install
|
|
|
|
assert !File.exist?(system_path), 'plugin written incorrect written to system plugins_dir'
|
|
assert File.exist?(build_root_path), 'plugin not written to build_root'
|
|
|
|
refute_includes File.read(build_root_path), build_root
|
|
end
|
|
|
|
def test_keeps_plugins_up_to_date
|
|
# NOTE: version a-2 is already installed by setup hooks
|
|
|
|
write_file File.join(@tempdir, 'lib', 'rubygems_plugin.rb') do |io|
|
|
io.write "puts __FILE__"
|
|
end
|
|
|
|
build_rake_in do
|
|
util_setup_installer do |spec|
|
|
spec.version = '1'
|
|
spec.files += %w[lib/rubygems_plugin.rb]
|
|
end.install
|
|
|
|
plugin_path = File.join Gem.plugindir, 'a_plugin.rb'
|
|
refute File.exist?(plugin_path), 'old version installed while newer version without plugin also installed, but plugin written'
|
|
|
|
util_setup_installer do |spec|
|
|
spec.version = '2'
|
|
spec.files += %w[lib/rubygems_plugin.rb]
|
|
end.install
|
|
|
|
plugin_path = File.join Gem.plugindir, 'a_plugin.rb'
|
|
assert File.exist?(plugin_path), 'latest version reinstalled, but plugin not written'
|
|
assert_match %r{\Arequire.*a-2/lib/rubygems_plugin\.rb}, File.read(plugin_path), 'written plugin has incorrect content'
|
|
|
|
util_setup_installer do |spec|
|
|
spec.version = '3'
|
|
spec.files += %w[lib/rubygems_plugin.rb]
|
|
end.install
|
|
|
|
plugin_path = File.join Gem.plugindir, 'a_plugin.rb'
|
|
assert File.exist?(plugin_path), 'latest version installed, but plugin removed'
|
|
assert_match %r{\Arequire.*a-3/lib/rubygems_plugin\.rb}, File.read(plugin_path), 'written plugin has incorrect content'
|
|
|
|
util_setup_installer do |spec|
|
|
spec.version = '4'
|
|
end.install
|
|
|
|
refute File.exist?(plugin_path), 'new version installed without a plugin while older version with a plugin installed, but plugin not removed'
|
|
end
|
|
end
|
|
|
|
def test_generates_plugins_dir_under_install_dir_if_not_there
|
|
Gem.use_paths "#{@gemhome}2" # Set GEM_HOME to an uninitialized repo
|
|
|
|
@spec = util_spec 'a'
|
|
|
|
path = Gem::Package.build @spec
|
|
|
|
installer = Gem::Installer.at path, :install_dir => "#{@gemhome}3"
|
|
assert_equal @spec, installer.install
|
|
end
|
|
|
|
def test_initialize
|
|
spec = util_spec 'a' do |s|
|
|
s.platform = Gem::Platform.new 'mswin32'
|
|
end
|
|
|
|
gem = File.join @tempdir, spec.file_name
|
|
|
|
Dir.mkdir util_inst_bindir
|
|
util_build_gem spec
|
|
FileUtils.mv spec.cache_file, @tempdir
|
|
|
|
installer = Gem::Installer.at gem
|
|
|
|
assert_equal File.join(@gemhome, 'gems', spec.full_name), installer.gem_dir
|
|
assert_equal File.join(@gemhome, 'bin'), installer.bin_dir
|
|
end
|
|
|
|
def test_initialize_user_install
|
|
@gem = setup_base_gem
|
|
|
|
installer = Gem::Installer.at @gem, :user_install => true
|
|
|
|
assert_equal File.join(Gem.user_dir, 'gems', @spec.full_name),
|
|
installer.gem_dir
|
|
assert_equal Gem.bindir(Gem.user_dir), installer.bin_dir
|
|
end
|
|
|
|
def test_initialize_user_install_bin_dir
|
|
@gem = setup_base_gem
|
|
|
|
installer =
|
|
Gem::Installer.at @gem, :user_install => true, :bin_dir => @tempdir
|
|
|
|
assert_equal File.join(Gem.user_dir, 'gems', @spec.full_name),
|
|
installer.gem_dir
|
|
assert_equal @tempdir, installer.bin_dir
|
|
end
|
|
|
|
def test_install
|
|
installer = util_setup_installer
|
|
|
|
gemdir = File.join @gemhome, 'gems', @spec.full_name
|
|
cache_file = File.join @gemhome, 'cache', @spec.file_name
|
|
stub_exe = File.join @gemhome, 'bin', 'executable'
|
|
rakefile = File.join gemdir, 'ext', 'a', 'Rakefile'
|
|
spec_file = File.join @gemhome, 'specifications', @spec.spec_name
|
|
|
|
Gem.pre_install do
|
|
assert_path_not_exist cache_file, 'cache file must not exist yet'
|
|
true
|
|
end
|
|
|
|
Gem.post_build do
|
|
assert_path_exist gemdir, 'gem install dir must exist'
|
|
assert_path_exist rakefile, 'gem executable must exist'
|
|
assert_path_not_exist stub_exe, 'gem executable must not exist'
|
|
true
|
|
end
|
|
|
|
Gem.post_install do
|
|
assert_path_exist cache_file, 'cache file must exist'
|
|
end
|
|
|
|
@newspec = nil
|
|
build_rake_in do
|
|
use_ui @ui do
|
|
@newspec = installer.install
|
|
end
|
|
end
|
|
|
|
assert_equal @spec, @newspec
|
|
assert_path_exist gemdir
|
|
assert_path_exist stub_exe, 'gem executable must exist'
|
|
|
|
exe = File.join gemdir, 'bin', 'executable'
|
|
assert_path_exist exe
|
|
|
|
exe_mode = File.stat(exe).mode & 0111
|
|
assert_equal 0111, exe_mode, "0%o" % exe_mode unless win_platform?
|
|
|
|
assert_path_exist File.join gemdir, 'lib', 'code.rb'
|
|
|
|
assert_path_exist rakefile
|
|
|
|
assert_equal spec_file, @newspec.loaded_from
|
|
assert_path_exist spec_file
|
|
|
|
assert_same installer, @post_build_hook_arg
|
|
assert_same installer, @post_install_hook_arg
|
|
assert_same installer, @pre_install_hook_arg
|
|
end
|
|
|
|
def test_install_creates_working_binstub
|
|
installer = util_setup_installer
|
|
|
|
installer.wrappers = true
|
|
|
|
gemdir = File.join @gemhome, 'gems', @spec.full_name
|
|
|
|
@newspec = nil
|
|
build_rake_in do
|
|
use_ui @ui do
|
|
@newspec = installer.install
|
|
end
|
|
end
|
|
|
|
exe = File.join gemdir, 'bin', 'executable'
|
|
|
|
e = assert_raise RuntimeError do
|
|
instance_eval File.read(exe)
|
|
end
|
|
|
|
assert_match(/ran executable/, e.message)
|
|
end
|
|
|
|
def test_conflicting_binstubs
|
|
@gem = setup_base_gem
|
|
|
|
# build old version that has a bin file
|
|
installer = util_setup_gem do |spec|
|
|
File.open File.join('bin', 'executable'), 'w' do |f|
|
|
f.puts "require 'code'"
|
|
end
|
|
File.open File.join('lib', 'code.rb'), 'w' do |f|
|
|
f.puts 'raise "I have an executable"'
|
|
end
|
|
end
|
|
|
|
installer.wrappers = true
|
|
build_rake_in do
|
|
use_ui @ui do
|
|
@newspec = installer.install
|
|
end
|
|
end
|
|
|
|
old_bin_file = File.join installer.bin_dir, 'executable'
|
|
|
|
# build new version that doesn't have a bin file
|
|
installer = util_setup_gem do |spec|
|
|
FileUtils.rm File.join('bin', 'executable')
|
|
spec.files.delete File.join('bin', 'executable')
|
|
spec.executables.delete 'executable'
|
|
spec.version = @spec.version.bump
|
|
File.open File.join('lib', 'code.rb'), 'w' do |f|
|
|
f.puts 'raise "I do not have an executable"'
|
|
end
|
|
end
|
|
|
|
build_rake_in do
|
|
use_ui @ui do
|
|
@newspec = installer.install
|
|
end
|
|
end
|
|
|
|
e = assert_raise RuntimeError do
|
|
instance_eval File.read(old_bin_file)
|
|
end
|
|
|
|
# We expect the bin stub to activate the version that actually contains
|
|
# the binstub.
|
|
assert_match('I have an executable', e.message)
|
|
end
|
|
|
|
def test_install_creates_binstub_that_understand_version
|
|
installer = util_setup_installer
|
|
|
|
installer.wrappers = true
|
|
|
|
@newspec = nil
|
|
build_rake_in do
|
|
use_ui @ui do
|
|
@newspec = installer.install
|
|
end
|
|
end
|
|
|
|
exe = File.join @gemhome, 'bin', 'executable'
|
|
|
|
ARGV.unshift "_3.0_"
|
|
|
|
begin
|
|
Gem::Specification.reset
|
|
|
|
e = assert_raise Gem::GemNotFoundException do
|
|
instance_eval File.read(exe)
|
|
end
|
|
ensure
|
|
ARGV.shift if ARGV.first == "_3.0_"
|
|
end
|
|
|
|
assert_includes(e.message, "can't find gem a (= 3.0)")
|
|
end
|
|
|
|
def test_install_creates_binstub_that_prefers_user_installed_gem_to_default
|
|
default_spec = new_default_spec('default', '2', nil, 'exe/executable')
|
|
default_spec.executables = 'executable'
|
|
install_default_gems default_spec
|
|
|
|
exe = File.join @gemhome, 'bin', 'executable'
|
|
|
|
assert_path_exist exe, "default gem's executable not installed"
|
|
|
|
installer = util_setup_installer do |spec|
|
|
spec.name = 'default'
|
|
spec.version = '2'
|
|
end
|
|
|
|
util_clear_gems
|
|
|
|
installer.wrappers = true
|
|
|
|
@newspec = nil
|
|
build_rake_in do
|
|
use_ui @ui do
|
|
@newspec = installer.install
|
|
end
|
|
end
|
|
|
|
e = assert_raise RuntimeError do
|
|
instance_eval File.read(exe)
|
|
end
|
|
|
|
assert_equal(e.message, "ran executable")
|
|
end
|
|
|
|
def test_install_creates_binstub_that_dont_trust_encoding
|
|
installer = util_setup_installer
|
|
|
|
installer.wrappers = true
|
|
|
|
@newspec = nil
|
|
build_rake_in do
|
|
use_ui @ui do
|
|
@newspec = installer.install
|
|
end
|
|
end
|
|
|
|
exe = File.join @gemhome, 'bin', 'executable'
|
|
|
|
extra_arg = "\xE4pfel".dup.force_encoding("UTF-8")
|
|
ARGV.unshift extra_arg
|
|
|
|
begin
|
|
Gem::Specification.reset
|
|
|
|
e = assert_raise RuntimeError do
|
|
instance_eval File.read(exe)
|
|
end
|
|
ensure
|
|
ARGV.shift if ARGV.first == extra_arg
|
|
end
|
|
|
|
assert_match(/ran executable/, e.message)
|
|
end
|
|
|
|
def test_install_with_no_prior_files
|
|
installer = util_setup_installer
|
|
|
|
build_rake_in do
|
|
use_ui @ui do
|
|
assert_equal @spec, installer.install
|
|
end
|
|
end
|
|
|
|
gemdir = File.join(@gemhome, 'gems', @spec.full_name)
|
|
assert_path_exist File.join gemdir, 'lib', 'code.rb'
|
|
|
|
installer = util_setup_installer
|
|
|
|
# Morph spec to have lib/other.rb instead of code.rb and recreate
|
|
@spec.files = File.join('lib', 'other.rb')
|
|
Dir.chdir @tempdir do
|
|
File.open File.join('lib', 'other.rb'), 'w' do |f|
|
|
f.puts '1'
|
|
end
|
|
|
|
use_ui ui do
|
|
FileUtils.rm @gem
|
|
Gem::Package.build @spec
|
|
end
|
|
end
|
|
installer = Gem::Installer.at @gem, :force => true
|
|
build_rake_in do
|
|
use_ui @ui do
|
|
assert_equal @spec, installer.install
|
|
end
|
|
end
|
|
|
|
assert_path_exist File.join gemdir, 'lib', 'other.rb'
|
|
assert_path_not_exist File.join gemdir, 'lib', 'code.rb',
|
|
"code.rb from prior install of same gem shouldn't remain here"
|
|
end
|
|
|
|
def test_install_force
|
|
_, missing_dep_gem = util_gem 'missing_dep', '1' do |s|
|
|
s.add_dependency 'doesnt_exist', '1'
|
|
end
|
|
|
|
use_ui @ui do
|
|
installer = Gem::Installer.at missing_dep_gem, :force => true
|
|
installer.install
|
|
end
|
|
|
|
gem_dir = File.join(@gemhome, 'gems', 'missing_dep-1')
|
|
assert_path_exist gem_dir
|
|
end
|
|
|
|
def test_install_build_root
|
|
build_root = File.join(@tempdir, 'build_root')
|
|
|
|
@gem = setup_base_gem
|
|
installer = Gem::Installer.at @gem, :build_root => build_root
|
|
|
|
assert_equal @spec, installer.install
|
|
end
|
|
|
|
def test_install_missing_dirs
|
|
installer = setup_base_installer
|
|
|
|
FileUtils.rm_f File.join(Gem.dir, 'cache')
|
|
FileUtils.rm_f File.join(Gem.dir, 'doc')
|
|
FileUtils.rm_f File.join(Gem.dir, 'specifications')
|
|
|
|
use_ui @ui do
|
|
installer.install
|
|
end
|
|
|
|
assert_directory_exists File.join(Gem.dir, 'cache')
|
|
assert_directory_exists File.join(Gem.dir, 'doc')
|
|
assert_directory_exists File.join(Gem.dir, 'specifications')
|
|
|
|
assert_path_exist File.join @gemhome, 'cache', @spec.file_name
|
|
assert_path_exist File.join @gemhome, 'specifications', @spec.spec_name
|
|
end
|
|
|
|
def test_install_post_build_false
|
|
@spec = util_spec 'a'
|
|
|
|
util_build_gem @spec
|
|
|
|
installer = util_installer @spec, @gemhome
|
|
|
|
Gem.post_build do
|
|
false
|
|
end
|
|
|
|
use_ui @ui do
|
|
e = assert_raise Gem::InstallError do
|
|
installer.install
|
|
end
|
|
|
|
location = "#{__FILE__}:#{__LINE__ - 9}"
|
|
|
|
assert_equal "post-build hook at #{location} failed for a-2", e.message
|
|
end
|
|
|
|
spec_file = File.join @gemhome, 'specifications', @spec.spec_name
|
|
assert_path_not_exist spec_file
|
|
|
|
gem_dir = File.join @gemhome, 'gems', @spec.full_name
|
|
assert_path_not_exist gem_dir
|
|
end
|
|
|
|
def test_install_post_build_nil
|
|
installer = setup_base_installer
|
|
|
|
Gem.post_build do
|
|
nil
|
|
end
|
|
|
|
use_ui @ui do
|
|
installer.install
|
|
end
|
|
|
|
spec_file = File.join @gemhome, 'specifications', @spec.spec_name
|
|
assert_path_exist spec_file
|
|
|
|
gem_dir = File.join @gemhome, 'gems', @spec.full_name
|
|
assert_path_exist gem_dir
|
|
end
|
|
|
|
def test_install_pre_install_false
|
|
@spec = util_spec 'a'
|
|
|
|
util_build_gem @spec
|
|
|
|
installer = util_installer @spec, @gemhome
|
|
|
|
Gem.pre_install do
|
|
false
|
|
end
|
|
|
|
use_ui @ui do
|
|
e = assert_raise Gem::InstallError do
|
|
installer.install
|
|
end
|
|
|
|
location = "#{__FILE__}:#{__LINE__ - 9}"
|
|
|
|
assert_equal "pre-install hook at #{location} failed for a-2", e.message
|
|
end
|
|
|
|
spec_file = File.join @gemhome, 'specifications', @spec.spec_name
|
|
assert_path_not_exist spec_file
|
|
end
|
|
|
|
def test_install_pre_install_nil
|
|
installer = setup_base_installer
|
|
|
|
Gem.pre_install do
|
|
nil
|
|
end
|
|
|
|
use_ui @ui do
|
|
installer.install
|
|
end
|
|
|
|
spec_file = File.join @gemhome, 'specifications', @spec.spec_name
|
|
assert_path_exist spec_file
|
|
end
|
|
|
|
def test_install_with_message
|
|
@spec = setup_base_spec
|
|
@spec.post_install_message = 'I am a shiny gem!'
|
|
|
|
use_ui @ui do
|
|
path = Gem::Package.build @spec
|
|
|
|
installer = Gem::Installer.at path
|
|
installer.install
|
|
end
|
|
|
|
assert_match %r{I am a shiny gem!}, @ui.output
|
|
end
|
|
|
|
def test_install_with_skipped_message
|
|
@spec = setup_base_spec
|
|
@spec.post_install_message = 'I am a shiny gem!'
|
|
|
|
use_ui @ui do
|
|
path = Gem::Package.build @spec
|
|
|
|
installer = Gem::Installer.at path, :post_install_message => false
|
|
installer.install
|
|
end
|
|
|
|
refute_match %r{I am a shiny gem!}, @ui.output
|
|
end
|
|
|
|
def test_install_extension_dir
|
|
gemhome2 = "#{@gemhome}2"
|
|
|
|
@spec = setup_base_spec
|
|
@spec.extensions << "extconf.rb"
|
|
write_file File.join(@tempdir, "extconf.rb") do |io|
|
|
io.write <<-RUBY
|
|
require "mkmf"
|
|
create_makefile("#{@spec.name}")
|
|
RUBY
|
|
end
|
|
|
|
@spec.files += %w[extconf.rb]
|
|
|
|
use_ui @ui do
|
|
path = Gem::Package.build @spec
|
|
|
|
installer = Gem::Installer.at path, :install_dir => gemhome2
|
|
installer.install
|
|
end
|
|
|
|
expected_makefile = File.join gemhome2, 'gems', @spec.full_name, 'Makefile'
|
|
|
|
assert_path_exist expected_makefile
|
|
end
|
|
|
|
def test_install_extension_dir_is_removed_on_reinstall
|
|
@spec = setup_base_spec
|
|
|
|
@spec.extensions << "extconf.rb"
|
|
write_file File.join(@tempdir, "extconf.rb") do |io|
|
|
io.write <<-RUBY
|
|
require "mkmf"
|
|
create_makefile("#{@spec.name}")
|
|
RUBY
|
|
end
|
|
|
|
@spec.files += %w[extconf.rb]
|
|
|
|
path = Gem::Package.build @spec
|
|
|
|
# Install a gem with an extension
|
|
use_ui @ui do
|
|
installer = Gem::Installer.at path
|
|
installer.install
|
|
end
|
|
|
|
# pretend that a binary file was created as part of the build
|
|
should_be_removed = File.join(@spec.extension_dir, "#{@spec.name}.so")
|
|
write_file should_be_removed do |io|
|
|
io.write "DELETE ME ON REINSTALL"
|
|
end
|
|
assert_path_exist should_be_removed
|
|
|
|
# reinstall the gem, this is also the same as pristine
|
|
use_ui @ui do
|
|
installer = Gem::Installer.at path, :force => true
|
|
installer.install
|
|
end
|
|
|
|
assert_path_not_exist should_be_removed
|
|
end
|
|
|
|
def test_install_user_extension_dir
|
|
@spec = setup_base_spec
|
|
@spec.extensions << "extconf.rb"
|
|
write_file File.join(@tempdir, "extconf.rb") do |io|
|
|
io.write <<-RUBY
|
|
require "mkmf"
|
|
create_makefile("#{@spec.name}")
|
|
RUBY
|
|
end
|
|
|
|
@spec.files += %w[extconf.rb]
|
|
|
|
# Create the non-user ext dir
|
|
expected_extension_dir = @spec.extension_dir.dup
|
|
FileUtils.mkdir_p expected_extension_dir
|
|
|
|
use_ui @ui do
|
|
path = Gem::Package.build @spec
|
|
|
|
installer = Gem::Installer.at path, :user_install => true
|
|
installer.install
|
|
end
|
|
|
|
expected_makefile = File.join Gem.user_dir, 'gems', @spec.full_name, 'Makefile'
|
|
|
|
assert_path_exist expected_makefile
|
|
assert_path_exist expected_extension_dir
|
|
assert_path_not_exist File.join expected_extension_dir, 'gem_make.out'
|
|
end
|
|
|
|
def test_find_lib_file_after_install
|
|
pend "extensions don't quite work on jruby" if Gem.java_platform?
|
|
|
|
@spec = setup_base_spec
|
|
@spec.extensions << "extconf.rb"
|
|
write_file File.join(@tempdir, "extconf.rb") do |io|
|
|
io.write <<-RUBY
|
|
require "mkmf"
|
|
|
|
CONFIG['CC'] = '$(TOUCH) $@ ||'
|
|
CONFIG['LDSHARED'] = '$(TOUCH) $@ ||'
|
|
$ruby = '#{Gem.ruby}'
|
|
|
|
create_makefile("#{@spec.name}")
|
|
RUBY
|
|
end
|
|
|
|
write_file File.join(@tempdir, "depend")
|
|
|
|
write_file File.join(@tempdir, "a.c") do |io|
|
|
io.write <<-C
|
|
#include <ruby.h>
|
|
void Init_a() { }
|
|
C
|
|
end
|
|
|
|
Dir.mkdir File.join(@tempdir, "lib")
|
|
write_file File.join(@tempdir, 'lib', "b.rb") do |io|
|
|
io.write "# b.rb"
|
|
end
|
|
|
|
@spec.files += %w[extconf.rb lib/b.rb depend a.c]
|
|
|
|
use_ui @ui do
|
|
path = Gem::Package.build @spec
|
|
|
|
installer = Gem::Installer.at path
|
|
installer.install
|
|
end
|
|
|
|
expected = File.join @spec.full_require_paths.find {|path|
|
|
File.exist? File.join path, 'b.rb'
|
|
}, 'b.rb'
|
|
assert_equal expected, @spec.matches_for_glob('b.rb').first
|
|
end
|
|
|
|
def test_install_extension_and_script
|
|
pend "Makefile creation crashes on jruby" if Gem.java_platform?
|
|
pend if /mswin/ =~ RUBY_PLATFORM && ENV.key?('GITHUB_ACTIONS') # not working from the beginning
|
|
|
|
@spec = setup_base_spec
|
|
@spec.extensions << "extconf.rb"
|
|
write_file File.join(@tempdir, "extconf.rb") do |io|
|
|
io.write <<-RUBY
|
|
require "mkmf"
|
|
create_makefile("#{@spec.name}")
|
|
RUBY
|
|
end
|
|
|
|
rb = File.join("lib", "#{@spec.name}.rb")
|
|
@spec.files += [rb]
|
|
write_file File.join(@tempdir, rb) do |io|
|
|
io.write <<-RUBY
|
|
# #{@spec.name}.rb
|
|
RUBY
|
|
end
|
|
|
|
Dir.mkdir(File.join("lib", @spec.name))
|
|
rb2 = File.join("lib", @spec.name, "#{@spec.name}.rb")
|
|
@spec.files << rb2
|
|
write_file File.join(@tempdir, rb2) do |io|
|
|
io.write <<-RUBY
|
|
# #{@spec.name}/#{@spec.name}.rb
|
|
RUBY
|
|
end
|
|
|
|
assert_path_not_exist File.join @spec.gem_dir, rb
|
|
assert_path_not_exist File.join @spec.gem_dir, rb2
|
|
use_ui @ui do
|
|
path = Gem::Package.build @spec
|
|
|
|
installer = Gem::Installer.at path
|
|
installer.install
|
|
end
|
|
assert_path_exist File.join @spec.gem_dir, rb
|
|
assert_path_exist File.join @spec.gem_dir, rb2
|
|
end
|
|
|
|
def test_install_extension_flat
|
|
pend "extensions don't quite work on jruby" if Gem.java_platform?
|
|
|
|
begin
|
|
@spec = setup_base_spec
|
|
@spec.require_paths = ["."]
|
|
|
|
@spec.extensions << "extconf.rb"
|
|
|
|
write_file File.join(@tempdir, "extconf.rb") do |io|
|
|
io.write <<-RUBY
|
|
require "mkmf"
|
|
|
|
CONFIG['CC'] = '$(TOUCH) $@ ||'
|
|
CONFIG['LDSHARED'] = '$(TOUCH) $@ ||'
|
|
$ruby = '#{Gem.ruby}'
|
|
|
|
create_makefile("#{@spec.name}")
|
|
RUBY
|
|
end
|
|
|
|
# empty depend file for no auto dependencies
|
|
@spec.files += %W[depend #{@spec.name}.c].each do |file|
|
|
write_file File.join(@tempdir, file)
|
|
end
|
|
|
|
so = File.join(@spec.gem_dir, "#{@spec.name}.#{RbConfig::CONFIG["DLEXT"]}")
|
|
assert_path_not_exist so
|
|
use_ui @ui do
|
|
path = Gem::Package.build @spec
|
|
|
|
installer = Gem::Installer.at path
|
|
installer.install
|
|
end
|
|
assert_path_exist so
|
|
rescue
|
|
puts '-' * 78
|
|
puts File.read File.join(@gemhome, 'gems', 'a-2', 'Makefile')
|
|
puts '-' * 78
|
|
|
|
path = File.join(@gemhome, 'gems', 'a-2', 'gem_make.out')
|
|
|
|
if File.exist?(path)
|
|
puts File.read(path)
|
|
puts '-' * 78
|
|
end
|
|
|
|
raise
|
|
end
|
|
end
|
|
|
|
def test_installation_satisfies_dependency_eh
|
|
installer = setup_base_installer
|
|
|
|
util_spec 'a'
|
|
|
|
dep = Gem::Dependency.new 'a', '>= 2'
|
|
assert installer.installation_satisfies_dependency?(dep)
|
|
|
|
dep = Gem::Dependency.new 'a', '> 2'
|
|
refute installer.installation_satisfies_dependency?(dep)
|
|
end
|
|
|
|
def test_installation_satisfies_dependency_eh_development
|
|
installer = setup_base_installer
|
|
installer.options[:development] = true
|
|
installer.options[:dev_shallow] = true
|
|
|
|
util_spec 'a'
|
|
|
|
dep = Gem::Dependency.new 'a', :development
|
|
assert installer.installation_satisfies_dependency?(dep)
|
|
end
|
|
|
|
def test_pre_install_checks_dependencies
|
|
installer = setup_base_installer
|
|
@spec.add_dependency 'b', '> 5'
|
|
installer = util_setup_gem
|
|
installer.force = false
|
|
|
|
use_ui @ui do
|
|
assert_raise Gem::InstallError do
|
|
installer.install
|
|
end
|
|
end
|
|
end
|
|
|
|
def test_pre_install_checks_dependencies_ignore
|
|
installer = util_setup_installer
|
|
@spec.add_dependency 'b', '> 5'
|
|
installer.ignore_dependencies = true
|
|
|
|
build_rake_in do
|
|
use_ui @ui do
|
|
assert installer.pre_install_checks
|
|
end
|
|
end
|
|
end
|
|
|
|
def test_pre_install_checks_dependencies_install_dir
|
|
gemhome2 = "#{@gemhome}2"
|
|
|
|
@gem = setup_base_gem
|
|
@spec.add_dependency 'd'
|
|
|
|
quick_gem 'd', 2
|
|
|
|
gem = File.join @gemhome, @spec.file_name
|
|
|
|
FileUtils.mv @gemhome, gemhome2
|
|
FileUtils.mkdir @gemhome
|
|
|
|
FileUtils.mv File.join(gemhome2, 'cache', @spec.file_name), gem
|
|
|
|
# Don't leak any already activated gems into the installer, require
|
|
# that it work everything out on it's own.
|
|
Gem::Specification.reset
|
|
|
|
installer = Gem::Installer.at gem, :install_dir => gemhome2
|
|
|
|
build_rake_in do
|
|
use_ui @ui do
|
|
assert installer.pre_install_checks
|
|
end
|
|
end
|
|
end
|
|
|
|
def test_pre_install_checks_malicious_name
|
|
spec = util_spec '../malicious', '1'
|
|
def spec.full_name # so the spec is buildable
|
|
"malicious-1"
|
|
end
|
|
def spec.validate(packaging, strict); end
|
|
|
|
util_build_gem spec
|
|
|
|
gem = File.join(@gemhome, 'cache', spec.file_name)
|
|
|
|
use_ui @ui do
|
|
installer = Gem::Installer.at gem
|
|
e = assert_raise Gem::InstallError do
|
|
installer.pre_install_checks
|
|
end
|
|
assert_equal '#<Gem::Specification name=../malicious version=1> has an invalid name', e.message
|
|
end
|
|
end
|
|
|
|
def test_pre_install_checks_malicious_name_before_eval
|
|
spec = util_spec "malicious\n::Object.const_set(:FROM_EVAL, true)#", '1'
|
|
def spec.full_name # so the spec is buildable
|
|
"malicious-1"
|
|
end
|
|
def spec.validate(*args); end
|
|
|
|
util_build_gem spec
|
|
|
|
gem = File.join(@gemhome, 'cache', spec.file_name)
|
|
|
|
use_ui @ui do
|
|
installer = Gem::Installer.at gem
|
|
e = assert_raise Gem::InstallError do
|
|
installer.pre_install_checks
|
|
end
|
|
assert_equal "#<Gem::Specification name=malicious\n::Object.const_set(:FROM_EVAL, true)# version=1> has an invalid name", e.message
|
|
end
|
|
refute defined?(::Object::FROM_EVAL)
|
|
end
|
|
|
|
def test_pre_install_checks_malicious_require_paths_before_eval
|
|
spec = util_spec "malicious", '1'
|
|
def spec.full_name # so the spec is buildable
|
|
"malicious-1"
|
|
end
|
|
def spec.validate(*args); end
|
|
spec.require_paths = ["malicious\n``"]
|
|
|
|
util_build_gem spec
|
|
|
|
gem = File.join(@gemhome, 'cache', spec.file_name)
|
|
|
|
use_ui @ui do
|
|
installer = Gem::Installer.at gem
|
|
e = assert_raise Gem::InstallError do
|
|
installer.pre_install_checks
|
|
end
|
|
assert_equal "#<Gem::Specification name=malicious version=1> has an invalid require_paths", e.message
|
|
end
|
|
end
|
|
|
|
def test_pre_install_checks_malicious_extensions_before_eval
|
|
pend "mswin environment disallow to create file contained the carriage return code." if Gem.win_platform?
|
|
|
|
spec = util_spec "malicious", '1'
|
|
def spec.full_name # so the spec is buildable
|
|
"malicious-1"
|
|
end
|
|
def spec.validate(*args); end
|
|
spec.extensions = ["malicious\n``"]
|
|
|
|
util_build_gem spec
|
|
|
|
gem = File.join(@gemhome, 'cache', spec.file_name)
|
|
|
|
use_ui @ui do
|
|
installer = Gem::Installer.at gem
|
|
e = assert_raise Gem::InstallError do
|
|
installer.pre_install_checks
|
|
end
|
|
assert_equal "#<Gem::Specification name=malicious version=1> has an invalid extensions", e.message
|
|
end
|
|
end
|
|
|
|
def test_pre_install_checks_malicious_specification_version_before_eval
|
|
spec = util_spec "malicious", '1'
|
|
def spec.full_name # so the spec is buildable
|
|
"malicious-1"
|
|
end
|
|
def spec.validate(*args); end
|
|
spec.specification_version = "malicious\n``"
|
|
|
|
util_build_gem spec
|
|
|
|
gem = File.join(@gemhome, 'cache', spec.file_name)
|
|
|
|
use_ui @ui do
|
|
installer = Gem::Installer.at gem
|
|
e = assert_raise Gem::InstallError do
|
|
installer.pre_install_checks
|
|
end
|
|
assert_equal "#<Gem::Specification name=malicious version=1> has an invalid specification_version", e.message
|
|
end
|
|
end
|
|
|
|
def test_pre_install_checks_malicious_dependencies_before_eval
|
|
spec = util_spec "malicious", '1'
|
|
def spec.full_name # so the spec is buildable
|
|
"malicious-1"
|
|
end
|
|
def spec.validate(*args); end
|
|
spec.add_dependency "b\nfoo", '> 5'
|
|
|
|
util_build_gem spec
|
|
|
|
gem = File.join(@gemhome, 'cache', spec.file_name)
|
|
|
|
use_ui @ui do
|
|
installer = Gem::Installer.at gem
|
|
installer.ignore_dependencies = true
|
|
e = assert_raise Gem::InstallError do
|
|
installer.pre_install_checks
|
|
end
|
|
assert_equal "#<Gem::Specification name=malicious version=1> has an invalid dependencies", e.message
|
|
end
|
|
end
|
|
|
|
def test_pre_install_checks_malicious_platform_before_eval
|
|
gem_with_ill_formated_platform = File.expand_path("packages/ill-formatted-platform-1.0.0.10.gem", __dir__)
|
|
|
|
installer = Gem::Installer.at(
|
|
gem_with_ill_formated_platform,
|
|
:install_dir => @gem_home,
|
|
:user_install => false,
|
|
:force => true
|
|
)
|
|
|
|
use_ui @ui do
|
|
e = assert_raise Gem::InstallError do
|
|
installer.pre_install_checks
|
|
end
|
|
|
|
assert_equal "x86-mswin32\n system('id > /tmp/nyangawa')# is an invalid platform", e.message
|
|
assert_empty @ui.output
|
|
end
|
|
end
|
|
|
|
def test_shebang
|
|
installer = setup_base_installer
|
|
|
|
util_make_exec @spec, "#!/usr/bin/ruby"
|
|
|
|
shebang = installer.shebang 'executable'
|
|
|
|
assert_equal "#!#{Gem.ruby}", shebang
|
|
end
|
|
|
|
def test_process_options
|
|
installer = setup_base_installer
|
|
|
|
assert_nil installer.build_root
|
|
assert_equal File.join(@gemhome, 'bin'), installer.bin_dir
|
|
assert_equal @gemhome, installer.gem_home
|
|
end
|
|
|
|
def test_process_options_build_root
|
|
build_root = File.join @tempdir, 'build_root'
|
|
bin_dir = File.join(build_root, @gemhome.gsub(/^[a-zA-Z]:/, ''), 'bin')
|
|
gem_home = File.join(build_root, @gemhome.gsub(/^[a-zA-Z]:/, ''))
|
|
plugins_dir = File.join(build_root, @gemhome.gsub(/^[a-zA-Z]:/, ''), 'plugins')
|
|
|
|
@gem = setup_base_gem
|
|
installer = use_ui(@ui) { Gem::Installer.at @gem, :build_root => build_root }
|
|
|
|
assert_equal build_root, installer.build_root
|
|
assert_equal bin_dir, installer.bin_dir
|
|
assert_equal gem_home, installer.gem_home
|
|
|
|
errors = @ui.error.split("\n")
|
|
|
|
assert_equal "WARNING: You build with buildroot.", errors.shift
|
|
assert_equal " Build root: #{build_root}", errors.shift
|
|
assert_equal " Bin dir: #{bin_dir}", errors.shift
|
|
assert_equal " Gem home: #{gem_home}", errors.shift
|
|
assert_equal " Plugins dir: #{plugins_dir}", errors.shift
|
|
end
|
|
|
|
def test_shebang_arguments
|
|
installer = setup_base_installer
|
|
|
|
util_make_exec @spec, "#!/usr/bin/ruby -ws"
|
|
|
|
shebang = installer.shebang 'executable'
|
|
|
|
assert_equal "#!#{Gem.ruby} -ws", shebang
|
|
end
|
|
|
|
def test_shebang_empty
|
|
installer = setup_base_installer
|
|
|
|
util_make_exec @spec, ''
|
|
|
|
shebang = installer.shebang 'executable'
|
|
assert_equal "#!#{Gem.ruby}", shebang
|
|
end
|
|
|
|
def test_shebang_env
|
|
installer = setup_base_installer
|
|
|
|
util_make_exec @spec, "#!/usr/bin/env ruby"
|
|
|
|
shebang = installer.shebang 'executable'
|
|
|
|
assert_equal "#!#{Gem.ruby}", shebang
|
|
end
|
|
|
|
def test_shebang_env_arguments
|
|
installer = setup_base_installer
|
|
|
|
util_make_exec @spec, "#!/usr/bin/env ruby -ws"
|
|
|
|
shebang = installer.shebang 'executable'
|
|
|
|
assert_equal "#!#{Gem.ruby} -ws", shebang
|
|
end
|
|
|
|
def test_shebang_env_shebang
|
|
installer = setup_base_installer
|
|
|
|
util_make_exec @spec, ''
|
|
installer.env_shebang = true
|
|
|
|
shebang = installer.shebang 'executable'
|
|
|
|
bin_env = get_bin_env
|
|
|
|
assert_equal("#!#{bin_env} #{RbConfig::CONFIG['ruby_install_name']}",
|
|
shebang)
|
|
end
|
|
|
|
def test_shebang_nested
|
|
installer = setup_base_installer
|
|
|
|
util_make_exec @spec, "#!/opt/local/ruby/bin/ruby"
|
|
|
|
shebang = installer.shebang 'executable'
|
|
|
|
assert_equal "#!#{Gem.ruby}", shebang
|
|
end
|
|
|
|
def test_shebang_nested_arguments
|
|
installer = setup_base_installer
|
|
|
|
util_make_exec @spec, "#!/opt/local/ruby/bin/ruby -ws"
|
|
|
|
shebang = installer.shebang 'executable'
|
|
|
|
assert_equal "#!#{Gem.ruby} -ws", shebang
|
|
end
|
|
|
|
def test_shebang_version
|
|
installer = setup_base_installer
|
|
|
|
util_make_exec @spec, "#!/usr/bin/ruby18"
|
|
|
|
shebang = installer.shebang 'executable'
|
|
|
|
assert_equal "#!#{Gem.ruby}", shebang
|
|
end
|
|
|
|
def test_shebang_version_arguments
|
|
installer = setup_base_installer
|
|
|
|
util_make_exec @spec, "#!/usr/bin/ruby18 -ws"
|
|
|
|
shebang = installer.shebang 'executable'
|
|
|
|
assert_equal "#!#{Gem.ruby} -ws", shebang
|
|
end
|
|
|
|
def test_shebang_version_env
|
|
installer = setup_base_installer
|
|
|
|
util_make_exec @spec, "#!/usr/bin/env ruby18"
|
|
|
|
shebang = installer.shebang 'executable'
|
|
|
|
assert_equal "#!#{Gem.ruby}", shebang
|
|
end
|
|
|
|
def test_shebang_version_env_arguments
|
|
installer = setup_base_installer
|
|
|
|
util_make_exec @spec, "#!/usr/bin/env ruby18 -ws"
|
|
|
|
shebang = installer.shebang 'executable'
|
|
|
|
assert_equal "#!#{Gem.ruby} -ws", shebang
|
|
end
|
|
|
|
def test_shebang_custom
|
|
installer = setup_base_installer
|
|
|
|
conf = Gem::ConfigFile.new []
|
|
conf[:custom_shebang] = 'test'
|
|
|
|
Gem.configuration = conf
|
|
|
|
util_make_exec @spec, "#!/usr/bin/ruby"
|
|
|
|
shebang = installer.shebang 'executable'
|
|
|
|
assert_equal "#!test", shebang
|
|
end
|
|
|
|
def get_bin_env
|
|
if win_platform?
|
|
""
|
|
else
|
|
%w[/usr/bin/env /bin/env].find {|f| File.executable?(f) }
|
|
end
|
|
end
|
|
|
|
def test_shebang_custom_with_expands
|
|
installer = setup_base_installer
|
|
|
|
bin_env = get_bin_env
|
|
conf = Gem::ConfigFile.new []
|
|
conf[:custom_shebang] = '1 $env 2 $ruby 3 $exec 4 $name'
|
|
|
|
Gem.configuration = conf
|
|
|
|
util_make_exec @spec, "#!/usr/bin/ruby"
|
|
|
|
shebang = installer.shebang 'executable'
|
|
|
|
assert_equal "#!1 #{bin_env} 2 #{Gem.ruby} 3 executable 4 a", shebang
|
|
end
|
|
|
|
def test_shebang_custom_with_expands_and_arguments
|
|
installer = setup_base_installer
|
|
|
|
bin_env = get_bin_env
|
|
conf = Gem::ConfigFile.new []
|
|
conf[:custom_shebang] = '1 $env 2 $ruby 3 $exec'
|
|
|
|
Gem.configuration = conf
|
|
|
|
util_make_exec @spec, "#!/usr/bin/ruby -ws"
|
|
|
|
shebang = installer.shebang 'executable'
|
|
|
|
assert_equal "#!1 #{bin_env} 2 #{Gem.ruby} -ws 3 executable", shebang
|
|
end
|
|
|
|
def test_unpack
|
|
installer = util_setup_installer
|
|
|
|
dest = File.join @gemhome, 'gems', @spec.full_name
|
|
|
|
Gem::Deprecate.skip_during do
|
|
installer.unpack dest
|
|
end
|
|
|
|
assert_path_exist File.join dest, 'lib', 'code.rb'
|
|
assert_path_exist File.join dest, 'bin', 'executable'
|
|
end
|
|
|
|
def test_write_build_info_file
|
|
installer = setup_base_installer
|
|
|
|
assert_path_not_exist @spec.build_info_file
|
|
|
|
installer.build_args = %w[
|
|
--with-libyaml-dir /usr/local/Cellar/libyaml/0.1.4
|
|
]
|
|
|
|
installer.write_build_info_file
|
|
|
|
assert_path_exist @spec.build_info_file
|
|
|
|
expected = "--with-libyaml-dir\n/usr/local/Cellar/libyaml/0.1.4\n"
|
|
|
|
assert_equal expected, File.read(@spec.build_info_file)
|
|
end
|
|
|
|
def test_write_build_info_file_empty
|
|
installer = setup_base_installer
|
|
|
|
assert_path_not_exist @spec.build_info_file
|
|
|
|
installer.write_build_info_file
|
|
|
|
assert_path_not_exist @spec.build_info_file
|
|
end
|
|
|
|
def test_write_build_info_file_install_dir
|
|
@gem = setup_base_gem
|
|
installer = Gem::Installer.at @gem, :install_dir => "#{@gemhome}2"
|
|
|
|
installer.build_args = %w[
|
|
--with-libyaml-dir /usr/local/Cellar/libyaml/0.1.4
|
|
]
|
|
|
|
installer.write_build_info_file
|
|
|
|
assert_path_not_exist @spec.build_info_file
|
|
assert_path_exist \
|
|
File.join("#{@gemhome}2", 'build_info', "#{@spec.full_name}.info")
|
|
end
|
|
|
|
def test_write_cache_file
|
|
@gem = setup_base_gem
|
|
cache_file = File.join @gemhome, 'cache', @spec.file_name
|
|
gem = File.join @gemhome, @spec.file_name
|
|
|
|
FileUtils.mv cache_file, gem
|
|
assert_path_not_exist cache_file
|
|
|
|
installer = Gem::Installer.at gem
|
|
installer.gem_home = @gemhome
|
|
|
|
installer.write_cache_file
|
|
|
|
assert_path_exist cache_file
|
|
end
|
|
|
|
def test_write_spec
|
|
@spec = setup_base_spec
|
|
FileUtils.rm @spec.spec_file
|
|
assert_path_not_exist @spec.spec_file
|
|
|
|
installer = Gem::Installer.for_spec @spec
|
|
installer.gem_home = @gemhome
|
|
|
|
installer.write_spec
|
|
|
|
assert_path_exist @spec.spec_file
|
|
|
|
loaded = Gem::Specification.load @spec.spec_file
|
|
|
|
assert_equal @spec, loaded
|
|
|
|
assert_equal Gem.rubygems_version, @spec.installed_by_version
|
|
end
|
|
|
|
def test_write_spec_writes_cached_spec
|
|
@spec = setup_base_spec
|
|
FileUtils.rm @spec.spec_file
|
|
assert_path_not_exist @spec.spec_file
|
|
|
|
@spec.files = %w[a.rb b.rb c.rb]
|
|
|
|
installer = Gem::Installer.for_spec @spec
|
|
installer.gem_home = @gemhome
|
|
|
|
installer.write_spec
|
|
|
|
# cached specs have no file manifest:
|
|
@spec.files = []
|
|
|
|
assert_equal @spec, eval(File.read(@spec.spec_file))
|
|
end
|
|
|
|
def test_dir
|
|
installer = setup_base_installer
|
|
|
|
assert_match %r{/gemhome/gems/a-2$}, installer.dir
|
|
end
|
|
|
|
def test_default_gem_loaded_from
|
|
spec = util_spec 'a'
|
|
installer = Gem::Installer.for_spec spec, :install_as_default => true
|
|
installer.install
|
|
assert_predicate spec, :default_gem?
|
|
end
|
|
|
|
def test_default_gem_without_wrappers
|
|
installer = setup_base_installer
|
|
|
|
FileUtils.rm_f File.join(Gem.dir, 'specifications')
|
|
|
|
installer.wrappers = false
|
|
installer.options[:install_as_default] = true
|
|
installer.gem_dir = @spec.gem_dir
|
|
|
|
use_ui @ui do
|
|
installer.install
|
|
end
|
|
|
|
assert_directory_exists File.join(@spec.gem_dir, 'bin')
|
|
installed_exec = File.join @spec.gem_dir, 'bin', 'executable'
|
|
assert_path_exist installed_exec
|
|
|
|
assert_directory_exists File.join(Gem.default_dir, 'specifications')
|
|
assert_directory_exists File.join(Gem.default_dir, 'specifications', 'default')
|
|
|
|
default_spec = eval File.read File.join(Gem.default_dir, 'specifications', 'default', 'a-2.gemspec')
|
|
assert_equal Gem::Version.new("2"), default_spec.version
|
|
assert_equal ['bin/executable'], default_spec.files
|
|
|
|
assert_directory_exists util_inst_bindir
|
|
|
|
installed_exec = File.join util_inst_bindir, 'executable'
|
|
assert_path_exist installed_exec
|
|
|
|
wrapper = File.read installed_exec
|
|
|
|
if symlink_supported?
|
|
refute_match %r{generated by RubyGems}, wrapper
|
|
else # when symlink not supported, it warns and fallbacks back to installing wrapper
|
|
assert_match %r{Unable to use symlinks, installing wrapper}, @ui.error
|
|
assert_match %r{generated by RubyGems}, wrapper
|
|
end
|
|
end
|
|
|
|
def test_default_gem_with_wrappers
|
|
installer = setup_base_installer
|
|
|
|
installer.wrappers = true
|
|
installer.options[:install_as_default] = true
|
|
installer.gem_dir = @spec.gem_dir
|
|
|
|
use_ui @ui do
|
|
installer.install
|
|
end
|
|
|
|
assert_directory_exists util_inst_bindir
|
|
|
|
installed_exec = File.join util_inst_bindir, 'executable'
|
|
assert_path_exist installed_exec
|
|
|
|
wrapper = File.read installed_exec
|
|
assert_match %r{generated by RubyGems}, wrapper
|
|
end
|
|
|
|
def test_default_gem_with_exe_as_bindir
|
|
@spec = quick_gem 'c' do |spec|
|
|
util_make_exec spec, '#!/usr/bin/ruby', 'exe'
|
|
end
|
|
|
|
util_build_gem @spec
|
|
|
|
@spec.cache_file
|
|
|
|
installer = util_installer @spec, @gemhome
|
|
|
|
installer.options[:install_as_default] = true
|
|
installer.gem_dir = @spec.gem_dir
|
|
|
|
use_ui @ui do
|
|
installer.install
|
|
end
|
|
|
|
assert_directory_exists File.join(@spec.gem_dir, 'exe')
|
|
installed_exec = File.join @spec.gem_dir, 'exe', 'executable'
|
|
assert_path_exist installed_exec
|
|
|
|
assert_directory_exists File.join(Gem.default_dir, 'specifications')
|
|
assert_directory_exists File.join(Gem.default_dir, 'specifications', 'default')
|
|
|
|
default_spec = eval File.read File.join(Gem.default_dir, 'specifications', 'default', 'c-2.gemspec')
|
|
assert_equal Gem::Version.new("2"), default_spec.version
|
|
assert_equal ['exe/executable'], default_spec.files
|
|
end
|
|
|
|
def test_default_gem_to_specific_install_dir
|
|
@gem = setup_base_gem
|
|
installer = util_installer @spec, "#{@gemhome}2"
|
|
installer.options[:install_as_default] = true
|
|
|
|
use_ui @ui do
|
|
installer.install
|
|
end
|
|
|
|
assert_directory_exists File.join("#{@gemhome}2", 'specifications')
|
|
assert_directory_exists File.join("#{@gemhome}2", 'specifications', 'default')
|
|
|
|
default_spec = eval File.read File.join("#{@gemhome}2", 'specifications', 'default', 'a-2.gemspec')
|
|
assert_equal Gem::Version.new("2"), default_spec.version
|
|
assert_equal ['bin/executable'], default_spec.files
|
|
end
|
|
|
|
def test_package_attribute
|
|
gem = quick_gem 'c' do |spec|
|
|
util_make_exec spec, '#!/usr/bin/ruby', 'exe'
|
|
end
|
|
|
|
installer = util_installer(gem, @gemhome)
|
|
assert_respond_to(installer, :package)
|
|
assert_kind_of(Gem::Package, installer.package)
|
|
end
|
|
|
|
def test_gem_attribute
|
|
gem = quick_gem 'c' do |spec|
|
|
util_make_exec spec, '#!/usr/bin/ruby', 'exe'
|
|
end
|
|
|
|
installer = util_installer(gem, @gemhome)
|
|
assert_respond_to(installer, :gem)
|
|
assert_kind_of(String, installer.gem)
|
|
end
|
|
|
|
def util_execless
|
|
@spec = util_spec 'z'
|
|
util_build_gem @spec
|
|
|
|
util_installer @spec, @gemhome
|
|
end
|
|
|
|
def util_conflict_executable(wrappers)
|
|
conflict = quick_gem 'conflict' do |spec|
|
|
util_make_exec spec
|
|
end
|
|
|
|
util_build_gem conflict
|
|
|
|
installer = util_installer conflict, @gemhome
|
|
installer.wrappers = wrappers
|
|
installer.generate_bin
|
|
end
|
|
|
|
def mask
|
|
0100755
|
|
end
|
|
end
|