bundler 2.6.5 → 2.7.1
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 +1172 -1024
- data/README.md +7 -7
- data/bundler.gemspec +2 -2
- data/lib/bundler/build_metadata.rb +10 -11
- data/lib/bundler/checksum.rb +22 -12
- data/lib/bundler/cli/common.rb +1 -1
- data/lib/bundler/cli/config.rb +2 -2
- data/lib/bundler/cli/doctor/diagnose.rb +167 -0
- data/lib/bundler/cli/doctor/ssl.rb +249 -0
- data/lib/bundler/cli/doctor.rb +27 -155
- data/lib/bundler/cli/gem.rb +62 -30
- data/lib/bundler/cli/inject.rb +2 -2
- data/lib/bundler/cli/install.rb +5 -5
- data/lib/bundler/cli/issue.rb +2 -2
- data/lib/bundler/cli/lock.rb +2 -1
- data/lib/bundler/cli/outdated.rb +1 -1
- data/lib/bundler/cli/update.rb +3 -3
- data/lib/bundler/cli.rb +26 -49
- data/lib/bundler/compact_index_client/cache.rb +1 -1
- data/lib/bundler/compact_index_client/parser.rb +1 -1
- data/lib/bundler/compact_index_client/updater.rb +2 -1
- data/lib/bundler/compact_index_client.rb +1 -5
- data/lib/bundler/current_ruby.rb +27 -3
- data/lib/bundler/definition.rb +184 -151
- data/lib/bundler/dependency.rb +1 -1
- data/lib/bundler/dsl.rb +35 -26
- data/lib/bundler/errors.rb +18 -0
- data/lib/bundler/feature_flag.rb +15 -12
- data/lib/bundler/fetcher/dependency.rb +2 -1
- data/lib/bundler/fetcher/downloader.rb +33 -7
- data/lib/bundler/fetcher.rb +49 -19
- data/lib/bundler/friendly_errors.rb +3 -2
- data/lib/bundler/index.rb +7 -2
- data/lib/bundler/injector.rb +9 -9
- data/lib/bundler/installer.rb +6 -5
- data/lib/bundler/lazy_specification.rb +38 -19
- data/lib/bundler/lockfile_parser.rb +29 -10
- data/lib/bundler/man/bundle-add.1 +1 -1
- data/lib/bundler/man/bundle-binstubs.1 +1 -1
- data/lib/bundler/man/bundle-cache.1 +1 -1
- data/lib/bundler/man/bundle-check.1 +1 -1
- data/lib/bundler/man/bundle-clean.1 +1 -1
- data/lib/bundler/man/bundle-config.1 +175 -129
- data/lib/bundler/man/bundle-config.1.ronn +93 -88
- data/lib/bundler/man/bundle-console.1 +1 -1
- data/lib/bundler/man/bundle-doctor.1 +43 -4
- data/lib/bundler/man/bundle-doctor.1.ronn +48 -4
- data/lib/bundler/man/bundle-env.1 +1 -1
- data/lib/bundler/man/bundle-exec.1 +3 -3
- data/lib/bundler/man/bundle-exec.1.ronn +2 -2
- data/lib/bundler/man/bundle-fund.1 +1 -1
- data/lib/bundler/man/bundle-gem.1 +67 -44
- data/lib/bundler/man/bundle-gem.1.ronn +8 -4
- data/lib/bundler/man/bundle-help.1 +1 -1
- data/lib/bundler/man/bundle-info.1 +1 -1
- data/lib/bundler/man/bundle-init.1 +1 -1
- data/lib/bundler/man/bundle-inject.1 +2 -2
- data/lib/bundler/man/bundle-inject.1.ronn +1 -1
- data/lib/bundler/man/bundle-install.1 +4 -4
- data/lib/bundler/man/bundle-install.1.ronn +3 -4
- data/lib/bundler/man/bundle-issue.1 +1 -1
- data/lib/bundler/man/bundle-licenses.1 +1 -1
- data/lib/bundler/man/bundle-list.1 +1 -1
- data/lib/bundler/man/bundle-lock.1 +1 -1
- data/lib/bundler/man/bundle-open.1 +1 -1
- data/lib/bundler/man/bundle-outdated.1 +1 -1
- 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-remove.1 +1 -1
- data/lib/bundler/man/bundle-show.1 +1 -1
- data/lib/bundler/man/bundle-update.1 +5 -5
- data/lib/bundler/man/bundle-update.1.ronn +4 -4
- data/lib/bundler/man/bundle-version.1 +1 -1
- data/lib/bundler/man/bundle-viz.1 +1 -1
- data/lib/bundler/man/bundle.1 +1 -1
- data/lib/bundler/man/gemfile.5 +1 -1
- data/lib/bundler/match_platform.rb +31 -12
- data/lib/bundler/materialization.rb +2 -2
- data/lib/bundler/plugin/api/source.rb +1 -1
- data/lib/bundler/plugin/index.rb +1 -1
- data/lib/bundler/plugin/installer/path.rb +8 -0
- data/lib/bundler/plugin.rb +1 -1
- data/lib/bundler/resolver/candidate.rb +12 -9
- data/lib/bundler/resolver/package.rb +1 -1
- data/lib/bundler/resolver/strategy.rb +40 -0
- data/lib/bundler/resolver.rb +18 -27
- data/lib/bundler/rubygems_ext.rb +131 -120
- data/lib/bundler/rubygems_integration.rb +11 -6
- data/lib/bundler/runtime.rb +9 -6
- data/lib/bundler/self_manager.rb +32 -42
- data/lib/bundler/settings/validator.rb +0 -23
- data/lib/bundler/settings.rb +4 -6
- data/lib/bundler/shared_helpers.rb +10 -4
- data/lib/bundler/source/gemspec.rb +1 -4
- data/lib/bundler/source/git/git_proxy.rb +17 -6
- data/lib/bundler/source/git.rb +5 -1
- data/lib/bundler/source/path.rb +9 -2
- data/lib/bundler/source/rubygems/remote.rb +11 -3
- data/lib/bundler/source_list.rb +30 -16
- data/lib/bundler/source_map.rb +1 -1
- data/lib/bundler/spec_set.rb +55 -16
- data/lib/bundler/templates/Executable +0 -11
- data/lib/bundler/templates/newgem/github/workflows/main.yml.tt +2 -0
- data/lib/bundler/templates/newgem/newgem.gemspec.tt +6 -5
- data/lib/bundler/ui/shell.rb +2 -2
- data/lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb +53 -3
- data/lib/bundler/vendor/connection_pool/lib/connection_pool/version.rb +1 -1
- data/lib/bundler/vendor/connection_pool/lib/connection_pool.rb +11 -0
- data/lib/bundler/vendor/net-http-persistent/README.rdoc +1 -1
- data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/timed_stack_multi.rb +2 -1
- data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb +81 -42
- data/lib/bundler/vendor/pub_grub/lib/pub_grub/basic_package_source.rb +4 -24
- data/lib/bundler/vendor/pub_grub/lib/pub_grub/strategy.rb +42 -0
- data/lib/bundler/vendor/pub_grub/lib/pub_grub/version_range.rb +20 -8
- data/lib/bundler/vendor/pub_grub/lib/pub_grub/version_solver.rb +17 -29
- data/lib/bundler/vendor/uri/lib/uri/common.rb +7 -3
- data/lib/bundler/vendor/uri/lib/uri/generic.rb +12 -11
- data/lib/bundler/vendor/uri/lib/uri/rfc2396_parser.rb +6 -6
- data/lib/bundler/vendor/uri/lib/uri/version.rb +1 -1
- data/lib/bundler/version.rb +10 -2
- data/lib/bundler/worker.rb +1 -1
- data/lib/bundler.rb +14 -12
- metadata +9 -16
- data/lib/bundler/compact_index_client/gem_parser.rb +0 -32
- data/lib/bundler/gem_helpers.rb +0 -144
- data/lib/bundler/templates/Executable.bundler +0 -109
- data/lib/bundler/vendor/connection_pool/.document +0 -1
- data/lib/bundler/vendor/fileutils/.document +0 -1
- data/lib/bundler/vendor/net-http-persistent/.document +0 -1
- data/lib/bundler/vendor/pub_grub/.document +0 -1
- data/lib/bundler/vendor/securerandom/.document +0 -1
- data/lib/bundler/vendor/thor/.document +0 -1
- data/lib/bundler/vendor/tsort/.document +0 -1
- data/lib/bundler/vendor/uri/.document +0 -1
data/lib/bundler/definition.rb
CHANGED
@@ -4,8 +4,6 @@ require_relative "lockfile_parser"
|
|
4
4
|
|
5
5
|
module Bundler
|
6
6
|
class Definition
|
7
|
-
include GemHelpers
|
8
|
-
|
9
7
|
class << self
|
10
8
|
# Do not create or modify a lockfile (Makes #lock a noop)
|
11
9
|
attr_accessor :no_lock
|
@@ -62,6 +60,7 @@ module Bundler
|
|
62
60
|
|
63
61
|
if unlock == true
|
64
62
|
@unlocking_all = true
|
63
|
+
strict = false
|
65
64
|
@unlocking_bundler = false
|
66
65
|
@unlocking = unlock
|
67
66
|
@sources_to_unlock = []
|
@@ -70,6 +69,7 @@ module Bundler
|
|
70
69
|
conservative = false
|
71
70
|
else
|
72
71
|
@unlocking_all = false
|
72
|
+
strict = unlock.delete(:strict)
|
73
73
|
@unlocking_bundler = unlock.delete(:bundler)
|
74
74
|
@unlocking = unlock.any? {|_k, v| !Array(v).empty? }
|
75
75
|
@sources_to_unlock = unlock.delete(:sources) || []
|
@@ -94,11 +94,12 @@ module Bundler
|
|
94
94
|
|
95
95
|
@locked_ruby_version = nil
|
96
96
|
@new_platforms = []
|
97
|
-
@
|
97
|
+
@removed_platforms = []
|
98
|
+
@originally_invalid_platforms = []
|
98
99
|
|
99
100
|
if lockfile_exists?
|
100
101
|
@lockfile_contents = Bundler.read_file(lockfile)
|
101
|
-
@locked_gems = LockfileParser.new(@lockfile_contents)
|
102
|
+
@locked_gems = LockfileParser.new(@lockfile_contents, strict: strict)
|
102
103
|
@locked_platforms = @locked_gems.platforms
|
103
104
|
@most_specific_locked_platform = @locked_gems.most_specific_locked_platform
|
104
105
|
@platforms = @locked_platforms.dup
|
@@ -147,9 +148,8 @@ module Bundler
|
|
147
148
|
|
148
149
|
@current_platform_missing = add_current_platform unless Bundler.frozen_bundle?
|
149
150
|
|
150
|
-
converge_path_sources_to_gemspec_sources
|
151
|
-
@path_changes = converge_paths
|
152
151
|
@source_changes = converge_sources
|
152
|
+
@path_changes = converge_paths
|
153
153
|
|
154
154
|
if conservative
|
155
155
|
@gems_to_unlock = @explicit_unlocks.any? ? @explicit_unlocks : @dependencies.map(&:name)
|
@@ -257,7 +257,7 @@ module Bundler
|
|
257
257
|
rescue BundlerError => e
|
258
258
|
@resolve = nil
|
259
259
|
@resolver = nil
|
260
|
-
@
|
260
|
+
@resolution_base = nil
|
261
261
|
@source_requirements = nil
|
262
262
|
@specs = nil
|
263
263
|
|
@@ -282,7 +282,7 @@ module Bundler
|
|
282
282
|
end
|
283
283
|
|
284
284
|
def filter_relevant(dependencies)
|
285
|
-
platforms_array = [generic_local_platform].freeze
|
285
|
+
platforms_array = [Bundler.generic_local_platform].freeze
|
286
286
|
dependencies.select do |d|
|
287
287
|
d.should_include? && !d.gem_platforms(platforms_array).empty?
|
288
288
|
end
|
@@ -330,18 +330,14 @@ module Bundler
|
|
330
330
|
SpecSet.new(filter_specs(@locked_specs, @dependencies - deleted_deps))
|
331
331
|
else
|
332
332
|
Bundler.ui.debug "Found no changes, using resolution from the lockfile"
|
333
|
-
if @
|
333
|
+
if @removed_platforms.any? || @locked_gems.may_include_redundant_platform_specific_gems?
|
334
334
|
SpecSet.new(filter_specs(@locked_specs, @dependencies))
|
335
335
|
else
|
336
336
|
@locked_specs
|
337
337
|
end
|
338
338
|
end
|
339
339
|
else
|
340
|
-
|
341
|
-
Bundler.ui.debug "Found changes from the lockfile, re-resolving dependencies because #{change_reason}"
|
342
|
-
else
|
343
|
-
Bundler.ui.debug "Resolving dependencies because there's no lockfile"
|
344
|
-
end
|
340
|
+
Bundler.ui.debug resolve_needed_reason
|
345
341
|
|
346
342
|
start_resolution
|
347
343
|
end
|
@@ -412,41 +408,8 @@ module Bundler
|
|
412
408
|
|
413
409
|
raise ProductionError, "Frozen mode is set, but there's no lockfile" unless lockfile_exists?
|
414
410
|
|
415
|
-
|
416
|
-
|
417
|
-
changed = []
|
418
|
-
|
419
|
-
new_platforms = @platforms - @locked_platforms
|
420
|
-
deleted_platforms = @locked_platforms - @platforms
|
421
|
-
added.concat new_platforms.map {|p| "* platform: #{p}" }
|
422
|
-
deleted.concat deleted_platforms.map {|p| "* platform: #{p}" }
|
423
|
-
|
424
|
-
added.concat new_deps.map {|d| "* #{pretty_dep(d)}" } if new_deps.any?
|
425
|
-
deleted.concat deleted_deps.map {|d| "* #{pretty_dep(d)}" } if deleted_deps.any?
|
426
|
-
|
427
|
-
both_sources = Hash.new {|h, k| h[k] = [] }
|
428
|
-
current_dependencies.each {|d| both_sources[d.name][0] = d }
|
429
|
-
current_locked_dependencies.each {|d| both_sources[d.name][1] = d }
|
430
|
-
|
431
|
-
both_sources.each do |name, (dep, lock_dep)|
|
432
|
-
next if dep.nil? || lock_dep.nil?
|
433
|
-
|
434
|
-
gemfile_source = dep.source || default_source
|
435
|
-
lock_source = lock_dep.source || default_source
|
436
|
-
next if lock_source.include?(gemfile_source)
|
437
|
-
|
438
|
-
gemfile_source_name = dep.source ? gemfile_source.to_gemfile : "no specified source"
|
439
|
-
lockfile_source_name = lock_dep.source ? lock_source.to_gemfile : "no specified source"
|
440
|
-
changed << "* #{name} from `#{lockfile_source_name}` to `#{gemfile_source_name}`"
|
441
|
-
end
|
442
|
-
|
443
|
-
reason = resolve_needed? ? change_reason : "some dependencies were deleted from your gemfile"
|
444
|
-
msg = String.new
|
445
|
-
msg << "#{reason.capitalize.strip}, but the lockfile can't be updated because frozen mode is set"
|
446
|
-
msg << "\n\nYou have added to the Gemfile:\n" << added.join("\n") if added.any?
|
447
|
-
msg << "\n\nYou have deleted from the Gemfile:\n" << deleted.join("\n") if deleted.any?
|
448
|
-
msg << "\n\nYou have changed in the Gemfile:\n" << changed.join("\n") if changed.any?
|
449
|
-
msg << "\n\nRun `bundle install` elsewhere and add the updated #{SharedHelpers.relative_gemfile_path} to version control.\n" unless unlocking?
|
411
|
+
msg = lockfile_changes_summary("frozen mode is set")
|
412
|
+
return unless msg
|
450
413
|
|
451
414
|
unless explicit_flag
|
452
415
|
suggested_command = unless Bundler.settings.locations("frozen").keys.include?(:env)
|
@@ -456,7 +419,7 @@ module Bundler
|
|
456
419
|
"freeze by running `#{suggested_command}`." if suggested_command
|
457
420
|
end
|
458
421
|
|
459
|
-
raise ProductionError, msg
|
422
|
+
raise ProductionError, msg
|
460
423
|
end
|
461
424
|
|
462
425
|
def validate_runtime!
|
@@ -493,12 +456,12 @@ module Bundler
|
|
493
456
|
return if current_platform_locked? || @platforms.include?(Gem::Platform::RUBY)
|
494
457
|
|
495
458
|
raise ProductionError, "Your bundle only supports platforms #{@platforms.map(&:to_s)} " \
|
496
|
-
"but your local platform is #{local_platform}. " \
|
497
|
-
"Add the current platform to the lockfile with\n`bundle lock --add-platform #{local_platform}` and try again."
|
459
|
+
"but your local platform is #{Bundler.local_platform}. " \
|
460
|
+
"Add the current platform to the lockfile with\n`bundle lock --add-platform #{Bundler.local_platform}` and try again."
|
498
461
|
end
|
499
462
|
|
500
463
|
def normalize_platforms
|
501
|
-
|
464
|
+
resolve.normalize_platforms!(current_dependencies, platforms)
|
502
465
|
|
503
466
|
@resolve = SpecSet.new(resolve.for(current_dependencies, @platforms))
|
504
467
|
end
|
@@ -511,10 +474,10 @@ module Bundler
|
|
511
474
|
end
|
512
475
|
|
513
476
|
def remove_platform(platform)
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
477
|
+
raise InvalidOption, "Unable to remove the platform `#{platform}` since the only platforms are #{@platforms.join ", "}" unless @platforms.include?(platform)
|
478
|
+
|
479
|
+
@removed_platforms << platform
|
480
|
+
@platforms.delete(platform)
|
518
481
|
end
|
519
482
|
|
520
483
|
def nothing_changed?
|
@@ -541,6 +504,45 @@ module Bundler
|
|
541
504
|
|
542
505
|
private
|
543
506
|
|
507
|
+
def lockfile_changes_summary(update_refused_reason)
|
508
|
+
added = []
|
509
|
+
deleted = []
|
510
|
+
changed = []
|
511
|
+
|
512
|
+
added.concat @new_platforms.map {|p| "* platform: #{p}" }
|
513
|
+
deleted.concat @removed_platforms.map {|p| "* platform: #{p}" }
|
514
|
+
|
515
|
+
added.concat new_deps.map {|d| "* #{pretty_dep(d)}" } if new_deps.any?
|
516
|
+
deleted.concat deleted_deps.map {|d| "* #{pretty_dep(d)}" } if deleted_deps.any?
|
517
|
+
|
518
|
+
both_sources = Hash.new {|h, k| h[k] = [] }
|
519
|
+
current_dependencies.each {|d| both_sources[d.name][0] = d }
|
520
|
+
current_locked_dependencies.each {|d| both_sources[d.name][1] = d }
|
521
|
+
|
522
|
+
both_sources.each do |name, (dep, lock_dep)|
|
523
|
+
next if dep.nil? || lock_dep.nil?
|
524
|
+
|
525
|
+
gemfile_source = dep.source || default_source
|
526
|
+
lock_source = lock_dep.source || default_source
|
527
|
+
next if lock_source.include?(gemfile_source)
|
528
|
+
|
529
|
+
gemfile_source_name = dep.source ? gemfile_source.to_gemfile : "no specified source"
|
530
|
+
lockfile_source_name = lock_dep.source ? lock_source.to_gemfile : "no specified source"
|
531
|
+
changed << "* #{name} from `#{lockfile_source_name}` to `#{gemfile_source_name}`"
|
532
|
+
end
|
533
|
+
|
534
|
+
return unless added.any? || deleted.any? || changed.any? || resolve_needed?
|
535
|
+
|
536
|
+
msg = String.new("#{change_reason.capitalize.strip}, but ")
|
537
|
+
msg << "the lockfile " unless msg.start_with?("Your lockfile")
|
538
|
+
msg << "can't be updated because #{update_refused_reason}"
|
539
|
+
msg << "\n\nYou have added to the Gemfile:\n" << added.join("\n") if added.any?
|
540
|
+
msg << "\n\nYou have deleted from the Gemfile:\n" << deleted.join("\n") if deleted.any?
|
541
|
+
msg << "\n\nYou have changed in the Gemfile:\n" << changed.join("\n") if changed.any?
|
542
|
+
msg << "\n\nRun `bundle install` elsewhere and add the updated #{SharedHelpers.relative_lockfile_path} to version control.\n" unless unlocking?
|
543
|
+
msg
|
544
|
+
end
|
545
|
+
|
544
546
|
def install_needed?
|
545
547
|
resolve_needed? || missing_specs?
|
546
548
|
end
|
@@ -556,6 +558,7 @@ module Bundler
|
|
556
558
|
@local_changes ||
|
557
559
|
@missing_lockfile_dep ||
|
558
560
|
@unlocking_bundler ||
|
561
|
+
@locked_spec_with_missing_checksums ||
|
559
562
|
@locked_spec_with_missing_deps ||
|
560
563
|
@locked_spec_with_invalid_deps
|
561
564
|
end
|
@@ -565,7 +568,7 @@ module Bundler
|
|
565
568
|
end
|
566
569
|
|
567
570
|
def should_add_extra_platforms?
|
568
|
-
!lockfile_exists? && generic_local_platform_is_ruby? && !Bundler.settings[:force_ruby_platform]
|
571
|
+
!lockfile_exists? && Bundler::MatchPlatform.generic_local_platform_is_ruby? && !Bundler.settings[:force_ruby_platform]
|
569
572
|
end
|
570
573
|
|
571
574
|
def lockfile_exists?
|
@@ -601,13 +604,17 @@ module Bundler
|
|
601
604
|
return
|
602
605
|
end
|
603
606
|
|
604
|
-
|
605
|
-
|
607
|
+
begin
|
608
|
+
SharedHelpers.filesystem_access(file) do |p|
|
609
|
+
File.open(p, "wb") {|f| f.puts(contents) }
|
610
|
+
end
|
611
|
+
rescue ReadOnlyFileSystemError
|
612
|
+
raise ProductionError, lockfile_changes_summary("file system is read-only")
|
606
613
|
end
|
607
614
|
end
|
608
615
|
|
609
616
|
def resolver
|
610
|
-
@resolver ||= Resolver.new(
|
617
|
+
@resolver ||= Resolver.new(resolution_base, gem_version_promoter, @most_specific_locked_platform)
|
611
618
|
end
|
612
619
|
|
613
620
|
def expanded_dependencies
|
@@ -621,14 +628,15 @@ module Bundler
|
|
621
628
|
[Dependency.new("bundler", @unlocking_bundler)] + dependencies
|
622
629
|
end
|
623
630
|
|
624
|
-
def
|
625
|
-
@
|
631
|
+
def resolution_base
|
632
|
+
@resolution_base ||= begin
|
626
633
|
last_resolve = converge_locked_specs
|
627
634
|
remove_invalid_platforms!
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
635
|
+
new_resolution_platforms = @current_platform_missing ? @new_platforms + [Bundler.local_platform] : @new_platforms
|
636
|
+
base = Resolver::Base.new(source_requirements, expanded_dependencies, last_resolve, @platforms, locked_specs: @originally_locked_specs, unlock: @unlocking_all || @gems_to_unlock, prerelease: gem_version_promoter.pre?, prefer_local: @prefer_local, new_platforms: new_resolution_platforms)
|
637
|
+
base = additional_base_requirements_to_prevent_downgrades(base)
|
638
|
+
base = additional_base_requirements_to_force_updates(base)
|
639
|
+
base
|
632
640
|
end
|
633
641
|
end
|
634
642
|
|
@@ -703,8 +711,7 @@ module Bundler
|
|
703
711
|
still_incomplete_specs = resolve.incomplete_specs
|
704
712
|
|
705
713
|
if still_incomplete_specs == incomplete_specs
|
706
|
-
|
707
|
-
resolver.raise_not_found! package
|
714
|
+
resolver.raise_incomplete! incomplete_specs
|
708
715
|
end
|
709
716
|
|
710
717
|
incomplete_specs = still_incomplete_specs
|
@@ -726,28 +733,40 @@ module Bundler
|
|
726
733
|
end
|
727
734
|
|
728
735
|
def reresolve_without(incomplete_specs)
|
729
|
-
|
736
|
+
resolution_base.delete(incomplete_specs)
|
730
737
|
@resolve = start_resolution
|
731
738
|
end
|
732
739
|
|
733
740
|
def start_resolution
|
734
|
-
local_platform_needed_for_resolvability = @most_specific_non_local_locked_platform && !@platforms.include?(local_platform)
|
735
|
-
@platforms << local_platform if local_platform_needed_for_resolvability
|
741
|
+
local_platform_needed_for_resolvability = @most_specific_non_local_locked_platform && !@platforms.include?(Bundler.local_platform)
|
742
|
+
@platforms << Bundler.local_platform if local_platform_needed_for_resolvability
|
736
743
|
add_platform(Gem::Platform::RUBY) if RUBY_ENGINE == "truffleruby"
|
737
744
|
|
738
745
|
result = SpecSet.new(resolver.start)
|
739
746
|
|
740
747
|
@resolved_bundler_version = result.find {|spec| spec.name == "bundler" }&.version
|
741
748
|
|
749
|
+
@new_platforms.each do |platform|
|
750
|
+
incomplete_specs = result.incomplete_specs_for_platform(current_dependencies, platform)
|
751
|
+
|
752
|
+
if incomplete_specs.any?
|
753
|
+
resolver.raise_incomplete! incomplete_specs
|
754
|
+
end
|
755
|
+
end
|
756
|
+
|
742
757
|
if @most_specific_non_local_locked_platform
|
743
|
-
if
|
758
|
+
if result.incomplete_for_platform?(current_dependencies, @most_specific_non_local_locked_platform)
|
744
759
|
@platforms.delete(@most_specific_non_local_locked_platform)
|
745
760
|
elsif local_platform_needed_for_resolvability
|
746
|
-
@platforms.delete(local_platform)
|
761
|
+
@platforms.delete(Bundler.local_platform)
|
747
762
|
end
|
748
763
|
end
|
749
764
|
|
750
|
-
|
765
|
+
if should_add_extra_platforms?
|
766
|
+
result.add_extra_platforms!(platforms)
|
767
|
+
elsif @originally_invalid_platforms.any?
|
768
|
+
result.add_originally_invalid_platforms!(platforms, @originally_invalid_platforms)
|
769
|
+
end
|
751
770
|
|
752
771
|
SpecSet.new(result.for(dependencies, @platforms | [Gem::Platform::RUBY]))
|
753
772
|
end
|
@@ -758,18 +777,17 @@ module Bundler
|
|
758
777
|
|
759
778
|
def current_platform_locked?
|
760
779
|
@platforms.any? do |bundle_platform|
|
761
|
-
generic_local_platform == bundle_platform || local_platform === bundle_platform
|
780
|
+
Bundler.generic_local_platform == bundle_platform || Bundler.local_platform === bundle_platform
|
762
781
|
end
|
763
782
|
end
|
764
783
|
|
765
784
|
def add_current_platform
|
766
|
-
return if @platforms.include?(local_platform)
|
785
|
+
return if @platforms.include?(Bundler.local_platform)
|
767
786
|
|
768
787
|
@most_specific_non_local_locked_platform = find_most_specific_locked_platform
|
769
788
|
return if @most_specific_non_local_locked_platform
|
770
789
|
|
771
|
-
@
|
772
|
-
@platforms << local_platform
|
790
|
+
@platforms << Bundler.local_platform
|
773
791
|
true
|
774
792
|
end
|
775
793
|
|
@@ -779,32 +797,58 @@ module Bundler
|
|
779
797
|
@most_specific_locked_platform
|
780
798
|
end
|
781
799
|
|
782
|
-
def
|
783
|
-
if
|
784
|
-
|
785
|
-
|
786
|
-
|
787
|
-
|
800
|
+
def resolve_needed_reason
|
801
|
+
if lockfile_exists?
|
802
|
+
if unlocking?
|
803
|
+
"Re-resolving dependencies because #{unlocking_reason}"
|
804
|
+
else
|
805
|
+
"Found changes from the lockfile, re-resolving dependencies because #{lockfile_changed_reason}"
|
788
806
|
end
|
807
|
+
else
|
808
|
+
"Resolving dependencies because there's no lockfile"
|
809
|
+
end
|
810
|
+
end
|
789
811
|
|
790
|
-
|
791
|
-
|
812
|
+
def change_reason
|
813
|
+
if resolve_needed?
|
814
|
+
if unlocking?
|
815
|
+
unlocking_reason
|
792
816
|
else
|
793
|
-
|
817
|
+
lockfile_changed_reason
|
794
818
|
end
|
819
|
+
else
|
820
|
+
"some dependencies were deleted from your gemfile"
|
821
|
+
end
|
822
|
+
end
|
795
823
|
|
796
|
-
|
824
|
+
def unlocking_reason
|
825
|
+
unlock_targets = if @gems_to_unlock.any?
|
826
|
+
["gems", @gems_to_unlock]
|
827
|
+
elsif @sources_to_unlock.any?
|
828
|
+
["sources", @sources_to_unlock]
|
829
|
+
end
|
830
|
+
|
831
|
+
unlock_reason = if unlock_targets
|
832
|
+
"#{unlock_targets.first}: (#{unlock_targets.last.join(", ")})"
|
833
|
+
else
|
834
|
+
@unlocking_ruby ? "ruby" : ""
|
797
835
|
end
|
836
|
+
|
837
|
+
"bundler is unlocking #{unlock_reason}"
|
838
|
+
end
|
839
|
+
|
840
|
+
def lockfile_changed_reason
|
798
841
|
[
|
799
842
|
[@source_changes, "the list of sources changed"],
|
800
843
|
[@dependency_changes, "the dependencies in your gemfile changed"],
|
801
|
-
[@current_platform_missing, "your lockfile
|
802
|
-
[@new_platforms.any?, "you
|
844
|
+
[@current_platform_missing, "your lockfile is missing the current platform"],
|
845
|
+
[@new_platforms.any?, "you are adding a new platform to your lockfile"],
|
803
846
|
[@path_changes, "the gemspecs for path gems changed"],
|
804
847
|
[@local_changes, "the gemspecs for git local gems changed"],
|
805
|
-
[@missing_lockfile_dep, "your
|
848
|
+
[@missing_lockfile_dep, "your lockfile is missing \"#{@missing_lockfile_dep}\""],
|
806
849
|
[@unlocking_bundler, "an update to the version of Bundler itself was requested"],
|
807
|
-
[@
|
850
|
+
[@locked_spec_with_missing_checksums, "your lockfile is missing a CHECKSUMS entry for \"#{@locked_spec_with_missing_checksums}\""],
|
851
|
+
[@locked_spec_with_missing_deps, "your lockfile includes \"#{@locked_spec_with_missing_deps}\" but not some of its dependencies"],
|
808
852
|
[@locked_spec_with_invalid_deps, "your lockfile does not satisfy dependencies of \"#{@locked_spec_with_invalid_deps}\""],
|
809
853
|
].select(&:first).map(&:last).join(", ")
|
810
854
|
end
|
@@ -821,8 +865,8 @@ module Bundler
|
|
821
865
|
!locked || dependencies_for_source_changed?(source, locked) || specs_for_source_changed?(source)
|
822
866
|
end
|
823
867
|
|
824
|
-
def dependencies_for_source_changed?(source, locked_source
|
825
|
-
deps_for_source = @dependencies.select {|
|
868
|
+
def dependencies_for_source_changed?(source, locked_source)
|
869
|
+
deps_for_source = @dependencies.select {|dep| dep.source == source }
|
826
870
|
locked_deps_for_source = locked_dependencies.select {|dep| dep.source == locked_source }
|
827
871
|
|
828
872
|
deps_for_source.uniq.sort != locked_deps_for_source.sort
|
@@ -830,7 +874,7 @@ module Bundler
|
|
830
874
|
|
831
875
|
def specs_for_source_changed?(source)
|
832
876
|
locked_index = Index.new
|
833
|
-
locked_index.use(@locked_specs.select {|s|
|
877
|
+
locked_index.use(@locked_specs.select {|s| s.replace_source_with!(source) })
|
834
878
|
|
835
879
|
!locked_index.subset?(source.specs)
|
836
880
|
rescue PathError, GitError => e
|
@@ -862,21 +906,27 @@ module Bundler
|
|
862
906
|
def check_lockfile
|
863
907
|
@locked_spec_with_invalid_deps = nil
|
864
908
|
@locked_spec_with_missing_deps = nil
|
909
|
+
@locked_spec_with_missing_checksums = nil
|
865
910
|
|
866
|
-
|
911
|
+
missing_deps = []
|
912
|
+
missing_checksums = []
|
867
913
|
invalid = []
|
868
914
|
|
869
915
|
@locked_specs.each do |s|
|
916
|
+
missing_checksums << s if @locked_checksums && s.source.checksum_store.missing?(s)
|
917
|
+
|
870
918
|
validation = @locked_specs.validate_deps(s)
|
871
919
|
|
872
|
-
|
920
|
+
missing_deps << s if validation == :missing
|
873
921
|
invalid << s if validation == :invalid
|
874
922
|
end
|
875
923
|
|
876
|
-
if
|
877
|
-
|
924
|
+
@locked_spec_with_missing_checksums = missing_checksums.first.name if missing_checksums.any?
|
925
|
+
|
926
|
+
if missing_deps.any?
|
927
|
+
@locked_specs.delete(missing_deps)
|
878
928
|
|
879
|
-
@locked_spec_with_missing_deps =
|
929
|
+
@locked_spec_with_missing_deps = missing_deps.first.name
|
880
930
|
end
|
881
931
|
|
882
932
|
if invalid.any?
|
@@ -892,24 +942,6 @@ module Bundler
|
|
892
942
|
end
|
893
943
|
end
|
894
944
|
|
895
|
-
def converge_path_source_to_gemspec_source(source)
|
896
|
-
return source unless source.instance_of?(Source::Path)
|
897
|
-
gemspec_source = sources.path_sources.find {|s| s.is_a?(Source::Gemspec) && s.as_path_source == source }
|
898
|
-
gemspec_source || source
|
899
|
-
end
|
900
|
-
|
901
|
-
def converge_path_sources_to_gemspec_sources
|
902
|
-
@locked_sources.map! do |source|
|
903
|
-
converge_path_source_to_gemspec_source(source)
|
904
|
-
end
|
905
|
-
@locked_specs.each do |spec|
|
906
|
-
spec.source &&= converge_path_source_to_gemspec_source(spec.source)
|
907
|
-
end
|
908
|
-
@locked_deps.each do |_, dep|
|
909
|
-
dep.source &&= converge_path_source_to_gemspec_source(dep.source)
|
910
|
-
end
|
911
|
-
end
|
912
|
-
|
913
945
|
def converge_sources
|
914
946
|
# Replace the sources from the Gemfile with the sources from the Gemfile.lock,
|
915
947
|
# if they exist in the Gemfile.lock and are `==`. If you can't find an equivalent
|
@@ -952,11 +984,17 @@ module Bundler
|
|
952
984
|
unless name == "bundler"
|
953
985
|
locked_specs = @originally_locked_specs[name]
|
954
986
|
|
955
|
-
if locked_specs.
|
956
|
-
@
|
957
|
-
|
958
|
-
|
959
|
-
|
987
|
+
if locked_specs.empty?
|
988
|
+
@missing_lockfile_dep = name if dep_changed == false
|
989
|
+
else
|
990
|
+
if locked_specs.map(&:source).uniq.size > 1
|
991
|
+
@locked_specs.delete(locked_specs.select {|s| s.source != dep.source })
|
992
|
+
end
|
993
|
+
|
994
|
+
unless dep.matches_spec?(locked_specs.first)
|
995
|
+
@gems_to_unlock << name
|
996
|
+
dep_changed = true
|
997
|
+
end
|
960
998
|
end
|
961
999
|
end
|
962
1000
|
|
@@ -999,17 +1037,16 @@ module Bundler
|
|
999
1037
|
lockfile_source = s.source
|
1000
1038
|
|
1001
1039
|
if dep
|
1002
|
-
|
1003
|
-
|
1004
|
-
deps << dep if !dep.source || lockfile_source.include?(dep.source) || new_deps.include?(dep)
|
1040
|
+
replacement_source = dep.source
|
1005
1041
|
|
1006
|
-
|
1007
|
-
s.source = gemfile_source
|
1042
|
+
deps << dep if !replacement_source || lockfile_source.include?(replacement_source) || new_deps.include?(dep)
|
1008
1043
|
else
|
1009
|
-
|
1010
|
-
s.source = default_source unless sources.get(lockfile_source)
|
1044
|
+
replacement_source = sources.get(lockfile_source)
|
1011
1045
|
end
|
1012
1046
|
|
1047
|
+
# Replace the locked dependency's source with the equivalent source from the Gemfile
|
1048
|
+
s.source = replacement_source || default_source
|
1049
|
+
|
1013
1050
|
source = s.source
|
1014
1051
|
next if @sources_to_unlock.include?(source.name)
|
1015
1052
|
|
@@ -1093,27 +1130,27 @@ module Bundler
|
|
1093
1130
|
current == proposed
|
1094
1131
|
end
|
1095
1132
|
|
1096
|
-
def additional_base_requirements_to_prevent_downgrades(
|
1097
|
-
return
|
1133
|
+
def additional_base_requirements_to_prevent_downgrades(resolution_base)
|
1134
|
+
return resolution_base unless @locked_gems && !sources.expired_sources?(@locked_gems.sources)
|
1098
1135
|
@originally_locked_specs.each do |locked_spec|
|
1099
1136
|
next if locked_spec.source.is_a?(Source::Path)
|
1100
1137
|
|
1101
1138
|
name = locked_spec.name
|
1102
1139
|
next if @changed_dependencies.include?(name)
|
1103
1140
|
|
1104
|
-
|
1141
|
+
resolution_base.base_requirements[name] = Gem::Requirement.new(">= #{locked_spec.version}")
|
1105
1142
|
end
|
1106
|
-
|
1143
|
+
resolution_base
|
1107
1144
|
end
|
1108
1145
|
|
1109
|
-
def additional_base_requirements_to_force_updates(
|
1110
|
-
return
|
1146
|
+
def additional_base_requirements_to_force_updates(resolution_base)
|
1147
|
+
return resolution_base if @explicit_unlocks.empty?
|
1111
1148
|
full_update = dup_for_full_unlock.resolve
|
1112
1149
|
@explicit_unlocks.each do |name|
|
1113
1150
|
version = full_update.version_for(name)
|
1114
|
-
|
1151
|
+
resolution_base.base_requirements[name] = Gem::Requirement.new("= #{version}") if version
|
1115
1152
|
end
|
1116
|
-
|
1153
|
+
resolution_base
|
1117
1154
|
end
|
1118
1155
|
|
1119
1156
|
def dup_for_full_unlock
|
@@ -1130,20 +1167,16 @@ module Bundler
|
|
1130
1167
|
def remove_invalid_platforms!
|
1131
1168
|
return if Bundler.frozen_bundle?
|
1132
1169
|
|
1133
|
-
|
1134
|
-
next if local_platform == platform ||
|
1135
|
-
@new_platforms.include?(platform) ||
|
1136
|
-
@path_changes ||
|
1137
|
-
@dependency_changes ||
|
1138
|
-
@locked_spec_with_invalid_deps ||
|
1139
|
-
!spec_set_incomplete_for_platform?(@originally_locked_specs, platform)
|
1170
|
+
skips = (@new_platforms + [Bundler.local_platform]).uniq
|
1140
1171
|
|
1141
|
-
|
1142
|
-
|
1143
|
-
|
1172
|
+
# We should probably avoid removing non-ruby platforms, since that means
|
1173
|
+
# lockfile will no longer install on those platforms, so a error to give
|
1174
|
+
# heads up to the user may be better. However, we have tests expecting
|
1175
|
+
# non ruby platform autoremoval to work, so leaving that in place for
|
1176
|
+
# now.
|
1177
|
+
skips |= platforms - [Gem::Platform::RUBY] if @dependency_changes
|
1144
1178
|
|
1145
|
-
|
1146
|
-
spec_set.incomplete_for_platform?(current_dependencies, platform)
|
1179
|
+
@originally_invalid_platforms = @originally_locked_specs.remove_invalid_platforms!(current_dependencies, platforms, skips: skips)
|
1147
1180
|
end
|
1148
1181
|
|
1149
1182
|
def source_map
|
data/lib/bundler/dependency.rb
CHANGED
@@ -99,7 +99,7 @@ module Bundler
|
|
99
99
|
return RUBY_PLATFORM_ARRAY if force_ruby_platform
|
100
100
|
return valid_platforms if platforms.empty?
|
101
101
|
|
102
|
-
valid_platforms.select {|p| expanded_platforms.include?(
|
102
|
+
valid_platforms.select {|p| expanded_platforms.include?(Gem::Platform.generic(p)) }
|
103
103
|
end
|
104
104
|
|
105
105
|
def expanded_platforms
|