1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
# frozen_string_literal: true
require_relative "path"
$LOAD_PATH.unshift(Spec::Path.source_lib_dir.to_s)
module Spec
module Rubygems
extend self
def dev_setup
install_gems(dev_gemfile, dev_lockfile)
end
def gem_load(gem_name, bin_container)
require_relative "switch_rubygems"
gem_load_and_activate(gem_name, bin_container)
end
def gem_require(gem_name)
gem_activate(gem_name)
require gem_name
end
def test_setup
setup_test_paths
require "fileutils"
FileUtils.mkdir_p(Path.home)
FileUtils.mkdir_p(Path.tmpdir)
ENV["HOME"] = Path.home.to_s
ENV["TMPDIR"] = Path.tmpdir.to_s
require "rubygems/user_interaction"
Gem::DefaultUserInteraction.ui = Gem::SilentUI.new
end
def install_parallel_test_deps
require "parallel"
prev_env_test_number = ENV["TEST_ENV_NUMBER"]
begin
Parallel.processor_count.times do |n|
ENV["TEST_ENV_NUMBER"] = (n + 1).to_s
install_test_deps
end
ensure
ENV["TEST_ENV_NUMBER"] = prev_env_test_number
end
end
def setup_test_paths
Gem.clear_paths
ENV["BUNDLE_PATH"] = nil
ENV["GEM_HOME"] = ENV["GEM_PATH"] = Path.base_system_gems.to_s
ENV["PATH"] = [Path.system_gem_path.join("bin"), ENV["PATH"]].join(File::PATH_SEPARATOR)
ENV["PATH"] = [Path.bindir, ENV["PATH"]].join(File::PATH_SEPARATOR) if Path.ruby_core?
end
def install_test_deps
setup_test_paths
workaround_loaded_specs_issue
install_gems(test_gemfile, test_lockfile)
end
private
# Some rubygems versions include loaded specs when loading gemspec stubs
# from the file system. In this situation, that makes bundler incorrectly
# assume that `rake` is already installed at `tmp/` because it's installed
# globally, and makes it skip installing it to the proper location for our
# tests. To workaround, we remove `rake` from the loaded specs when running
# under those versions, so that `bundler` does the right thing.
def workaround_loaded_specs_issue
current_rubygems_version = Gem::Version.new(Gem::VERSION)
Gem.loaded_specs.delete("rake") if current_rubygems_version >= Gem::Version.new("3.0.0.beta2") && current_rubygems_version < Gem::Version.new("3.2.0")
end
def gem_load_and_activate(gem_name, bin_container)
gem_activate(gem_name)
load Gem.bin_path(gem_name, bin_container)
rescue Gem::LoadError => e
abort "We couln't activate #{gem_name} (#{e.requirement}). Run `gem install #{gem_name}:'#{e.requirement}'`"
end
def gem_activate(gem_name)
require "bundler"
gem_requirement = Bundler::LockfileParser.new(File.read(dev_lockfile)).dependencies[gem_name]&.requirement
gem gem_name, gem_requirement
end
def install_gems(gemfile, lockfile)
old_gemfile = ENV["BUNDLE_GEMFILE"]
ENV["BUNDLE_GEMFILE"] = gemfile.to_s
require "bundler"
definition = Bundler::Definition.build(gemfile, lockfile, nil)
definition.validate_runtime!
Bundler::Installer.install(Path.source_root, definition, :path => ENV["GEM_HOME"])
ensure
ENV["BUNDLE_GEMFILE"] = old_gemfile
end
def test_gemfile
Path.test_gemfile
end
def test_lockfile
lockfile_for(test_gemfile)
end
def dev_gemfile
Path.dev_gemfile
end
def dev_lockfile
lockfile_for(dev_gemfile)
end
def lockfile_for(gemfile)
Pathname.new("#{gemfile.expand_path}.lock")
end
end
end
|