mirror of
https://github.com/ruby/ruby.git
synced 2025-08-15 13:39:04 +02:00

If a previous copy of a gem is already installed, RubyGems will not
reinstall the gem but only recompile its extensions. This seems like a
good idea, but only if the gem is being installed from the registry.
If we are installing a locally built package, then the package should be
completely reinstalled and extensions compiled from the sources in the
locally built package, not from the sources in the previous
installation.
1c282d98d5
1279 lines
30 KiB
Ruby
1279 lines
30 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require_relative "helper"
|
|
require "rubygems/dependency_installer"
|
|
require "rubygems/security"
|
|
|
|
class TestGemDependencyInstaller < Gem::TestCase
|
|
def setup
|
|
super
|
|
common_installer_setup
|
|
|
|
@gems_dir = File.join @tempdir, "gems"
|
|
@cache_dir = File.join @gemhome, "cache"
|
|
|
|
FileUtils.mkdir @gems_dir
|
|
|
|
Gem::RemoteFetcher.fetcher = @fetcher = Gem::FakeFetcher.new
|
|
|
|
@original_platforms = Gem.platforms
|
|
Gem.platforms = []
|
|
end
|
|
|
|
def teardown
|
|
Gem.platforms = @original_platforms
|
|
super
|
|
end
|
|
|
|
def util_setup_gems
|
|
@a1, @a1_gem = util_gem "a", "1" do |s|
|
|
s.executables << "a_bin"
|
|
end
|
|
|
|
@a1_pre, @a1_pre_gem = util_gem "a", "1.a"
|
|
|
|
@b1, @b1_gem = util_gem "b", "1" do |s|
|
|
s.add_dependency "a"
|
|
s.add_development_dependency "aa"
|
|
end
|
|
|
|
@c1, @c1_gem = util_gem "c", "1" do |s|
|
|
s.add_development_dependency "b"
|
|
end
|
|
|
|
@d1, @d1_gem = util_gem "d", "1" do |s|
|
|
s.add_development_dependency "c"
|
|
end
|
|
|
|
util_setup_spec_fetcher(@a1, @a1_pre, @b1, @d1)
|
|
end
|
|
|
|
def test_install
|
|
util_setup_gems
|
|
|
|
FileUtils.mv @a1_gem, @tempdir
|
|
inst = nil
|
|
|
|
Dir.chdir @tempdir do
|
|
inst = Gem::DependencyInstaller.new
|
|
inst.install "a"
|
|
end
|
|
|
|
assert_equal %w[a-1], Gem::Specification.map(&:full_name)
|
|
assert_equal [@a1], inst.installed_gems
|
|
end
|
|
|
|
def test_install_prerelease
|
|
util_setup_gems
|
|
|
|
p1a, gem = util_gem "a", "10.a"
|
|
|
|
util_setup_spec_fetcher(p1a, @a1, @a1_pre)
|
|
|
|
p1a_data = Gem.read_binary(gem)
|
|
|
|
@fetcher.data["http://gems.example.com/gems/a-10.a.gem"] = p1a_data
|
|
|
|
dep = Gem::Dependency.new "a"
|
|
inst = Gem::DependencyInstaller.new prerelease: true
|
|
inst.install dep
|
|
|
|
assert_equal %w[a-10.a], Gem::Specification.map(&:full_name)
|
|
assert_equal [p1a], inst.installed_gems
|
|
end
|
|
|
|
def test_install_prerelease_bug_990
|
|
spec_fetcher do |fetcher|
|
|
fetcher.gem "a", "1.b" do |s|
|
|
s.add_dependency "b", "~> 1.a"
|
|
end
|
|
|
|
fetcher.gem "b", "1.b" do |s|
|
|
s.add_dependency "c", ">= 1"
|
|
end
|
|
|
|
fetcher.gem "c", "1.1.b"
|
|
end
|
|
|
|
dep = Gem::Dependency.new "a"
|
|
|
|
inst = Gem::DependencyInstaller.new prerelease: true
|
|
inst.install dep
|
|
|
|
assert_equal %w[a-1.b b-1.b c-1.1.b], Gem::Specification.map(&:full_name)
|
|
end
|
|
|
|
def test_install_when_only_prerelease
|
|
p1a, gem = util_gem "p", "1.a"
|
|
|
|
util_setup_spec_fetcher(p1a)
|
|
|
|
p1a_data = Gem.read_binary(gem)
|
|
|
|
@fetcher.data["http://gems.example.com/gems/p-1.a.gem"] = p1a_data
|
|
|
|
dep = Gem::Dependency.new "p"
|
|
inst = Gem::DependencyInstaller.new
|
|
assert_raise Gem::UnsatisfiableDependencyError do
|
|
inst.install dep
|
|
end
|
|
|
|
assert_equal %w[], Gem::Specification.map(&:full_name)
|
|
assert_equal [], inst.installed_gems
|
|
end
|
|
|
|
def test_install_prerelease_skipped_when_normal_ver
|
|
util_setup_gems
|
|
|
|
util_setup_spec_fetcher(@a1, @a1_pre)
|
|
|
|
p1a_data = Gem.read_binary(@a1_gem)
|
|
|
|
@fetcher.data["http://gems.example.com/gems/a-1.gem"] = p1a_data
|
|
|
|
dep = Gem::Dependency.new "a"
|
|
inst = Gem::DependencyInstaller.new prerelease: true
|
|
inst.install dep
|
|
|
|
assert_equal %w[a-1], Gem::Specification.map(&:full_name)
|
|
assert_equal [@a1], inst.installed_gems
|
|
end
|
|
|
|
def test_install_all_dependencies
|
|
util_setup_gems
|
|
|
|
_, e1_gem = util_gem "e", "1" do |s|
|
|
s.add_dependency "b"
|
|
end
|
|
|
|
FileUtils.mv @a1_gem, @tempdir
|
|
FileUtils.mv @b1_gem, @tempdir
|
|
FileUtils.mv e1_gem, @tempdir
|
|
|
|
inst = nil
|
|
|
|
Dir.chdir @tempdir do
|
|
inst = Gem::DependencyInstaller.new ignore_dependencies: true
|
|
inst.install "b"
|
|
end
|
|
|
|
assert_equal %w[b-1], inst.installed_gems.map(&:full_name),
|
|
"sanity check"
|
|
|
|
Dir.chdir @tempdir do
|
|
inst = Gem::DependencyInstaller.new
|
|
inst.install "e"
|
|
end
|
|
|
|
assert_equal %w[a-1 e-1], inst.installed_gems.map(&:full_name)
|
|
end
|
|
|
|
def test_install_cache_dir
|
|
util_setup_gems
|
|
|
|
dir = "dir"
|
|
Dir.mkdir dir
|
|
FileUtils.mv @a1_gem, dir
|
|
FileUtils.mv @b1_gem, dir
|
|
inst = nil
|
|
|
|
Dir.chdir dir do
|
|
inst = Gem::DependencyInstaller.new cache_dir: @tempdir
|
|
inst.install "b"
|
|
end
|
|
|
|
assert_equal %w[a-1 b-1], inst.installed_gems.map(&:full_name)
|
|
|
|
assert File.exist? File.join(@gemhome, "cache", @a1.file_name)
|
|
assert File.exist? File.join(@gemhome, "cache", @b1.file_name)
|
|
end
|
|
|
|
def test_install_dependencies_satisfied
|
|
util_setup_gems
|
|
|
|
a2, a2_gem = util_gem "a", "2"
|
|
|
|
FileUtils.rm_rf File.join(@gemhome, "gems")
|
|
|
|
Gem::Specification.reset
|
|
|
|
FileUtils.mv @a1_gem, @tempdir
|
|
FileUtils.mv a2_gem, @tempdir # not in index
|
|
FileUtils.mv @b1_gem, @tempdir
|
|
inst = nil
|
|
|
|
Dir.chdir @tempdir do
|
|
inst = Gem::DependencyInstaller.new
|
|
inst.install "a", req("= 2")
|
|
end
|
|
|
|
assert_equal %w[a-2], inst.installed_gems.map(&:full_name),
|
|
"sanity check"
|
|
|
|
FileUtils.rm File.join(@tempdir, a2.file_name)
|
|
|
|
Dir.chdir @tempdir do
|
|
inst = Gem::DependencyInstaller.new
|
|
inst.install "b"
|
|
end
|
|
|
|
assert_equal %w[a-2 b-1], Gem::Specification.map(&:full_name)
|
|
assert_equal %w[b-1], inst.installed_gems.map(&:full_name)
|
|
end
|
|
|
|
# This asserts that if a gem's dependency is satisfied by an
|
|
# already installed gem, RubyGems doesn't installed a newer
|
|
# version
|
|
def test_install_doesnt_upgrade_installed_dependencies
|
|
util_setup_gems
|
|
|
|
a2, a2_gem = util_gem "a", "2"
|
|
a3, a3_gem = util_gem "a", "3"
|
|
|
|
util_setup_spec_fetcher @a1, a3, @b1
|
|
|
|
FileUtils.rm_rf File.join(@gemhome, "gems")
|
|
|
|
Gem::Specification.reset
|
|
|
|
FileUtils.mv @a1_gem, @tempdir
|
|
FileUtils.mv a2_gem, @tempdir # not in index
|
|
FileUtils.mv @b1_gem, @tempdir
|
|
FileUtils.mv a3_gem, @tempdir
|
|
|
|
Dir.chdir @tempdir do
|
|
Gem::DependencyInstaller.new.install "a", req("= 2")
|
|
end
|
|
|
|
FileUtils.rm File.join(@tempdir, a2.file_name)
|
|
|
|
inst = nil
|
|
|
|
Dir.chdir @tempdir do
|
|
inst = Gem::DependencyInstaller.new
|
|
inst.install "b"
|
|
end
|
|
|
|
assert_equal %w[a-2 b-1], Gem::Specification.map(&:full_name)
|
|
assert_equal %w[b-1], inst.installed_gems.map(&:full_name)
|
|
end
|
|
|
|
def test_install_dependency
|
|
util_setup_gems
|
|
|
|
done_installing_ran = false
|
|
inst = nil
|
|
|
|
Gem.done_installing do |installer, specs|
|
|
done_installing_ran = true
|
|
refute_nil installer
|
|
assert_equal [@a1, @b1], specs
|
|
end
|
|
|
|
FileUtils.mv @a1_gem, @tempdir
|
|
FileUtils.mv @b1_gem, @tempdir
|
|
|
|
Dir.chdir @tempdir do
|
|
inst = Gem::DependencyInstaller.new(build_docs_in_background: false)
|
|
inst.install "b"
|
|
end
|
|
|
|
assert_equal %w[a-1 b-1], inst.installed_gems.map(&:full_name)
|
|
|
|
assert done_installing_ran, "post installs hook was not run"
|
|
end
|
|
|
|
def test_install_dependency_development
|
|
util_setup_gems
|
|
|
|
@aa1, @aa1_gem = util_gem "aa", "1"
|
|
|
|
FileUtils.mv @a1_gem, @tempdir
|
|
FileUtils.mv @aa1_gem, @tempdir
|
|
FileUtils.mv @b1_gem, @tempdir
|
|
inst = nil
|
|
|
|
Dir.chdir @tempdir do
|
|
inst = Gem::DependencyInstaller.new(development: true)
|
|
inst.install "b"
|
|
end
|
|
|
|
assert_equal %w[a-1 aa-1 b-1], inst.installed_gems.map(&:full_name)
|
|
end
|
|
|
|
def test_install_dependency_development_deep
|
|
util_setup_gems
|
|
|
|
@aa1, @aa1_gem = util_gem "aa", "1"
|
|
|
|
FileUtils.mv @a1_gem, @tempdir
|
|
FileUtils.mv @aa1_gem, @tempdir
|
|
FileUtils.mv @b1_gem, @tempdir
|
|
FileUtils.mv @c1_gem, @tempdir
|
|
FileUtils.mv @d1_gem, @tempdir
|
|
inst = nil
|
|
|
|
Dir.chdir @tempdir do
|
|
inst = Gem::DependencyInstaller.new(development: true)
|
|
inst.install "d"
|
|
end
|
|
|
|
assert_equal %w[a-1 aa-1 b-1 c-1 d-1], inst.installed_gems.map(&:full_name)
|
|
end
|
|
|
|
def test_install_dependency_development_shallow
|
|
util_setup_gems
|
|
|
|
@aa1, @aa1_gem = util_gem "aa", "1"
|
|
|
|
FileUtils.mv @a1_gem, @tempdir
|
|
FileUtils.mv @aa1_gem, @tempdir
|
|
FileUtils.mv @b1_gem, @tempdir
|
|
FileUtils.mv @c1_gem, @tempdir
|
|
FileUtils.mv @d1_gem, @tempdir
|
|
inst = nil
|
|
|
|
Dir.chdir @tempdir do
|
|
inst = Gem::DependencyInstaller.new(development: true, dev_shallow: true)
|
|
inst.install "d"
|
|
end
|
|
|
|
assert_equal %w[c-1 d-1], inst.installed_gems.map(&:full_name)
|
|
end
|
|
|
|
def test_install_dependency_existing
|
|
util_setup_gems
|
|
|
|
Gem::Installer.at(@a1_gem).install
|
|
FileUtils.mv @a1_gem, @tempdir
|
|
FileUtils.mv @b1_gem, @tempdir
|
|
inst = nil
|
|
|
|
Dir.chdir @tempdir do
|
|
inst = Gem::DependencyInstaller.new
|
|
inst.install "b"
|
|
end
|
|
|
|
assert_equal %w[b-1], inst.installed_gems.map(&:full_name)
|
|
end
|
|
|
|
def test_install_dependency_existing_extension
|
|
extconf_rb = File.join @gemhome, "gems", "e-1", "extconf.rb"
|
|
FileUtils.mkdir_p File.dirname extconf_rb
|
|
|
|
File.open extconf_rb, "w" do |io|
|
|
io.write <<-EXTCONF_RB
|
|
require 'mkmf'
|
|
create_makefile 'e'
|
|
EXTCONF_RB
|
|
end
|
|
|
|
e1 = util_spec "e", "1", nil, "extconf.rb" do |s|
|
|
s.extensions << "extconf.rb"
|
|
end
|
|
e1_gem = e1.cache_file
|
|
|
|
_, f1_gem = util_gem "f", "1", "e" => nil
|
|
|
|
Gem::Installer.at(e1_gem).install
|
|
FileUtils.rm_r e1.extension_dir
|
|
|
|
FileUtils.mv e1_gem, @tempdir
|
|
FileUtils.mv f1_gem, @tempdir
|
|
inst = nil
|
|
|
|
Dir.chdir @tempdir do
|
|
inst = Gem::DependencyInstaller.new
|
|
inst.install "f"
|
|
end
|
|
|
|
assert_equal %w[f-1], inst.installed_gems.map(&:full_name)
|
|
|
|
assert_path_exist e1.extension_dir
|
|
end
|
|
|
|
def test_install_dependency_old
|
|
_, e1_gem = util_gem "e", "1"
|
|
_, f1_gem = util_gem "f", "1", "e" => nil
|
|
_, f2_gem = util_gem "f", "2"
|
|
|
|
FileUtils.mv e1_gem, @tempdir
|
|
FileUtils.mv f1_gem, @tempdir
|
|
FileUtils.mv f2_gem, @tempdir
|
|
inst = nil
|
|
|
|
Dir.chdir @tempdir do
|
|
inst = Gem::DependencyInstaller.new
|
|
inst.install "f"
|
|
end
|
|
|
|
assert_equal %w[f-2], inst.installed_gems.map(&:full_name)
|
|
end
|
|
|
|
def test_install_local
|
|
util_setup_gems
|
|
|
|
FileUtils.mv @a1_gem, @tempdir
|
|
inst = nil
|
|
|
|
Dir.chdir @tempdir do
|
|
inst = Gem::DependencyInstaller.new domain: :local
|
|
inst.install "a-1.gem"
|
|
end
|
|
|
|
assert_equal %w[a-1], inst.installed_gems.map(&:full_name)
|
|
end
|
|
|
|
def test_install_local_prerelease
|
|
util_setup_gems
|
|
|
|
FileUtils.mv @a1_pre_gem, @tempdir
|
|
inst = nil
|
|
|
|
Dir.chdir @tempdir do
|
|
inst = Gem::DependencyInstaller.new domain: :local
|
|
inst.install "a-1.a.gem"
|
|
end
|
|
|
|
assert_equal %w[a-1.a], inst.installed_gems.map(&:full_name)
|
|
end
|
|
|
|
def test_install_local_dependency
|
|
util_setup_gems
|
|
|
|
FileUtils.mv @a1_gem, @tempdir
|
|
FileUtils.mv @b1_gem, @tempdir
|
|
|
|
inst = nil
|
|
|
|
Dir.chdir @tempdir do
|
|
inst = Gem::DependencyInstaller.new domain: :local
|
|
inst.install "b-1.gem"
|
|
end
|
|
|
|
assert_equal %w[a-1 b-1], inst.installed_gems.map(&:full_name)
|
|
end
|
|
|
|
def test_install_local_dependency_installed
|
|
util_setup_gems
|
|
|
|
FileUtils.mv @a1_gem, @tempdir
|
|
FileUtils.mv @b1_gem, @tempdir
|
|
|
|
inst = nil
|
|
|
|
Dir.chdir @tempdir do
|
|
Gem::Installer.at("a-1.gem").install
|
|
|
|
inst = Gem::DependencyInstaller.new domain: :local
|
|
inst.install "b-1.gem"
|
|
end
|
|
|
|
assert_equal %w[b-1], inst.installed_gems.map(&:full_name)
|
|
end
|
|
|
|
def test_install_local_dependency_no_network_for_target_gem
|
|
a1, a1_gem = util_gem "a", "1"
|
|
_, b1_gem = util_gem "b", "1" do |s|
|
|
s.add_dependency "a"
|
|
end
|
|
|
|
util_setup_spec_fetcher(a1)
|
|
|
|
a1_data = Gem.read_binary(a1_gem)
|
|
@fetcher.data["http://gems.example.com/gems/a-1.gem"] = a1_data
|
|
|
|
# compact index is available
|
|
compact_index_response = Gem::Net::HTTPResponse.new "1.1", 200, "OK"
|
|
compact_index_response.uri = Gem::URI("http://gems.example.com")
|
|
@fetcher.data["http://gems.example.com/"] = compact_index_response
|
|
|
|
# but private local gem not present there
|
|
@fetcher.data["http://gems.example.com/info/b"] =
|
|
proc do
|
|
raise "should not happen"
|
|
end
|
|
|
|
FileUtils.mv b1_gem, @tempdir
|
|
|
|
inst = nil
|
|
|
|
Dir.chdir @tempdir do
|
|
inst = Gem::DependencyInstaller.new
|
|
inst.install "b-1.gem"
|
|
end
|
|
|
|
assert_equal %w[a-1 b-1], inst.installed_gems.map(&:full_name)
|
|
end
|
|
|
|
def test_install_local_subdir
|
|
util_setup_gems
|
|
|
|
inst = nil
|
|
|
|
Dir.chdir @tempdir do
|
|
inst = Gem::DependencyInstaller.new domain: :local
|
|
inst.install "gems/a-1.gem"
|
|
end
|
|
|
|
assert_equal %w[a-1], inst.installed_gems.map(&:full_name)
|
|
end
|
|
|
|
def test_install_local_with_extensions_already_installed
|
|
pend "needs investigation" if Gem.java_platform?
|
|
pend "ruby.h is not provided by ruby repo" if ruby_repo?
|
|
|
|
@spec = quick_gem "a" do |s|
|
|
s.extensions << "extconf.rb"
|
|
s.files += %w[extconf.rb a.c]
|
|
end
|
|
|
|
write_dummy_extconf "a"
|
|
|
|
c_source_path = File.join(@tempdir, "a.c")
|
|
|
|
write_file c_source_path do |io|
|
|
io.write <<-C
|
|
#include <ruby.h>
|
|
void Init_a() { }
|
|
C
|
|
end
|
|
|
|
package_path = Gem::Package.build @spec
|
|
installer = Gem::Installer.at(package_path)
|
|
|
|
# Make sure the gem is installed and backup the correct package
|
|
|
|
installer.install
|
|
|
|
package_bkp_path = "#{package_path}.bkp"
|
|
FileUtils.cp package_path, package_bkp_path
|
|
|
|
# Break the extension, rebuild it, and try to install it
|
|
|
|
write_file c_source_path do |io|
|
|
io.write "typo"
|
|
end
|
|
|
|
Gem::Package.build @spec
|
|
|
|
assert_raise Gem::Ext::BuildError do
|
|
installer.install
|
|
end
|
|
|
|
# Make sure installing the good package again still works
|
|
|
|
FileUtils.cp "#{package_path}.bkp", package_path
|
|
|
|
Dir.chdir @tempdir do
|
|
inst = Gem::DependencyInstaller.new domain: :local
|
|
inst.install package_path
|
|
end
|
|
end
|
|
|
|
def test_install_minimal_deps
|
|
util_setup_gems
|
|
|
|
_, e1_gem = util_gem "e", "1" do |s|
|
|
s.add_dependency "b"
|
|
end
|
|
|
|
_, b2_gem = util_gem "b", "2" do |s|
|
|
s.add_dependency "a"
|
|
end
|
|
|
|
FileUtils.mv @a1_gem, @tempdir
|
|
FileUtils.mv @b1_gem, @tempdir
|
|
FileUtils.mv b2_gem, @tempdir
|
|
FileUtils.mv e1_gem, @tempdir
|
|
|
|
inst = nil
|
|
|
|
Dir.chdir @tempdir do
|
|
inst = Gem::DependencyInstaller.new ignore_dependencies: true
|
|
inst.install "b", req("= 1")
|
|
end
|
|
|
|
assert_equal %w[b-1], inst.installed_gems.map(&:full_name),
|
|
"sanity check"
|
|
|
|
Dir.chdir @tempdir do
|
|
inst = Gem::DependencyInstaller.new minimal_deps: true
|
|
inst.install "e"
|
|
end
|
|
|
|
assert_equal %w[a-1 e-1], inst.installed_gems.map(&:full_name)
|
|
end
|
|
|
|
def test_install_no_minimal_deps
|
|
util_setup_gems
|
|
|
|
_, e1_gem = util_gem "e", "1" do |s|
|
|
s.add_dependency "b"
|
|
end
|
|
|
|
_, b2_gem = util_gem "b", "2" do |s|
|
|
s.add_dependency "a"
|
|
end
|
|
|
|
FileUtils.mv @a1_gem, @tempdir
|
|
FileUtils.mv @b1_gem, @tempdir
|
|
FileUtils.mv b2_gem, @tempdir
|
|
FileUtils.mv e1_gem, @tempdir
|
|
|
|
inst = nil
|
|
|
|
Dir.chdir @tempdir do
|
|
inst = Gem::DependencyInstaller.new ignore_dependencies: true
|
|
inst.install "b", req("= 1")
|
|
end
|
|
|
|
assert_equal %w[b-1], inst.installed_gems.map(&:full_name),
|
|
"sanity check"
|
|
|
|
Dir.chdir @tempdir do
|
|
inst = Gem::DependencyInstaller.new minimal_deps: false
|
|
inst.install "e"
|
|
end
|
|
|
|
assert_equal %w[a-1 b-2 e-1], inst.installed_gems.map(&:full_name)
|
|
end
|
|
|
|
def test_install_no_document
|
|
util_setup_gems
|
|
|
|
done_installing_called = false
|
|
|
|
Gem.done_installing do |dep_installer, _specs|
|
|
done_installing_called = true
|
|
assert_empty dep_installer.document
|
|
end
|
|
|
|
inst = Gem::DependencyInstaller.new domain: :local, document: []
|
|
|
|
inst.install @a1_gem
|
|
|
|
assert done_installing_called
|
|
end
|
|
|
|
def test_install_env_shebang
|
|
util_setup_gems
|
|
|
|
FileUtils.mv @a1_gem, @tempdir
|
|
inst = nil
|
|
|
|
Dir.chdir @tempdir do
|
|
inst = Gem::DependencyInstaller.new env_shebang: true, wrappers: true, format_executable: false
|
|
inst.install "a"
|
|
end
|
|
|
|
env = "/\\S+/env" unless Gem.win_platform?
|
|
|
|
assert_match(/\A#!#{env} #{RbConfig::CONFIG["ruby_install_name"]}\n/,
|
|
File.read(File.join(@gemhome, "bin", "a_bin")))
|
|
end
|
|
|
|
def test_install_force
|
|
util_setup_gems
|
|
|
|
FileUtils.mv @b1_gem, @tempdir
|
|
si = util_setup_spec_fetcher @b1
|
|
@fetcher.data["http://gems.example.com/gems/yaml"] = si.to_yaml
|
|
inst = nil
|
|
|
|
Dir.chdir @tempdir do
|
|
inst = Gem::DependencyInstaller.new force: true
|
|
inst.install "b"
|
|
end
|
|
|
|
assert_equal %w[b-1], inst.installed_gems.map(&:full_name)
|
|
end
|
|
|
|
def test_install_build_args
|
|
util_setup_gems
|
|
|
|
FileUtils.mv @a1_gem, @tempdir
|
|
inst = nil
|
|
build_args = %w[--a --b="c"]
|
|
|
|
Dir.chdir @tempdir do
|
|
inst = Gem::DependencyInstaller.new(build_args: build_args)
|
|
inst.install "a"
|
|
end
|
|
|
|
assert_equal build_args.join("\n"), File.read(inst.installed_gems.first.build_info_file).strip
|
|
end
|
|
|
|
def test_install_ignore_dependencies
|
|
util_setup_gems
|
|
|
|
FileUtils.mv @b1_gem, @tempdir
|
|
inst = nil
|
|
|
|
Dir.chdir @tempdir do
|
|
inst = Gem::DependencyInstaller.new ignore_dependencies: true
|
|
inst.install "b"
|
|
end
|
|
|
|
assert_equal %w[b-1], inst.installed_gems.map(&:full_name)
|
|
end
|
|
|
|
def test_install_install_dir
|
|
util_setup_gems
|
|
|
|
FileUtils.mv @a1_gem, @tempdir
|
|
FileUtils.mv @b1_gem, @tempdir
|
|
|
|
inst = Gem::Installer.at @a1.file_name
|
|
inst.install
|
|
|
|
gemhome2 = File.join @tempdir, "gemhome2"
|
|
Dir.mkdir gemhome2
|
|
inst = nil
|
|
|
|
Dir.chdir @tempdir do
|
|
inst = Gem::DependencyInstaller.new install_dir: gemhome2
|
|
inst.install "b"
|
|
end
|
|
|
|
assert_equal %w[a-1 b-1], inst.installed_gems.map(&:full_name)
|
|
|
|
assert File.exist?(File.join(gemhome2, "specifications", @a1.spec_name))
|
|
assert File.exist?(File.join(gemhome2, "cache", @a1.file_name))
|
|
end
|
|
|
|
def test_install_domain_both
|
|
util_setup_gems
|
|
|
|
a1_data = nil
|
|
File.open @a1_gem, "rb" do |fp|
|
|
a1_data = fp.read
|
|
end
|
|
|
|
@fetcher.data["http://gems.example.com/gems/a-1.gem"] = a1_data
|
|
|
|
FileUtils.mv @b1_gem, @tempdir
|
|
inst = nil
|
|
|
|
Dir.chdir @tempdir do
|
|
inst = Gem::DependencyInstaller.new domain: :both
|
|
inst.install "b"
|
|
end
|
|
|
|
assert_equal %w[a-1 b-1], inst.installed_gems.map(&:full_name)
|
|
a1, b1 = inst.installed_gems
|
|
|
|
assert_equal a1.spec_file, a1.loaded_from
|
|
assert_equal b1.spec_file, b1.loaded_from
|
|
end
|
|
|
|
def test_install_domain_both_no_network
|
|
util_setup_gems
|
|
|
|
@fetcher.data["http://gems.example.com/gems/Marshal.#{@marshal_version}"] =
|
|
proc do
|
|
raise Gem::RemoteFetcher::FetchError
|
|
end
|
|
|
|
FileUtils.mv @a1_gem, @tempdir
|
|
FileUtils.mv @b1_gem, @tempdir
|
|
inst = nil
|
|
|
|
Dir.chdir @tempdir do
|
|
inst = Gem::DependencyInstaller.new domain: :both
|
|
inst.install "b"
|
|
end
|
|
|
|
assert_equal %w[a-1 b-1], inst.installed_gems.map(&:full_name)
|
|
end
|
|
|
|
def test_install_domain_local
|
|
util_setup_gems
|
|
|
|
FileUtils.mv @b1_gem, @tempdir
|
|
inst = nil
|
|
|
|
Dir.chdir @tempdir do
|
|
e = assert_raise Gem::UnsatisfiableDependencyError do
|
|
inst = Gem::DependencyInstaller.new domain: :local
|
|
inst.install "b"
|
|
end
|
|
|
|
expected = "Unable to resolve dependency: 'b (>= 0)' requires 'a (>= 0)'"
|
|
assert_equal expected, e.message
|
|
end
|
|
|
|
assert_equal [], inst.installed_gems.map(&:full_name)
|
|
end
|
|
|
|
def test_install_domain_remote
|
|
util_setup_gems
|
|
|
|
a1_data = nil
|
|
File.open @a1_gem, "rb" do |fp|
|
|
a1_data = fp.read
|
|
end
|
|
|
|
@fetcher.data["http://gems.example.com/gems/a-1.gem"] = a1_data
|
|
|
|
inst = Gem::DependencyInstaller.new domain: :remote
|
|
inst.install "a"
|
|
|
|
assert_equal %w[a-1], inst.installed_gems.map(&:full_name)
|
|
end
|
|
|
|
def test_install_dual_repository
|
|
util_setup_gems
|
|
|
|
FileUtils.mv @a1_gem, @tempdir
|
|
FileUtils.mv @b1_gem, @tempdir
|
|
inst = nil
|
|
|
|
gemhome2 = "#{@gemhome}2"
|
|
|
|
Dir.chdir @tempdir do
|
|
inst = Gem::DependencyInstaller.new install_dir: gemhome2
|
|
inst.install "a"
|
|
end
|
|
|
|
assert_equal %w[a-1], inst.installed_gems.map(&:full_name),
|
|
"sanity check"
|
|
|
|
ENV["GEM_HOME"] = @gemhome
|
|
ENV["GEM_PATH"] = [@gemhome, gemhome2].join File::PATH_SEPARATOR
|
|
Gem.clear_paths
|
|
|
|
Dir.chdir @tempdir do
|
|
inst = Gem::DependencyInstaller.new
|
|
inst.install "b"
|
|
end
|
|
|
|
assert_equal %w[b-1], inst.installed_gems.map(&:full_name)
|
|
end
|
|
|
|
def test_install_reinstall
|
|
util_setup_gems
|
|
|
|
Gem::Installer.at(@a1_gem).install
|
|
FileUtils.mv @a1_gem, @tempdir
|
|
inst = nil
|
|
|
|
Dir.chdir @tempdir do
|
|
inst = Gem::DependencyInstaller.new force: true
|
|
inst.install "a"
|
|
end
|
|
|
|
assert_equal %w[a-1], Gem::Specification.map(&:full_name)
|
|
assert_equal %w[a-1], inst.installed_gems.map(&:full_name)
|
|
end
|
|
|
|
def test_install_dual_repository_and_done_installing_hooks
|
|
util_setup_gems
|
|
|
|
FileUtils.mv @a1_gem, @tempdir
|
|
FileUtils.mv @b1_gem, @tempdir
|
|
inst = nil
|
|
|
|
# Make sure gem is installed to standard GEM_HOME
|
|
|
|
Dir.chdir @tempdir do
|
|
inst = Gem::DependencyInstaller.new install_dir: @gemhome
|
|
inst.install "b"
|
|
end
|
|
|
|
# and also to an additional GEM_PATH
|
|
|
|
gemhome2 = "#{@gemhome}2"
|
|
|
|
Dir.chdir @tempdir do
|
|
inst = Gem::DependencyInstaller.new install_dir: gemhome2
|
|
inst.install "b"
|
|
end
|
|
|
|
# Now install the local gem with the additional GEM_PATH
|
|
|
|
ENV["GEM_HOME"] = @gemhome
|
|
ENV["GEM_PATH"] = [@gemhome, gemhome2].join File::PATH_SEPARATOR
|
|
Gem.clear_paths
|
|
|
|
Gem.done_installing do |installer, specs|
|
|
refute_nil installer
|
|
assert_equal [@b1], specs
|
|
end
|
|
|
|
Dir.chdir @tempdir do
|
|
inst = Gem::DependencyInstaller.new
|
|
inst.install "b-1.gem"
|
|
end
|
|
|
|
assert_equal %w[b-1], inst.installed_gems.map(&:full_name)
|
|
end
|
|
|
|
def test_install_remote
|
|
util_setup_gems
|
|
|
|
a1_data = nil
|
|
File.open @a1_gem, "rb" do |fp|
|
|
a1_data = fp.read
|
|
end
|
|
|
|
@fetcher.data["http://gems.example.com/gems/a-1.gem"] = a1_data
|
|
|
|
inst = Gem::DependencyInstaller.new
|
|
|
|
Dir.chdir @tempdir do
|
|
inst.install "a"
|
|
end
|
|
|
|
assert_equal %w[a-1], inst.installed_gems.map(&:full_name)
|
|
end
|
|
|
|
def test_install_remote_dep
|
|
util_setup_gems
|
|
|
|
a1_data = nil
|
|
File.open @a1_gem, "rb" do |fp|
|
|
a1_data = fp.read
|
|
end
|
|
|
|
@fetcher.data["http://gems.example.com/gems/a-1.gem"] = a1_data
|
|
|
|
inst = Gem::DependencyInstaller.new
|
|
|
|
Dir.chdir @tempdir do
|
|
dep = Gem::Dependency.new @a1.name, @a1.version
|
|
inst.install dep
|
|
end
|
|
|
|
assert_equal %w[a-1], inst.installed_gems.map(&:full_name)
|
|
end
|
|
|
|
def test_install_remote_platform_newer
|
|
util_setup_gems
|
|
|
|
a2_o, a2_o_gem = util_gem "a", "2" do |s|
|
|
s.platform = Gem::Platform.new %w[cpu other_platform 1]
|
|
end
|
|
|
|
si = util_setup_spec_fetcher @a1, a2_o
|
|
|
|
@fetcher.data["http://gems.example.com/gems/yaml"] = si.to_yaml
|
|
|
|
a1_data = nil
|
|
a2_o_data = nil
|
|
|
|
File.open @a1_gem, "rb" do |fp|
|
|
a1_data = fp.read
|
|
end
|
|
|
|
File.open a2_o_gem, "rb" do |fp|
|
|
a2_o_data = fp.read
|
|
end
|
|
|
|
@fetcher.data["http://gems.example.com/gems/#{@a1.file_name}"] =
|
|
a1_data
|
|
@fetcher.data["http://gems.example.com/gems/#{a2_o.file_name}"] =
|
|
a2_o_data
|
|
|
|
inst = Gem::DependencyInstaller.new domain: :remote
|
|
inst.install "a"
|
|
|
|
assert_equal %w[a-1], inst.installed_gems.map(&:full_name)
|
|
end
|
|
|
|
def test_install_platform_is_ignored_when_a_file_is_specified
|
|
_, a_gem = util_gem "a", "1" do |s|
|
|
s.platform = Gem::Platform.new %w[cpu other_platform 1]
|
|
end
|
|
|
|
inst = Gem::DependencyInstaller.new domain: :local
|
|
inst.install a_gem
|
|
|
|
assert_equal %w[a-1-cpu-other_platform-1], inst.installed_gems.map(&:full_name)
|
|
end
|
|
|
|
require "rubygems/openssl"
|
|
|
|
if Gem::HAVE_OPENSSL
|
|
def test_install_security_policy
|
|
util_setup_gems
|
|
|
|
data = File.open(@a1_gem, "rb", &:read)
|
|
@fetcher.data["http://gems.example.com/gems/a-1.gem"] = data
|
|
|
|
data = File.open(@b1_gem, "rb", &:read)
|
|
@fetcher.data["http://gems.example.com/gems/b-1.gem"] = data
|
|
|
|
policy = Gem::Security::HighSecurity
|
|
inst = Gem::DependencyInstaller.new security_policy: policy
|
|
|
|
e = assert_raise Gem::Security::Exception do
|
|
inst.install "b"
|
|
end
|
|
|
|
assert_equal "unsigned gems are not allowed by the High Security policy",
|
|
e.message
|
|
|
|
assert_equal %w[], inst.installed_gems.map(&:full_name)
|
|
end
|
|
end
|
|
|
|
# Wrappers don't work on mswin
|
|
unless Gem.win_platform?
|
|
def test_install_no_wrappers
|
|
util_setup_gems
|
|
|
|
@fetcher.data["http://gems.example.com/gems/a-1.gem"] = read_binary(@a1_gem)
|
|
|
|
inst = Gem::DependencyInstaller.new wrappers: false, format_executable: false
|
|
inst.install "a"
|
|
|
|
refute_match(/This file was generated by RubyGems./,
|
|
File.read(File.join(@gemhome, "bin", "a_bin")))
|
|
end
|
|
end
|
|
|
|
def test_install_version
|
|
util_setup_d
|
|
|
|
data = File.open(@d2_gem, "rb", &:read)
|
|
@fetcher.data["http://gems.example.com/gems/d-2.gem"] = data
|
|
|
|
data = File.open(@d1_gem, "rb", &:read)
|
|
@fetcher.data["http://gems.example.com/gems/d-1.gem"] = data
|
|
|
|
inst = Gem::DependencyInstaller.new
|
|
|
|
inst.install "d", "= 1"
|
|
|
|
assert_equal %w[d-1], inst.installed_gems.map(&:full_name)
|
|
end
|
|
|
|
def test_install_version_default
|
|
util_setup_d
|
|
|
|
data = File.open(@d2_gem, "rb", &:read)
|
|
@fetcher.data["http://gems.example.com/gems/d-2.gem"] = data
|
|
|
|
data = File.open(@d1_gem, "rb", &:read)
|
|
@fetcher.data["http://gems.example.com/gems/d-1.gem"] = data
|
|
|
|
inst = Gem::DependencyInstaller.new
|
|
inst.install "d"
|
|
|
|
assert_equal %w[d-2], inst.installed_gems.map(&:full_name)
|
|
end
|
|
|
|
def test_install_legacy_spec_with_nil_required_ruby_version
|
|
path = File.expand_path "data/null-required-ruby-version.gemspec.rz", __dir__
|
|
spec = Marshal.load Gem.read_binary(path)
|
|
def spec.validate(*args); end
|
|
|
|
util_build_gem spec
|
|
|
|
cache_file = File.join @tempdir, "gems", "#{spec.original_name}.gem"
|
|
FileUtils.mkdir_p File.dirname cache_file
|
|
FileUtils.mv spec.cache_file, cache_file
|
|
|
|
util_setup_spec_fetcher spec
|
|
|
|
data = Gem.read_binary(cache_file)
|
|
|
|
@fetcher.data["http://gems.example.com/gems/activesupport-1.0.0.gem"] = data
|
|
|
|
dep = Gem::Dependency.new "activesupport"
|
|
|
|
inst = Gem::DependencyInstaller.new
|
|
inst.install dep
|
|
|
|
assert_equal %w[activesupport-1.0.0], Gem::Specification.map(&:full_name)
|
|
end
|
|
|
|
def test_install_legacy_spec_with_nil_required_rubygems_version
|
|
path = File.expand_path "data/null-required-rubygems-version.gemspec.rz", __dir__
|
|
spec = Marshal.load Gem.read_binary(path)
|
|
def spec.validate(*args); end
|
|
|
|
util_build_gem spec
|
|
|
|
cache_file = File.join @tempdir, "gems", "#{spec.original_name}.gem"
|
|
FileUtils.mkdir_p File.dirname cache_file
|
|
FileUtils.mv spec.cache_file, cache_file
|
|
|
|
util_setup_spec_fetcher spec
|
|
|
|
data = Gem.read_binary(cache_file)
|
|
|
|
@fetcher.data["http://gems.example.com/gems/activesupport-1.0.0.gem"] = data
|
|
|
|
dep = Gem::Dependency.new "activesupport"
|
|
|
|
inst = Gem::DependencyInstaller.new
|
|
inst.install dep
|
|
|
|
assert_equal %w[activesupport-1.0.0], Gem::Specification.map(&:full_name)
|
|
end
|
|
|
|
def test_find_gems_gems_with_sources
|
|
util_setup_gems
|
|
|
|
inst = Gem::DependencyInstaller.new
|
|
dep = Gem::Dependency.new "b", ">= 0"
|
|
|
|
Gem::Specification.reset
|
|
|
|
set = Gem::Deprecate.skip_during do
|
|
inst.find_gems_with_sources(dep)
|
|
end
|
|
|
|
assert_kind_of Gem::AvailableSet, set
|
|
|
|
s = set.set.first
|
|
|
|
assert_equal @b1, s.spec
|
|
assert_equal Gem::Source.new(@gem_repo), s.source
|
|
end
|
|
|
|
def test_find_gems_with_sources_local
|
|
util_setup_gems
|
|
|
|
FileUtils.mv @a1_gem, @tempdir
|
|
inst = Gem::DependencyInstaller.new
|
|
dep = Gem::Dependency.new "a", ">= 0"
|
|
set = nil
|
|
|
|
Dir.chdir @tempdir do
|
|
set = Gem::Deprecate.skip_during do
|
|
inst.find_gems_with_sources dep
|
|
end
|
|
end
|
|
|
|
gems = set.sorted
|
|
|
|
assert_equal 2, gems.length
|
|
|
|
remote, local = gems
|
|
|
|
assert_equal "a-1", local.spec.full_name, "local spec"
|
|
assert_equal File.join(@tempdir, @a1.file_name),
|
|
local.source.download(local.spec), "local path"
|
|
|
|
assert_equal "a-1", remote.spec.full_name, "remote spec"
|
|
assert_equal Gem::Source.new(@gem_repo), remote.source, "remote path"
|
|
end
|
|
|
|
def test_find_gems_with_sources_prerelease
|
|
util_setup_gems
|
|
|
|
installer = Gem::DependencyInstaller.new
|
|
|
|
dependency = Gem::Dependency.new("a", Gem::Requirement.default)
|
|
|
|
set = Gem::Deprecate.skip_during do
|
|
installer.find_gems_with_sources(dependency)
|
|
end
|
|
|
|
releases = set.all_specs
|
|
|
|
assert releases.any? {|s| s.name == "a" && s.version.to_s == "1" }
|
|
refute releases.any? {|s| s.name == "a" && s.version.to_s == "1.a" }
|
|
|
|
dependency.prerelease = true
|
|
|
|
set = Gem::Deprecate.skip_during do
|
|
installer.find_gems_with_sources(dependency)
|
|
end
|
|
|
|
prereleases = set.all_specs
|
|
|
|
assert_equal [@a1_pre, @a1], prereleases
|
|
end
|
|
|
|
def test_find_gems_with_sources_with_best_only_and_platform
|
|
util_setup_gems
|
|
a1_x86_mingw32, = util_gem "a", "1" do |s|
|
|
s.platform = "x86-mingw32"
|
|
end
|
|
util_setup_spec_fetcher @a1, a1_x86_mingw32
|
|
Gem.platforms << Gem::Platform.new("x86-mingw32")
|
|
|
|
installer = Gem::DependencyInstaller.new
|
|
|
|
dependency = Gem::Dependency.new("a", Gem::Requirement.default)
|
|
|
|
set = Gem::Deprecate.skip_during do
|
|
installer.find_gems_with_sources(dependency, true)
|
|
end
|
|
|
|
releases = set.all_specs
|
|
|
|
assert_equal [a1_x86_mingw32], releases
|
|
end
|
|
|
|
def test_find_gems_with_sources_with_bad_source
|
|
Gem.sources.replace ["http://not-there.nothing"]
|
|
|
|
installer = Gem::DependencyInstaller.new
|
|
|
|
dep = Gem::Dependency.new("a")
|
|
|
|
out = Gem::Deprecate.skip_during do
|
|
installer.find_gems_with_sources(dep)
|
|
end
|
|
|
|
assert out.empty?
|
|
assert_kind_of Gem::SourceFetchProblem, installer.errors.first
|
|
end
|
|
|
|
def test_resolve_dependencies
|
|
util_setup_gems
|
|
|
|
FileUtils.mv @a1_gem, @tempdir
|
|
FileUtils.mv @b1_gem, @tempdir
|
|
|
|
inst = Gem::DependencyInstaller.new
|
|
request_set = inst.resolve_dependencies "b", req(">= 0")
|
|
|
|
requests = request_set.sorted_requests.map(&:full_name)
|
|
|
|
assert_equal %w[a-1 b-1], requests
|
|
end
|
|
|
|
def test_resolve_dependencies_ignore_dependencies
|
|
util_setup_gems
|
|
|
|
FileUtils.mv @a1_gem, @tempdir
|
|
FileUtils.mv @b1_gem, @tempdir
|
|
|
|
inst = Gem::DependencyInstaller.new ignore_dependencies: true
|
|
request_set = inst.resolve_dependencies "b", req(">= 0")
|
|
|
|
requests = request_set.sorted_requests.map(&:full_name)
|
|
|
|
assert request_set.ignore_dependencies
|
|
|
|
assert_equal %w[b-1], requests
|
|
end
|
|
|
|
def test_resolve_dependencies_local
|
|
util_setup_gems
|
|
|
|
@a2, @a2_gem = util_gem "a", "2"
|
|
FileUtils.mv @a1_gem, @tempdir
|
|
FileUtils.mv @a2_gem, @tempdir
|
|
|
|
inst = Gem::DependencyInstaller.new
|
|
request_set = inst.resolve_dependencies "a-1.gem", req(">= 0")
|
|
|
|
requests = request_set.sorted_requests.map(&:full_name)
|
|
|
|
assert_equal %w[a-1], requests
|
|
end
|
|
|
|
def util_setup_d
|
|
@d1, @d1_gem = util_gem "d", "1"
|
|
@d2, @d2_gem = util_gem "d", "2"
|
|
|
|
util_setup_spec_fetcher(@d1, @d2)
|
|
end
|
|
end
|