bundler 2.7.1 → 4.0.0.beta1

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.
Files changed (144) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1001 -902
  3. data/README.md +4 -4
  4. data/bundler.gemspec +3 -3
  5. data/lib/bundler/build_metadata.rb +2 -2
  6. data/lib/bundler/capistrano.rb +1 -19
  7. data/lib/bundler/checksum.rb +6 -0
  8. data/lib/bundler/cli/cache.rb +1 -12
  9. data/lib/bundler/cli/common.rb +21 -4
  10. data/lib/bundler/cli/config.rb +1 -2
  11. data/lib/bundler/cli/console.rb +5 -0
  12. data/lib/bundler/cli/exec.rb +29 -4
  13. data/lib/bundler/cli/gem.rb +19 -33
  14. data/lib/bundler/cli/install.rb +7 -84
  15. data/lib/bundler/cli/issue.rb +2 -2
  16. data/lib/bundler/cli/list.rb +33 -2
  17. data/lib/bundler/cli/lock.rb +5 -5
  18. data/lib/bundler/cli/plugin.rb +5 -1
  19. data/lib/bundler/cli/show.rb +3 -7
  20. data/lib/bundler/cli/update.rb +3 -3
  21. data/lib/bundler/cli.rb +97 -95
  22. data/lib/bundler/compact_index_client.rb +0 -1
  23. data/lib/bundler/current_ruby.rb +3 -15
  24. data/lib/bundler/definition.rb +122 -95
  25. data/lib/bundler/deployment.rb +1 -64
  26. data/lib/bundler/digest.rb +1 -1
  27. data/lib/bundler/dsl.rb +14 -36
  28. data/lib/bundler/endpoint_specification.rb +0 -22
  29. data/lib/bundler/errors.rb +1 -5
  30. data/lib/bundler/feature_flag.rb +0 -33
  31. data/lib/bundler/fetcher/compact_index.rb +1 -1
  32. data/lib/bundler/friendly_errors.rb +2 -2
  33. data/lib/bundler/index.rb +0 -7
  34. data/lib/bundler/inline.rb +1 -1
  35. data/lib/bundler/installer/gem_installer.rb +0 -11
  36. data/lib/bundler/installer.rb +0 -6
  37. data/lib/bundler/lockfile_generator.rb +1 -1
  38. data/lib/bundler/lockfile_parser.rb +2 -12
  39. data/lib/bundler/man/bundle-add.1 +1 -1
  40. data/lib/bundler/man/bundle-binstubs.1 +3 -6
  41. data/lib/bundler/man/bundle-binstubs.1.ronn +4 -6
  42. data/lib/bundler/man/bundle-cache.1 +2 -14
  43. data/lib/bundler/man/bundle-cache.1.ronn +1 -14
  44. data/lib/bundler/man/bundle-check.1 +2 -5
  45. data/lib/bundler/man/bundle-check.1.ronn +0 -5
  46. data/lib/bundler/man/bundle-clean.1 +1 -1
  47. data/lib/bundler/man/bundle-config.1 +36 -46
  48. data/lib/bundler/man/bundle-config.1.ronn +69 -75
  49. data/lib/bundler/man/bundle-console.1 +1 -1
  50. data/lib/bundler/man/bundle-doctor.1 +4 -4
  51. data/lib/bundler/man/bundle-doctor.1.ronn +4 -4
  52. data/lib/bundler/man/bundle-env.1 +1 -1
  53. data/lib/bundler/man/bundle-exec.1 +2 -5
  54. data/lib/bundler/man/bundle-exec.1.ronn +1 -5
  55. data/lib/bundler/man/bundle-fund.1 +1 -1
  56. data/lib/bundler/man/bundle-gem.1 +3 -6
  57. data/lib/bundler/man/bundle-gem.1.ronn +2 -5
  58. data/lib/bundler/man/bundle-help.1 +1 -1
  59. data/lib/bundler/man/bundle-info.1 +1 -1
  60. data/lib/bundler/man/bundle-init.1 +1 -1
  61. data/lib/bundler/man/bundle-install.1 +8 -59
  62. data/lib/bundler/man/bundle-install.1.ronn +12 -107
  63. data/lib/bundler/man/bundle-issue.1 +1 -1
  64. data/lib/bundler/man/bundle-licenses.1 +1 -1
  65. data/lib/bundler/man/bundle-list.1 +6 -1
  66. data/lib/bundler/man/bundle-list.1.ronn +5 -0
  67. data/lib/bundler/man/bundle-lock.1 +1 -1
  68. data/lib/bundler/man/bundle-open.1 +1 -1
  69. data/lib/bundler/man/bundle-outdated.1 +1 -1
  70. data/lib/bundler/man/bundle-platform.1 +1 -1
  71. data/lib/bundler/man/bundle-plugin.1 +33 -15
  72. data/lib/bundler/man/bundle-plugin.1.ronn +36 -15
  73. data/lib/bundler/man/bundle-pristine.1 +1 -1
  74. data/lib/bundler/man/bundle-remove.1 +2 -8
  75. data/lib/bundler/man/bundle-remove.1.ronn +1 -8
  76. data/lib/bundler/man/bundle-show.1 +2 -5
  77. data/lib/bundler/man/bundle-show.1.ronn +0 -4
  78. data/lib/bundler/man/bundle-update.1 +1 -1
  79. data/lib/bundler/man/bundle-version.1 +1 -1
  80. data/lib/bundler/man/bundle.1 +1 -10
  81. data/lib/bundler/man/bundle.1.ronn +0 -9
  82. data/lib/bundler/man/gemfile.5 +1 -1
  83. data/lib/bundler/man/index.txt +0 -2
  84. data/lib/bundler/materialization.rb +1 -1
  85. data/lib/bundler/plugin/installer.rb +0 -10
  86. data/lib/bundler/plugin/source_list.rb +1 -1
  87. data/lib/bundler/plugin.rb +1 -1
  88. data/lib/bundler/resolver/package.rb +1 -0
  89. data/lib/bundler/resolver.rb +1 -1
  90. data/lib/bundler/ruby_dsl.rb +2 -0
  91. data/lib/bundler/ruby_version.rb +1 -3
  92. data/lib/bundler/rubygems_ext.rb +1 -1
  93. data/lib/bundler/rubygems_gem_installer.rb +1 -1
  94. data/lib/bundler/rubygems_integration.rb +1 -5
  95. data/lib/bundler/self_manager.rb +1 -1
  96. data/lib/bundler/settings.rb +8 -27
  97. data/lib/bundler/shared_helpers.rb +8 -20
  98. data/lib/bundler/source/gemspec.rb +4 -0
  99. data/lib/bundler/source/git/git_proxy.rb +3 -11
  100. data/lib/bundler/source/git.rb +2 -3
  101. data/lib/bundler/source/path.rb +5 -7
  102. data/lib/bundler/source/rubygems.rb +11 -17
  103. data/lib/bundler/source.rb +1 -1
  104. data/lib/bundler/source_list.rb +4 -45
  105. data/lib/bundler/source_map.rb +2 -5
  106. data/lib/bundler/spec_set.rb +6 -15
  107. data/lib/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt +7 -129
  108. data/lib/bundler/templates/newgem/circleci/config.yml.tt +12 -0
  109. data/lib/bundler/templates/newgem/ext/newgem/Cargo.toml.tt +1 -1
  110. data/lib/bundler/templates/newgem/ext/newgem/extconf-go.rb.tt +11 -0
  111. data/lib/bundler/templates/newgem/ext/newgem/go.mod.tt +5 -0
  112. data/lib/bundler/templates/newgem/ext/newgem/newgem-go.c.tt +2 -0
  113. data/lib/bundler/templates/newgem/ext/newgem/newgem.go.tt +31 -0
  114. data/lib/bundler/templates/newgem/github/workflows/main.yml.tt +6 -0
  115. data/lib/bundler/templates/newgem/gitlab-ci.yml.tt +9 -0
  116. data/lib/bundler/templates/newgem/newgem.gemspec.tt +7 -4
  117. data/lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb +26 -23
  118. data/lib/bundler/vendor/connection_pool/lib/connection_pool/version.rb +1 -1
  119. data/lib/bundler/vendor/connection_pool/lib/connection_pool.rb +50 -6
  120. data/lib/bundler/vendor/fileutils/lib/fileutils.rb +57 -52
  121. data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb +5 -2
  122. data/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb +42 -6
  123. data/lib/bundler/vendor/thor/lib/thor/parser/options.rb +1 -1
  124. data/lib/bundler/vendor/thor/lib/thor/runner.rb +2 -2
  125. data/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +3 -7
  126. data/lib/bundler/vendor/thor/lib/thor/version.rb +1 -1
  127. data/lib/bundler/vendor/uri/lib/uri/common.rb +57 -15
  128. data/lib/bundler/vendor/uri/lib/uri/file.rb +1 -1
  129. data/lib/bundler/vendor/uri/lib/uri/generic.rb +34 -21
  130. data/lib/bundler/vendor/uri/lib/uri/http.rb +12 -0
  131. data/lib/bundler/vendor/uri/lib/uri/rfc2396_parser.rb +9 -8
  132. data/lib/bundler/vendor/uri/lib/uri/version.rb +2 -2
  133. data/lib/bundler/version.rb +1 -1
  134. data/lib/bundler/vlad.rb +1 -14
  135. data/lib/bundler.rb +6 -28
  136. metadata +9 -13
  137. data/lib/bundler/cli/inject.rb +0 -60
  138. data/lib/bundler/cli/viz.rb +0 -31
  139. data/lib/bundler/graph.rb +0 -152
  140. data/lib/bundler/man/bundle-inject.1 +0 -31
  141. data/lib/bundler/man/bundle-inject.1.ronn +0 -32
  142. data/lib/bundler/man/bundle-viz.1 +0 -30
  143. data/lib/bundler/man/bundle-viz.1.ronn +0 -36
  144. data/lib/bundler/similarity_detector.rb +0 -63
@@ -107,6 +107,7 @@ module Bundler
107
107
  @locked_ruby_version = @locked_gems.ruby_version
108
108
  @locked_deps = @locked_gems.dependencies
109
109
  @originally_locked_specs = SpecSet.new(@locked_gems.specs)
110
+ @originally_locked_sources = @locked_gems.sources
110
111
  @locked_checksums = @locked_gems.checksums
111
112
 
112
113
  if @unlocking_all
@@ -114,7 +115,16 @@ module Bundler
114
115
  @locked_sources = []
115
116
  else
116
117
  @locked_specs = @originally_locked_specs
117
- @locked_sources = @locked_gems.sources
118
+ @locked_sources = @originally_locked_sources
119
+ end
120
+
121
+ locked_gem_sources = @originally_locked_sources.select {|s| s.is_a?(Source::Rubygems) }
122
+ multisource_lockfile = locked_gem_sources.size == 1 && locked_gem_sources.first.multiple_remotes?
123
+
124
+ if multisource_lockfile
125
+ msg = "Your lockfile contains a single rubygems source section with multiple remotes, which is insecure. Make sure you run `bundle install` in non frozen mode and commit the result to make your lockfile secure."
126
+
127
+ Bundler::SharedHelpers.feature_removed! msg
118
128
  end
119
129
  else
120
130
  @locked_gems = nil
@@ -123,22 +133,10 @@ module Bundler
123
133
  @platforms = []
124
134
  @locked_deps = {}
125
135
  @locked_specs = SpecSet.new([])
126
- @originally_locked_specs = @locked_specs
127
136
  @locked_sources = []
128
- @locked_checksums = Bundler.feature_flag.lockfile_checksums?
129
- end
130
-
131
- locked_gem_sources = @locked_sources.select {|s| s.is_a?(Source::Rubygems) }
132
- @multisource_allowed = locked_gem_sources.size == 1 && locked_gem_sources.first.multiple_remotes? && Bundler.frozen_bundle?
133
-
134
- if @multisource_allowed
135
- unless sources.aggregate_global_source?
136
- msg = "Your lockfile contains a single rubygems source section with multiple remotes, which is insecure. Make sure you run `bundle install` in non frozen mode and commit the result to make your lockfile secure."
137
-
138
- Bundler::SharedHelpers.major_deprecation 2, msg
139
- end
140
-
141
- @sources.merged_gem_lockfile_sections!(locked_gem_sources.first)
137
+ @originally_locked_specs = @locked_specs
138
+ @originally_locked_sources = @locked_sources
139
+ @locked_checksums = Bundler.settings[:lockfile_checksums]
142
140
  end
143
141
 
144
142
  @unlocking_ruby ||= if @ruby_version && locked_ruby_version_object
@@ -189,12 +187,14 @@ module Bundler
189
187
  def setup_domain!(options = {})
190
188
  prefer_local! if options[:"prefer-local"]
191
189
 
190
+ sources.cached!
191
+
192
192
  if options[:add_checksums] || (!options[:local] && install_needed?)
193
- remotely!
193
+ sources.remote!
194
194
  true
195
195
  else
196
196
  Bundler.settings.set_command_option(:jobs, 1) unless install_needed? # to avoid the overhead of Bundler::Worker
197
- with_cache!
197
+ sources.local!
198
198
  false
199
199
  end
200
200
  end
@@ -282,12 +282,17 @@ module Bundler
282
282
  end
283
283
 
284
284
  def filter_relevant(dependencies)
285
- platforms_array = [Bundler.generic_local_platform].freeze
286
285
  dependencies.select do |d|
287
- d.should_include? && !d.gem_platforms(platforms_array).empty?
286
+ relevant_deps?(d)
288
287
  end
289
288
  end
290
289
 
290
+ def relevant_deps?(dep)
291
+ platforms_array = [Bundler.generic_local_platform].freeze
292
+
293
+ dep.should_include? && !dep.gem_platforms(platforms_array).empty?
294
+ end
295
+
291
296
  def locked_dependencies
292
297
  @locked_deps.values
293
298
  end
@@ -367,12 +372,50 @@ module Bundler
367
372
 
368
373
  msg = "`Definition#lock` was passed a target file argument. #{suggestion}"
369
374
 
370
- Bundler::SharedHelpers.major_deprecation 2, msg
375
+ Bundler::SharedHelpers.feature_removed! msg
371
376
  end
372
377
 
373
378
  write_lock(target_lockfile, preserve_unknown_sections)
374
379
  end
375
380
 
381
+ def write_lock(file, preserve_unknown_sections)
382
+ return if Definition.no_lock || file.nil?
383
+
384
+ contents = to_lock
385
+
386
+ # Convert to \r\n if the existing lock has them
387
+ # i.e., Windows with `git config core.autocrlf=true`
388
+ contents.gsub!(/\n/, "\r\n") if @lockfile_contents.match?("\r\n")
389
+
390
+ if @locked_bundler_version
391
+ locked_major = @locked_bundler_version.segments.first
392
+ current_major = bundler_version_to_lock.segments.first
393
+
394
+ updating_major = locked_major < current_major
395
+ end
396
+
397
+ preserve_unknown_sections ||= !updating_major && (Bundler.frozen_bundle? || !(unlocking? || @unlocking_bundler))
398
+
399
+ if File.exist?(file) && lockfiles_equal?(@lockfile_contents, contents, preserve_unknown_sections)
400
+ return if Bundler.frozen_bundle?
401
+ SharedHelpers.filesystem_access(file) { FileUtils.touch(file) }
402
+ return
403
+ end
404
+
405
+ if Bundler.frozen_bundle?
406
+ Bundler.ui.error "Cannot write a changed lockfile while frozen."
407
+ return
408
+ end
409
+
410
+ begin
411
+ SharedHelpers.filesystem_access(file) do |p|
412
+ File.open(p, "wb") {|f| f.puts(contents) }
413
+ end
414
+ rescue ReadOnlyFileSystemError
415
+ raise ProductionError, lockfile_changes_summary("file system is read-only")
416
+ end
417
+ end
418
+
376
419
  def locked_ruby_version
377
420
  return unless ruby_version
378
421
  if @unlocking_ruby || !@locked_ruby_version
@@ -492,14 +535,23 @@ module Bundler
492
535
  @unlocking
493
536
  end
494
537
 
495
- attr_writer :source_requirements
496
-
497
538
  def add_checksums
498
539
  @locked_checksums = true
499
540
 
500
541
  setup_domain!(add_checksums: true)
501
542
 
502
- specs # force materialization to real specifications, so that checksums are fetched
543
+ # force materialization to real specifications, so that checksums are fetched
544
+ specs.each do |spec|
545
+ next unless spec.source.is_a?(Bundler::Source::Rubygems)
546
+ # Checksum was fetched from the compact index API.
547
+ next if !spec.source.checksum_store.missing?(spec) && !spec.source.checksum_store.empty?(spec)
548
+ # The gem isn't installed, can't compute the checksum.
549
+ next unless spec.loaded_from
550
+
551
+ package = Gem::Package.new(spec.source.cached_built_in_gem(spec))
552
+ checksum = Checksum.from_gem_package(package)
553
+ spec.source.checksum_store.register(spec, checksum)
554
+ end
503
555
  end
504
556
 
505
557
  private
@@ -533,7 +585,7 @@ module Bundler
533
585
 
534
586
  return unless added.any? || deleted.any? || changed.any? || resolve_needed?
535
587
 
536
- msg = String.new("#{change_reason.capitalize.strip}, but ")
588
+ msg = String.new("#{change_reason[0].upcase}#{change_reason[1..-1].strip}, but ")
537
589
  msg << "the lockfile " unless msg.start_with?("Your lockfile")
538
590
  msg << "can't be updated because #{update_refused_reason}"
539
591
  msg << "\n\nYou have added to the Gemfile:\n" << added.join("\n") if added.any?
@@ -559,6 +611,7 @@ module Bundler
559
611
  @missing_lockfile_dep ||
560
612
  @unlocking_bundler ||
561
613
  @locked_spec_with_missing_checksums ||
614
+ @locked_spec_with_empty_checksums ||
562
615
  @locked_spec_with_missing_deps ||
563
616
  @locked_spec_with_invalid_deps
564
617
  end
@@ -575,46 +628,8 @@ module Bundler
575
628
  lockfile && File.exist?(lockfile)
576
629
  end
577
630
 
578
- def write_lock(file, preserve_unknown_sections)
579
- return if Definition.no_lock || file.nil?
580
-
581
- contents = to_lock
582
-
583
- # Convert to \r\n if the existing lock has them
584
- # i.e., Windows with `git config core.autocrlf=true`
585
- contents.gsub!(/\n/, "\r\n") if @lockfile_contents.match?("\r\n")
586
-
587
- if @locked_bundler_version
588
- locked_major = @locked_bundler_version.segments.first
589
- current_major = bundler_version_to_lock.segments.first
590
-
591
- updating_major = locked_major < current_major
592
- end
593
-
594
- preserve_unknown_sections ||= !updating_major && (Bundler.frozen_bundle? || !(unlocking? || @unlocking_bundler))
595
-
596
- if File.exist?(file) && lockfiles_equal?(@lockfile_contents, contents, preserve_unknown_sections)
597
- return if Bundler.frozen_bundle?
598
- SharedHelpers.filesystem_access(file) { FileUtils.touch(file) }
599
- return
600
- end
601
-
602
- if Bundler.frozen_bundle?
603
- Bundler.ui.error "Cannot write a changed lockfile while frozen."
604
- return
605
- end
606
-
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")
613
- end
614
- end
615
-
616
631
  def resolver
617
- @resolver ||= Resolver.new(resolution_base, gem_version_promoter, @most_specific_locked_platform)
632
+ @resolver ||= new_resolver(resolution_base)
618
633
  end
619
634
 
620
635
  def expanded_dependencies
@@ -632,8 +647,7 @@ module Bundler
632
647
  @resolution_base ||= begin
633
648
  last_resolve = converge_locked_specs
634
649
  remove_invalid_platforms!
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)
650
+ base = new_resolution_base(last_resolve: last_resolve, unlock: @unlocking_all || @gems_to_unlock)
637
651
  base = additional_base_requirements_to_prevent_downgrades(base)
638
652
  base = additional_base_requirements_to_force_updates(base)
639
653
  base
@@ -645,20 +659,12 @@ module Bundler
645
659
  end
646
660
 
647
661
  def materialize(dependencies)
648
- # Tracks potential endless loops trying to re-resolve.
649
- # TODO: Remove as dead code if not reports are received in a while
650
- incorrect_spec = nil
651
-
652
662
  specs = begin
653
663
  resolve.materialize(dependencies)
654
664
  rescue IncorrectLockfileDependencies => e
655
665
  raise if Bundler.frozen_bundle?
656
666
 
657
- spec = e.spec
658
- raise "Infinite loop while fixing lockfile dependencies" if incorrect_spec == spec
659
-
660
- incorrect_spec = spec
661
- reresolve_without([spec])
667
+ reresolve_without([e.spec])
662
668
  retry
663
669
  end
664
670
 
@@ -740,7 +746,6 @@ module Bundler
740
746
  def start_resolution
741
747
  local_platform_needed_for_resolvability = @most_specific_non_local_locked_platform && !@platforms.include?(Bundler.local_platform)
742
748
  @platforms << Bundler.local_platform if local_platform_needed_for_resolvability
743
- add_platform(Gem::Platform::RUBY) if RUBY_ENGINE == "truffleruby"
744
749
 
745
750
  result = SpecSet.new(resolver.start)
746
751
 
@@ -772,7 +777,7 @@ module Bundler
772
777
  end
773
778
 
774
779
  def precompute_source_requirements_for_indirect_dependencies?
775
- sources.non_global_rubygems_sources.all?(&:dependency_api_available?) && !sources.aggregate_global_source?
780
+ sources.non_global_rubygems_sources.all?(&:dependency_api_available?)
776
781
  end
777
782
 
778
783
  def current_platform_locked?
@@ -848,6 +853,7 @@ module Bundler
848
853
  [@missing_lockfile_dep, "your lockfile is missing \"#{@missing_lockfile_dep}\""],
849
854
  [@unlocking_bundler, "an update to the version of Bundler itself was requested"],
850
855
  [@locked_spec_with_missing_checksums, "your lockfile is missing a CHECKSUMS entry for \"#{@locked_spec_with_missing_checksums}\""],
856
+ [@locked_spec_with_empty_checksums, "your lockfile has an empty CHECKSUMS entry for \"#{@locked_spec_with_empty_checksums}\""],
851
857
  [@locked_spec_with_missing_deps, "your lockfile includes \"#{@locked_spec_with_missing_deps}\" but not some of its dependencies"],
852
858
  [@locked_spec_with_invalid_deps, "your lockfile does not satisfy dependencies of \"#{@locked_spec_with_invalid_deps}\""],
853
859
  ].select(&:first).map(&:last).join(", ")
@@ -907,13 +913,23 @@ module Bundler
907
913
  @locked_spec_with_invalid_deps = nil
908
914
  @locked_spec_with_missing_deps = nil
909
915
  @locked_spec_with_missing_checksums = nil
916
+ @locked_spec_with_empty_checksums = nil
910
917
 
911
918
  missing_deps = []
912
919
  missing_checksums = []
920
+ empty_checksums = []
913
921
  invalid = []
914
922
 
915
923
  @locked_specs.each do |s|
916
- missing_checksums << s if @locked_checksums && s.source.checksum_store.missing?(s)
924
+ if @locked_checksums
925
+ checksum_store = s.source.checksum_store
926
+
927
+ if checksum_store.missing?(s)
928
+ missing_checksums << s
929
+ elsif checksum_store.empty?(s)
930
+ empty_checksums << s
931
+ end
932
+ end
917
933
 
918
934
  validation = @locked_specs.validate_deps(s)
919
935
 
@@ -922,6 +938,7 @@ module Bundler
922
938
  end
923
939
 
924
940
  @locked_spec_with_missing_checksums = missing_checksums.first.name if missing_checksums.any?
941
+ @locked_spec_with_empty_checksums = empty_checksums.first.name if empty_checksums.any?
925
942
 
926
943
  if missing_deps.any?
927
944
  @locked_specs.delete(missing_deps)
@@ -951,7 +968,7 @@ module Bundler
951
968
  sources.all_sources.each do |source|
952
969
  # has to be done separately, because we want to keep the locked checksum
953
970
  # store for a source, even when doing a full update
954
- if @locked_checksums && @locked_gems && locked_source = @locked_gems.sources.find {|s| s == source && !s.equal?(source) }
971
+ if @locked_checksums && @locked_gems && locked_source = @originally_locked_sources.find {|s| s == source && !s.equal?(source) }
955
972
  source.checksum_store.merge!(locked_source.checksum_store)
956
973
  end
957
974
  # If the source is unlockable and the current command allows an unlock of
@@ -972,10 +989,11 @@ module Bundler
972
989
  @missing_lockfile_dep = nil
973
990
  @changed_dependencies = []
974
991
 
975
- current_dependencies.each do |dep|
992
+ @dependencies.each do |dep|
976
993
  if dep.source
977
994
  dep.source = sources.get(dep.source)
978
995
  end
996
+ next unless relevant_deps?(dep)
979
997
 
980
998
  name = dep.name
981
999
 
@@ -1033,6 +1051,8 @@ module Bundler
1033
1051
 
1034
1052
  specs.each do |s|
1035
1053
  name = s.name
1054
+ next if @gems_to_unlock.include?(name)
1055
+
1036
1056
  dep = @dependencies.find {|d| s.satisfies?(d) }
1037
1057
  lockfile_source = s.source
1038
1058
 
@@ -1046,12 +1066,13 @@ module Bundler
1046
1066
 
1047
1067
  # Replace the locked dependency's source with the equivalent source from the Gemfile
1048
1068
  s.source = replacement_source || default_source
1069
+ next if s.source_changed?
1049
1070
 
1050
1071
  source = s.source
1051
1072
  next if @sources_to_unlock.include?(source.name)
1052
1073
 
1053
1074
  # Path sources have special logic
1054
- if source.instance_of?(Source::Path) || source.instance_of?(Source::Gemspec) || (source.instance_of?(Source::Git) && !@gems_to_unlock.include?(name) && deps.include?(dep))
1075
+ if source.is_a?(Source::Path)
1055
1076
  new_spec = source.specs[s].first
1056
1077
  if new_spec
1057
1078
  s.runtime_dependencies.replace(new_spec.runtime_dependencies)
@@ -1131,9 +1152,9 @@ module Bundler
1131
1152
  end
1132
1153
 
1133
1154
  def additional_base_requirements_to_prevent_downgrades(resolution_base)
1134
- return resolution_base unless @locked_gems && !sources.expired_sources?(@locked_gems.sources)
1155
+ return resolution_base unless @locked_gems
1135
1156
  @originally_locked_specs.each do |locked_spec|
1136
- next if locked_spec.source.is_a?(Source::Path)
1157
+ next if locked_spec.source.is_a?(Source::Path) || locked_spec.source_changed?
1137
1158
 
1138
1159
  name = locked_spec.name
1139
1160
  next if @changed_dependencies.include?(name)
@@ -1145,7 +1166,7 @@ module Bundler
1145
1166
 
1146
1167
  def additional_base_requirements_to_force_updates(resolution_base)
1147
1168
  return resolution_base if @explicit_unlocks.empty?
1148
- full_update = dup_for_full_unlock.resolve
1169
+ full_update = SpecSet.new(new_resolver_for_full_update.start)
1149
1170
  @explicit_unlocks.each do |name|
1150
1171
  version = full_update.version_for(name)
1151
1172
  resolution_base.base_requirements[name] = Gem::Requirement.new("= #{version}") if version
@@ -1153,17 +1174,6 @@ module Bundler
1153
1174
  resolution_base
1154
1175
  end
1155
1176
 
1156
- def dup_for_full_unlock
1157
- unlocked_definition = self.class.new(@lockfile, @dependencies, @sources, true, @ruby_version, @optional_groups, @gemfiles)
1158
- unlocked_definition.source_requirements = source_requirements
1159
- unlocked_definition.gem_version_promoter.tap do |gvp|
1160
- gvp.level = gem_version_promoter.level
1161
- gvp.strict = gem_version_promoter.strict
1162
- gvp.pre = gem_version_promoter.pre
1163
- end
1164
- unlocked_definition
1165
- end
1166
-
1167
1177
  def remove_invalid_platforms!
1168
1178
  return if Bundler.frozen_bundle?
1169
1179
 
@@ -1182,5 +1192,22 @@ module Bundler
1182
1192
  def source_map
1183
1193
  @source_map ||= SourceMap.new(sources, dependencies, @locked_specs)
1184
1194
  end
1195
+
1196
+ def new_resolver_for_full_update
1197
+ new_resolver(unlocked_resolution_base)
1198
+ end
1199
+
1200
+ def unlocked_resolution_base
1201
+ new_resolution_base(last_resolve: SpecSet.new([]), unlock: true)
1202
+ end
1203
+
1204
+ def new_resolution_base(last_resolve:, unlock:)
1205
+ new_resolution_platforms = @current_platform_missing ? @new_platforms + [Bundler.local_platform] : @new_platforms
1206
+ Resolver::Base.new(source_requirements, expanded_dependencies, last_resolve, @platforms, locked_specs: @originally_locked_specs, unlock: unlock, prerelease: gem_version_promoter.pre?, prefer_local: @prefer_local, new_platforms: new_resolution_platforms)
1207
+ end
1208
+
1209
+ def new_resolver(base)
1210
+ Resolver.new(base, gem_version_promoter, @most_specific_locked_platform)
1211
+ end
1185
1212
  end
1186
1213
  end
@@ -1,69 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "shared_helpers"
4
- Bundler::SharedHelpers.major_deprecation 2, "Bundler no longer integrates with " \
4
+ Bundler::SharedHelpers.feature_removed! "Bundler no longer integrates with " \
5
5
  "Capistrano, but Capistrano provides its own integration with " \
6
6
  "Bundler via the capistrano-bundler gem. Use it instead."
7
-
8
- module Bundler
9
- class Deployment
10
- def self.define_task(context, task_method = :task, opts = {})
11
- if defined?(Capistrano) && context.is_a?(Capistrano::Configuration)
12
- context_name = "capistrano"
13
- role_default = "{:except => {:no_release => true}}"
14
- error_type = ::Capistrano::CommandError
15
- else
16
- context_name = "vlad"
17
- role_default = "[:app]"
18
- error_type = ::Rake::CommandFailedError
19
- end
20
-
21
- roles = context.fetch(:bundle_roles, false)
22
- opts[:roles] = roles if roles
23
-
24
- context.send :namespace, :bundle do
25
- send :desc, <<-DESC
26
- Install the current Bundler environment. By default, gems will be \
27
- installed to the shared/bundle path. Gems in the development and \
28
- test group will not be installed. The install command is executed \
29
- with the --deployment and --quiet flags. If the bundle cmd cannot \
30
- be found then you can override the bundle_cmd variable to specify \
31
- which one it should use. The base path to the app is fetched from \
32
- the :latest_release variable. Set it for custom deploy layouts.
33
-
34
- You can override any of these defaults by setting the variables shown below.
35
-
36
- N.B. bundle_roles must be defined before you require 'bundler/#{context_name}' \
37
- in your deploy.rb file.
38
-
39
- set :bundle_gemfile, "Gemfile"
40
- set :bundle_dir, File.join(fetch(:shared_path), 'bundle')
41
- set :bundle_flags, "--deployment --quiet"
42
- set :bundle_without, [:development, :test]
43
- set :bundle_with, [:mysql]
44
- set :bundle_cmd, "bundle" # e.g. "/opt/ruby/bin/bundle"
45
- set :bundle_roles, #{role_default} # e.g. [:app, :batch]
46
- DESC
47
- send task_method, :install, opts do
48
- bundle_cmd = context.fetch(:bundle_cmd, "bundle")
49
- bundle_flags = context.fetch(:bundle_flags, "--deployment --quiet")
50
- bundle_dir = context.fetch(:bundle_dir, File.join(context.fetch(:shared_path), "bundle"))
51
- bundle_gemfile = context.fetch(:bundle_gemfile, "Gemfile")
52
- bundle_without = [*context.fetch(:bundle_without, [:development, :test])].compact
53
- bundle_with = [*context.fetch(:bundle_with, [])].compact
54
- app_path = context.fetch(:latest_release)
55
- if app_path.to_s.empty?
56
- raise error_type.new("Cannot detect current release path - make sure you have deployed at least once.")
57
- end
58
- args = ["--gemfile #{File.join(app_path, bundle_gemfile)}"]
59
- args << "--path #{bundle_dir}" unless bundle_dir.to_s.empty?
60
- args << bundle_flags.to_s
61
- args << "--without #{bundle_without.join(" ")}" unless bundle_without.empty?
62
- args << "--with #{bundle_with.join(" ")}" unless bundle_with.empty?
63
-
64
- run "cd #{app_path} && #{bundle_cmd} install #{args.join(" ")}"
65
- end
66
- end
67
- end
68
- end
69
- end
@@ -26,7 +26,7 @@ module Bundler
26
26
  end
27
27
  a, b, c, d, e = *words
28
28
  (16..79).each do |i|
29
- w[i] = SHA1_MASK & rotate((w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16]), 1)
29
+ w[i] = SHA1_MASK & rotate(w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16], 1)
30
30
  end
31
31
  0.upto(79) do |i|
32
32
  case i
data/lib/bundler/dsl.rb CHANGED
@@ -290,7 +290,7 @@ module Bundler
290
290
  @dependencies.delete(current)
291
291
  elsif dep.gemspec_dev_dep?
292
292
  return
293
- elsif current.source != dep.source
293
+ elsif current.source.to_s != dep.source.to_s
294
294
  raise GemfileError, "You cannot specify the same gem twice coming from different sources.\n" \
295
295
  "You specified that #{name} (#{dep.requirement}) should come from " \
296
296
  "#{current.source || "an unspecified source"} and #{dep.source}\n"
@@ -411,7 +411,13 @@ module Bundler
411
411
  next if VALID_PLATFORMS.include?(p)
412
412
  raise GemfileError, "`#{p}` is not a valid platform. The available options are: #{VALID_PLATFORMS.inspect}"
413
413
  end
414
- deprecate_legacy_windows_platforms(platforms)
414
+
415
+ windows_platforms = platforms.select {|pl| pl.to_s.match?(/mingw|mswin/) }
416
+ if windows_platforms.any?
417
+ windows_platforms = windows_platforms.map! {|pl| ":#{pl}" }.join(", ")
418
+ removed_message = "Platform #{windows_platforms} has been removed. Please use platform :windows instead."
419
+ Bundler::SharedHelpers.feature_removed! removed_message
420
+ end
415
421
 
416
422
  # Save sources passed in a key
417
423
  if opts.key?("source")
@@ -477,14 +483,10 @@ module Bundler
477
483
  def normalize_source(source)
478
484
  case source
479
485
  when :gemcutter, :rubygems, :rubyforge
480
- message =
481
- "The source :#{source} is deprecated because HTTP requests are insecure.\n" \
482
- "Please change your source to 'https://rubygems.org' if possible, or 'http://rubygems.org' if not."
483
486
  removed_message =
484
487
  "The source :#{source} is disallowed because HTTP requests are insecure.\n" \
485
488
  "Please change your source to 'https://rubygems.org' if possible, or 'http://rubygems.org' if not."
486
- Bundler::SharedHelpers.major_deprecation 2, message, removed_message: removed_message
487
- "http://rubygems.org"
489
+ Bundler::SharedHelpers.feature_removed! removed_message
488
490
  when String
489
491
  source
490
492
  else
@@ -492,16 +494,6 @@ module Bundler
492
494
  end
493
495
  end
494
496
 
495
- def deprecate_legacy_windows_platforms(platforms)
496
- windows_platforms = platforms.select {|pl| pl.to_s.match?(/mingw|mswin/) }
497
- return if windows_platforms.empty?
498
-
499
- windows_platforms = windows_platforms.map! {|pl| ":#{pl}" }.join(", ")
500
- message = "Platform #{windows_platforms} is deprecated. Please use platform :windows instead."
501
- removed_message = "Platform #{windows_platforms} has been removed. Please use platform :windows instead."
502
- Bundler::SharedHelpers.major_deprecation 2, message, removed_message: removed_message
503
- end
504
-
505
497
  def check_path_source_safety
506
498
  return if @sources.global_path_source.nil?
507
499
 
@@ -513,7 +505,7 @@ module Bundler
513
505
  " gem 'rails'\n" \
514
506
  " end\n\n"
515
507
 
516
- SharedHelpers.major_deprecation(2, msg.strip)
508
+ SharedHelpers.feature_removed! msg.strip
517
509
  end
518
510
 
519
511
  def check_rubygems_source_safety
@@ -521,24 +513,10 @@ module Bundler
521
513
  end
522
514
 
523
515
  def multiple_global_source_warning
524
- if Bundler.feature_flag.bundler_4_mode?
525
- msg = "This Gemfile contains multiple global sources. " \
526
- "Each source after the first must include a block to indicate which gems " \
527
- "should come from that source"
528
- raise GemfileEvalError, msg
529
- else
530
- message =
531
- "Your Gemfile contains multiple global sources. " \
532
- "Using `source` more than once without a block is a security risk, and " \
533
- "may result in installing unexpected gems. To resolve this warning, use " \
534
- "a block to indicate which gems should come from the secondary source."
535
- removed_message =
536
- "Your Gemfile contains multiple global sources. " \
537
- "Using `source` more than once without a block is a security risk, and " \
538
- "may result in installing unexpected gems. To resolve this error, use " \
539
- "a block to indicate which gems should come from the secondary source."
540
- Bundler::SharedHelpers.major_deprecation 2, message, removed_message: removed_message
541
- end
516
+ msg = "This Gemfile contains multiple global sources. " \
517
+ "Each source after the first must include a block to indicate which gems " \
518
+ "should come from that source"
519
+ raise GemfileEvalError, msg
542
520
  end
543
521
 
544
522
  class DSLError < GemfileError
@@ -60,28 +60,6 @@ module Bundler
60
60
  end
61
61
  end
62
62
 
63
- # needed for binstubs
64
- def executables
65
- if @remote_specification
66
- @remote_specification.executables
67
- elsif _local_specification
68
- _local_specification.executables
69
- else
70
- super
71
- end
72
- end
73
-
74
- # needed for bundle clean
75
- def bindir
76
- if @remote_specification
77
- @remote_specification.bindir
78
- elsif _local_specification
79
- _local_specification.bindir
80
- else
81
- super
82
- end
83
- end
84
-
85
63
  # needed for post_install_messages during install
86
64
  def post_install_message
87
65
  if @remote_specification
@@ -25,6 +25,7 @@ module Bundler
25
25
 
26
26
  class GemNotFound < BundlerError; status_code(7); end
27
27
  class InstallHookError < BundlerError; status_code(8); end
28
+ class RemovedError < BundlerError; status_code(9); end
28
29
  class GemfileNotFound < BundlerError; status_code(10); end
29
30
  class GitError < BundlerError; status_code(11); end
30
31
  class DeprecatedError < BundlerError; status_code(12); end
@@ -76,11 +77,6 @@ module Bundler
76
77
  def mismatch_resolution_instructions
77
78
  removable, remote = [@existing, @checksum].partition(&:removable?)
78
79
  case removable.size
79
- when 0
80
- msg = +"Mismatched checksums each have an authoritative source:\n"
81
- msg << " 1. #{@existing.sources.reject(&:removable?).map(&:to_s).join(" and ")}\n"
82
- msg << " 2. #{@checksum.sources.reject(&:removable?).map(&:to_s).join(" and ")}\n"
83
- msg << "You may need to alter your Gemfile sources to resolve this issue.\n"
84
80
  when 1
85
81
  msg = +"If you trust #{remote.first.sources.first}, to resolve this issue you can:\n"
86
82
  msg << removable.first.removal_instructions