Skip to content

Commit a555fd6

Browse files
segiddinsmartinemde
authored andcommitted
Allow bundle pristine to run in parallel
Also fix running when BUNDLE_NO_INSTALL happens to be set, same as with install/update commands
1 parent 705c534 commit a555fd6

File tree

3 files changed

+48
-35
lines changed

3 files changed

+48
-35
lines changed

bundler/lib/bundler/cli.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -660,7 +660,9 @@ def issue
660660
D
661661
def pristine(*gems)
662662
require_relative "cli/pristine"
663-
Pristine.new(gems).run
663+
Bundler.settings.temporary(no_install: false) do
664+
Pristine.new(gems).run
665+
end
664666
end
665667

666668
if Bundler.feature_flag.plugins?

bundler/lib/bundler/cli/pristine.rb

Lines changed: 38 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -12,40 +12,48 @@ def run
1212
definition.validate_runtime!
1313
installer = Bundler::Installer.new(Bundler.root, definition)
1414

15-
Bundler.load.specs.each do |spec|
16-
next if spec.name == "bundler" # Source::Rubygems doesn't install bundler
17-
next if !@gems.empty? && !@gems.include?(spec.name)
18-
19-
gem_name = "#{spec.name} (#{spec.version}#{spec.git_version})"
20-
gem_name += " (#{spec.platform})" if !spec.platform.nil? && spec.platform != Gem::Platform::RUBY
21-
22-
case source = spec.source
23-
when Source::Rubygems
24-
cached_gem = spec.cache_file
25-
unless File.exist?(cached_gem)
26-
Bundler.ui.error("Failed to pristine #{gem_name}. Cached gem #{cached_gem} does not exist.")
15+
ProcessLock.lock do
16+
installed_specs = definition.specs.reject do |spec|
17+
next if spec.name == "bundler" # Source::Rubygems doesn't install bundler
18+
next if !@gems.empty? && !@gems.include?(spec.name)
19+
20+
gem_name = "#{spec.name} (#{spec.version}#{spec.git_version})"
21+
gem_name += " (#{spec.platform})" if !spec.platform.nil? && spec.platform != Gem::Platform::RUBY
22+
23+
case source = spec.source
24+
when Source::Rubygems
25+
cached_gem = spec.cache_file
26+
unless File.exist?(cached_gem)
27+
Bundler.ui.error("Failed to pristine #{gem_name}. Cached gem #{cached_gem} does not exist.")
28+
next
29+
end
30+
31+
FileUtils.rm_rf spec.full_gem_path
32+
when Source::Git
33+
if source.local?
34+
Bundler.ui.warn("Cannot pristine #{gem_name}. Gem is locally overridden.")
35+
next
36+
end
37+
38+
source.remote!
39+
if extension_cache_path = source.extension_cache_path(spec)
40+
FileUtils.rm_rf extension_cache_path
41+
end
42+
FileUtils.rm_rf spec.extension_dir
43+
FileUtils.rm_rf spec.full_gem_path
44+
else
45+
Bundler.ui.warn("Cannot pristine #{gem_name}. Gem is sourced from local path.")
2746
next
2847
end
2948

30-
FileUtils.rm_rf spec.full_gem_path
31-
when Source::Git
32-
if source.local?
33-
Bundler.ui.warn("Cannot pristine #{gem_name}. Gem is locally overridden.")
34-
next
35-
end
49+
true
50+
end.map(&:name)
3651

37-
source.remote!
38-
if extension_cache_path = source.extension_cache_path(spec)
39-
FileUtils.rm_rf extension_cache_path
40-
end
41-
FileUtils.rm_rf spec.extension_dir
42-
FileUtils.rm_rf spec.full_gem_path
43-
else
44-
Bundler.ui.warn("Cannot pristine #{gem_name}. Gem is sourced from local path.")
45-
next
46-
end
47-
48-
Bundler::GemInstaller.new(spec, installer, false, 0, true).install_from_spec
52+
jobs = installer.send(:installation_parallelization, {})
53+
pristine_count = definition.specs.count - installed_specs.count
54+
# allow a pristining a single gem to skip the parallel worker
55+
jobs = [jobs, pristine_count].min
56+
ParallelInstaller.call(installer, definition.specs, jobs, false, true, skip: installed_specs)
4957
end
5058
end
5159
end

bundler/lib/bundler/installer/parallel_installer.rb

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,20 +62,23 @@ def to_s
6262
end
6363
end
6464

65-
def self.call(*args)
66-
new(*args).call
65+
def self.call(*args, **kwargs)
66+
new(*args, **kwargs).call
6767
end
6868

6969
attr_reader :size
7070

71-
def initialize(installer, all_specs, size, standalone, force)
71+
def initialize(installer, all_specs, size, standalone, force, skip: nil)
7272
@installer = installer
7373
@size = size
7474
@standalone = standalone
7575
@force = force
7676
@specs = all_specs.map {|s| SpecInstallation.new(s) }
77+
@specs.each do |spec_install|
78+
spec_install.state = :installed if skip.include?(spec_install.name)
79+
end if skip
7780
@spec_set = all_specs
78-
@rake = @specs.find {|s| s.name == "rake" }
81+
@rake = @specs.find {|s| s.name == "rake" unless s.installed? }
7982
end
8083

8184
def call

0 commit comments

Comments
 (0)