summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Giddins <segiddins@segiddins.me>2017-06-13 14:38:26 -0500
committerSamuel Giddins <segiddins@segiddins.me>2017-06-14 16:05:34 -0500
commita6d0a2c9b5e170603ee31ce59c6a5199d82cbd59 (patch)
tree75e51994b5399b40f6ec80a474b0e52fa4c412e7
parentddcca6254cc4e63cbb25b78f8ec93462fa56249c (diff)
downloadbundler-seg-reduce-gemfile-eval-count.tar.gz
Eval Gemfiles one fewer time when running `bundle install`seg-reduce-gemfile-eval-count
-rw-r--r--lib/bundler/definition.rb13
-rw-r--r--lib/bundler/installer.rb13
-rw-r--r--lib/bundler/source/path.rb2
-rw-r--r--lib/bundler/source/rubygems.rb1
-rw-r--r--spec/install/gemfile/lockfile_spec.rb48
-rw-r--r--spec/spec_helper.rb1
6 files changed, 65 insertions, 13 deletions
diff --git a/lib/bundler/definition.rb b/lib/bundler/definition.rb
index 4b75b39065..d7faff53e7 100644
--- a/lib/bundler/definition.rb
+++ b/lib/bundler/definition.rb
@@ -194,10 +194,19 @@ module Bundler
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
diff --git a/lib/bundler/installer.rb b/lib/bundler/installer.rb
index efad66e202..0f150591d2 100644
--- a/lib/bundler/installer.rb
+++ b/lib/bundler/installer.rb
@@ -78,7 +78,7 @@ module Bundler
return
end
- resolve_if_need(options)
+ resolve_if_needed(options)
ensure_specs_are_compatible!
install(options)
@@ -214,18 +214,11 @@ module Bundler
"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
diff --git a/lib/bundler/source/path.rb b/lib/bundler/source/path.rb
index 82f987fdd8..99808d2ef2 100644
--- a/lib/bundler/source/path.rb
+++ b/lib/bundler/source/path.rb
@@ -35,10 +35,12 @@ module Bundler
end
def remote!
+ @local_specs = nil
@allow_remote = true
end
def cached!
+ @local_specs = nil
@allow_cached = true
end
diff --git a/lib/bundler/source/rubygems.rb b/lib/bundler/source/rubygems.rb
index 353194f53f..a1d4266960 100644
--- a/lib/bundler/source/rubygems.rb
+++ b/lib/bundler/source/rubygems.rb
@@ -31,6 +31,7 @@ module Bundler
end
def cached!
+ @specs = nil
@allow_cached = true
end
diff --git a/spec/install/gemfile/lockfile_spec.rb b/spec/install/gemfile/lockfile_spec.rb
new file mode 100644
index 0000000000..dc1baca6ea
--- /dev/null
+++ b/spec/install/gemfile/lockfile_spec.rb
@@ -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
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index f9285463b5..2700d944dc 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -45,7 +45,6 @@ Spec::Rubygems.setup
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"