Skip to content

Commit

Permalink
bundle exec does less work
Browse files Browse the repository at this point in the history
It isn't necessary for bundle exec to load up
and test the entire environment, when the process
it is exec'ing into has to do the same work
anyway.

This change makes bundle exec do the minimal env
setup work, and defer the checking to the
subprocess it is `exec`ing to.
  • Loading branch information
tomhuda committed May 20, 2012
1 parent a267192 commit 1f254ed
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 27 deletions.
25 changes: 25 additions & 0 deletions lib/bundler.rb
Expand Up @@ -216,6 +216,31 @@ def clean_exec(*args)
with_clean_env { Kernel.exec(*args) }
end

def setup_environment
begin
ENV["BUNDLE_BIN_PATH"] = Bundler.rubygems.bin_path("bundler", "bundle", VERSION)
rescue Gem::GemNotFoundException
ENV["BUNDLE_BIN_PATH"] = File.expand_path("../../../bin/bundle", __FILE__)
end

# Set PATH
paths = (ENV["PATH"] || "").split(File::PATH_SEPARATOR)
paths.unshift "#{Bundler.bundle_path}/bin"
ENV["PATH"] = paths.uniq.join(File::PATH_SEPARATOR)

# Set BUNDLE_GEMFILE
ENV["BUNDLE_GEMFILE"] = default_gemfile.to_s

# Set RUBYOPT
rubyopt = [ENV["RUBYOPT"]].compact
if rubyopt.empty? || rubyopt.first !~ /-rbundler\/setup/
rubyopt.unshift "-rbundler/setup"
rubyopt.unshift "-I#{File.expand_path('..', __FILE__)}"
ENV["RUBYOPT"] = rubyopt.join(' ')
end
end


def default_gemfile
SharedHelpers.default_gemfile
end
Expand Down
3 changes: 1 addition & 2 deletions lib/bundler/cli.rb
Expand Up @@ -419,8 +419,7 @@ def package
def exec(*)
ARGV.shift # remove "exec"

Bundler.definition.validate_ruby!
Bundler.load.setup_environment
Bundler.setup_environment

begin
# Run
Expand Down
22 changes: 1 addition & 21 deletions lib/bundler/runtime.rb
Expand Up @@ -201,27 +201,7 @@ def clean
end

def setup_environment
begin
ENV["BUNDLE_BIN_PATH"] = Bundler.rubygems.bin_path("bundler", "bundle", VERSION)
rescue Gem::GemNotFoundException
ENV["BUNDLE_BIN_PATH"] = File.expand_path("../../../bin/bundle", __FILE__)
end

# Set PATH
paths = (ENV["PATH"] || "").split(File::PATH_SEPARATOR)
paths.unshift "#{Bundler.bundle_path}/bin"
ENV["PATH"] = paths.uniq.join(File::PATH_SEPARATOR)

# Set BUNDLE_GEMFILE
ENV["BUNDLE_GEMFILE"] = default_gemfile.to_s

# Set RUBYOPT
rubyopt = [ENV["RUBYOPT"]].compact
if rubyopt.empty? || rubyopt.first !~ /-rbundler\/setup/
rubyopt.unshift "-rbundler/setup"
rubyopt.unshift "-I#{File.expand_path('../..', __FILE__)}"
ENV["RUBYOPT"] = rubyopt.join(' ')
end
Bundler.setup_environment
end

private
Expand Down
8 changes: 6 additions & 2 deletions lib/bundler/settings.rb
Expand Up @@ -2,8 +2,12 @@ module Bundler
class Settings
def initialize(root)
@root = root
@local_config = (File.exist?(local_config_file) && yaml = YAML.load_file(local_config_file)) ? yaml : {}
@global_config = (File.exist?(global_config_file) && yaml = YAML.load_file(global_config_file)) ? yaml : {}

local_config_exists = File.exists?(local_config_file) && File.size(local_config_file).nonzero?
@local_config = (local_config_exists && yaml = YAML.load_file(local_config_file)) ? yaml : {}

global_config_exists = File.exists?(global_config_file) && File.size(global_config_file).nonzero?
@global_config = (global_config_exists && yaml = YAML.load_file(global_config_file)) ? yaml : {}
end

def [](key)
Expand Down
11 changes: 9 additions & 2 deletions spec/install/gems/simple_case_spec.rb
Expand Up @@ -315,27 +315,34 @@
end

it "doesn't blow up when the local .bundle/config is empty" do
config_file = bundled_app(".bundle/config")
FileUtils.mkdir_p(bundled_app(".bundle"))
FileUtils.touch(bundled_app(".bundle/config"))
FileUtils.touch(config_file)

install_gemfile(<<-G, :exitstatus => true)
source "file://#{gem_repo1}"
gem 'foo'
G
exitstatus.should == 0
File.exists?(config_file).should be_true
File.size(config_file).should be_zero
end

it "doesn't blow up when the global .bundle/config is empty" do
config_file = "#{Bundler.rubygems.user_home}/.bundle/config"
FileUtils.mkdir_p("#{Bundler.rubygems.user_home}/.bundle")
FileUtils.touch("#{Bundler.rubygems.user_home}/.bundle/config")
FileUtils.touch(config_file)

install_gemfile(<<-G, :exitstatus => true)
source "file://#{gem_repo1}"
gem 'foo'
G

exitstatus.should == 0
File.exists?(config_file).should be_true
File.size(config_file).should be_zero
end
end

Expand Down
14 changes: 14 additions & 0 deletions spec/runtime/with_clean_env_spec.rb
Expand Up @@ -25,6 +25,20 @@

it_should_behave_like "Bundler.with_*_env"

it "should keep the original GEM_PATH even in sub processes" do
gemfile ""
bundle "install --path vendor/bundle"

gem_path = ENV['GEM_PATH']

code = "Bundler.with_clean_env do;" +
" print ENV['GEM_PATH'] != '';" +
"end"

result = bundle "exec ruby -e #{code.inspect}"
result.should == "true"
end

it "should not pass any bundler environment variables" do
Bundler.with_clean_env do
`echo $BUNDLE_PATH`.strip.should_not == './Gemfile'
Expand Down

0 comments on commit 1f254ed

Please sign in to comment.