Skip to content
This repository has been archived by the owner on Apr 14, 2021. It is now read-only.

Commit

Permalink
Auto merge of #5718 - bundler:seg-reduce-gemfile-eval-count, r=indirect
Browse files Browse the repository at this point in the history
Eval Gemfiles one fewer time when running `bundle install`

This is just a straight port of #4952 to master from `2-0-dev`.
Unfortunately, the Gemfile is still eval'ed twice when plugins are enabled.
  • Loading branch information
bundlerbot committed Jun 16, 2017
2 parents 0c651a9 + a6d0a2c commit 71c82a1
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 13 deletions.
13 changes: 11 additions & 2 deletions lib/bundler/definition.rb
Original file line number Diff line number Diff line change
Expand Up @@ -194,10 +194,19 @@ def missing_specs
missing
end

def missing_dependencies
def missing_dependencies?
missing = []
resolve.materialize(current_dependencies, missing)
missing
return false if missing.empty?
Bundler.ui.debug "The definition is missing #{missing.map(&:full_name)}"
true
rescue BundlerError => e
Bundler.ui.debug "The definition is missing dependencies, failed to resolve & materialize locally (#{e})"
true
ensure
@index = nil
@resolve = nil
@specs = nil
end

def requested_specs
Expand Down
13 changes: 3 additions & 10 deletions lib/bundler/installer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ def run(options)
return
end

resolve_if_need(options)
resolve_if_needed(options)
ensure_specs_are_compatible!
install(options)

Expand Down Expand Up @@ -229,18 +229,11 @@ def create_bundle_path
"because a file already exists at that path. Either remove or rename the file so the directory can be created."
end

def resolve_if_need(options)
def resolve_if_needed(options)
if !options["update"] && !options[:inline] && !options["force"] && Bundler.default_lockfile.file?
local = Bundler.ui.silence do
begin
tmpdef = Definition.build(Bundler.default_gemfile, Bundler.default_lockfile, nil)
true unless tmpdef.new_platform? || tmpdef.missing_dependencies.any?
rescue BundlerError
end
end
return if @definition.nothing_changed? && !@definition.missing_dependencies?
end

return if local
options["local"] ? @definition.resolve_with_cache! : @definition.resolve_remotely!
end

Expand Down
2 changes: 2 additions & 0 deletions lib/bundler/source/path.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,12 @@ def initialize(options)
end

def remote!
@local_specs = nil
@allow_remote = true
end

def cached!
@local_specs = nil
@allow_cached = true
end

Expand Down
1 change: 1 addition & 0 deletions lib/bundler/source/rubygems.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ def remote!
end

def cached!
@specs = nil
@allow_cached = true
end

Expand Down
48 changes: 48 additions & 0 deletions spec/install/gemfile/lockfile_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# frozen_string_literal: true

RSpec.describe "bundle install with a lockfile present" do
let(:gf) { <<-G }
source "file://#{gem_repo1}"
gem "rack", "1.0.0"
G

subject do
install_gemfile(gf)
end

context "gemfile evaluation" do
let(:gf) { super() + "\n\n File.open('evals', 'a') {|f| f << %(1\n) } unless ENV['BUNDLER_SPEC_NO_APPEND']" }

context "with plugins disabled" do
before do
bundle! "config plugins false"
subject
end

it "does not evaluate the gemfile twice" do
bundle! :install

with_env_vars("BUNDLER_SPEC_NO_APPEND" => "1") { expect(the_bundle).to include_gem "rack 1.0.0" }

# The first eval is from the initial install, we're testing that the
# second install doesn't double-eval
expect(bundled_app("evals").read.lines.to_a.size).to eq(2)
end

context "when the gem is not installed" do
before { FileUtils.rm_rf ".bundle" }

it "does not evaluate the gemfile twice" do
bundle! :install

with_env_vars("BUNDLER_SPEC_NO_APPEND" => "1") { expect(the_bundle).to include_gem "rack 1.0.0" }

# The first eval is from the initial install, we're testing that the
# second install doesn't double-eval
expect(bundled_app("evals").read.lines.to_a.size).to eq(2)
end
end
end
end
end
1 change: 0 additions & 1 deletion spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@
FileUtils.rm_rf(Spec::Path.gem_repo1)
ENV["RUBYOPT"] = "#{ENV["RUBYOPT"]} -r#{Spec::Path.root}/spec/support/hax.rb"
ENV["BUNDLE_SPEC_RUN"] = "true"
ENV["BUNDLE_PLUGINS"] = "true"

# Don't wrap output in tests
ENV["THOR_COLUMNS"] = "10000"
Expand Down

0 comments on commit 71c82a1

Please sign in to comment.