summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Giddins <segiddins@segiddins.me>2017-03-28 13:52:01 -0500
committerSamuel Giddins <segiddins@segiddins.me>2017-03-28 13:52:01 -0500
commit1a105ba9705fa20febbd5f7fd63838d28b9ecedd (patch)
tree09323656a32500d067bbd7e86b28d41661b212b0
parent81d53b52444572cf1454da4c741242e2dd47de5c (diff)
downloadbundler-seg-split-gem-download-from-install.tar.gz
[ParallelInstaller] Split gem downloads from installsseg-split-gem-download-from-install
-rw-r--r--lib/bundler/installer/gem_installer.rb15
-rw-r--r--lib/bundler/installer/parallel_installer.rb15
-rw-r--r--lib/bundler/source/rubygems.rb30
3 files changed, 38 insertions, 22 deletions
diff --git a/lib/bundler/installer/gem_installer.rb b/lib/bundler/installer/gem_installer.rb
index 10e7c7fcd7..5cb3c586bf 100644
--- a/lib/bundler/installer/gem_installer.rb
+++ b/lib/bundler/installer/gem_installer.rb
@@ -1,14 +1,15 @@
# frozen_string_literal: true
module Bundler
class GemInstaller
- attr_reader :spec, :standalone, :worker, :force, :installer
+ attr_reader :spec, :standalone, :worker, :force, :installer, :installations
- def initialize(spec, installer, standalone = false, worker = 0, force = false)
+ def initialize(spec, installer, standalone = false, worker = 0, force = false, installations = [])
@spec = spec
@installer = installer
@standalone = standalone
@worker = worker
@force = force
+ @installations = []
end
def install_from_spec
@@ -52,7 +53,15 @@ module Bundler
end
def install
- spec.source.install(spec, :force => force, :ensure_builtin_gems_cached => standalone, :build_args => Array(spec_settings))
+ spec.source.download_gem(spec, :force => force)
+ spec.dependencies.each do |dep|
+ next unless dep.type == :runtime
+ next if installations.find do |si|
+ si.installed? && dep.matches_spec?(si)
+ end
+ raise "Dependency #{dep} for #{spec} is not satisfied at installation time"
+ end
+ spec.source.install(spec, :force => force, :ensure_builtin_gems_cached => standalone, :build_args => Array(spec_settings), :skip_download => true)
end
def install_with_settings
diff --git a/lib/bundler/installer/parallel_installer.rb b/lib/bundler/installer/parallel_installer.rb
index 97c124e015..8affd7b98e 100644
--- a/lib/bundler/installer/parallel_installer.rb
+++ b/lib/bundler/installer/parallel_installer.rb
@@ -59,8 +59,7 @@ module Bundler
end
def missing_lockfile_dependencies(all_spec_names)
- deps = all_dependencies.reject {|dep| ignorable_dependency? dep }
- deps.reject {|dep| all_spec_names.include? dep.name }
+ dependencies.reject {|dep| all_spec_names.include? dep.name }
end
# Represents all dependencies
@@ -110,12 +109,13 @@ module Bundler
def worker_pool
@worker_pool ||= Bundler::Worker.new @size, "Parallel Installer", lambda { |spec_install, worker_num|
gem_installer = Bundler::GemInstaller.new(
- spec_install.spec, @installer, @standalone, worker_num, @force
+ spec_install.spec, @installer, @standalone, worker_num, @force, @specs
)
success, message = gem_installer.install_from_spec
- if success && !message.nil?
- spec_install.post_install_message = message
- elsif !success
+ if success
+ spec_install.post_install_message = message unless message.nil?
+ spec_install.state = :installed
+ else
spec_install.state = :failed
spec_install.error = "#{message}\n\n#{require_tree_for_spec(spec_install.spec)}"
end
@@ -129,8 +129,7 @@ module Bundler
# processed so the call to `enqueue_specs` is important after every
# dequeue.
def process_specs
- spec = worker_pool.deq
- spec.state = :installed unless spec.failed?
+ worker_pool.deq
enqueue_specs
end
diff --git a/lib/bundler/source/rubygems.rb b/lib/bundler/source/rubygems.rb
index 8c592cb727..b3fb42b7d0 100644
--- a/lib/bundler/source/rubygems.rb
+++ b/lib/bundler/source/rubygems.rb
@@ -86,6 +86,23 @@ module Bundler
end
end
+ def download_gem(spec, opts = {})
+ force = opts[:force]
+
+ return if installed?(spec) && (!force || spec.name.eql?("bundler"))
+
+ return unless spec.remote
+
+ # Check for this spec from other sources
+ uris = [spec.remote.anonymized_uri]
+ uris += remotes_for_spec(spec).map(&:anonymized_uri)
+ uris.uniq!
+ Installer.ambiguous_gems << [spec.name, *uris] if uris.length > 1
+
+ s = Bundler.rubygems.spec_from_gem(fetch_gem(spec), Bundler.settings["trust-policy"])
+ spec.__swap__(s)
+ end
+
def install(spec, opts = {})
force = opts[:force]
ensure_builtin_gems_cached = opts[:ensure_builtin_gems_cached]
@@ -105,17 +122,8 @@ module Bundler
end
# Download the gem to get the spec, because some specs that are returned
- # by rubygems.org are broken and wrong.
- if spec.remote
- # Check for this spec from other sources
- uris = [spec.remote.anonymized_uri]
- uris += remotes_for_spec(spec).map(&:anonymized_uri)
- uris.uniq!
- Installer.ambiguous_gems << [spec.name, *uris] if uris.length > 1
-
- s = Bundler.rubygems.spec_from_gem(fetch_gem(spec), Bundler.settings["trust-policy"])
- spec.__swap__(s)
- end
+ # by rubygems.org are inconsistent.
+ download_gem(spec, opts) unless opts[:skip_download]
unless Bundler.settings[:no_install]
message = "Installing #{version_message(spec)}"