Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor setting ENV and ruby flags when shelling out during specs #7375

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion bundler/spec/install/gems/compact_index_spec.rb
Expand Up @@ -729,7 +729,7 @@ def require(*args)
gem "rack"
G

bundle :install, env: { "RUBYOPT" => opt_add("-I#{bundled_app("broken_ssl")}", ENV["RUBYOPT"]) }, raise_on_error: false
bundle :install, env: { "RUBYOPT" => "-I#{bundled_app("broken_ssl")}" }, raise_on_error: false
expect(err).to include("OpenSSL")
end
end
Expand Down
2 changes: 1 addition & 1 deletion bundler/spec/install/gems/dependency_api_spec.rb
Expand Up @@ -713,7 +713,7 @@ def require(*args)
gem "rack"
G

bundle :install, env: { "RUBYOPT" => opt_add("-I#{bundled_app("broken_ssl")}", ENV["RUBYOPT"]) }, raise_on_error: false
bundle :install, env: { "RUBYOPT" => "-I#{bundled_app("broken_ssl")}" }, raise_on_error: false
expect(err).to include("OpenSSL")
end
end
Expand Down
4 changes: 2 additions & 2 deletions bundler/spec/runtime/requiring_spec.rb
Expand Up @@ -2,13 +2,13 @@

RSpec.describe "Requiring bundler" do
it "takes care of requiring rubygems when entrypoint is bundler/setup" do
sys_exec("#{Gem.ruby} -I#{lib_dir} -rbundler/setup -e'puts true'", env: { "RUBYOPT" => opt_add("--disable=gems", ENV["RUBYOPT"]) })
sys_exec("#{Gem.ruby} -I#{lib_dir} -rbundler/setup -e'puts true'", env: { "RUBYOPT" => "--disable=gems" })

expect(last_command.stdboth).to eq("true")
end

it "takes care of requiring rubygems when requiring just bundler" do
sys_exec("#{Gem.ruby} -I#{lib_dir} -rbundler -e'puts true'", env: { "RUBYOPT" => opt_add("--disable=gems", ENV["RUBYOPT"]) })
sys_exec("#{Gem.ruby} -I#{lib_dir} -rbundler -e'puts true'", env: { "RUBYOPT" => "--disable=gems" })

expect(last_command.stdboth).to eq("true")
end
Expand Down
2 changes: 1 addition & 1 deletion bundler/spec/runtime/with_unbundled_env_spec.rb
Expand Up @@ -65,7 +65,7 @@ def run_bundler_script(env, script)
# Simulate bundler has not yet been loaded
ENV.replace(ENV.to_hash.delete_if {|k, _v| k.start_with?(Bundler::EnvironmentPreserver::BUNDLER_PREFIX) })

original = ruby('puts ENV.to_a.map {|e| e.join("=") }.sort.join("\n")')
original = ruby('puts ENV.to_a.map {|e| e.join("=") }.sort.join("\n")', artifice: "fail")
create_file("source.rb", <<-RUBY)
puts Bundler.original_env.to_a.map {|e| e.join("=") }.sort.join("\n")
RUBY
Expand Down
91 changes: 42 additions & 49 deletions bundler/spec/support/helpers.rb
Expand Up @@ -81,29 +81,9 @@ def bundle(cmd, options = {}, &block)
bundle_bin = options.delete(:bundle_bin)
bundle_bin ||= installed_bindir.join("bundle")

env = options.delete(:env) || {}

requires = options.delete(:requires) || []
realworld = RSpec.current_example.metadata[:realworld]

artifice = options.delete(:artifice) do
if realworld
"vcr"
else
"fail"
end
end
if artifice
requires << "#{Path.spec_dir}/support/artifice/#{artifice}.rb"
end

load_path = []
load_path << spec_dir

dir = options.delete(:dir) || bundled_app
raise_on_error = options.delete(:raise_on_error)

args = options.map do |k, v|
next if [:env, :requires, :artifice, :dir, :raise_on_error].include?(k)

case v
when nil
next
Expand All @@ -116,9 +96,9 @@ def bundle(cmd, options = {}, &block)
end
end.join

ruby_cmd = build_ruby_cmd({ load_path: load_path, requires: requires, env: env })
cmd = "#{ruby_cmd} #{bundle_bin} #{cmd}#{args}"
sys_exec(cmd, { env: env, dir: dir, raise_on_error: raise_on_error }, &block)
cmd = "#{Gem.ruby} -I#{spec_dir} #{bundle_bin} #{cmd}#{args}"

sys_exec(cmd, options, &block)
end

def bundler(cmd, options = {})
Expand All @@ -127,9 +107,8 @@ def bundler(cmd, options = {})
end

def ruby(ruby, options = {})
ruby_cmd = build_ruby_cmd
escaped_ruby = ruby.shellescape
sys_exec(%(#{ruby_cmd} -w -e #{escaped_ruby}), options)
sys_exec(%(#{Gem.ruby} -w -e #{escaped_ruby}), { artifice: nil }.merge(options))
end

def load_error_ruby(ruby, name, opts = {})
Expand All @@ -142,32 +121,12 @@ def load_error_ruby(ruby, name, opts = {})
R
end

def build_ruby_cmd(options = {})
libs = options.delete(:load_path)
lib_option = libs ? "-I#{libs.join(File::PATH_SEPARATOR)}" : []

requires = options.delete(:requires) || []

hax_path = "#{Path.spec_dir}/support/hax.rb"

# For specs that need to ignore the default Bundler gem, load hax before
# anything else since other stuff may actually load bundler and not skip
# the default version
options[:env]&.include?("BUNDLER_IGNORE_DEFAULT_GEM") ? requires.prepend(hax_path) : requires.append(hax_path)
require_option = requires.map {|r| "-r#{r}" }

[Gem.ruby, *lib_option, *require_option].compact.join(" ")
end

def gembin(cmd, options = {})
cmd = bundled_app("bin/#{cmd}") unless cmd.to_s.include?("/")
sys_exec(cmd.to_s, options)
end

def gem_command(command, options = {})
env = options[:env] || {}
env["RUBYOPT"] = opt_add(opt_add("-r#{spec_dir}/support/hax.rb", env["RUBYOPT"]), ENV["RUBYOPT"])
options[:env] = env
sys_exec("#{Path.gem_bin} #{command}", options)
end

Expand All @@ -180,8 +139,7 @@ def git(cmd, path, options = {})
end

def sys_exec(cmd, options = {})
env = options[:env] || {}
env["RUBYOPT"] = opt_add(opt_add("-r#{spec_dir}/support/switch_rubygems.rb", env["RUBYOPT"]), ENV["RUBYOPT"])
env = prepare_env(options)
dir = options[:dir] || bundled_app
command_execution = CommandExecution.new(cmd.to_s, dir)

Expand Down Expand Up @@ -558,6 +516,41 @@ def exit_status_for_signal(signal_number)

private

def prepare_env(options)
env = options.delete(:env) || {}
requires = options.delete(:requires) || []

current_example = RSpec.current_example

if current_example
artifice = options.delete(:artifice) do
if current_example.metadata[:realworld]
"vcr"
else
"fail"
end
end

if artifice
requires << "#{artifice_dir}/#{artifice}.rb"
end
end

rubyopt = env["RUBYOPT"] || ""

rubyopt = opt_add(ENV["RUBYOPT"], rubyopt) if ENV["RUBYOPT"]

requires.each do |r|
rubyopt = opt_add("-r#{r}", rubyopt)
end

rubyopt = opt_add("-r#{hax}", rubyopt)
rubyopt = opt_add("-r#{switch}", rubyopt)

env["RUBYOPT"] = rubyopt
env
end

def git_root_dir?
root.to_s == `git rev-parse --show-toplevel`.chomp
end
Expand Down
12 changes: 12 additions & 0 deletions bundler/spec/support/path.rb
Expand Up @@ -75,6 +75,18 @@ def man_dir
@man_dir ||= lib_dir.join("bundler/man")
end

def hax
spec_dir.join("support/hax.rb")
end

def switch
spec_dir.join("support/switch_rubygems.rb")
end

def artifice_dir
spec_dir.join("support/artifice")
end

def tracked_files
@tracked_files ||= git_ls_files(tracked_files_glob)
end
Expand Down