bundler 2.3.26 → 2.4.5

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 (190) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +110 -1
  3. data/README.md +2 -2
  4. data/bundler.gemspec +2 -2
  5. data/exe/bundle +1 -4
  6. data/lib/bundler/build_metadata.rb +2 -2
  7. data/lib/bundler/cli/add.rb +1 -1
  8. data/lib/bundler/cli/check.rb +1 -1
  9. data/lib/bundler/cli/common.rb +1 -0
  10. data/lib/bundler/cli/console.rb +2 -2
  11. data/lib/bundler/cli/doctor.rb +4 -6
  12. data/lib/bundler/cli/gem.rb +62 -40
  13. data/lib/bundler/cli/install.rb +2 -3
  14. data/lib/bundler/cli/lock.rb +8 -5
  15. data/lib/bundler/cli/open.rb +6 -4
  16. data/lib/bundler/cli/outdated.rb +1 -3
  17. data/lib/bundler/cli/viz.rb +1 -1
  18. data/lib/bundler/cli.rb +44 -2
  19. data/lib/bundler/compact_index_client/cache.rb +1 -1
  20. data/lib/bundler/compact_index_client/updater.rb +40 -39
  21. data/lib/bundler/constants.rb +1 -1
  22. data/lib/bundler/definition.rb +87 -51
  23. data/lib/bundler/dependency.rb +12 -11
  24. data/lib/bundler/digest.rb +1 -1
  25. data/lib/bundler/dsl.rb +3 -3
  26. data/lib/bundler/env.rb +1 -1
  27. data/lib/bundler/environment_preserver.rb +1 -0
  28. data/lib/bundler/errors.rb +1 -11
  29. data/lib/bundler/fetcher/compact_index.rb +9 -11
  30. data/lib/bundler/fetcher/dependency.rb +1 -1
  31. data/lib/bundler/fetcher/downloader.rb +2 -5
  32. data/lib/bundler/fetcher.rb +2 -6
  33. data/lib/bundler/force_platform.rb +18 -0
  34. data/lib/bundler/friendly_errors.rb +0 -3
  35. data/lib/bundler/gem_version_promoter.rb +52 -86
  36. data/lib/bundler/graph.rb +3 -3
  37. data/lib/bundler/index.rb +5 -13
  38. data/lib/bundler/injector.rb +1 -1
  39. data/lib/bundler/inline.rb +2 -2
  40. data/lib/bundler/installer/parallel_installer.rb +0 -31
  41. data/lib/bundler/installer.rb +9 -23
  42. data/lib/bundler/lazy_specification.rb +37 -33
  43. data/lib/bundler/lockfile_parser.rb +5 -5
  44. data/lib/bundler/man/bundle-add.1 +1 -1
  45. data/lib/bundler/man/bundle-binstubs.1 +1 -1
  46. data/lib/bundler/man/bundle-cache.1 +1 -1
  47. data/lib/bundler/man/bundle-check.1 +1 -1
  48. data/lib/bundler/man/bundle-clean.1 +1 -1
  49. data/lib/bundler/man/bundle-config.1 +2 -2
  50. data/lib/bundler/man/bundle-config.1.ronn +1 -1
  51. data/lib/bundler/man/bundle-console.1 +1 -1
  52. data/lib/bundler/man/bundle-doctor.1 +1 -1
  53. data/lib/bundler/man/bundle-exec.1 +5 -5
  54. data/lib/bundler/man/bundle-exec.1.ronn +5 -5
  55. data/lib/bundler/man/bundle-gem.1 +27 -37
  56. data/lib/bundler/man/bundle-gem.1.ronn +5 -5
  57. data/lib/bundler/man/bundle-help.1 +1 -1
  58. data/lib/bundler/man/bundle-info.1 +1 -1
  59. data/lib/bundler/man/bundle-init.1 +1 -1
  60. data/lib/bundler/man/bundle-inject.1 +1 -1
  61. data/lib/bundler/man/bundle-install.1 +1 -30
  62. data/lib/bundler/man/bundle-install.1.ronn +0 -29
  63. data/lib/bundler/man/bundle-list.1 +1 -1
  64. data/lib/bundler/man/bundle-lock.1 +1 -1
  65. data/lib/bundler/man/bundle-open.1 +22 -2
  66. data/lib/bundler/man/bundle-open.1.ronn +9 -1
  67. data/lib/bundler/man/bundle-outdated.1 +1 -1
  68. data/lib/bundler/man/bundle-platform.1 +2 -2
  69. data/lib/bundler/man/bundle-platform.1.ronn +1 -1
  70. data/lib/bundler/man/bundle-plugin.1 +1 -1
  71. data/lib/bundler/man/bundle-pristine.1 +1 -1
  72. data/lib/bundler/man/bundle-remove.1 +1 -1
  73. data/lib/bundler/man/bundle-show.1 +1 -1
  74. data/lib/bundler/man/bundle-update.1 +1 -1
  75. data/lib/bundler/man/bundle-version.1 +1 -1
  76. data/lib/bundler/man/bundle-viz.1 +1 -1
  77. data/lib/bundler/man/bundle.1 +1 -1
  78. data/lib/bundler/man/gemfile.5 +1 -1
  79. data/lib/bundler/mirror.rb +5 -7
  80. data/lib/bundler/plugin/index.rb +4 -4
  81. data/lib/bundler/plugin/installer/rubygems.rb +0 -4
  82. data/lib/bundler/resolver/base.rb +42 -15
  83. data/lib/bundler/resolver/candidate.rb +94 -0
  84. data/lib/bundler/resolver/incompatibility.rb +15 -0
  85. data/lib/bundler/resolver/package.rb +72 -0
  86. data/lib/bundler/resolver/root.rb +25 -0
  87. data/lib/bundler/resolver/spec_group.rb +26 -36
  88. data/lib/bundler/resolver.rb +314 -278
  89. data/lib/bundler/rubygems_ext.rb +11 -6
  90. data/lib/bundler/rubygems_gem_installer.rb +4 -2
  91. data/lib/bundler/rubygems_integration.rb +1 -9
  92. data/lib/bundler/runtime.rb +1 -5
  93. data/lib/bundler/settings.rb +0 -6
  94. data/lib/bundler/shared_helpers.rb +1 -0
  95. data/lib/bundler/source/git/git_proxy.rb +193 -67
  96. data/lib/bundler/source/git.rb +15 -17
  97. data/lib/bundler/source/metadata.rb +0 -1
  98. data/lib/bundler/source/path/installer.rb +1 -22
  99. data/lib/bundler/source/path.rb +5 -5
  100. data/lib/bundler/source/rubygems.rb +14 -68
  101. data/lib/bundler/source_list.rb +8 -2
  102. data/lib/bundler/spec_set.rb +7 -9
  103. data/lib/bundler/templates/Executable +1 -1
  104. data/lib/bundler/templates/Executable.bundler +4 -9
  105. data/lib/bundler/templates/Executable.standalone +2 -0
  106. data/lib/bundler/templates/newgem/Cargo.toml.tt +7 -0
  107. data/lib/bundler/templates/newgem/Gemfile.tt +3 -0
  108. data/lib/bundler/templates/newgem/README.md.tt +6 -4
  109. data/lib/bundler/templates/newgem/Rakefile.tt +2 -1
  110. data/lib/bundler/templates/newgem/circleci/config.yml.tt +12 -0
  111. data/lib/bundler/templates/newgem/ext/newgem/Cargo.toml.tt +15 -0
  112. data/lib/bundler/templates/newgem/ext/newgem/{extconf.rb.tt → extconf-c.rb.tt} +0 -0
  113. data/lib/bundler/templates/newgem/ext/newgem/extconf-rust.rb.tt +6 -0
  114. data/lib/bundler/templates/newgem/ext/newgem/src/lib.rs.tt +12 -0
  115. data/lib/bundler/templates/newgem/github/workflows/main.yml.tt +10 -0
  116. data/lib/bundler/templates/newgem/gitignore.tt +3 -0
  117. data/lib/bundler/templates/newgem/gitlab-ci.yml.tt +8 -0
  118. data/lib/bundler/templates/newgem/newgem.gemspec.tt +8 -2
  119. data/lib/bundler/ui/shell.rb +35 -12
  120. data/lib/bundler/ui/silent.rb +21 -5
  121. data/lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb +3 -3
  122. data/lib/bundler/vendor/connection_pool/lib/connection_pool/wrapper.rb +0 -1
  123. data/lib/bundler/vendor/connection_pool/lib/connection_pool.rb +3 -1
  124. data/lib/bundler/vendor/fileutils/lib/fileutils.rb +1350 -408
  125. data/lib/bundler/vendor/net-http-persistent/README.rdoc +1 -1
  126. data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb +1 -1
  127. data/lib/bundler/vendor/pub_grub/LICENSE.txt +21 -0
  128. data/lib/bundler/vendor/pub_grub/lib/pub_grub/assignment.rb +20 -0
  129. data/lib/bundler/vendor/pub_grub/lib/pub_grub/basic_package_source.rb +189 -0
  130. data/lib/bundler/vendor/pub_grub/lib/pub_grub/failure_writer.rb +182 -0
  131. data/lib/bundler/vendor/pub_grub/lib/pub_grub/incompatibility.rb +151 -0
  132. data/lib/bundler/vendor/pub_grub/lib/pub_grub/package.rb +43 -0
  133. data/lib/bundler/vendor/pub_grub/lib/pub_grub/partial_solution.rb +121 -0
  134. data/lib/bundler/vendor/pub_grub/lib/pub_grub/rubygems.rb +45 -0
  135. data/lib/bundler/vendor/pub_grub/lib/pub_grub/solve_failure.rb +19 -0
  136. data/lib/bundler/vendor/pub_grub/lib/pub_grub/static_package_source.rb +53 -0
  137. data/lib/bundler/vendor/pub_grub/lib/pub_grub/term.rb +105 -0
  138. data/lib/bundler/vendor/pub_grub/lib/pub_grub/version.rb +3 -0
  139. data/lib/bundler/vendor/pub_grub/lib/pub_grub/version_constraint.rb +128 -0
  140. data/lib/bundler/vendor/pub_grub/lib/pub_grub/version_range.rb +409 -0
  141. data/lib/bundler/vendor/pub_grub/lib/pub_grub/version_solver.rb +240 -0
  142. data/lib/bundler/vendor/pub_grub/lib/pub_grub/version_union.rb +178 -0
  143. data/lib/bundler/vendor/pub_grub/lib/pub_grub.rb +31 -0
  144. data/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +1 -1
  145. data/lib/bundler/vendor/uri/lib/uri/common.rb +64 -16
  146. data/lib/bundler/vendor/uri/lib/uri/file.rb +7 -1
  147. data/lib/bundler/vendor/uri/lib/uri/ftp.rb +2 -1
  148. data/lib/bundler/vendor/uri/lib/uri/generic.rb +27 -7
  149. data/lib/bundler/vendor/uri/lib/uri/http.rb +40 -2
  150. data/lib/bundler/vendor/uri/lib/uri/https.rb +2 -1
  151. data/lib/bundler/vendor/uri/lib/uri/ldap.rb +1 -1
  152. data/lib/bundler/vendor/uri/lib/uri/ldaps.rb +2 -1
  153. data/lib/bundler/vendor/uri/lib/uri/mailto.rb +2 -2
  154. data/lib/bundler/vendor/uri/lib/uri/rfc2396_parser.rb +13 -7
  155. data/lib/bundler/vendor/uri/lib/uri/rfc3986_parser.rb +10 -5
  156. data/lib/bundler/vendor/uri/lib/uri/version.rb +1 -1
  157. data/lib/bundler/vendor/uri/lib/uri/ws.rb +1 -2
  158. data/lib/bundler/vendor/uri/lib/uri/wss.rb +2 -1
  159. data/lib/bundler/vendor/uri/lib/uri.rb +3 -2
  160. data/lib/bundler/vendored_persistent.rb +1 -33
  161. data/lib/bundler/{vendored_tmpdir.rb → vendored_pub_grub.rb} +1 -1
  162. data/lib/bundler/version.rb +5 -1
  163. data/lib/bundler/worker.rb +5 -7
  164. data/lib/bundler.rb +20 -64
  165. metadata +33 -32
  166. data/lib/bundler/templates/newgem/travis.yml.tt +0 -6
  167. data/lib/bundler/vendor/molinillo/LICENSE +0 -9
  168. data/lib/bundler/vendor/molinillo/lib/molinillo/delegates/resolution_state.rb +0 -57
  169. data/lib/bundler/vendor/molinillo/lib/molinillo/delegates/specification_provider.rb +0 -88
  170. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/action.rb +0 -36
  171. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb +0 -66
  172. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_vertex.rb +0 -62
  173. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/delete_edge.rb +0 -63
  174. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb +0 -61
  175. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/log.rb +0 -126
  176. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/set_payload.rb +0 -46
  177. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/tag.rb +0 -36
  178. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb +0 -164
  179. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb +0 -255
  180. data/lib/bundler/vendor/molinillo/lib/molinillo/errors.rb +0 -149
  181. data/lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb +0 -6
  182. data/lib/bundler/vendor/molinillo/lib/molinillo/modules/specification_provider.rb +0 -112
  183. data/lib/bundler/vendor/molinillo/lib/molinillo/modules/ui.rb +0 -67
  184. data/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb +0 -839
  185. data/lib/bundler/vendor/molinillo/lib/molinillo/resolver.rb +0 -46
  186. data/lib/bundler/vendor/molinillo/lib/molinillo/state.rb +0 -58
  187. data/lib/bundler/vendor/molinillo/lib/molinillo.rb +0 -11
  188. data/lib/bundler/vendor/tmpdir/lib/tmpdir.rb +0 -154
  189. data/lib/bundler/vendored_molinillo.rb +0 -4
  190. data/lib/bundler/version_ranges.rb +0 -122
@@ -68,7 +68,7 @@ module Bundler
68
68
 
69
69
  def info_path(name)
70
70
  name = name.to_s
71
- if name =~ /[^a-z0-9_-]/
71
+ if /[^a-z0-9_-]/.match?(name)
72
72
  name += "-#{SharedHelpers.digest(:MD5).hexdigest(name).downcase}"
73
73
  info_roots.last.join(name)
74
74
  else
@@ -20,63 +20,64 @@ module Bundler
20
20
 
21
21
  def initialize(fetcher)
22
22
  @fetcher = fetcher
23
- require_relative "../vendored_tmpdir"
24
23
  end
25
24
 
26
25
  def update(local_path, remote_path, retrying = nil)
27
26
  headers = {}
28
27
 
29
- Bundler::Dir.mktmpdir("bundler-compact-index-") do |local_temp_dir|
30
- local_temp_path = Pathname.new(local_temp_dir).join(local_path.basename)
31
-
32
- # first try to fetch any new bytes on the existing file
33
- if retrying.nil? && local_path.file?
34
- copy_file local_path, local_temp_path
35
-
36
- headers["If-None-Match"] = etag_for(local_temp_path)
37
- headers["Range"] =
38
- if local_temp_path.size.nonzero?
39
- # Subtract a byte to ensure the range won't be empty.
40
- # Avoids 416 (Range Not Satisfiable) responses.
41
- "bytes=#{local_temp_path.size - 1}-"
42
- else
43
- "bytes=#{local_temp_path.size}-"
44
- end
45
- end
28
+ local_temp_path = local_path.sub(/$/, ".#{$$}")
29
+ local_temp_path = local_temp_path.sub(/$/, ".retrying") if retrying
30
+ local_temp_path = local_temp_path.sub(/$/, ".tmp")
46
31
 
47
- response = @fetcher.call(remote_path, headers)
48
- return nil if response.is_a?(Net::HTTPNotModified)
32
+ # first try to fetch any new bytes on the existing file
33
+ if retrying.nil? && local_path.file?
34
+ copy_file local_path, local_temp_path
49
35
 
50
- content = response.body
36
+ headers["If-None-Match"] = etag_for(local_temp_path)
37
+ headers["Range"] =
38
+ if local_temp_path.size.nonzero?
39
+ # Subtract a byte to ensure the range won't be empty.
40
+ # Avoids 416 (Range Not Satisfiable) responses.
41
+ "bytes=#{local_temp_path.size - 1}-"
42
+ else
43
+ "bytes=#{local_temp_path.size}-"
44
+ end
45
+ end
51
46
 
52
- etag = (response["ETag"] || "").gsub(%r{\AW/}, "")
53
- correct_response = SharedHelpers.filesystem_access(local_temp_path) do
54
- if response.is_a?(Net::HTTPPartialContent) && local_temp_path.size.nonzero?
55
- local_temp_path.open("a") {|f| f << slice_body(content, 1..-1) }
47
+ response = @fetcher.call(remote_path, headers)
48
+ return nil if response.is_a?(Net::HTTPNotModified)
56
49
 
57
- etag_for(local_temp_path) == etag
58
- else
59
- local_temp_path.open("wb") {|f| f << content }
50
+ content = response.body
60
51
 
61
- etag.length.zero? || etag_for(local_temp_path) == etag
62
- end
63
- end
52
+ etag = (response["ETag"] || "").gsub(%r{\AW/}, "")
53
+ correct_response = SharedHelpers.filesystem_access(local_temp_path) do
54
+ if response.is_a?(Net::HTTPPartialContent) && local_temp_path.size.nonzero?
55
+ local_temp_path.open("a") {|f| f << slice_body(content, 1..-1) }
64
56
 
65
- if correct_response
66
- SharedHelpers.filesystem_access(local_path) do
67
- FileUtils.mv(local_temp_path, local_path)
68
- end
69
- return nil
57
+ etag_for(local_temp_path) == etag
58
+ else
59
+ local_temp_path.open("wb") {|f| f << content }
60
+
61
+ etag.length.zero? || etag_for(local_temp_path) == etag
70
62
  end
63
+ end
71
64
 
72
- if retrying
73
- raise MisMatchedChecksumError.new(remote_path, etag, etag_for(local_temp_path))
65
+ if correct_response
66
+ SharedHelpers.filesystem_access(local_path) do
67
+ FileUtils.mv(local_temp_path, local_path)
74
68
  end
69
+ return nil
70
+ end
75
71
 
76
- update(local_path, remote_path, :retrying)
72
+ if retrying
73
+ raise MisMatchedChecksumError.new(remote_path, etag, etag_for(local_temp_path))
77
74
  end
75
+
76
+ update(local_path, remote_path, :retrying)
78
77
  rescue Zlib::GzipFile::Error
79
78
  raise Bundler::HTTPError
79
+ ensure
80
+ FileUtils.remove_file(local_temp_path) if File.exist?(local_temp_path)
80
81
  end
81
82
 
82
83
  def etag_for(path)
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Bundler
4
4
  WINDOWS = RbConfig::CONFIG["host_os"] =~ /(msdos|mswin|djgpp|mingw)/
5
- FREEBSD = RbConfig::CONFIG["host_os"] =~ /bsd/
5
+ FREEBSD = RbConfig::CONFIG["host_os"].to_s.include?("bsd")
6
6
  NULL = WINDOWS ? "NUL" : "/dev/null"
7
7
  end
@@ -16,7 +16,6 @@ module Bundler
16
16
  :locked_deps,
17
17
  :locked_gems,
18
18
  :platforms,
19
- :requires,
20
19
  :ruby_version,
21
20
  :lockfile,
22
21
  :gemfiles
@@ -80,6 +79,7 @@ module Bundler
80
79
  @locked_bundler_version = nil
81
80
  @locked_ruby_version = nil
82
81
  @new_platform = nil
82
+ @removed_platform = nil
83
83
 
84
84
  if lockfile && File.exist?(lockfile)
85
85
  @lockfile_contents = Bundler.read_file(lockfile)
@@ -130,7 +130,7 @@ module Bundler
130
130
  end
131
131
  @unlocking ||= @unlock[:ruby] ||= (!@locked_ruby_version ^ !@ruby_version)
132
132
 
133
- add_current_platform unless current_ruby_platform_locked? || Bundler.frozen_bundle?
133
+ add_current_platform unless Bundler.frozen_bundle?
134
134
 
135
135
  converge_path_sources_to_gemspec_sources
136
136
  @path_changes = converge_paths
@@ -146,11 +146,11 @@ module Bundler
146
146
  @dependency_changes = converge_dependencies
147
147
  @local_changes = converge_locals
148
148
 
149
- @requires = compute_requires
149
+ @incomplete_lockfile = check_missing_lockfile_specs
150
150
  end
151
151
 
152
152
  def gem_version_promoter
153
- @gem_version_promoter ||= GemVersionPromoter.new(@originally_locked_specs, @unlock[:gems])
153
+ @gem_version_promoter ||= GemVersionPromoter.new
154
154
  end
155
155
 
156
156
  def resolve_only_locally!
@@ -159,13 +159,6 @@ module Bundler
159
159
  resolve
160
160
  end
161
161
 
162
- def resolve_prefering_local!
163
- @prefer_local = true
164
- @remote = true
165
- sources.remote!
166
- resolve
167
- end
168
-
169
162
  def resolve_with_cache!
170
163
  sources.cached!
171
164
  resolve
@@ -177,6 +170,23 @@ module Bundler
177
170
  resolve
178
171
  end
179
172
 
173
+ def resolution_mode=(options)
174
+ if options["local"]
175
+ @remote = false
176
+ else
177
+ @remote = true
178
+ @prefer_local = options["prefer-local"]
179
+ end
180
+ end
181
+
182
+ def setup_sources_for_resolve
183
+ if @remote == false
184
+ sources.cached!
185
+ else
186
+ sources.remote!
187
+ end
188
+ end
189
+
180
190
  # For given dependency list returns a SpecSet with Gemspec of all the required
181
191
  # dependencies.
182
192
  # 1. The method first resolves the dependencies specified in Gemfile
@@ -264,19 +274,19 @@ module Bundler
264
274
  @locked_specs
265
275
  elsif !unlocking? && nothing_changed?
266
276
  if deleted_deps.any?
267
- Bundler.ui.debug("Some dependencies were deleted, using a subset of the resolution from the lockfile")
277
+ Bundler.ui.debug "Some dependencies were deleted, using a subset of the resolution from the lockfile"
268
278
  SpecSet.new(filter_specs(@locked_specs, @dependencies - deleted_deps))
269
279
  else
270
- Bundler.ui.debug("Found no changes, using resolution from the lockfile")
271
- if @locked_gems.may_include_redundant_platform_specific_gems?
280
+ Bundler.ui.debug "Found no changes, using resolution from the lockfile"
281
+ if @removed_platform || @locked_gems.may_include_redundant_platform_specific_gems?
272
282
  SpecSet.new(filter_specs(@locked_specs, @dependencies))
273
283
  else
274
284
  @locked_specs
275
285
  end
276
286
  end
277
287
  else
278
- Bundler.ui.debug("Found changes from the lockfile, re-resolving dependencies because #{change_reason}")
279
- resolver.start(expanded_dependencies)
288
+ Bundler.ui.debug "Found changes from the lockfile, re-resolving dependencies because #{change_reason}"
289
+ start_resolution
280
290
  end
281
291
  end
282
292
 
@@ -295,11 +305,11 @@ module Bundler
295
305
 
296
306
  # Convert to \r\n if the existing lock has them
297
307
  # i.e., Windows with `git config core.autocrlf=true`
298
- contents.gsub!(/\n/, "\r\n") if @lockfile_contents.match("\r\n")
308
+ contents.gsub!(/\n/, "\r\n") if @lockfile_contents.match?("\r\n")
299
309
 
300
310
  if @locked_bundler_version
301
311
  locked_major = @locked_bundler_version.segments.first
302
- current_major = Gem::Version.create(Bundler::VERSION).segments.first
312
+ current_major = Bundler.gem_version.segments.first
303
313
 
304
314
  updating_major = locked_major < current_major
305
315
  end
@@ -447,7 +457,9 @@ module Bundler
447
457
  end
448
458
 
449
459
  def remove_platform(platform)
450
- return if @platforms.delete(Gem::Platform.new(platform))
460
+ removed_platform = @platforms.delete(Gem::Platform.new(platform))
461
+ @removed_platform ||= removed_platform
462
+ return if removed_platform
451
463
  raise InvalidOption, "Unable to remove the platform `#{platform}` since the only platforms are #{@platforms.join ", "}"
452
464
  end
453
465
 
@@ -461,7 +473,7 @@ module Bundler
461
473
  private :sources
462
474
 
463
475
  def nothing_changed?
464
- !@source_changes && !@dependency_changes && !@new_platform && !@path_changes && !@local_changes
476
+ !@source_changes && !@dependency_changes && !@new_platform && !@path_changes && !@local_changes && !@incomplete_lockfile
465
477
  end
466
478
 
467
479
  def unlocking?
@@ -471,15 +483,20 @@ module Bundler
471
483
  private
472
484
 
473
485
  def resolver
474
- @resolver ||= begin
475
- last_resolve = converge_locked_specs
476
- remove_ruby_from_platforms_if_necessary!(current_dependencies)
477
- Resolver.new(source_requirements, last_resolve, gem_version_promoter, additional_base_requirements_for_resolve(last_resolve), platforms)
478
- end
486
+ @resolver ||= Resolver.new(resolution_packages, gem_version_promoter)
479
487
  end
480
488
 
481
489
  def expanded_dependencies
482
- @expanded_dependencies ||= dependencies + metadata_dependencies
490
+ dependencies + metadata_dependencies
491
+ end
492
+
493
+ def resolution_packages
494
+ @resolution_packages ||= begin
495
+ last_resolve = converge_locked_specs
496
+ remove_ruby_from_platforms_if_necessary!(current_dependencies)
497
+ packages = Resolver::Base.new(source_requirements, expanded_dependencies, last_resolve, @platforms, :locked_specs => @originally_locked_specs, :unlock => @unlock[:gems], :prerelease => gem_version_promoter.pre?)
498
+ additional_base_requirements_for_resolve(packages, last_resolve)
499
+ end
483
500
  end
484
501
 
485
502
  def filter_specs(specs, deps)
@@ -507,23 +524,40 @@ module Bundler
507
524
  raise GemNotFound, "Could not find #{missing_specs_list.join(" nor ")}"
508
525
  end
509
526
 
527
+ incomplete_specs = specs.incomplete_specs
510
528
  loop do
511
- incomplete_specs = specs.incomplete_specs
512
529
  break if incomplete_specs.empty?
513
530
 
514
531
  Bundler.ui.debug("The lockfile does not have all gems needed for the current platform though, Bundler will still re-resolve dependencies")
515
- @resolve = resolver.start(expanded_dependencies, :exclude_specs => incomplete_specs)
532
+ setup_sources_for_resolve
533
+ resolution_packages.delete(incomplete_specs)
534
+ @resolve = start_resolution
516
535
  specs = resolve.materialize(dependencies)
536
+
537
+ still_incomplete_specs = specs.incomplete_specs
538
+
539
+ if still_incomplete_specs == incomplete_specs
540
+ package = resolution_packages.get_package(incomplete_specs.first.name)
541
+ resolver.raise_not_found! package
542
+ end
543
+
544
+ incomplete_specs = still_incomplete_specs
517
545
  end
518
546
 
519
- bundler = sources.metadata_source.specs.search(Gem::Dependency.new("bundler", VERSION)).last
547
+ bundler = sources.metadata_source.specs.search(["bundler", Bundler.gem_version]).last
520
548
  specs["bundler"] = bundler
521
549
 
522
550
  specs
523
551
  end
524
552
 
553
+ def start_resolution
554
+ result = resolver.start
555
+
556
+ SpecSet.new(SpecSet.new(result).for(dependencies, false, @platforms))
557
+ end
558
+
525
559
  def precompute_source_requirements_for_indirect_dependencies?
526
- @remote && sources.non_global_rubygems_sources.all?(&:dependency_api_available?) && !sources.aggregate_global_source?
560
+ sources.non_global_rubygems_sources.all?(&:dependency_api_available?) && !sources.aggregate_global_source?
527
561
  end
528
562
 
529
563
  def pin_locally_available_names(source_requirements)
@@ -553,6 +587,8 @@ module Bundler
553
587
  end
554
588
 
555
589
  def add_current_platform
590
+ return if current_ruby_platform_locked?
591
+
556
592
  add_platform(local_platform)
557
593
  end
558
594
 
@@ -574,6 +610,7 @@ module Bundler
574
610
  [@new_platform, "you added a new platform to your gemfile"],
575
611
  [@path_changes, "the gemspecs for path gems changed"],
576
612
  [@local_changes, "the gemspecs for git local gems changed"],
613
+ [@incomplete_lockfile, "your lock file is missing some gems"],
577
614
  ].select(&:first).map(&:last).join(", ")
578
615
  end
579
616
 
@@ -628,6 +665,14 @@ module Bundler
628
665
  !sources_with_changes.each {|source| @unlock[:sources] << source.name }.empty?
629
666
  end
630
667
 
668
+ def check_missing_lockfile_specs
669
+ all_locked_specs = @locked_specs.map(&:name) << "bundler"
670
+
671
+ @locked_specs.any? do |s|
672
+ s.dependencies.any? {|dep| !all_locked_specs.include?(dep.name) }
673
+ end
674
+ end
675
+
631
676
  def converge_paths
632
677
  sources.path_sources.any? do |source|
633
678
  specs_changed?(source)
@@ -766,12 +811,13 @@ module Bundler
766
811
  end
767
812
 
768
813
  new_spec = new_specs[s].first
769
-
770
- # If the spec is no longer in the path source, unlock it. This
771
- # commonly happens if the version changed in the gemspec
772
- next unless new_spec
773
-
774
- s.dependencies.replace(new_spec.dependencies)
814
+ if new_spec
815
+ s.dependencies.replace(new_spec.dependencies)
816
+ else
817
+ # If the spec is no longer in the path source, unlock it. This
818
+ # commonly happens if the version changed in the gemspec
819
+ @unlock[:gems] << s.name
820
+ end
775
821
  end
776
822
 
777
823
  if dep.nil? && requested_dependencies.find {|d| s.name == d.name }
@@ -839,22 +885,12 @@ module Bundler
839
885
  current == proposed
840
886
  end
841
887
 
842
- def compute_requires
843
- dependencies.reduce({}) do |requires, dep|
844
- next requires unless dep.should_include?
845
- requires[dep.name] = Array(dep.autorequire || dep.name).map do |file|
846
- # Allow `require: true` as an alias for `require: <name>`
847
- file == true ? dep.name : file
848
- end
849
- requires
888
+ def additional_base_requirements_for_resolve(resolution_packages, last_resolve)
889
+ return resolution_packages unless @locked_gems && unlocking? && !sources.expired_sources?(@locked_gems.sources)
890
+ converge_specs(@originally_locked_specs - last_resolve).each do |locked_spec|
891
+ resolution_packages.base_requirements[locked_spec.name] = Gem::Requirement.new(">= #{locked_spec.version}")
850
892
  end
851
- end
852
-
853
- def additional_base_requirements_for_resolve(last_resolve)
854
- return [] unless @locked_gems && unlocking? && !sources.expired_sources?(@locked_gems.sources)
855
- converge_specs(@originally_locked_specs - last_resolve).map do |locked_spec|
856
- Dependency.new(locked_spec.name, ">= #{locked_spec.version}")
857
- end.uniq
893
+ resolution_packages
858
894
  end
859
895
 
860
896
  def remove_ruby_from_platforms_if_necessary!(dependencies)
@@ -7,20 +7,20 @@ require_relative "rubygems_ext"
7
7
  module Bundler
8
8
  class Dependency < Gem::Dependency
9
9
  attr_reader :autorequire
10
- attr_reader :groups, :platforms, :gemfile, :path, :git, :github, :branch, :ref, :force_ruby_platform
10
+ attr_reader :groups, :platforms, :gemfile, :path, :git, :github, :branch, :ref
11
11
 
12
12
  ALL_RUBY_VERSIONS = ((18..27).to_a + (30..31).to_a).freeze
13
13
  PLATFORM_MAP = {
14
- :ruby => [Gem::Platform::RUBY, ALL_RUBY_VERSIONS],
15
- :mri => [Gem::Platform::RUBY, ALL_RUBY_VERSIONS],
16
- :rbx => [Gem::Platform::RUBY],
14
+ :ruby => [Gem::Platform::RUBY, ALL_RUBY_VERSIONS],
15
+ :mri => [Gem::Platform::RUBY, ALL_RUBY_VERSIONS],
16
+ :rbx => [Gem::Platform::RUBY],
17
17
  :truffleruby => [Gem::Platform::RUBY],
18
- :jruby => [Gem::Platform::JAVA, [18, 19]],
19
- :windows => [Gem::Platform::WINDOWS, ALL_RUBY_VERSIONS],
20
- :mswin => [Gem::Platform::MSWIN, ALL_RUBY_VERSIONS],
21
- :mswin64 => [Gem::Platform::MSWIN64, ALL_RUBY_VERSIONS - [18]],
22
- :mingw => [Gem::Platform::MINGW, ALL_RUBY_VERSIONS],
23
- :x64_mingw => [Gem::Platform::X64_MINGW, ALL_RUBY_VERSIONS - [18, 19]],
18
+ :jruby => [Gem::Platform::JAVA, [18, 19]],
19
+ :windows => [Gem::Platform::WINDOWS, ALL_RUBY_VERSIONS],
20
+ :mswin => [Gem::Platform::MSWIN, ALL_RUBY_VERSIONS],
21
+ :mswin64 => [Gem::Platform::MSWIN64, ALL_RUBY_VERSIONS - [18]],
22
+ :mingw => [Gem::Platform::MINGW, ALL_RUBY_VERSIONS],
23
+ :x64_mingw => [Gem::Platform::X64_MINGW, ALL_RUBY_VERSIONS - [18, 19]],
24
24
  }.each_with_object({}) do |(platform, spec), hash|
25
25
  hash[platform] = spec[0]
26
26
  spec[1]&.each {|version| hash[:"#{platform}_#{version}"] = spec[0] }
@@ -42,7 +42,7 @@ module Bundler
42
42
  @env = options["env"]
43
43
  @should_include = options.fetch("should_include", true)
44
44
  @gemfile = options["gemfile"]
45
- @force_ruby_platform = options["force_ruby_platform"]
45
+ @force_ruby_platform = options["force_ruby_platform"] if options.key?("force_ruby_platform")
46
46
 
47
47
  @autorequire = Array(options["require"] || []) if options.key?("require")
48
48
  end
@@ -50,6 +50,7 @@ module Bundler
50
50
  # Returns the platforms this dependency is valid for, in the same order as
51
51
  # passed in the `valid_platforms` parameter
52
52
  def gem_platforms(valid_platforms)
53
+ return [Gem::Platform::RUBY] if force_ruby_platform
53
54
  return valid_platforms if @platforms.empty?
54
55
 
55
56
  valid_platforms.select {|p| expanded_platforms.include?(GemHelpers.generic(p)) }
@@ -43,7 +43,7 @@ module Bundler
43
43
  f = (b ^ c ^ d)
44
44
  k = 0xCA62C1D6
45
45
  end
46
- t = SHA1_MASK & (SHA1_MASK & rotate(a, 5) + f + e + k + w[i])
46
+ t = SHA1_MASK & rotate(a, 5) + f + e + k + w[i]
47
47
  a, b, c, d, e = t, a, SHA1_MASK & rotate(b, 30), c, d # rubocop:disable Style/ParallelAssignment
48
48
  end
49
49
  mutated = [a, b, c, d, e]
data/lib/bundler/dsl.rb CHANGED
@@ -277,8 +277,8 @@ module Bundler
277
277
  if repo_name =~ GITHUB_PULL_REQUEST_URL
278
278
  {
279
279
  "git" => "https://github.com/#{$1}.git",
280
- "branch" => "refs/pull/#{$2}/head",
281
- "ref" => nil,
280
+ "branch" => nil,
281
+ "ref" => "refs/pull/#{$2}/head",
282
282
  "tag" => nil,
283
283
  }
284
284
  else
@@ -324,7 +324,7 @@ module Bundler
324
324
  if name.is_a?(Symbol)
325
325
  raise GemfileError, %(You need to specify gem names as Strings. Use 'gem "#{name}"' instead)
326
326
  end
327
- if name =~ /\s/
327
+ if /\s/.match?(name)
328
328
  raise GemfileError, %('#{name}' is not a valid gem name because it contains whitespace)
329
329
  end
330
330
  raise GemfileError, %(an empty gem name is not valid) if name.empty?
data/lib/bundler/env.rb CHANGED
@@ -75,7 +75,7 @@ module Bundler
75
75
  end
76
76
 
77
77
  def self.git_version
78
- Bundler::Source::Git::GitProxy.new(nil, nil, nil).full_version
78
+ Bundler::Source::Git::GitProxy.new(nil, nil).full_version
79
79
  rescue Bundler::Source::Git::GitNotInstalledError
80
80
  "not installed"
81
81
  end
@@ -7,6 +7,7 @@ module Bundler
7
7
  BUNDLE_BIN_PATH
8
8
  BUNDLE_GEMFILE
9
9
  BUNDLER_VERSION
10
+ BUNDLER_SETUP
10
11
  GEM_HOME
11
12
  GEM_PATH
12
13
  MANPATH
@@ -21,16 +21,7 @@ module Bundler
21
21
  class InstallError < BundlerError; status_code(5); end
22
22
 
23
23
  # Internal error, should be rescued
24
- class VersionConflict < BundlerError
25
- attr_reader :conflicts
26
-
27
- def initialize(conflicts, msg = nil)
28
- super(msg)
29
- @conflicts = conflicts
30
- end
31
-
32
- status_code(6)
33
- end
24
+ class SolveFailure < BundlerError; status_code(6); end
34
25
 
35
26
  class GemNotFound < BundlerError; status_code(7); end
36
27
  class InstallHookError < BundlerError; status_code(8); end
@@ -55,7 +46,6 @@ module Bundler
55
46
  class CyclicDependencyError < BundlerError; status_code(21); end
56
47
  class GemfileLockNotFound < BundlerError; status_code(22); end
57
48
  class PluginError < BundlerError; status_code(29); end
58
- class SudoNotPermittedError < BundlerError; status_code(30); end
59
49
  class ThreadCreationError < BundlerError; status_code(33); end
60
50
  class APIResponseMismatchError < BundlerError; status_code(34); end
61
51
  class APIResponseInvalidDependenciesError < BundlerError; status_code(35); end
@@ -12,17 +12,15 @@ module Bundler
12
12
  method = instance_method(method_name)
13
13
  undef_method(method_name)
14
14
  define_method(method_name) do |*args, &blk|
15
- begin
16
- method.bind(self).call(*args, &blk)
17
- rescue NetworkDownError, CompactIndexClient::Updater::MisMatchedChecksumError => e
18
- raise HTTPError, e.message
19
- rescue AuthenticationRequiredError
20
- # Fail since we got a 401 from the server.
21
- raise
22
- rescue HTTPError => e
23
- Bundler.ui.trace(e)
24
- nil
25
- end
15
+ method.bind(self).call(*args, &blk)
16
+ rescue NetworkDownError, CompactIndexClient::Updater::MisMatchedChecksumError => e
17
+ raise HTTPError, e.message
18
+ rescue AuthenticationRequiredError
19
+ # Fail since we got a 401 from the server.
20
+ raise
21
+ rescue HTTPError => e
22
+ Bundler.ui.trace(e)
23
+ nil
26
24
  end
27
25
  end
28
26
 
@@ -55,7 +55,7 @@ module Bundler
55
55
  gem_list = []
56
56
  gem_names.each_slice(Source::Rubygems::API_REQUEST_SIZE) do |names|
57
57
  marshalled_deps = downloader.fetch(dependency_api_uri(names)).body
58
- gem_list.concat(Bundler.load_marshal(marshalled_deps))
58
+ gem_list.concat(Bundler.safe_load_marshal(marshalled_deps))
59
59
  end
60
60
  gem_list
61
61
  end
@@ -61,14 +61,11 @@ module Bundler
61
61
  req.basic_auth(user, password)
62
62
  end
63
63
  connection.request(uri, req)
64
- rescue NoMethodError => e
65
- raise unless ["undefined method", "use_ssl="].all? {|snippet| e.message.include? snippet }
66
- raise LoadError.new("cannot load such file -- openssl")
67
64
  rescue OpenSSL::SSL::SSLError
68
65
  raise CertificateFailureError.new(uri)
69
66
  rescue *HTTP_ERRORS => e
70
67
  Bundler.ui.trace e
71
- if e.is_a?(SocketError) || e.message =~ /host down:/
68
+ if e.is_a?(SocketError) || e.message.to_s.include?("host down:")
72
69
  raise NetworkDownError, "Could not reach host #{uri.host}. Check your network " \
73
70
  "connection and try again."
74
71
  else
@@ -80,7 +77,7 @@ module Bundler
80
77
  private
81
78
 
82
79
  def validate_uri_scheme!(uri)
83
- return if uri.scheme =~ /\Ahttps?\z/
80
+ return if /\Ahttps?\z/.match?(uri.scheme)
84
81
  raise InvalidOption,
85
82
  "The request uri `#{uri}` has an invalid scheme (`#{uri.scheme}`). " \
86
83
  "Did you mean `http` or `https`?"
@@ -29,9 +29,7 @@ module Bundler
29
29
  " is a chance you are experiencing a man-in-the-middle attack, but" \
30
30
  " most likely your system doesn't have the CA certificates needed" \
31
31
  " for verification. For information about OpenSSL certificates, see" \
32
- " https://railsapps.github.io/openssl-certificate-verify-failed.html." \
33
- " To connect without using SSL, edit your Gemfile" \
34
- " sources and change 'https' to 'http'."
32
+ " https://railsapps.github.io/openssl-certificate-verify-failed.html."
35
33
  end
36
34
  end
37
35
 
@@ -39,9 +37,7 @@ module Bundler
39
37
  class SSLError < HTTPError
40
38
  def initialize(msg = nil)
41
39
  super msg || "Could not load OpenSSL.\n" \
42
- "You must recompile Ruby with OpenSSL support or change the sources in your " \
43
- "Gemfile from 'https' to 'http'. Instructions for compiling with OpenSSL " \
44
- "using RVM are available at rvm.io/packages/openssl."
40
+ "You must recompile Ruby with OpenSSL support."
45
41
  end
46
42
  end
47
43
 
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bundler
4
+ module ForcePlatform
5
+ private
6
+
7
+ # The `:force_ruby_platform` value used by dependencies for resolution, and
8
+ # by locked specifications for materialization is `false` by default, except
9
+ # for TruffleRuby. TruffleRuby generally needs to force the RUBY platform
10
+ # variant unless the name is explicitly allowlisted.
11
+
12
+ def default_force_ruby_platform
13
+ return false unless RUBY_ENGINE == "truffleruby"
14
+
15
+ !Gem::Platform::REUSE_AS_BINARY_ON_TRUFFLERUBY.include?(name)
16
+ end
17
+ end
18
+ end
@@ -36,9 +36,6 @@ module Bundler
36
36
  end
37
37
  when Thor::Error
38
38
  Bundler.ui.error error.message
39
- when LoadError
40
- raise error unless error.message =~ /cannot load such file -- openssl|openssl.so|libcrypto.so/
41
- Bundler.ui.error "\nCould not load OpenSSL. #{error.class}: #{error}\n#{error.backtrace.join("\n ")}"
42
39
  when Interrupt
43
40
  Bundler.ui.error "\nQuitting..."
44
41
  Bundler.ui.trace error