bundler 2.1.4 → 2.2.18

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of bundler might be problematic. Click here for more details.

Files changed (227) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1790 -1430
  3. data/README.md +6 -8
  4. data/bundler.gemspec +5 -6
  5. data/exe/bundle +3 -0
  6. data/lib/bundler/build_metadata.rb +3 -11
  7. data/lib/bundler/cli/add.rb +1 -1
  8. data/lib/bundler/cli/binstubs.rb +6 -2
  9. data/lib/bundler/cli/cache.rb +2 -7
  10. data/lib/bundler/cli/clean.rb +1 -1
  11. data/lib/bundler/cli/common.rb +29 -2
  12. data/lib/bundler/cli/console.rb +1 -1
  13. data/lib/bundler/cli/doctor.rb +1 -1
  14. data/lib/bundler/cli/exec.rb +4 -4
  15. data/lib/bundler/cli/fund.rb +36 -0
  16. data/lib/bundler/cli/gem.rb +129 -28
  17. data/lib/bundler/cli/info.rb +15 -4
  18. data/lib/bundler/cli/init.rb +2 -2
  19. data/lib/bundler/cli/inject.rb +1 -1
  20. data/lib/bundler/cli/install.rb +13 -11
  21. data/lib/bundler/cli/issue.rb +2 -2
  22. data/lib/bundler/cli/list.rb +12 -10
  23. data/lib/bundler/cli/outdated.rb +94 -76
  24. data/lib/bundler/cli/plugin.rb +10 -0
  25. data/lib/bundler/cli/pristine.rb +5 -0
  26. data/lib/bundler/cli/show.rb +1 -1
  27. data/lib/bundler/cli/update.rb +3 -1
  28. data/lib/bundler/cli.rb +72 -56
  29. data/lib/bundler/compact_index_client/cache.rb +6 -14
  30. data/lib/bundler/compact_index_client/gem_parser.rb +28 -0
  31. data/lib/bundler/compact_index_client/updater.rb +13 -17
  32. data/lib/bundler/compact_index_client.rb +1 -1
  33. data/lib/bundler/current_ruby.rb +1 -0
  34. data/lib/bundler/definition.rb +117 -188
  35. data/lib/bundler/dep_proxy.rb +16 -9
  36. data/lib/bundler/dependency.rb +3 -10
  37. data/lib/bundler/dsl.rb +40 -33
  38. data/lib/bundler/endpoint_specification.rb +1 -1
  39. data/lib/bundler/env.rb +1 -1
  40. data/lib/bundler/environment_preserver.rb +26 -2
  41. data/lib/bundler/errors.rb +1 -0
  42. data/lib/bundler/feature_flag.rb +0 -6
  43. data/lib/bundler/fetcher/base.rb +1 -1
  44. data/lib/bundler/fetcher/compact_index.rb +1 -1
  45. data/lib/bundler/fetcher/downloader.rb +9 -5
  46. data/lib/bundler/fetcher/index.rb +3 -4
  47. data/lib/bundler/fetcher.rb +5 -4
  48. data/lib/bundler/friendly_errors.rb +22 -13
  49. data/lib/bundler/gem_helper.rb +51 -18
  50. data/lib/bundler/gem_helpers.rb +36 -25
  51. data/lib/bundler/gem_version_promoter.rb +4 -4
  52. data/lib/bundler/graph.rb +1 -1
  53. data/lib/bundler/index.rb +13 -9
  54. data/lib/bundler/injector.rb +23 -5
  55. data/lib/bundler/inline.rb +3 -2
  56. data/lib/bundler/installer/gem_installer.rb +3 -3
  57. data/lib/bundler/installer/parallel_installer.rb +46 -25
  58. data/lib/bundler/installer/standalone.rb +17 -2
  59. data/lib/bundler/installer.rb +37 -49
  60. data/lib/bundler/lazy_specification.rb +45 -25
  61. data/lib/bundler/lockfile_generator.rb +1 -1
  62. data/lib/bundler/lockfile_parser.rb +4 -14
  63. data/lib/bundler/man/.document +1 -0
  64. data/{man → lib/bundler/man}/bundle-add.1 +1 -1
  65. data/{man/bundle-add.ronn → lib/bundler/man/bundle-add.1.ronn} +0 -0
  66. data/{man → lib/bundler/man}/bundle-binstubs.1 +5 -3
  67. data/{man/bundle-binstubs.ronn → lib/bundler/man/bundle-binstubs.1.ronn} +2 -4
  68. data/{man → lib/bundler/man}/bundle-cache.1 +1 -1
  69. data/{man/bundle-cache.ronn → lib/bundler/man/bundle-cache.1.ronn} +0 -0
  70. data/{man → lib/bundler/man}/bundle-check.1 +1 -1
  71. data/{man/bundle-check.ronn → lib/bundler/man/bundle-check.1.ronn} +0 -0
  72. data/{man → lib/bundler/man}/bundle-clean.1 +1 -1
  73. data/{man/bundle-clean.ronn → lib/bundler/man/bundle-clean.1.ronn} +0 -0
  74. data/{man → lib/bundler/man}/bundle-config.1 +40 -38
  75. data/{man/bundle-config.ronn → lib/bundler/man/bundle-config.1.ronn} +50 -50
  76. data/{man → lib/bundler/man}/bundle-doctor.1 +1 -1
  77. data/{man/bundle-doctor.ronn → lib/bundler/man/bundle-doctor.1.ronn} +0 -0
  78. data/{man → lib/bundler/man}/bundle-exec.1 +1 -1
  79. data/{man/bundle-exec.ronn → lib/bundler/man/bundle-exec.1.ronn} +0 -0
  80. data/{man → lib/bundler/man}/bundle-gem.1 +25 -3
  81. data/{man/bundle-gem.ronn → lib/bundler/man/bundle-gem.1.ronn} +30 -7
  82. data/{man → lib/bundler/man}/bundle-info.1 +1 -1
  83. data/{man/bundle-info.ronn → lib/bundler/man/bundle-info.1.ronn} +0 -0
  84. data/{man → lib/bundler/man}/bundle-init.1 +1 -1
  85. data/{man/bundle-init.ronn → lib/bundler/man/bundle-init.1.ronn} +0 -0
  86. data/{man → lib/bundler/man}/bundle-inject.1 +1 -1
  87. data/{man/bundle-inject.ronn → lib/bundler/man/bundle-inject.1.ronn} +0 -0
  88. data/{man → lib/bundler/man}/bundle-install.1 +30 -3
  89. data/{man/bundle-install.ronn → lib/bundler/man/bundle-install.1.ronn} +25 -3
  90. data/{man → lib/bundler/man}/bundle-list.1 +7 -7
  91. data/{man/bundle-list.ronn → lib/bundler/man/bundle-list.1.ronn} +6 -6
  92. data/{man → lib/bundler/man}/bundle-lock.1 +1 -1
  93. data/{man/bundle-lock.ronn → lib/bundler/man/bundle-lock.1.ronn} +0 -0
  94. data/{man → lib/bundler/man}/bundle-open.1 +1 -1
  95. data/{man/bundle-open.ronn → lib/bundler/man/bundle-open.1.ronn} +0 -0
  96. data/{man → lib/bundler/man}/bundle-outdated.1 +1 -1
  97. data/{man/bundle-outdated.ronn → lib/bundler/man/bundle-outdated.1.ronn} +0 -0
  98. data/{man → lib/bundler/man}/bundle-platform.1 +1 -1
  99. data/{man/bundle-platform.ronn → lib/bundler/man/bundle-platform.1.ronn} +0 -0
  100. data/{man → lib/bundler/man}/bundle-pristine.1 +1 -1
  101. data/{man/bundle-pristine.ronn → lib/bundler/man/bundle-pristine.1.ronn} +0 -0
  102. data/{man → lib/bundler/man}/bundle-remove.1 +1 -1
  103. data/{man/bundle-remove.ronn → lib/bundler/man/bundle-remove.1.ronn} +0 -0
  104. data/{man → lib/bundler/man}/bundle-show.1 +1 -1
  105. data/{man/bundle-show.ronn → lib/bundler/man/bundle-show.1.ronn} +0 -0
  106. data/{man → lib/bundler/man}/bundle-update.1 +1 -1
  107. data/{man/bundle-update.ronn → lib/bundler/man/bundle-update.1.ronn} +0 -0
  108. data/{man → lib/bundler/man}/bundle-viz.1 +1 -1
  109. data/{man/bundle-viz.ronn → lib/bundler/man/bundle-viz.1.ronn} +0 -0
  110. data/{man → lib/bundler/man}/bundle.1 +1 -1
  111. data/{man/bundle.ronn → lib/bundler/man/bundle.1.ronn} +0 -0
  112. data/{man → lib/bundler/man}/gemfile.5 +4 -4
  113. data/{man → lib/bundler/man}/gemfile.5.ronn +4 -4
  114. data/{man → lib/bundler/man}/index.txt +0 -0
  115. data/lib/bundler/mirror.rb +2 -2
  116. data/lib/bundler/plugin/api/source.rb +22 -1
  117. data/lib/bundler/plugin/dsl.rb +1 -1
  118. data/lib/bundler/plugin/index.rb +10 -1
  119. data/lib/bundler/plugin/installer/rubygems.rb +1 -1
  120. data/lib/bundler/plugin/installer.rb +9 -11
  121. data/lib/bundler/plugin/source_list.rb +5 -1
  122. data/lib/bundler/plugin.rb +33 -7
  123. data/lib/bundler/psyched_yaml.rb +0 -15
  124. data/lib/bundler/remote_specification.rb +5 -2
  125. data/lib/bundler/resolver/spec_group.rb +56 -53
  126. data/lib/bundler/resolver.rb +88 -115
  127. data/lib/bundler/retry.rb +2 -2
  128. data/lib/bundler/ruby_version.rb +1 -1
  129. data/lib/bundler/rubygems_ext.rb +71 -11
  130. data/lib/bundler/rubygems_gem_installer.rb +50 -9
  131. data/lib/bundler/rubygems_integration.rb +25 -60
  132. data/lib/bundler/runtime.rb +4 -14
  133. data/lib/bundler/settings.rb +107 -55
  134. data/lib/bundler/shared_helpers.rb +3 -3
  135. data/lib/bundler/similarity_detector.rb +1 -1
  136. data/lib/bundler/source/git/git_proxy.rb +82 -80
  137. data/lib/bundler/source/git.rb +24 -22
  138. data/lib/bundler/source/metadata.rb +0 -4
  139. data/lib/bundler/source/path/installer.rb +10 -10
  140. data/lib/bundler/source/path.rb +10 -4
  141. data/lib/bundler/source/rubygems/remote.rb +1 -1
  142. data/lib/bundler/source/rubygems.rb +60 -28
  143. data/lib/bundler/source/rubygems_aggregate.rb +64 -0
  144. data/lib/bundler/source.rb +16 -1
  145. data/lib/bundler/source_list.rb +52 -28
  146. data/lib/bundler/source_map.rb +58 -0
  147. data/lib/bundler/spec_set.rb +29 -17
  148. data/lib/bundler/stub_specification.rb +25 -7
  149. data/lib/bundler/templates/Gemfile +1 -1
  150. data/lib/bundler/templates/gems.rb +1 -1
  151. data/lib/bundler/templates/newgem/CHANGELOG.md.tt +5 -0
  152. data/lib/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt +57 -47
  153. data/lib/bundler/templates/newgem/Gemfile.tt +9 -1
  154. data/lib/bundler/templates/newgem/README.md.tt +6 -5
  155. data/lib/bundler/templates/newgem/Rakefile.tt +19 -5
  156. data/lib/bundler/templates/newgem/bin/console.tt +1 -0
  157. data/lib/bundler/templates/newgem/circleci/config.yml.tt +13 -0
  158. data/lib/bundler/templates/newgem/ext/newgem/extconf.rb.tt +2 -0
  159. data/lib/bundler/templates/newgem/github/workflows/main.yml.tt +16 -0
  160. data/lib/bundler/templates/newgem/gitlab-ci.yml.tt +9 -0
  161. data/lib/bundler/templates/newgem/lib/newgem/version.rb.tt +2 -0
  162. data/lib/bundler/templates/newgem/lib/newgem.rb.tt +4 -2
  163. data/lib/bundler/templates/newgem/newgem.gemspec.tt +15 -7
  164. data/lib/bundler/templates/newgem/rubocop.yml.tt +13 -0
  165. data/lib/bundler/templates/newgem/spec/newgem_spec.rb.tt +2 -0
  166. data/lib/bundler/templates/newgem/spec/spec_helper.rb.tt +2 -1
  167. data/lib/bundler/templates/newgem/test/{newgem_test.rb.tt → minitest/newgem_test.rb.tt} +2 -0
  168. data/lib/bundler/templates/newgem/test/{test_helper.rb.tt → minitest/test_helper.rb.tt} +2 -0
  169. data/lib/bundler/templates/newgem/test/test-unit/newgem_test.rb.tt +15 -0
  170. data/lib/bundler/templates/newgem/test/test-unit/test_helper.rb.tt +6 -0
  171. data/lib/bundler/ui/shell.rb +5 -5
  172. data/lib/bundler/uri_credentials_filter.rb +3 -1
  173. data/lib/bundler/vendor/molinillo/lib/molinillo/delegates/specification_provider.rb +7 -0
  174. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/tag.rb +2 -2
  175. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb +11 -5
  176. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb +34 -2
  177. data/lib/bundler/vendor/molinillo/lib/molinillo/errors.rb +3 -3
  178. data/lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb +1 -1
  179. data/lib/bundler/vendor/molinillo/lib/molinillo/modules/specification_provider.rb +12 -1
  180. data/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb +49 -47
  181. data/lib/bundler/vendor/molinillo/lib/molinillo.rb +0 -1
  182. data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb +82 -189
  183. data/lib/bundler/vendor/thor/lib/thor/actions/create_link.rb +2 -1
  184. data/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb +4 -2
  185. data/lib/bundler/vendor/thor/lib/thor/actions.rb +1 -1
  186. data/lib/bundler/vendor/thor/lib/thor/base.rb +9 -0
  187. data/lib/bundler/vendor/thor/lib/thor/error.rb +1 -1
  188. data/lib/bundler/vendor/thor/lib/thor/parser/arguments.rb +5 -1
  189. data/lib/bundler/vendor/thor/lib/thor/parser/options.rb +9 -8
  190. data/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +5 -2
  191. data/lib/bundler/vendor/thor/lib/thor/shell/color.rb +5 -1
  192. data/lib/bundler/vendor/thor/lib/thor/version.rb +1 -1
  193. data/lib/bundler/vendor/thor/lib/thor.rb +5 -13
  194. data/lib/bundler/vendor/tmpdir/lib/tmpdir.rb +154 -0
  195. data/lib/bundler/vendored_persistent.rb +0 -7
  196. data/lib/bundler/vendored_tmpdir.rb +4 -0
  197. data/lib/bundler/version.rb +1 -1
  198. data/lib/bundler/worker.rb +1 -1
  199. data/lib/bundler/yaml_serializer.rb +1 -1
  200. data/lib/bundler.rb +34 -9
  201. metadata +77 -86
  202. data/lib/bundler/vendor/molinillo/lib/molinillo/compatibility.rb +0 -26
  203. data/man/bundle-add.1.txt +0 -58
  204. data/man/bundle-binstubs.1.txt +0 -48
  205. data/man/bundle-cache.1.txt +0 -78
  206. data/man/bundle-check.1.txt +0 -33
  207. data/man/bundle-clean.1.txt +0 -26
  208. data/man/bundle-config.1.txt +0 -528
  209. data/man/bundle-doctor.1.txt +0 -44
  210. data/man/bundle-exec.1.txt +0 -178
  211. data/man/bundle-gem.1.txt +0 -91
  212. data/man/bundle-info.1.txt +0 -21
  213. data/man/bundle-init.1.txt +0 -34
  214. data/man/bundle-inject.1.txt +0 -32
  215. data/man/bundle-install.1.txt +0 -401
  216. data/man/bundle-list.1.txt +0 -43
  217. data/man/bundle-lock.1.txt +0 -93
  218. data/man/bundle-open.1.txt +0 -29
  219. data/man/bundle-outdated.1.txt +0 -131
  220. data/man/bundle-platform.1.txt +0 -57
  221. data/man/bundle-pristine.1.txt +0 -44
  222. data/man/bundle-remove.1.txt +0 -34
  223. data/man/bundle-show.1.txt +0 -27
  224. data/man/bundle-update.1.txt +0 -390
  225. data/man/bundle-viz.1.txt +0 -39
  226. data/man/bundle.1.txt +0 -116
  227. data/man/gemfile.5.txt +0 -649
@@ -3,61 +3,58 @@
3
3
  module Bundler
4
4
  class Resolver
5
5
  class SpecGroup
6
- include GemHelpers
7
-
8
6
  attr_accessor :name, :version, :source
9
- attr_accessor :ignores_bundler_dependencies
7
+ attr_accessor :activated_platforms
8
+
9
+ def self.create_for(specs, all_platforms, specific_platform)
10
+ specific_platform_specs = specs[specific_platform]
11
+ return unless specific_platform_specs.any?
12
+
13
+ platforms = all_platforms.select {|p| specs[p].any? }
14
+
15
+ new(specific_platform_specs.first, specs, platforms)
16
+ end
10
17
 
11
- def initialize(all_specs)
12
- raise ArgumentError, "cannot initialize with an empty value" unless exemplary_spec = all_specs.first
18
+ def initialize(exemplary_spec, specs, relevant_platforms)
19
+ @exemplary_spec = exemplary_spec
13
20
  @name = exemplary_spec.name
14
21
  @version = exemplary_spec.version
15
22
  @source = exemplary_spec.source
16
23
 
17
- @activated_platforms = []
18
- @dependencies = nil
19
- @specs = Hash.new do |specs, platform|
20
- specs[platform] = select_best_platform_match(all_specs, platform)
24
+ @activated_platforms = relevant_platforms
25
+ @dependencies = Hash.new do |dependencies, platforms|
26
+ dependencies[platforms] = dependencies_for(platforms)
21
27
  end
22
- @ignores_bundler_dependencies = true
28
+ @specs = specs
23
29
  end
24
30
 
25
31
  def to_specs
26
- @activated_platforms.map do |p|
27
- next unless s = @specs[p]
28
- lazy_spec = LazySpecification.new(name, version, s.platform, source)
29
- lazy_spec.dependencies.replace s.dependencies
30
- lazy_spec
31
- end.compact
32
- end
33
-
34
- def activate_platform!(platform)
35
- return unless for?(platform)
36
- return if @activated_platforms.include?(platform)
37
- @activated_platforms << platform
38
- end
32
+ activated_platforms.map do |p|
33
+ specs = @specs[p]
34
+ next unless specs.any?
39
35
 
40
- def for?(platform)
41
- spec = @specs[platform]
42
- !spec.nil?
36
+ specs.map do |s|
37
+ lazy_spec = LazySpecification.new(name, version, s.platform, source)
38
+ lazy_spec.dependencies.replace s.dependencies
39
+ lazy_spec
40
+ end
41
+ end.flatten.compact.uniq
43
42
  end
44
43
 
45
44
  def to_s
46
- @to_s ||= "#{name} (#{version})"
45
+ activated_platforms_string = sorted_activated_platforms.join(", ")
46
+ "#{name} (#{version}) (#{activated_platforms_string})"
47
47
  end
48
48
 
49
49
  def dependencies_for_activated_platforms
50
- dependencies = @activated_platforms.map {|p| __dependencies[p] }
51
- metadata_dependencies = @activated_platforms.map do |platform|
52
- metadata_dependencies(@specs[platform], platform)
53
- end
54
- dependencies.concat(metadata_dependencies).flatten
50
+ @dependencies[activated_platforms]
55
51
  end
56
52
 
57
53
  def ==(other)
58
54
  return unless other.is_a?(SpecGroup)
59
55
  name == other.name &&
60
56
  version == other.version &&
57
+ sorted_activated_platforms == other.sorted_activated_platforms &&
61
58
  source == other.source
62
59
  end
63
60
 
@@ -65,40 +62,46 @@ module Bundler
65
62
  return unless other.is_a?(SpecGroup)
66
63
  name.eql?(other.name) &&
67
64
  version.eql?(other.version) &&
65
+ sorted_activated_platforms.eql?(other.sorted_activated_platforms) &&
68
66
  source.eql?(other.source)
69
67
  end
70
68
 
71
69
  def hash
72
- to_s.hash ^ source.hash
70
+ name.hash ^ version.hash ^ sorted_activated_platforms.hash ^ source.hash
73
71
  end
74
72
 
75
- private
76
-
77
- def __dependencies
78
- @dependencies = Hash.new do |dependencies, platform|
79
- dependencies[platform] = []
80
- if spec = @specs[platform]
81
- spec.dependencies.each do |dep|
82
- next if dep.type == :development
83
- next if @ignores_bundler_dependencies && dep.name == "bundler".freeze
84
- dependencies[platform] << DepProxy.new(dep, platform)
85
- end
86
- end
87
- dependencies[platform]
73
+ protected
74
+
75
+ def sorted_activated_platforms
76
+ activated_platforms.sort_by(&:to_s)
77
+ end
78
+
79
+ private
80
+
81
+ def dependencies_for(platforms)
82
+ platforms.map do |platform|
83
+ __dependencies(platform) + metadata_dependencies(platform)
84
+ end.flatten
85
+ end
86
+
87
+ def __dependencies(platform)
88
+ dependencies = []
89
+ @specs[platform].first.dependencies.each do |dep|
90
+ next if dep.type == :development
91
+ dependencies << DepProxy.get_proxy(dep, platform)
88
92
  end
93
+ dependencies
89
94
  end
90
95
 
91
- def metadata_dependencies(spec, platform)
92
- return [] unless spec
93
- # Only allow endpoint specifications since they won't hit the network to
94
- # fetch the full gemspec when calling required_ruby_version
95
- return [] if !spec.is_a?(EndpointSpecification) && !spec.is_a?(Gem::Specification)
96
+ def metadata_dependencies(platform)
97
+ spec = @specs[platform].first
98
+ return [] unless spec.is_a?(Gem::Specification)
96
99
  dependencies = []
97
100
  if !spec.required_ruby_version.nil? && !spec.required_ruby_version.none?
98
- dependencies << DepProxy.new(Gem::Dependency.new("Ruby\0", spec.required_ruby_version), platform)
101
+ dependencies << DepProxy.get_proxy(Gem::Dependency.new("Ruby\0", spec.required_ruby_version), platform)
99
102
  end
100
103
  if !spec.required_rubygems_version.nil? && !spec.required_rubygems_version.none?
101
- dependencies << DepProxy.new(Gem::Dependency.new("RubyGems\0", spec.required_rubygems_version), platform)
104
+ dependencies << DepProxy.get_proxy(Gem::Dependency.new("RubyGems\0", spec.required_rubygems_version), platform)
102
105
  end
103
106
  dependencies
104
107
  end
@@ -5,6 +5,8 @@ module Bundler
5
5
  require_relative "vendored_molinillo"
6
6
  require_relative "resolver/spec_group"
7
7
 
8
+ include GemHelpers
9
+
8
10
  # Figures out the best possible configuration of gems that satisfies
9
11
  # the list of passed dependencies and any child dependencies without
10
12
  # causing any gem activation errors.
@@ -15,16 +17,14 @@ module Bundler
15
17
  # ==== Returns
16
18
  # <GemBundle>,nil:: If the list of dependencies can be resolved, a
17
19
  # collection of gemspecs is returned. Otherwise, nil is returned.
18
- def self.resolve(requirements, index, source_requirements = {}, base = [], gem_version_promoter = GemVersionPromoter.new, additional_base_requirements = [], platforms = nil)
19
- platforms = Set.new(platforms) if platforms
20
+ def self.resolve(requirements, source_requirements = {}, base = [], gem_version_promoter = GemVersionPromoter.new, additional_base_requirements = [], platforms = nil)
20
21
  base = SpecSet.new(base) unless base.is_a?(SpecSet)
21
- resolver = new(index, source_requirements, base, gem_version_promoter, additional_base_requirements, platforms)
22
+ resolver = new(source_requirements, base, gem_version_promoter, additional_base_requirements, platforms)
22
23
  result = resolver.start(requirements)
23
- SpecSet.new(result)
24
+ SpecSet.new(result).for(requirements.reject{|dep| dep.name.end_with?("\0") })
24
25
  end
25
26
 
26
- def initialize(index, source_requirements, base, gem_version_promoter, additional_base_requirements, platforms)
27
- @index = index
27
+ def initialize(source_requirements, base, gem_version_promoter, additional_base_requirements, platforms)
28
28
  @source_requirements = source_requirements
29
29
  @base = base
30
30
  @resolver = Molinillo::Resolver.new(self, self)
@@ -32,14 +32,13 @@ module Bundler
32
32
  @base_dg = Molinillo::DependencyGraph.new
33
33
  @base.each do |ls|
34
34
  dep = Dependency.new(ls.name, ls.version)
35
- @base_dg.add_vertex(ls.name, DepProxy.new(dep, ls.platform), true)
35
+ @base_dg.add_vertex(ls.name, DepProxy.get_proxy(dep, ls.platform), true)
36
36
  end
37
37
  additional_base_requirements.each {|d| @base_dg.add_vertex(d.name, d) }
38
- @platforms = platforms
38
+ @platforms = platforms.reject {|p| p != Gem::Platform::RUBY && (platforms - [p]).any? {|pl| generic(pl) == p } }
39
+ @resolving_only_for_ruby = platforms == [Gem::Platform::RUBY]
39
40
  @gem_version_promoter = gem_version_promoter
40
- @allow_bundler_dependency_conflicts = Bundler.feature_flag.allow_bundler_dependency_conflicts?
41
41
  @use_gvp = Bundler.feature_flag.use_gem_version_promoter_for_major_updates? || !@gem_version_promoter.major?
42
- @lockfile_uses_separate_rubygems_sources = Bundler.feature_flag.disable_multisource?
43
42
  end
44
43
 
45
44
  def start(requirements)
@@ -49,7 +48,6 @@ module Bundler
49
48
  verify_gemfile_dependencies_are_found!(requirements)
50
49
  dg = @resolver.resolve(requirements, @base_dg)
51
50
  dg.
52
- tap {|resolved| validate_resolved_specs!(resolved) }.
53
51
  map(&:payload).
54
52
  reject {|sg| sg.name.end_with?("\0") }.
55
53
  map(&:to_specs).
@@ -75,12 +73,17 @@ module Bundler
75
73
  return unless debug?
76
74
  debug_info = yield
77
75
  debug_info = debug_info.inspect unless debug_info.is_a?(String)
78
- warn debug_info.split("\n").map {|s| " " * depth + s }
76
+ puts debug_info.split("\n").map {|s| depth == 0 ? "BUNDLER: #{s}" : "BUNDLER(#{depth}): #{s}" }
79
77
  end
80
78
 
81
79
  def debug?
82
80
  return @debug_mode if defined?(@debug_mode)
83
- @debug_mode = ENV["DEBUG_RESOLVER"] || ENV["DEBUG_RESOLVER_TREE"] || false
81
+ @debug_mode =
82
+ ENV["BUNDLER_DEBUG_RESOLVER"] ||
83
+ ENV["BUNDLER_DEBUG_RESOLVER_TREE"] ||
84
+ ENV["DEBUG_RESOLVER"] ||
85
+ ENV["DEBUG_RESOLVER_TREE"] ||
86
+ false
84
87
  end
85
88
 
86
89
  def before_resolution
@@ -101,18 +104,18 @@ module Bundler
101
104
  specification.dependencies_for_activated_platforms
102
105
  end
103
106
 
104
- def search_for(dependency)
105
- platform = dependency.__platform
106
- dependency = dependency.dep unless dependency.is_a? Gem::Dependency
107
- search = @search_for[dependency] ||= begin
108
- index = index_for(dependency)
109
- results = index.search(dependency, @base[dependency.name])
107
+ def search_for(dependency_proxy)
108
+ platform = dependency_proxy.__platform
109
+ dependency = dependency_proxy.dep
110
+ name = dependency.name
111
+ @search_for[dependency_proxy] ||= begin
112
+ results = results_for(dependency, @base[name])
110
113
 
111
- if vertex = @base_dg.vertex_named(dependency.name)
114
+ if vertex = @base_dg.vertex_named(name)
112
115
  locked_requirement = vertex.payload.requirement
113
116
  end
114
117
 
115
- if !@prerelease_specified[dependency.name] && (!@use_gvp || locked_requirement.nil?)
118
+ if !@prerelease_specified[name] && (!@use_gvp || locked_requirement.nil?)
116
119
  # Move prereleases to the beginning of the list, so they're considered
117
120
  # last during resolution.
118
121
  pre, results = results.partition {|spec| spec.version.prerelease? }
@@ -131,9 +134,20 @@ module Bundler
131
134
  end
132
135
  nested.reduce([]) do |groups, (version, specs)|
133
136
  next groups if locked_requirement && !locked_requirement.satisfied_by?(version)
134
- spec_group = SpecGroup.new(specs)
135
- spec_group.ignores_bundler_dependencies = @allow_bundler_dependency_conflicts
136
- groups << spec_group
137
+
138
+ specs_by_platform = Hash.new do |current_specs, current_platform|
139
+ current_specs[current_platform] = select_best_platform_match(specs, current_platform)
140
+ end
141
+
142
+ spec_group_ruby = SpecGroup.create_for(specs_by_platform, [Gem::Platform::RUBY], Gem::Platform::RUBY)
143
+ groups << spec_group_ruby if spec_group_ruby
144
+
145
+ next groups if @resolving_only_for_ruby
146
+
147
+ spec_group = SpecGroup.create_for(specs_by_platform, @platforms, platform)
148
+ groups << spec_group if spec_group
149
+
150
+ groups
137
151
  end
138
152
  else
139
153
  []
@@ -146,24 +160,18 @@ module Bundler
146
160
  @gem_version_promoter.sort_versions(dependency, spec_groups)
147
161
  end
148
162
  end
149
- search.select {|sg| sg.for?(platform) }.each {|sg| sg.activate_platform!(platform) }
150
163
  end
151
164
 
152
165
  def index_for(dependency)
153
- source = @source_requirements[dependency.name]
154
- if source
155
- source.specs
156
- elsif @lockfile_uses_separate_rubygems_sources
157
- Index.build do |idx|
158
- if dependency.all_sources
159
- dependency.all_sources.each {|s| idx.add_source(s.specs) if s }
160
- else
161
- idx.add_source @source_requirements[:default].specs
162
- end
163
- end
164
- else
165
- @index
166
- end
166
+ source_for(dependency.name).specs
167
+ end
168
+
169
+ def source_for(name)
170
+ @source_requirements[name] || @source_requirements[:default]
171
+ end
172
+
173
+ def results_for(dependency, base)
174
+ index_for(dependency).search(dependency, base)
167
175
  end
168
176
 
169
177
  def name_for(dependency)
@@ -183,24 +191,15 @@ module Bundler
183
191
  end
184
192
 
185
193
  def requirement_satisfied_by?(requirement, activated, spec)
186
- return false unless requirement.matches_spec?(spec) || spec.source.is_a?(Source::Gemspec)
187
- spec.activate_platform!(requirement.__platform) if !@platforms || @platforms.include?(requirement.__platform)
188
- true
194
+ requirement.matches_spec?(spec) || spec.source.is_a?(Source::Gemspec)
189
195
  end
190
196
 
191
- def relevant_sources_for_vertex(vertex)
192
- if vertex.root?
193
- [@source_requirements[vertex.name]]
194
- elsif @lockfile_uses_separate_rubygems_sources
195
- vertex.recursive_predecessors.map do |v|
196
- @source_requirements[v.name]
197
- end << @source_requirements[:default]
198
- end
197
+ def dependencies_equal?(dependencies, other_dependencies)
198
+ dependencies.map(&:dep) == other_dependencies.map(&:dep)
199
199
  end
200
200
 
201
201
  def sort_dependencies(dependencies, activated, conflicts)
202
202
  dependencies.sort_by do |dependency|
203
- dependency.all_sources = relevant_sources_for_vertex(activated.vertex_named(dependency.name))
204
203
  name = name_for(dependency)
205
204
  vertex = activated.vertex_named(name)
206
205
  [
@@ -215,19 +214,13 @@ module Bundler
215
214
  end
216
215
  end
217
216
 
218
- # Sort platforms from most general to most specific
219
- def self.sort_platforms(platforms)
220
- platforms.sort_by do |platform|
221
- platform_sort_key(platform)
222
- end
223
- end
224
-
225
217
  def self.platform_sort_key(platform)
226
- return ["", "", ""] if Gem::Platform::RUBY == platform
227
- platform.to_a.map {|part| part || "" }
218
+ # Prefer specific platform to not specific platform
219
+ return ["99-LAST", "", "", ""] if Gem::Platform::RUBY == platform
220
+ ["00", *platform.to_a.map {|part| part || "" }]
228
221
  end
229
222
 
230
- private
223
+ private
231
224
 
232
225
  # returns an integer \in (-\infty, 0]
233
226
  # a number closer to 0 means the dependency is less constraining
@@ -275,16 +268,16 @@ module Bundler
275
268
  "If you are updating multiple gems in your Gemfile at once,\n" \
276
269
  "try passing them all to `bundle update`"
277
270
  elsif source = @source_requirements[name]
278
- specs = source.specs[name]
271
+ specs = source.specs.search(name)
279
272
  versions_with_platforms = specs.map {|s| [s.version, s.platform] }
280
273
  message = String.new("Could not find gem '#{SharedHelpers.pretty_dependency(requirement)}' in #{source}#{cache_message}.\n")
281
274
  message << if versions_with_platforms.any?
282
- "The source contains '#{name}' at: #{formatted_versions_with_platforms(versions_with_platforms)}"
275
+ "The source contains the following versions of '#{name}': #{formatted_versions_with_platforms(versions_with_platforms)}"
283
276
  else
284
277
  "The source does not contain any versions of '#{name}'"
285
278
  end
286
279
  else
287
- message = "Could not find gem '#{requirement}' in any of the gem sources " \
280
+ message = "Could not find gem '#{SharedHelpers.pretty_dependency(requirement)}' in any of the gem sources " \
288
281
  "listed in your Gemfile#{cache_message}."
289
282
  end
290
283
  raise GemNotFound, message
@@ -305,10 +298,16 @@ module Bundler
305
298
  def version_conflict_message(e)
306
299
  # only show essential conflicts, if possible
307
300
  conflicts = e.conflicts.dup
308
- conflicts.delete_if do |_name, conflict|
309
- deps = conflict.requirement_trees.map(&:last).flatten(1)
310
- !Bundler::VersionRanges.empty?(*Bundler::VersionRanges.for_many(deps.map(&:requirement)))
301
+
302
+ if conflicts["bundler"]
303
+ conflicts.replace("bundler" => conflicts["bundler"])
304
+ else
305
+ conflicts.delete_if do |_name, conflict|
306
+ deps = conflict.requirement_trees.map(&:last).flatten(1)
307
+ !Bundler::VersionRanges.empty?(*Bundler::VersionRanges.for_many(deps.map(&:requirement)))
308
+ end
311
309
  end
310
+
312
311
  e = Molinillo::VersionConflict.new(conflicts, e.specification_provider) unless conflicts.empty?
313
312
 
314
313
  solver_name = "Bundler"
@@ -336,32 +335,32 @@ module Bundler
336
335
  :additional_message_for_conflict => lambda do |o, name, conflict|
337
336
  if name == "bundler"
338
337
  o << %(\n Current Bundler version:\n bundler (#{Bundler::VERSION}))
339
- other_bundler_required = !conflict.requirement.requirement.satisfied_by?(Gem::Version.new(Bundler::VERSION))
340
- end
341
338
 
342
- if name == "bundler" && other_bundler_required
343
- o << "\n"
344
- o << "This Gemfile requires a different version of Bundler.\n"
345
- o << "Perhaps you need to update Bundler by running `gem install bundler`?\n"
346
- end
347
- if conflict.locked_requirement
339
+ conflict_dependency = conflict.requirement
340
+ conflict_requirement = conflict_dependency.requirement
341
+ other_bundler_required = !conflict_requirement.satisfied_by?(Gem::Version.new(Bundler::VERSION))
342
+
343
+ if other_bundler_required
344
+ o << "\n\n"
345
+
346
+ candidate_specs = source_for(:default_bundler).specs.search(conflict_dependency)
347
+ if candidate_specs.any?
348
+ target_version = candidate_specs.last.version
349
+ new_command = [File.basename($PROGRAM_NAME), "_#{target_version}_", *ARGV].join(" ")
350
+ o << "Your bundle requires a different version of Bundler than the one you're running.\n"
351
+ o << "Install the necessary version with `gem install bundler:#{target_version}` and rerun bundler using `#{new_command}`\n"
352
+ else
353
+ o << "Your bundle requires a different version of Bundler than the one you're running, and that version could not be found.\n"
354
+ end
355
+ end
356
+ elsif conflict.locked_requirement
348
357
  o << "\n"
349
358
  o << %(Running `bundle update` will rebuild your snapshot from scratch, using only\n)
350
359
  o << %(the gems in your Gemfile, which may resolve the conflict.\n)
351
360
  elsif !conflict.existing
352
361
  o << "\n"
353
362
 
354
- relevant_sources = if conflict.requirement.source
355
- [conflict.requirement.source]
356
- elsif conflict.requirement.all_sources
357
- conflict.requirement.all_sources
358
- elsif @lockfile_uses_separate_rubygems_sources
359
- # every conflict should have an explicit group of sources when we
360
- # enforce strict pinning
361
- raise "no source set for #{conflict}"
362
- else
363
- []
364
- end.compact.map(&:to_s).uniq.sort
363
+ relevant_source = conflict.requirement.source || source_for(name)
365
364
 
366
365
  metadata_requirement = name.end_with?("\0")
367
366
 
@@ -374,12 +373,10 @@ module Bundler
374
373
  end
375
374
  o << " "
376
375
 
377
- o << if relevant_sources.empty?
378
- "in any of the sources.\n"
379
- elsif metadata_requirement
380
- "is not available in #{relevant_sources.join(" or ")}"
376
+ o << if metadata_requirement
377
+ "is not available in #{relevant_source}"
381
378
  else
382
- "in any of the relevant sources:\n #{relevant_sources * "\n "}\n"
379
+ "in #{relevant_source}.\n"
383
380
  end
384
381
  end
385
382
  end,
@@ -393,29 +390,5 @@ module Bundler
393
390
  end
394
391
  )
395
392
  end
396
-
397
- def validate_resolved_specs!(resolved_specs)
398
- resolved_specs.each do |v|
399
- name = v.name
400
- next unless sources = relevant_sources_for_vertex(v)
401
- sources.compact!
402
- if default_index = sources.index(@source_requirements[:default])
403
- sources.delete_at(default_index)
404
- end
405
- sources.reject! {|s| s.specs[name].empty? }
406
- sources.uniq!
407
- next if sources.size <= 1
408
-
409
- multisource_disabled = Bundler.feature_flag.disable_multisource?
410
-
411
- msg = ["The gem '#{name}' was found in multiple relevant sources."]
412
- msg.concat sources.map {|s| " * #{s}" }.sort
413
- msg << "You #{multisource_disabled ? :must : :should} add this gem to the source block for the source you wish it to be installed from."
414
- msg = msg.join("\n")
415
-
416
- raise SecurityError, msg if multisource_disabled
417
- Bundler.ui.warn "Warning: #{msg}"
418
- end
419
- end
420
393
  end
421
394
  end
data/lib/bundler/retry.rb CHANGED
@@ -32,7 +32,7 @@ module Bundler
32
32
  end
33
33
  alias_method :attempts, :attempt
34
34
 
35
- private
35
+ private
36
36
 
37
37
  def run(&block)
38
38
  @failed = false
@@ -49,7 +49,7 @@ module Bundler
49
49
  raise e
50
50
  end
51
51
  return true unless name
52
- Bundler.ui.info "" unless Bundler.ui.debug? # Add new line incase dots preceded this
52
+ Bundler.ui.info "" unless Bundler.ui.debug? # Add new line in case dots preceded this
53
53
  Bundler.ui.warn "Retrying #{name} due to error (#{current_run.next}/#{total_runs}): #{e.class} #{e.message}", Bundler.ui.debug?
54
54
  end
55
55
 
@@ -123,7 +123,7 @@ module Bundler
123
123
  @exact = versions.all? {|v| Gem::Requirement.create(v).exact? }
124
124
  end
125
125
 
126
- private
126
+ private
127
127
 
128
128
  def matches?(requirements, version)
129
129
  # Handles RUBY_PATCHLEVEL of -1 for instances like ruby-head
@@ -47,14 +47,13 @@ module Gem
47
47
  full_require_paths
48
48
  end
49
49
 
50
- if method_defined?(:extension_dir)
51
- alias_method :rg_extension_dir, :extension_dir
52
- def extension_dir
53
- @bundler_extension_dir ||= if source.respond_to?(:extension_dir_name)
54
- File.expand_path(File.join(extensions_dir, source.extension_dir_name))
55
- else
56
- rg_extension_dir
57
- end
50
+ alias_method :rg_extension_dir, :extension_dir
51
+ def extension_dir
52
+ @bundler_extension_dir ||= if source.respond_to?(:extension_dir_name)
53
+ unique_extension_dir = [source.extension_dir_name, File.basename(full_gem_path)].uniq.join("-")
54
+ File.expand_path(File.join(extensions_dir, unique_extension_dir))
55
+ else
56
+ rg_extension_dir
58
57
  end
59
58
  end
60
59
 
@@ -86,7 +85,7 @@ module Gem
86
85
  dependencies - development_dependencies
87
86
  end
88
87
 
89
- private
88
+ private
90
89
 
91
90
  def dependencies_to_gemfile(dependencies, group = nil)
92
91
  gemfile = String.new
@@ -106,7 +105,7 @@ module Gem
106
105
  end
107
106
 
108
107
  class Dependency
109
- attr_accessor :source, :groups, :all_sources
108
+ attr_accessor :source, :groups
110
109
 
111
110
  alias_method :eql?, :==
112
111
 
@@ -117,7 +116,7 @@ module Gem
117
116
  end
118
117
 
119
118
  def to_yaml_properties
120
- instance_variables.reject {|p| ["@source", "@groups", "@all_sources"].include?(p.to_s) }
119
+ instance_variables.reject {|p| ["@source", "@groups"].include?(p.to_s) }
121
120
  end
122
121
 
123
122
  def to_lock
@@ -130,6 +129,51 @@ module Gem
130
129
  end
131
130
  end
132
131
 
132
+ # comparison is done order independently since rubygems 3.2.0.rc.2
133
+ unless Gem::Requirement.new("> 1", "< 2") == Gem::Requirement.new("< 2", "> 1")
134
+ class Requirement
135
+ module OrderIndependentComparison
136
+ def ==(other)
137
+ if _requirements_sorted? && other._requirements_sorted?
138
+ super
139
+ else
140
+ _with_sorted_requirements == other._with_sorted_requirements
141
+ end
142
+ end
143
+
144
+ protected
145
+
146
+ def _requirements_sorted?
147
+ return @_are_requirements_sorted if defined?(@_are_requirements_sorted)
148
+ strings = as_list
149
+ @_are_requirements_sorted = strings == strings.sort
150
+ end
151
+
152
+ def _with_sorted_requirements
153
+ @_with_sorted_requirements ||= _requirements_sorted? ? self : self.class.new(as_list.sort)
154
+ end
155
+ end
156
+
157
+ prepend OrderIndependentComparison
158
+ end
159
+ end
160
+
161
+ if Gem::Requirement.new("~> 2.0").hash == Gem::Requirement.new("~> 2.0.0").hash
162
+ class Requirement
163
+ module CorrectHashForLambdaOperator
164
+ def hash
165
+ if requirements.any? {|r| r.first == "~>" }
166
+ requirements.map {|r| r.first == "~>" ? [r[0], r[1].to_s] : r }.sort.hash
167
+ else
168
+ super
169
+ end
170
+ end
171
+ end
172
+
173
+ prepend CorrectHashForLambdaOperator
174
+ end
175
+ end
176
+
133
177
  class Platform
134
178
  JAVA = Gem::Platform.new("java") unless defined?(JAVA)
135
179
  MSWIN = Gem::Platform.new("mswin32") unless defined?(MSWIN)
@@ -145,6 +189,22 @@ module Gem
145
189
  undef_method :eql? if method_defined? :eql?
146
190
  alias_method :eql?, :==
147
191
  end
192
+
193
+ require "rubygems/util"
194
+
195
+ Util.singleton_class.module_eval do
196
+ if Util.singleton_methods.include?(:glob_files_in_dir) # since 3.0.0.beta.2
197
+ remove_method :glob_files_in_dir
198
+ end
199
+
200
+ def glob_files_in_dir(glob, base_path)
201
+ if RUBY_VERSION >= "2.5"
202
+ Dir.glob(glob, :base => base_path).map! {|f| File.expand_path(f, base_path) }
203
+ else
204
+ Dir.glob(File.join(base_path.to_s.gsub(/[\[\]]/, '\\\\\\&'), glob)).map! {|f| File.expand_path(f) }
205
+ end
206
+ end
207
+ end
148
208
  end
149
209
 
150
210
  module Gem