diff options
-rw-r--r-- | lib/bundler/cli.rb | 4 | ||||
-rw-r--r-- | lib/bundler/cli/pristine.rb | 68 | ||||
-rw-r--r-- | lib/bundler/installer/parallel_installer.rb | 11 |
3 files changed, 48 insertions, 35 deletions
diff --git a/lib/bundler/cli.rb b/lib/bundler/cli.rb index 022d2c9142..da5950917b 100644 --- a/lib/bundler/cli.rb +++ b/lib/bundler/cli.rb @@ -660,7 +660,9 @@ module Bundler D def pristine(*gems) require_relative "cli/pristine" - Pristine.new(gems).run + Bundler.settings.temporary(no_install: false) do + Pristine.new(gems).run + end end if Bundler.feature_flag.plugins? diff --git a/lib/bundler/cli/pristine.rb b/lib/bundler/cli/pristine.rb index d6654f8053..e0d7452c44 100644 --- a/lib/bundler/cli/pristine.rb +++ b/lib/bundler/cli/pristine.rb @@ -12,40 +12,48 @@ module Bundler definition.validate_runtime! installer = Bundler::Installer.new(Bundler.root, definition) - Bundler.load.specs.each do |spec| - next if spec.name == "bundler" # Source::Rubygems doesn't install bundler - next if !@gems.empty? && !@gems.include?(spec.name) - - gem_name = "#{spec.name} (#{spec.version}#{spec.git_version})" - gem_name += " (#{spec.platform})" if !spec.platform.nil? && spec.platform != Gem::Platform::RUBY - - case source = spec.source - when Source::Rubygems - cached_gem = spec.cache_file - unless File.exist?(cached_gem) - Bundler.ui.error("Failed to pristine #{gem_name}. Cached gem #{cached_gem} does not exist.") + ProcessLock.lock do + installed_specs = definition.specs.reject do |spec| + next if spec.name == "bundler" # Source::Rubygems doesn't install bundler + next if !@gems.empty? && !@gems.include?(spec.name) + + gem_name = "#{spec.name} (#{spec.version}#{spec.git_version})" + gem_name += " (#{spec.platform})" if !spec.platform.nil? && spec.platform != Gem::Platform::RUBY + + case source = spec.source + when Source::Rubygems + cached_gem = spec.cache_file + unless File.exist?(cached_gem) + Bundler.ui.error("Failed to pristine #{gem_name}. Cached gem #{cached_gem} does not exist.") + next + end + + FileUtils.rm_rf spec.full_gem_path + when Source::Git + if source.local? + Bundler.ui.warn("Cannot pristine #{gem_name}. Gem is locally overridden.") + next + end + + source.remote! + if extension_cache_path = source.extension_cache_path(spec) + FileUtils.rm_rf extension_cache_path + end + FileUtils.rm_rf spec.extension_dir + FileUtils.rm_rf spec.full_gem_path + else + Bundler.ui.warn("Cannot pristine #{gem_name}. Gem is sourced from local path.") next end - FileUtils.rm_rf spec.full_gem_path - when Source::Git - if source.local? - Bundler.ui.warn("Cannot pristine #{gem_name}. Gem is locally overridden.") - next - end + true + end.map(&:name) - source.remote! - if extension_cache_path = source.extension_cache_path(spec) - FileUtils.rm_rf extension_cache_path - end - FileUtils.rm_rf spec.extension_dir - FileUtils.rm_rf spec.full_gem_path - else - Bundler.ui.warn("Cannot pristine #{gem_name}. Gem is sourced from local path.") - next - end - - Bundler::GemInstaller.new(spec, installer, false, 0, true).install_from_spec + jobs = installer.send(:installation_parallelization, {}) + pristine_count = definition.specs.count - installed_specs.count + # allow a pristining a single gem to skip the parallel worker + jobs = [jobs, pristine_count].min + ParallelInstaller.call(installer, definition.specs, jobs, false, true, skip: installed_specs) end end end diff --git a/lib/bundler/installer/parallel_installer.rb b/lib/bundler/installer/parallel_installer.rb index 02ae7d535f..e745088f81 100644 --- a/lib/bundler/installer/parallel_installer.rb +++ b/lib/bundler/installer/parallel_installer.rb @@ -62,20 +62,23 @@ module Bundler end end - def self.call(*args) - new(*args).call + def self.call(*args, **kwargs) + new(*args, **kwargs).call end attr_reader :size - def initialize(installer, all_specs, size, standalone, force) + def initialize(installer, all_specs, size, standalone, force, skip: nil) @installer = installer @size = size @standalone = standalone @force = force @specs = all_specs.map {|s| SpecInstallation.new(s) } + @specs.each do |spec_install| + spec_install.state = :installed if skip.include?(spec_install.name) + end if skip @spec_set = all_specs - @rake = @specs.find {|s| s.name == "rake" } + @rake = @specs.find {|s| s.name == "rake" unless s.installed? } end def call |