bundler 2.5.16 → 2.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +194 -0
- data/bundler.gemspec +2 -2
- data/lib/bundler/build_metadata.rb +2 -2
- data/lib/bundler/cli/add.rb +3 -1
- data/lib/bundler/cli/check.rb +3 -3
- data/lib/bundler/cli/console.rb +0 -4
- data/lib/bundler/cli/doctor.rb +4 -4
- data/lib/bundler/cli/exec.rb +1 -0
- data/lib/bundler/cli/gem.rb +6 -3
- data/lib/bundler/cli/info.rb +2 -2
- data/lib/bundler/cli/inject.rb +1 -1
- data/lib/bundler/cli/install.rb +13 -4
- data/lib/bundler/cli/lock.rb +25 -6
- data/lib/bundler/cli/outdated.rb +16 -18
- data/lib/bundler/cli/pristine.rb +1 -1
- data/lib/bundler/cli/show.rb +2 -2
- data/lib/bundler/cli.rb +38 -68
- data/lib/bundler/compact_index_client/cache_file.rb +0 -5
- data/lib/bundler/compact_index_client/updater.rb +0 -11
- data/lib/bundler/definition.rb +186 -119
- data/lib/bundler/dependency.rb +1 -1
- data/lib/bundler/dsl.rb +67 -52
- data/lib/bundler/endpoint_specification.rb +10 -1
- data/lib/bundler/errors.rb +17 -5
- data/lib/bundler/feature_flag.rb +1 -0
- data/lib/bundler/fetcher/compact_index.rb +1 -1
- data/lib/bundler/fetcher.rb +12 -5
- data/lib/bundler/force_platform.rb +0 -2
- data/lib/bundler/gem_helpers.rb +21 -5
- data/lib/bundler/injector.rb +2 -2
- data/lib/bundler/inline.rb +42 -17
- data/lib/bundler/installer/gem_installer.rb +4 -2
- data/lib/bundler/installer/parallel_installer.rb +3 -2
- data/lib/bundler/installer/standalone.rb +2 -2
- data/lib/bundler/installer.rb +11 -47
- data/lib/bundler/lazy_specification.rb +74 -26
- data/lib/bundler/lockfile_generator.rb +1 -1
- data/lib/bundler/lockfile_parser.rb +10 -2
- data/lib/bundler/man/bundle-add.1 +42 -25
- data/lib/bundler/man/bundle-add.1.ronn +52 -23
- data/lib/bundler/man/bundle-binstubs.1 +7 -4
- data/lib/bundler/man/bundle-binstubs.1.ronn +6 -3
- data/lib/bundler/man/bundle-cache.1 +30 -2
- data/lib/bundler/man/bundle-cache.1.ronn +31 -2
- data/lib/bundler/man/bundle-check.1 +3 -3
- data/lib/bundler/man/bundle-check.1.ronn +4 -2
- data/lib/bundler/man/bundle-clean.1 +1 -1
- data/lib/bundler/man/bundle-config.1 +3 -5
- data/lib/bundler/man/bundle-config.1.ronn +2 -7
- data/lib/bundler/man/bundle-console.1 +2 -4
- data/lib/bundler/man/bundle-console.1.ronn +2 -7
- data/lib/bundler/man/bundle-doctor.1 +2 -2
- data/lib/bundler/man/bundle-doctor.1.ronn +1 -1
- data/lib/bundler/man/bundle-env.1 +9 -0
- data/lib/bundler/man/bundle-env.1.ronn +10 -0
- data/lib/bundler/man/bundle-exec.1 +5 -2
- data/lib/bundler/man/bundle-exec.1.ronn +4 -1
- data/lib/bundler/man/bundle-fund.1 +22 -0
- data/lib/bundler/man/bundle-fund.1.ronn +25 -0
- data/lib/bundler/man/bundle-gem.1 +17 -5
- data/lib/bundler/man/bundle-gem.1.ronn +27 -6
- data/lib/bundler/man/bundle-help.1 +1 -1
- data/lib/bundler/man/bundle-info.1 +5 -2
- data/lib/bundler/man/bundle-info.1.ronn +6 -2
- data/lib/bundler/man/bundle-init.1 +3 -3
- data/lib/bundler/man/bundle-init.1.ronn +3 -2
- data/lib/bundler/man/bundle-inject.1 +10 -2
- data/lib/bundler/man/bundle-inject.1.ronn +9 -1
- data/lib/bundler/man/bundle-install.1 +15 -12
- data/lib/bundler/man/bundle-install.1.ronn +22 -18
- data/lib/bundler/man/bundle-issue.1 +45 -0
- data/lib/bundler/man/bundle-issue.1.ronn +37 -0
- data/lib/bundler/man/bundle-licenses.1 +9 -0
- data/lib/bundler/man/bundle-licenses.1.ronn +10 -0
- data/lib/bundler/man/bundle-list.1 +1 -1
- data/lib/bundler/man/bundle-list.1.ronn +4 -1
- data/lib/bundler/man/bundle-lock.1 +21 -6
- data/lib/bundler/man/bundle-lock.1.ronn +25 -4
- data/lib/bundler/man/bundle-open.1 +2 -2
- data/lib/bundler/man/bundle-open.1.ronn +2 -1
- data/lib/bundler/man/bundle-outdated.1 +8 -5
- data/lib/bundler/man/bundle-outdated.1.ronn +8 -4
- data/lib/bundler/man/bundle-platform.1 +1 -1
- data/lib/bundler/man/bundle-plugin.1 +1 -1
- data/lib/bundler/man/bundle-pristine.1 +1 -1
- data/lib/bundler/man/bundle-pristine.1.ronn +1 -1
- data/lib/bundler/man/bundle-remove.1 +1 -1
- data/lib/bundler/man/bundle-remove.1.ronn +1 -1
- data/lib/bundler/man/bundle-show.1 +5 -2
- data/lib/bundler/man/bundle-show.1.ronn +4 -0
- data/lib/bundler/man/bundle-update.1 +13 -7
- data/lib/bundler/man/bundle-update.1.ronn +14 -6
- data/lib/bundler/man/bundle-version.1 +1 -1
- data/lib/bundler/man/bundle-viz.1 +4 -4
- data/lib/bundler/man/bundle-viz.1.ronn +7 -3
- data/lib/bundler/man/bundle.1 +1 -1
- data/lib/bundler/man/gemfile.5 +3 -1
- data/lib/bundler/man/gemfile.5.ronn +6 -0
- data/lib/bundler/man/index.txt +4 -0
- data/lib/bundler/materialization.rb +59 -0
- data/lib/bundler/plugin/api/source.rb +2 -1
- data/lib/bundler/plugin/events.rb +24 -0
- data/lib/bundler/plugin/installer.rb +1 -1
- data/lib/bundler/plugin.rb +20 -1
- data/lib/bundler/process_lock.rb +10 -14
- data/lib/bundler/remote_specification.rb +6 -1
- data/lib/bundler/resolver/base.rb +12 -6
- data/lib/bundler/resolver/candidate.rb +2 -2
- data/lib/bundler/resolver/package.rb +10 -1
- data/lib/bundler/resolver/spec_group.rb +4 -3
- data/lib/bundler/resolver.rb +36 -14
- data/lib/bundler/retry.rb +1 -1
- data/lib/bundler/ruby_version.rb +7 -1
- data/lib/bundler/rubygems_ext.rb +104 -51
- data/lib/bundler/rubygems_gem_installer.rb +7 -5
- data/lib/bundler/rubygems_integration.rb +23 -62
- data/lib/bundler/runtime.rb +22 -7
- data/lib/bundler/self_manager.rb +7 -7
- data/lib/bundler/settings.rb +6 -1
- data/lib/bundler/shared_helpers.rb +29 -17
- data/lib/bundler/source/git/git_proxy.rb +0 -2
- data/lib/bundler/source/git.rb +93 -40
- data/lib/bundler/source/metadata.rb +2 -3
- data/lib/bundler/source/path.rb +5 -3
- data/lib/bundler/source/rubygems.rb +6 -16
- data/lib/bundler/source_list.rb +1 -1
- data/lib/bundler/spec_set.rb +82 -57
- data/lib/bundler/stub_specification.rb +21 -2
- data/lib/bundler/templates/newgem/Gemfile.tt +0 -3
- data/lib/bundler/templates/newgem/README.md.tt +7 -3
- data/lib/bundler/templates/newgem/github/workflows/main.yml.tt +15 -15
- data/lib/bundler/templates/newgem/newgem.gemspec.tt +4 -4
- data/lib/bundler/ui/shell.rb +24 -2
- data/lib/bundler/ui/silent.rb +12 -1
- data/lib/bundler/uri_credentials_filter.rb +1 -1
- data/lib/bundler/vendor/fileutils/COPYING +56 -0
- data/lib/bundler/vendor/fileutils/lib/fileutils.rb +15 -13
- data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb +46 -8
- data/lib/bundler/vendor/securerandom/.document +1 -0
- data/lib/bundler/vendor/securerandom/COPYING +56 -0
- data/lib/bundler/vendor/securerandom/lib/securerandom.rb +102 -0
- data/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb +3 -5
- data/lib/bundler/vendor/thor/lib/thor/group.rb +11 -0
- data/lib/bundler/vendor/thor/lib/thor/parser/argument.rb +1 -4
- data/lib/bundler/vendor/thor/lib/thor/parser/option.rb +2 -2
- data/lib/bundler/vendor/thor/lib/thor/parser/options.rb +2 -1
- data/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +9 -9
- data/lib/bundler/vendor/thor/lib/thor/shell/html.rb +1 -1
- data/lib/bundler/vendor/thor/lib/thor/shell/table_printer.rb +5 -21
- data/lib/bundler/vendor/thor/lib/thor/util.rb +1 -1
- data/lib/bundler/vendor/thor/lib/thor/version.rb +1 -1
- data/lib/bundler/vendor/thor/lib/thor.rb +11 -0
- data/lib/bundler/vendor/uri/COPYING +56 -0
- data/lib/bundler/vendor/uri/lib/uri/common.rb +37 -14
- data/lib/bundler/vendor/uri/lib/uri/file.rb +3 -3
- data/lib/bundler/vendor/uri/lib/uri/ftp.rb +1 -1
- data/lib/bundler/vendor/uri/lib/uri/generic.rb +16 -26
- data/lib/bundler/vendor/uri/lib/uri/http.rb +2 -2
- data/lib/bundler/vendor/uri/lib/uri/rfc2396_parser.rb +10 -3
- data/lib/bundler/vendor/uri/lib/uri/rfc3986_parser.rb +26 -3
- data/lib/bundler/vendor/uri/lib/uri/version.rb +1 -1
- data/lib/bundler/vendor/uri/lib/uri.rb +9 -9
- data/lib/bundler/vendored_securerandom.rb +12 -0
- data/lib/bundler/version.rb +1 -1
- data/lib/bundler/yaml_serializer.rb +1 -1
- data/lib/bundler.rb +68 -36
- metadata +20 -10
- data/lib/bundler/vendor/fileutils/LICENSE.txt +0 -22
- data/lib/bundler/vendor/uri/LICENSE.txt +0 -22
data/lib/bundler/definition.rb
CHANGED
@@ -13,13 +13,14 @@ module Bundler
|
|
13
13
|
|
14
14
|
attr_reader(
|
15
15
|
:dependencies,
|
16
|
+
:locked_checksums,
|
16
17
|
:locked_deps,
|
17
18
|
:locked_gems,
|
18
19
|
:platforms,
|
19
20
|
:ruby_version,
|
20
21
|
:lockfile,
|
21
22
|
:gemfiles,
|
22
|
-
:
|
23
|
+
:sources
|
23
24
|
)
|
24
25
|
|
25
26
|
# Given a gemfile and lockfile creates a Bundler definition
|
@@ -88,6 +89,7 @@ module Bundler
|
|
88
89
|
@lockfile_contents = Bundler.read_file(lockfile)
|
89
90
|
@locked_gems = LockfileParser.new(@lockfile_contents)
|
90
91
|
@locked_platforms = @locked_gems.platforms
|
92
|
+
@most_specific_locked_platform = @locked_gems.most_specific_locked_platform
|
91
93
|
@platforms = @locked_platforms.dup
|
92
94
|
@locked_bundler_version = @locked_gems.bundler_version
|
93
95
|
@locked_ruby_version = @locked_gems.ruby_version
|
@@ -107,15 +109,16 @@ module Bundler
|
|
107
109
|
end
|
108
110
|
else
|
109
111
|
@unlock = {}
|
110
|
-
@platforms = []
|
111
112
|
@locked_gems = nil
|
113
|
+
@locked_platforms = []
|
114
|
+
@most_specific_locked_platform = nil
|
115
|
+
@platforms = []
|
112
116
|
@locked_deps = {}
|
113
117
|
@locked_specs = SpecSet.new([])
|
114
118
|
@originally_locked_deps = {}
|
115
119
|
@originally_locked_specs = @locked_specs
|
116
120
|
@locked_sources = []
|
117
|
-
@
|
118
|
-
@locked_checksums = nil
|
121
|
+
@locked_checksums = Bundler.feature_flag.lockfile_checksums?
|
119
122
|
end
|
120
123
|
|
121
124
|
locked_gem_sources = @locked_sources.select {|s| s.is_a?(Source::Rubygems) }
|
@@ -137,7 +140,7 @@ module Bundler
|
|
137
140
|
end
|
138
141
|
@unlocking ||= @unlock[:ruby] ||= (!@locked_ruby_version ^ !@ruby_version)
|
139
142
|
|
140
|
-
add_current_platform unless Bundler.frozen_bundle?
|
143
|
+
@current_platform_missing = add_current_platform unless Bundler.frozen_bundle?
|
141
144
|
|
142
145
|
converge_path_sources_to_gemspec_sources
|
143
146
|
@path_changes = converge_paths
|
@@ -149,7 +152,7 @@ module Bundler
|
|
149
152
|
@gems_to_unlock = @explicit_unlocks.any? ? @explicit_unlocks : @dependencies.map(&:name)
|
150
153
|
else
|
151
154
|
eager_unlock = @explicit_unlocks.map {|name| Dependency.new(name, ">= 0") }
|
152
|
-
@gems_to_unlock = @locked_specs.for(eager_unlock,
|
155
|
+
@gems_to_unlock = @locked_specs.for(eager_unlock, platforms).map(&:name).uniq
|
153
156
|
end
|
154
157
|
|
155
158
|
@dependency_changes = converge_dependencies
|
@@ -162,21 +165,57 @@ module Bundler
|
|
162
165
|
@gem_version_promoter ||= GemVersionPromoter.new
|
163
166
|
end
|
164
167
|
|
165
|
-
def
|
168
|
+
def check!
|
169
|
+
# If dependencies have changed, we need to resolve remotely. Otherwise,
|
170
|
+
# since we'll be resolving with a single local source, we may end up
|
171
|
+
# locking gems under the wrong source in the lockfile, and missing lockfile
|
172
|
+
# checksums
|
173
|
+
resolve_remotely! if @dependency_changes
|
174
|
+
|
175
|
+
# Now do a local only resolve, to verify if any gems are missing locally
|
166
176
|
sources.local_only!
|
167
177
|
resolve
|
168
178
|
end
|
169
179
|
|
180
|
+
#
|
181
|
+
# Setup sources according to the given options and the state of the
|
182
|
+
# definition.
|
183
|
+
#
|
184
|
+
# @return [Boolean] Whether fetching remote information will be necessary or not
|
185
|
+
#
|
186
|
+
def setup_domain!(options = {})
|
187
|
+
prefer_local! if options[:"prefer-local"]
|
188
|
+
|
189
|
+
if options[:add_checksums] || (!options[:local] && install_needed?)
|
190
|
+
remotely!
|
191
|
+
true
|
192
|
+
else
|
193
|
+
Bundler.settings.set_command_option(:jobs, 1) unless install_needed? # to avoid the overhead of Bundler::Worker
|
194
|
+
with_cache!
|
195
|
+
false
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
170
199
|
def resolve_with_cache!
|
200
|
+
with_cache!
|
201
|
+
|
202
|
+
resolve
|
203
|
+
end
|
204
|
+
|
205
|
+
def with_cache!
|
171
206
|
sources.local!
|
172
207
|
sources.cached!
|
173
|
-
resolve
|
174
208
|
end
|
175
209
|
|
176
210
|
def resolve_remotely!
|
211
|
+
remotely!
|
212
|
+
|
213
|
+
resolve
|
214
|
+
end
|
215
|
+
|
216
|
+
def remotely!
|
177
217
|
sources.cached!
|
178
218
|
sources.remote!
|
179
|
-
resolve
|
180
219
|
end
|
181
220
|
|
182
221
|
def prefer_local!
|
@@ -202,7 +241,7 @@ module Bundler
|
|
202
241
|
end
|
203
242
|
|
204
243
|
def missing_specs
|
205
|
-
resolve.
|
244
|
+
resolve.missing_specs_for(requested_dependencies)
|
206
245
|
end
|
207
246
|
|
208
247
|
def missing_specs?
|
@@ -214,6 +253,7 @@ module Bundler
|
|
214
253
|
@resolve = nil
|
215
254
|
@resolver = nil
|
216
255
|
@resolution_packages = nil
|
256
|
+
@source_requirements = nil
|
217
257
|
@specs = nil
|
218
258
|
|
219
259
|
Bundler.ui.debug "The definition is missing dependencies, failed to resolve & materialize locally (#{e})"
|
@@ -265,11 +305,7 @@ module Bundler
|
|
265
305
|
groups.map!(&:to_sym)
|
266
306
|
deps = current_dependencies # always returns a new array
|
267
307
|
deps.select! do |d|
|
268
|
-
|
269
|
-
d.groups.intersect?(groups)
|
270
|
-
else
|
271
|
-
!(d.groups & groups).empty?
|
272
|
-
end
|
308
|
+
d.groups.intersect?(groups)
|
273
309
|
end
|
274
310
|
deps
|
275
311
|
end
|
@@ -307,16 +343,16 @@ module Bundler
|
|
307
343
|
end
|
308
344
|
|
309
345
|
def spec_git_paths
|
310
|
-
sources.git_sources.
|
346
|
+
sources.git_sources.filter_map {|s| File.realpath(s.path) if File.exist?(s.path) }
|
311
347
|
end
|
312
348
|
|
313
349
|
def groups
|
314
|
-
dependencies.
|
350
|
+
dependencies.flat_map(&:groups).uniq
|
315
351
|
end
|
316
352
|
|
317
353
|
def lock(file_or_preserve_unknown_sections = false, preserve_unknown_sections_or_unused = false)
|
318
354
|
if [true, false, nil].include?(file_or_preserve_unknown_sections)
|
319
|
-
target_lockfile = lockfile
|
355
|
+
target_lockfile = lockfile
|
320
356
|
preserve_unknown_sections = file_or_preserve_unknown_sections
|
321
357
|
else
|
322
358
|
target_lockfile = file_or_preserve_unknown_sections
|
@@ -456,6 +492,12 @@ module Bundler
|
|
456
492
|
"Add the current platform to the lockfile with\n`bundle lock --add-platform #{local_platform}` and try again."
|
457
493
|
end
|
458
494
|
|
495
|
+
def normalize_platforms
|
496
|
+
@platforms = resolve.normalize_platforms!(current_dependencies, platforms)
|
497
|
+
|
498
|
+
@resolve = SpecSet.new(resolve.for(current_dependencies, @platforms))
|
499
|
+
end
|
500
|
+
|
459
501
|
def add_platform(platform)
|
460
502
|
return if @platforms.include?(platform)
|
461
503
|
|
@@ -470,53 +512,63 @@ module Bundler
|
|
470
512
|
raise InvalidOption, "Unable to remove the platform `#{platform}` since the only platforms are #{@platforms.join ", "}"
|
471
513
|
end
|
472
514
|
|
473
|
-
def most_specific_locked_platform
|
474
|
-
@platforms.min_by do |bundle_platform|
|
475
|
-
platform_specificity_match(bundle_platform, local_platform)
|
476
|
-
end
|
477
|
-
end
|
478
|
-
|
479
|
-
attr_reader :sources
|
480
|
-
private :sources
|
481
|
-
|
482
515
|
def nothing_changed?
|
483
|
-
|
484
|
-
|
485
|
-
!@source_changes &&
|
486
|
-
!@dependency_changes &&
|
487
|
-
@new_platforms.empty? &&
|
488
|
-
!@path_changes &&
|
489
|
-
!@local_changes &&
|
490
|
-
!@missing_lockfile_dep &&
|
491
|
-
!@unlocking_bundler &&
|
492
|
-
!@locked_spec_with_missing_deps &&
|
493
|
-
!@locked_spec_with_invalid_deps
|
516
|
+
!something_changed?
|
494
517
|
end
|
495
518
|
|
496
519
|
def no_resolve_needed?
|
497
|
-
!
|
520
|
+
!resolve_needed?
|
498
521
|
end
|
499
522
|
|
500
523
|
def unlocking?
|
501
524
|
@unlocking
|
502
525
|
end
|
503
526
|
|
527
|
+
attr_writer :source_requirements
|
528
|
+
|
529
|
+
def add_checksums
|
530
|
+
@locked_checksums = true
|
531
|
+
|
532
|
+
setup_domain!(add_checksums: true)
|
533
|
+
|
534
|
+
specs # force materialization to real specifications, so that checksums are fetched
|
535
|
+
end
|
536
|
+
|
504
537
|
private
|
505
538
|
|
539
|
+
def install_needed?
|
540
|
+
resolve_needed? || missing_specs?
|
541
|
+
end
|
542
|
+
|
543
|
+
def something_changed?
|
544
|
+
return true unless lockfile_exists?
|
545
|
+
|
546
|
+
@source_changes ||
|
547
|
+
@dependency_changes ||
|
548
|
+
@current_platform_missing ||
|
549
|
+
@new_platforms.any? ||
|
550
|
+
@path_changes ||
|
551
|
+
@local_changes ||
|
552
|
+
@missing_lockfile_dep ||
|
553
|
+
@unlocking_bundler ||
|
554
|
+
@locked_spec_with_missing_deps ||
|
555
|
+
@locked_spec_with_invalid_deps
|
556
|
+
end
|
557
|
+
|
558
|
+
def resolve_needed?
|
559
|
+
unlocking? || something_changed?
|
560
|
+
end
|
561
|
+
|
506
562
|
def should_add_extra_platforms?
|
507
563
|
!lockfile_exists? && generic_local_platform_is_ruby? && !Bundler.settings[:force_ruby_platform]
|
508
564
|
end
|
509
565
|
|
510
566
|
def lockfile_exists?
|
511
|
-
|
512
|
-
end
|
513
|
-
|
514
|
-
def file_exists?(file)
|
515
|
-
file && File.exist?(file)
|
567
|
+
lockfile && File.exist?(lockfile)
|
516
568
|
end
|
517
569
|
|
518
570
|
def write_lock(file, preserve_unknown_sections)
|
519
|
-
return if Definition.no_lock
|
571
|
+
return if Definition.no_lock || file.nil?
|
520
572
|
|
521
573
|
contents = to_lock
|
522
574
|
|
@@ -533,7 +585,7 @@ module Bundler
|
|
533
585
|
|
534
586
|
preserve_unknown_sections ||= !updating_major && (Bundler.frozen_bundle? || !(unlocking? || @unlocking_bundler))
|
535
587
|
|
536
|
-
if
|
588
|
+
if File.exist?(file) && lockfiles_equal?(@lockfile_contents, contents, preserve_unknown_sections)
|
537
589
|
return if Bundler.frozen_bundle?
|
538
590
|
SharedHelpers.filesystem_access(file) { FileUtils.touch(file) }
|
539
591
|
return
|
@@ -550,7 +602,7 @@ module Bundler
|
|
550
602
|
end
|
551
603
|
|
552
604
|
def resolver
|
553
|
-
@resolver ||= Resolver.new(resolution_packages, gem_version_promoter)
|
605
|
+
@resolver ||= Resolver.new(resolution_packages, gem_version_promoter, @most_specific_locked_platform)
|
554
606
|
end
|
555
607
|
|
556
608
|
def expanded_dependencies
|
@@ -559,7 +611,7 @@ module Bundler
|
|
559
611
|
|
560
612
|
def dependencies_with_bundler
|
561
613
|
return dependencies unless @unlocking_bundler
|
562
|
-
return dependencies if dependencies.
|
614
|
+
return dependencies if dependencies.any? {|d| d.name == "bundler" }
|
563
615
|
|
564
616
|
[Dependency.new("bundler", @unlocking_bundler)] + dependencies
|
565
617
|
end
|
@@ -568,29 +620,53 @@ module Bundler
|
|
568
620
|
@resolution_packages ||= begin
|
569
621
|
last_resolve = converge_locked_specs
|
570
622
|
remove_invalid_platforms!
|
571
|
-
packages = Resolver::Base.new(source_requirements, expanded_dependencies, last_resolve, @platforms, locked_specs: @originally_locked_specs, unlock: @gems_to_unlock, prerelease: gem_version_promoter.pre
|
623
|
+
packages = Resolver::Base.new(source_requirements, expanded_dependencies, last_resolve, @platforms, locked_specs: @originally_locked_specs, unlock: @gems_to_unlock, prerelease: gem_version_promoter.pre?, prefer_local: @prefer_local)
|
572
624
|
packages = additional_base_requirements_to_prevent_downgrades(packages, last_resolve)
|
573
625
|
packages = additional_base_requirements_to_force_updates(packages)
|
574
626
|
packages
|
575
627
|
end
|
576
628
|
end
|
577
629
|
|
578
|
-
def filter_specs(specs, deps)
|
579
|
-
SpecSet.new(specs).for(deps,
|
630
|
+
def filter_specs(specs, deps, skips: [])
|
631
|
+
SpecSet.new(specs).for(deps, platforms, skips: skips)
|
580
632
|
end
|
581
633
|
|
582
634
|
def materialize(dependencies)
|
583
|
-
|
584
|
-
|
635
|
+
# Tracks potential endless loops trying to re-resolve.
|
636
|
+
# TODO: Remove as dead code if not reports are received in a while
|
637
|
+
incorrect_spec = nil
|
638
|
+
|
639
|
+
specs = begin
|
640
|
+
resolve.materialize(dependencies)
|
641
|
+
rescue IncorrectLockfileDependencies => e
|
642
|
+
spec = e.spec
|
643
|
+
raise "Infinite loop while fixing lockfile dependencies" if incorrect_spec == spec
|
644
|
+
|
645
|
+
incorrect_spec = spec
|
646
|
+
reresolve_without([spec])
|
647
|
+
retry
|
648
|
+
end
|
649
|
+
|
650
|
+
missing_specs = resolve.missing_specs
|
585
651
|
|
586
652
|
if missing_specs.any?
|
587
653
|
missing_specs.each do |s|
|
588
654
|
locked_gem = @locked_specs[s.name].last
|
589
655
|
next if locked_gem.nil? || locked_gem.version != s.version || sources.local_mode?
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
656
|
+
|
657
|
+
message = if sources.implicit_global_source?
|
658
|
+
"Because your Gemfile specifies no global remote source, your bundle is locked to " \
|
659
|
+
"#{locked_gem} from #{locked_gem.source}. However, #{locked_gem} is not installed. You'll " \
|
660
|
+
"need to either add a global remote source to your Gemfile or make sure #{locked_gem} is " \
|
661
|
+
"available locally before rerunning Bundler."
|
662
|
+
else
|
663
|
+
"Your bundle is locked to #{locked_gem} from #{locked_gem.source}, but that version can " \
|
664
|
+
"no longer be found in that source. That means the author of #{locked_gem} has removed it. " \
|
665
|
+
"You'll need to update your bundle to a version other than #{locked_gem} that hasn't been " \
|
666
|
+
"removed in order to install."
|
667
|
+
end
|
668
|
+
|
669
|
+
raise GemNotFound, message
|
594
670
|
end
|
595
671
|
|
596
672
|
missing_specs_list = missing_specs.group_by(&:source).map do |source, missing_specs_for_source|
|
@@ -600,17 +676,24 @@ module Bundler
|
|
600
676
|
raise GemNotFound, "Could not find #{missing_specs_list.join(" nor ")}"
|
601
677
|
end
|
602
678
|
|
603
|
-
|
679
|
+
partially_missing_specs = resolve.partially_missing_specs
|
680
|
+
|
681
|
+
if partially_missing_specs.any? && !sources.local_mode?
|
682
|
+
Bundler.ui.warn "Some locked specs have possibly been yanked (#{partially_missing_specs.map(&:full_name).join(", ")}). Ignoring them..."
|
683
|
+
|
684
|
+
resolve.delete(partially_missing_specs)
|
685
|
+
end
|
686
|
+
|
687
|
+
incomplete_specs = resolve.incomplete_specs
|
604
688
|
loop do
|
605
689
|
break if incomplete_specs.empty?
|
606
690
|
|
607
691
|
Bundler.ui.debug("The lockfile does not have all gems needed for the current platform though, Bundler will still re-resolve dependencies")
|
608
692
|
sources.remote!
|
609
|
-
|
610
|
-
@resolve = start_resolution
|
693
|
+
reresolve_without(incomplete_specs)
|
611
694
|
specs = resolve.materialize(dependencies)
|
612
695
|
|
613
|
-
still_incomplete_specs =
|
696
|
+
still_incomplete_specs = resolve.incomplete_specs
|
614
697
|
|
615
698
|
if still_incomplete_specs == incomplete_specs
|
616
699
|
package = resolution_packages.get_package(incomplete_specs.first.name)
|
@@ -620,15 +703,30 @@ module Bundler
|
|
620
703
|
incomplete_specs = still_incomplete_specs
|
621
704
|
end
|
622
705
|
|
706
|
+
insecurely_materialized_specs = resolve.insecurely_materialized_specs
|
707
|
+
|
708
|
+
if insecurely_materialized_specs.any?
|
709
|
+
Bundler.ui.warn "The following platform specific gems are getting installed, yet the lockfile includes only their generic ruby version:\n" \
|
710
|
+
" * #{insecurely_materialized_specs.map(&:full_name).join("\n * ")}\n" \
|
711
|
+
"Please run `bundle lock --normalize-platforms` and commit the resulting lockfile.\n" \
|
712
|
+
"Alternatively, you may run `bundle lock --add-platform <list-of-platforms-that-you-want-to-support>`"
|
713
|
+
end
|
714
|
+
|
623
715
|
bundler = sources.metadata_source.specs.search(["bundler", Bundler.gem_version]).last
|
624
716
|
specs["bundler"] = bundler
|
625
717
|
|
626
718
|
specs
|
627
719
|
end
|
628
720
|
|
721
|
+
def reresolve_without(incomplete_specs)
|
722
|
+
resolution_packages.delete(incomplete_specs)
|
723
|
+
@resolve = start_resolution
|
724
|
+
end
|
725
|
+
|
629
726
|
def start_resolution
|
630
727
|
local_platform_needed_for_resolvability = @most_specific_non_local_locked_ruby_platform && !@platforms.include?(local_platform)
|
631
728
|
@platforms << local_platform if local_platform_needed_for_resolvability
|
729
|
+
add_platform(Gem::Platform::RUBY) if RUBY_ENGINE == "truffleruby"
|
632
730
|
|
633
731
|
result = SpecSet.new(resolver.start)
|
634
732
|
|
@@ -644,26 +742,13 @@ module Bundler
|
|
644
742
|
|
645
743
|
@platforms = result.add_extra_platforms!(platforms) if should_add_extra_platforms?
|
646
744
|
|
647
|
-
SpecSet.new(result.for(dependencies,
|
745
|
+
SpecSet.new(result.for(dependencies, @platforms))
|
648
746
|
end
|
649
747
|
|
650
748
|
def precompute_source_requirements_for_indirect_dependencies?
|
651
749
|
sources.non_global_rubygems_sources.all?(&:dependency_api_available?) && !sources.aggregate_global_source?
|
652
750
|
end
|
653
751
|
|
654
|
-
def pin_locally_available_names(source_requirements)
|
655
|
-
source_requirements.each_with_object({}) do |(name, original_source), new_source_requirements|
|
656
|
-
local_source = original_source.dup
|
657
|
-
local_source.local_only!
|
658
|
-
|
659
|
-
new_source_requirements[name] = if local_source.specs.search(name).any?
|
660
|
-
local_source
|
661
|
-
else
|
662
|
-
original_source
|
663
|
-
end
|
664
|
-
end
|
665
|
-
end
|
666
|
-
|
667
752
|
def current_platform_locked?
|
668
753
|
@platforms.any? do |bundle_platform|
|
669
754
|
MatchPlatform.platforms_match?(bundle_platform, local_platform)
|
@@ -671,19 +756,19 @@ module Bundler
|
|
671
756
|
end
|
672
757
|
|
673
758
|
def add_current_platform
|
674
|
-
|
759
|
+
return if @platforms.include?(local_platform)
|
760
|
+
|
761
|
+
@most_specific_non_local_locked_ruby_platform = find_most_specific_locked_ruby_platform
|
675
762
|
return if @most_specific_non_local_locked_ruby_platform
|
676
763
|
|
677
|
-
|
764
|
+
@platforms << local_platform
|
765
|
+
true
|
678
766
|
end
|
679
767
|
|
680
|
-
def
|
768
|
+
def find_most_specific_locked_ruby_platform
|
681
769
|
return unless generic_local_platform_is_ruby? && current_platform_locked?
|
682
770
|
|
683
|
-
|
684
|
-
return unless most_specific_locked_ruby_platform != local_platform
|
685
|
-
|
686
|
-
most_specific_locked_ruby_platform
|
771
|
+
@most_specific_locked_platform
|
687
772
|
end
|
688
773
|
|
689
774
|
def change_reason
|
@@ -705,6 +790,7 @@ module Bundler
|
|
705
790
|
[
|
706
791
|
[@source_changes, "the list of sources changed"],
|
707
792
|
[@dependency_changes, "the dependencies in your gemfile changed"],
|
793
|
+
[@current_platform_missing, "your lockfile does not include the current platform"],
|
708
794
|
[@new_platforms.any?, "you added a new platform to your gemfile"],
|
709
795
|
[@path_changes, "the gemspecs for path gems changed"],
|
710
796
|
[@local_changes, "the gemspecs for git local gems changed"],
|
@@ -883,7 +969,7 @@ module Bundler
|
|
883
969
|
def converge_locked_specs
|
884
970
|
converged = converge_specs(@locked_specs)
|
885
971
|
|
886
|
-
resolve = SpecSet.new(converged
|
972
|
+
resolve = SpecSet.new(converged)
|
887
973
|
|
888
974
|
diff = nil
|
889
975
|
|
@@ -904,8 +990,6 @@ module Bundler
|
|
904
990
|
converged = []
|
905
991
|
deps = []
|
906
992
|
|
907
|
-
@specs_that_changed_sources = []
|
908
|
-
|
909
993
|
specs.each do |s|
|
910
994
|
name = s.name
|
911
995
|
dep = @dependencies.find {|d| s.satisfies?(d) }
|
@@ -914,9 +998,7 @@ module Bundler
|
|
914
998
|
if dep
|
915
999
|
gemfile_source = dep.source || default_source
|
916
1000
|
|
917
|
-
|
918
|
-
deps << dep if !dep.source || lockfile_source.include?(dep.source)
|
919
|
-
@gems_to_unlock << name if lockfile_source.include?(dep.source) && lockfile_source != gemfile_source
|
1001
|
+
deps << dep if !dep.source || lockfile_source.include?(dep.source) || new_deps.include?(dep)
|
920
1002
|
|
921
1003
|
# Replace the locked dependency's source with the equivalent source from the Gemfile
|
922
1004
|
s.source = gemfile_source
|
@@ -925,25 +1007,14 @@ module Bundler
|
|
925
1007
|
s.source = default_source unless sources.get(lockfile_source)
|
926
1008
|
end
|
927
1009
|
|
928
|
-
|
1010
|
+
source = s.source
|
1011
|
+
next if @sources_to_unlock.include?(source.name)
|
929
1012
|
|
930
1013
|
# Path sources have special logic
|
931
|
-
if
|
932
|
-
|
933
|
-
s.source.specs
|
934
|
-
rescue PathError
|
935
|
-
# if we won't need the source (according to the lockfile),
|
936
|
-
# don't error if the path source isn't available
|
937
|
-
next if specs.
|
938
|
-
for(requested_dependencies, false).
|
939
|
-
none? {|locked_spec| locked_spec.source == s.source }
|
940
|
-
|
941
|
-
raise
|
942
|
-
end
|
943
|
-
|
944
|
-
new_spec = new_specs[s].first
|
1014
|
+
if source.instance_of?(Source::Path) || source.instance_of?(Source::Gemspec) || (source.instance_of?(Source::Git) && !@gems_to_unlock.include?(name) && deps.include?(dep))
|
1015
|
+
new_spec = source.specs[s].first
|
945
1016
|
if new_spec
|
946
|
-
s.
|
1017
|
+
s.runtime_dependencies.replace(new_spec.runtime_dependencies)
|
947
1018
|
else
|
948
1019
|
# If the spec is no longer in the path source, unlock it. This
|
949
1020
|
# commonly happens if the version changed in the gemspec
|
@@ -951,14 +1022,15 @@ module Bundler
|
|
951
1022
|
end
|
952
1023
|
end
|
953
1024
|
|
954
|
-
if dep.nil? && requested_dependencies.find {|d| name == d.name }
|
955
|
-
@gems_to_unlock <<
|
956
|
-
|
957
|
-
converged << s
|
1025
|
+
if dep.nil? && requested_dep = requested_dependencies.find {|d| name == d.name }
|
1026
|
+
@gems_to_unlock << name
|
1027
|
+
deps << requested_dep
|
958
1028
|
end
|
1029
|
+
|
1030
|
+
converged << s
|
959
1031
|
end
|
960
1032
|
|
961
|
-
filter_specs(converged, deps)
|
1033
|
+
filter_specs(converged, deps, skips: @gems_to_unlock)
|
962
1034
|
end
|
963
1035
|
|
964
1036
|
def metadata_dependencies
|
@@ -969,12 +1041,15 @@ module Bundler
|
|
969
1041
|
end
|
970
1042
|
|
971
1043
|
def source_requirements
|
1044
|
+
@source_requirements ||= find_source_requirements
|
1045
|
+
end
|
1046
|
+
|
1047
|
+
def find_source_requirements
|
972
1048
|
# Record the specs available in each gem's source, so that those
|
973
1049
|
# specs will be available later when the resolver knows where to
|
974
1050
|
# look for that gemspec (or its dependencies)
|
975
1051
|
source_requirements = if precompute_source_requirements_for_indirect_dependencies?
|
976
1052
|
all_requirements = source_map.all_requirements
|
977
|
-
all_requirements = pin_locally_available_names(all_requirements) if @prefer_local
|
978
1053
|
{ default: default_source }.merge(all_requirements)
|
979
1054
|
else
|
980
1055
|
{ default: Source::RubygemsAggregate.new(sources, source_map) }.merge(source_map.direct_requirements)
|
@@ -993,7 +1068,6 @@ module Bundler
|
|
993
1068
|
source_requirements["bundler"] = sources.metadata_source # needs to come last to override
|
994
1069
|
end
|
995
1070
|
|
996
|
-
verify_changed_sources!
|
997
1071
|
source_requirements
|
998
1072
|
end
|
999
1073
|
|
@@ -1001,14 +1075,6 @@ module Bundler
|
|
1001
1075
|
sources.default_source
|
1002
1076
|
end
|
1003
1077
|
|
1004
|
-
def verify_changed_sources!
|
1005
|
-
@specs_that_changed_sources.each do |s|
|
1006
|
-
if s.source.specs.search(s.name).empty?
|
1007
|
-
raise GemNotFound, "Could not find gem '#{s.name}' in #{s.source}"
|
1008
|
-
end
|
1009
|
-
end
|
1010
|
-
end
|
1011
|
-
|
1012
1078
|
def requested_groups
|
1013
1079
|
values = groups - Bundler.settings[:without] - @optional_groups + Bundler.settings[:with]
|
1014
1080
|
values &= Bundler.settings[:only] unless Bundler.settings[:only].empty?
|
@@ -1050,6 +1116,7 @@ module Bundler
|
|
1050
1116
|
|
1051
1117
|
def dup_for_full_unlock
|
1052
1118
|
unlocked_definition = self.class.new(@lockfile, @dependencies, @sources, true, @ruby_version, @optional_groups, @gemfiles)
|
1119
|
+
unlocked_definition.source_requirements = source_requirements
|
1053
1120
|
unlocked_definition.gem_version_promoter.tap do |gvp|
|
1054
1121
|
gvp.level = gem_version_promoter.level
|
1055
1122
|
gvp.strict = gem_version_promoter.strict
|
data/lib/bundler/dependency.rb
CHANGED