bundler 2.1.4 → 2.2.17

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 (225) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1774 -1430
  3. data/README.md +6 -8
  4. data/bundler.gemspec +4 -4
  5. data/exe/bundle +3 -0
  6. data/lib/bundler.rb +33 -9
  7. data/lib/bundler/build_metadata.rb +3 -11
  8. data/lib/bundler/cli.rb +59 -23
  9. data/lib/bundler/cli/add.rb +1 -1
  10. data/lib/bundler/cli/binstubs.rb +6 -2
  11. data/lib/bundler/cli/cache.rb +2 -7
  12. data/lib/bundler/cli/clean.rb +1 -1
  13. data/lib/bundler/cli/common.rb +29 -2
  14. data/lib/bundler/cli/console.rb +1 -1
  15. data/lib/bundler/cli/doctor.rb +1 -1
  16. data/lib/bundler/cli/exec.rb +4 -4
  17. data/lib/bundler/cli/fund.rb +36 -0
  18. data/lib/bundler/cli/gem.rb +129 -28
  19. data/lib/bundler/cli/info.rb +15 -4
  20. data/lib/bundler/cli/init.rb +2 -2
  21. data/lib/bundler/cli/inject.rb +1 -1
  22. data/lib/bundler/cli/install.rb +13 -11
  23. data/lib/bundler/cli/issue.rb +2 -2
  24. data/lib/bundler/cli/list.rb +12 -10
  25. data/lib/bundler/cli/outdated.rb +88 -67
  26. data/lib/bundler/cli/plugin.rb +10 -0
  27. data/lib/bundler/cli/pristine.rb +5 -0
  28. data/lib/bundler/cli/show.rb +1 -1
  29. data/lib/bundler/cli/update.rb +3 -1
  30. data/lib/bundler/compact_index_client.rb +1 -1
  31. data/lib/bundler/compact_index_client/cache.rb +6 -14
  32. data/lib/bundler/compact_index_client/gem_parser.rb +28 -0
  33. data/lib/bundler/compact_index_client/updater.rb +13 -17
  34. data/lib/bundler/current_ruby.rb +1 -0
  35. data/lib/bundler/definition.rb +121 -131
  36. data/lib/bundler/dep_proxy.rb +16 -9
  37. data/lib/bundler/dependency.rb +3 -10
  38. data/lib/bundler/dsl.rb +40 -33
  39. data/lib/bundler/endpoint_specification.rb +1 -1
  40. data/lib/bundler/env.rb +1 -1
  41. data/lib/bundler/environment_preserver.rb +26 -2
  42. data/lib/bundler/errors.rb +1 -0
  43. data/lib/bundler/feature_flag.rb +0 -5
  44. data/lib/bundler/fetcher.rb +5 -4
  45. data/lib/bundler/fetcher/base.rb +1 -1
  46. data/lib/bundler/fetcher/compact_index.rb +1 -1
  47. data/lib/bundler/fetcher/downloader.rb +9 -5
  48. data/lib/bundler/fetcher/index.rb +3 -4
  49. data/lib/bundler/friendly_errors.rb +22 -13
  50. data/lib/bundler/gem_helper.rb +51 -18
  51. data/lib/bundler/gem_helpers.rb +36 -25
  52. data/lib/bundler/gem_version_promoter.rb +4 -4
  53. data/lib/bundler/graph.rb +1 -1
  54. data/lib/bundler/index.rb +12 -7
  55. data/lib/bundler/injector.rb +23 -5
  56. data/lib/bundler/inline.rb +3 -2
  57. data/lib/bundler/installer.rb +37 -49
  58. data/lib/bundler/installer/gem_installer.rb +3 -3
  59. data/lib/bundler/installer/parallel_installer.rb +46 -25
  60. data/lib/bundler/installer/standalone.rb +17 -2
  61. data/lib/bundler/lazy_specification.rb +45 -25
  62. data/lib/bundler/lockfile_generator.rb +1 -1
  63. data/lib/bundler/lockfile_parser.rb +4 -14
  64. data/lib/bundler/man/.document +1 -0
  65. data/{man → lib/bundler/man}/bundle-add.1 +1 -1
  66. data/{man/bundle-add.ronn → lib/bundler/man/bundle-add.1.ronn} +0 -0
  67. data/{man → lib/bundler/man}/bundle-binstubs.1 +5 -3
  68. data/{man/bundle-binstubs.ronn → lib/bundler/man/bundle-binstubs.1.ronn} +2 -4
  69. data/{man → lib/bundler/man}/bundle-cache.1 +1 -1
  70. data/{man/bundle-cache.ronn → lib/bundler/man/bundle-cache.1.ronn} +0 -0
  71. data/{man → lib/bundler/man}/bundle-check.1 +1 -1
  72. data/{man/bundle-check.ronn → lib/bundler/man/bundle-check.1.ronn} +0 -0
  73. data/{man → lib/bundler/man}/bundle-clean.1 +1 -1
  74. data/{man/bundle-clean.ronn → lib/bundler/man/bundle-clean.1.ronn} +0 -0
  75. data/{man → lib/bundler/man}/bundle-config.1 +42 -34
  76. data/{man/bundle-config.ronn → lib/bundler/man/bundle-config.1.ronn} +51 -43
  77. data/{man → lib/bundler/man}/bundle-doctor.1 +1 -1
  78. data/{man/bundle-doctor.ronn → lib/bundler/man/bundle-doctor.1.ronn} +0 -0
  79. data/{man → lib/bundler/man}/bundle-exec.1 +1 -1
  80. data/{man/bundle-exec.ronn → lib/bundler/man/bundle-exec.1.ronn} +0 -0
  81. data/{man → lib/bundler/man}/bundle-gem.1 +25 -3
  82. data/{man/bundle-gem.ronn → lib/bundler/man/bundle-gem.1.ronn} +30 -7
  83. data/{man → lib/bundler/man}/bundle-info.1 +1 -1
  84. data/{man/bundle-info.ronn → lib/bundler/man/bundle-info.1.ronn} +0 -0
  85. data/{man → lib/bundler/man}/bundle-init.1 +1 -1
  86. data/{man/bundle-init.ronn → lib/bundler/man/bundle-init.1.ronn} +0 -0
  87. data/{man → lib/bundler/man}/bundle-inject.1 +1 -1
  88. data/{man/bundle-inject.ronn → lib/bundler/man/bundle-inject.1.ronn} +0 -0
  89. data/{man → lib/bundler/man}/bundle-install.1 +30 -3
  90. data/{man/bundle-install.ronn → lib/bundler/man/bundle-install.1.ronn} +25 -3
  91. data/{man → lib/bundler/man}/bundle-list.1 +7 -7
  92. data/{man/bundle-list.ronn → lib/bundler/man/bundle-list.1.ronn} +6 -6
  93. data/{man → lib/bundler/man}/bundle-lock.1 +1 -1
  94. data/{man/bundle-lock.ronn → lib/bundler/man/bundle-lock.1.ronn} +0 -0
  95. data/{man → lib/bundler/man}/bundle-open.1 +1 -1
  96. data/{man/bundle-open.ronn → lib/bundler/man/bundle-open.1.ronn} +0 -0
  97. data/{man → lib/bundler/man}/bundle-outdated.1 +1 -1
  98. data/{man/bundle-outdated.ronn → lib/bundler/man/bundle-outdated.1.ronn} +0 -0
  99. data/{man → lib/bundler/man}/bundle-platform.1 +1 -1
  100. data/{man/bundle-platform.ronn → lib/bundler/man/bundle-platform.1.ronn} +0 -0
  101. data/{man → lib/bundler/man}/bundle-pristine.1 +1 -1
  102. data/{man/bundle-pristine.ronn → lib/bundler/man/bundle-pristine.1.ronn} +0 -0
  103. data/{man → lib/bundler/man}/bundle-remove.1 +1 -1
  104. data/{man/bundle-remove.ronn → lib/bundler/man/bundle-remove.1.ronn} +0 -0
  105. data/{man → lib/bundler/man}/bundle-show.1 +1 -1
  106. data/{man/bundle-show.ronn → lib/bundler/man/bundle-show.1.ronn} +0 -0
  107. data/{man → lib/bundler/man}/bundle-update.1 +1 -1
  108. data/{man/bundle-update.ronn → lib/bundler/man/bundle-update.1.ronn} +0 -0
  109. data/{man → lib/bundler/man}/bundle-viz.1 +1 -1
  110. data/{man/bundle-viz.ronn → lib/bundler/man/bundle-viz.1.ronn} +0 -0
  111. data/{man → lib/bundler/man}/bundle.1 +1 -1
  112. data/{man/bundle.ronn → lib/bundler/man/bundle.1.ronn} +0 -0
  113. data/{man → lib/bundler/man}/gemfile.5 +4 -4
  114. data/{man → lib/bundler/man}/gemfile.5.ronn +4 -4
  115. data/{man → lib/bundler/man}/index.txt +0 -0
  116. data/lib/bundler/mirror.rb +2 -2
  117. data/lib/bundler/plugin.rb +33 -7
  118. data/lib/bundler/plugin/api/source.rb +8 -1
  119. data/lib/bundler/plugin/dsl.rb +1 -1
  120. data/lib/bundler/plugin/index.rb +10 -1
  121. data/lib/bundler/plugin/installer.rb +9 -11
  122. data/lib/bundler/plugin/installer/rubygems.rb +1 -1
  123. data/lib/bundler/plugin/source_list.rb +5 -1
  124. data/lib/bundler/psyched_yaml.rb +0 -15
  125. data/lib/bundler/remote_specification.rb +5 -2
  126. data/lib/bundler/resolver.rb +133 -77
  127. data/lib/bundler/resolver/spec_group.rb +75 -48
  128. data/lib/bundler/retry.rb +2 -2
  129. data/lib/bundler/ruby_version.rb +1 -1
  130. data/lib/bundler/rubygems_ext.rb +69 -9
  131. data/lib/bundler/rubygems_gem_installer.rb +50 -9
  132. data/lib/bundler/rubygems_integration.rb +25 -60
  133. data/lib/bundler/runtime.rb +4 -14
  134. data/lib/bundler/settings.rb +107 -54
  135. data/lib/bundler/shared_helpers.rb +3 -3
  136. data/lib/bundler/similarity_detector.rb +1 -1
  137. data/lib/bundler/source.rb +7 -1
  138. data/lib/bundler/source/git.rb +24 -22
  139. data/lib/bundler/source/git/git_proxy.rb +82 -80
  140. data/lib/bundler/source/metadata.rb +0 -4
  141. data/lib/bundler/source/path.rb +10 -4
  142. data/lib/bundler/source/path/installer.rb +10 -10
  143. data/lib/bundler/source/rubygems.rb +45 -24
  144. data/lib/bundler/source/rubygems/remote.rb +1 -1
  145. data/lib/bundler/source_list.rb +31 -26
  146. data/lib/bundler/spec_set.rb +29 -17
  147. data/lib/bundler/stub_specification.rb +25 -7
  148. data/lib/bundler/templates/Gemfile +1 -1
  149. data/lib/bundler/templates/gems.rb +1 -1
  150. data/lib/bundler/templates/newgem/CHANGELOG.md.tt +5 -0
  151. data/lib/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt +57 -47
  152. data/lib/bundler/templates/newgem/Gemfile.tt +9 -1
  153. data/lib/bundler/templates/newgem/README.md.tt +6 -5
  154. data/lib/bundler/templates/newgem/Rakefile.tt +19 -5
  155. data/lib/bundler/templates/newgem/bin/console.tt +1 -0
  156. data/lib/bundler/templates/newgem/circleci/config.yml.tt +13 -0
  157. data/lib/bundler/templates/newgem/ext/newgem/extconf.rb.tt +2 -0
  158. data/lib/bundler/templates/newgem/github/workflows/main.yml.tt +16 -0
  159. data/lib/bundler/templates/newgem/gitlab-ci.yml.tt +9 -0
  160. data/lib/bundler/templates/newgem/lib/newgem.rb.tt +4 -2
  161. data/lib/bundler/templates/newgem/lib/newgem/version.rb.tt +2 -0
  162. data/lib/bundler/templates/newgem/newgem.gemspec.tt +15 -7
  163. data/lib/bundler/templates/newgem/rubocop.yml.tt +13 -0
  164. data/lib/bundler/templates/newgem/spec/newgem_spec.rb.tt +2 -0
  165. data/lib/bundler/templates/newgem/spec/spec_helper.rb.tt +2 -1
  166. data/lib/bundler/templates/newgem/test/{newgem_test.rb.tt → minitest/newgem_test.rb.tt} +2 -0
  167. data/lib/bundler/templates/newgem/test/{test_helper.rb.tt → minitest/test_helper.rb.tt} +2 -0
  168. data/lib/bundler/templates/newgem/test/test-unit/newgem_test.rb.tt +15 -0
  169. data/lib/bundler/templates/newgem/test/test-unit/test_helper.rb.tt +6 -0
  170. data/lib/bundler/ui/shell.rb +5 -5
  171. data/lib/bundler/uri_credentials_filter.rb +3 -1
  172. data/lib/bundler/vendor/molinillo/lib/molinillo.rb +0 -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.rb +34 -2
  175. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/tag.rb +2 -2
  176. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb +11 -5
  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/net-http-persistent/lib/net/http/persistent.rb +82 -189
  182. data/lib/bundler/vendor/thor/lib/thor.rb +5 -13
  183. data/lib/bundler/vendor/thor/lib/thor/actions.rb +1 -1
  184. data/lib/bundler/vendor/thor/lib/thor/actions/create_link.rb +2 -1
  185. data/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb +4 -2
  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/tmpdir/lib/tmpdir.rb +154 -0
  194. data/lib/bundler/vendored_persistent.rb +0 -7
  195. data/lib/bundler/vendored_tmpdir.rb +4 -0
  196. data/lib/bundler/version.rb +1 -1
  197. data/lib/bundler/worker.rb +1 -1
  198. data/lib/bundler/yaml_serializer.rb +1 -1
  199. metadata +71 -85
  200. data/lib/bundler/vendor/molinillo/lib/molinillo/compatibility.rb +0 -26
  201. data/man/bundle-add.1.txt +0 -58
  202. data/man/bundle-binstubs.1.txt +0 -48
  203. data/man/bundle-cache.1.txt +0 -78
  204. data/man/bundle-check.1.txt +0 -33
  205. data/man/bundle-clean.1.txt +0 -26
  206. data/man/bundle-config.1.txt +0 -528
  207. data/man/bundle-doctor.1.txt +0 -44
  208. data/man/bundle-exec.1.txt +0 -178
  209. data/man/bundle-gem.1.txt +0 -91
  210. data/man/bundle-info.1.txt +0 -21
  211. data/man/bundle-init.1.txt +0 -34
  212. data/man/bundle-inject.1.txt +0 -32
  213. data/man/bundle-install.1.txt +0 -401
  214. data/man/bundle-list.1.txt +0 -43
  215. data/man/bundle-lock.1.txt +0 -93
  216. data/man/bundle-open.1.txt +0 -29
  217. data/man/bundle-outdated.1.txt +0 -131
  218. data/man/bundle-platform.1.txt +0 -57
  219. data/man/bundle-pristine.1.txt +0 -44
  220. data/man/bundle-remove.1.txt +0 -34
  221. data/man/bundle-show.1.txt +0 -27
  222. data/man/bundle-update.1.txt +0 -390
  223. data/man/bundle-viz.1.txt +0 -39
  224. data/man/bundle.1.txt +0 -116
  225. data/man/gemfile.5.txt +0 -649
@@ -34,7 +34,7 @@ module Bundler::Molinillo
34
34
 
35
35
  # An error caused by attempting to fulfil a dependency that was circular
36
36
  #
37
- # @note This exception will be thrown iff a {Vertex} is added to a
37
+ # @note This exception will be thrown if and only if a {Vertex} is added to a
38
38
  # {DependencyGraph} that has a {DependencyGraph::Vertex#path_to?} an
39
39
  # existing {DependencyGraph::Vertex}
40
40
  class CircularDependencyError < ResolverError
@@ -65,7 +65,7 @@ module Bundler::Molinillo
65
65
  # @param [SpecificationProvider] specification_provider see {#specification_provider}
66
66
  def initialize(conflicts, specification_provider)
67
67
  pairs = []
68
- Compatibility.flat_map(conflicts.values.flatten, &:requirements).each do |conflicting|
68
+ conflicts.values.flat_map(&:requirements).each do |conflicting|
69
69
  conflicting.each do |source, conflict_requirements|
70
70
  conflict_requirements.each do |c|
71
71
  pairs << [c, source]
@@ -121,7 +121,7 @@ module Bundler::Molinillo
121
121
  t = ''.dup
122
122
  depth = 2
123
123
  tree.each do |req|
124
- t << ' ' * depth << req.to_s
124
+ t << ' ' * depth << printable_requirement.call(req)
125
125
  unless tree.last == req
126
126
  if spec = conflict.activated_by_name[name_for(req)]
127
127
  t << %( was resolved to #{version_for_spec.call(spec)}, which)
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Bundler::Molinillo
4
4
  # The version of Bundler::Molinillo.
5
- VERSION = '0.6.6'.freeze
5
+ VERSION = '0.7.0'.freeze
6
6
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Bundler::Molinillo
4
- # Provides information about specifcations and dependencies to the resolver,
4
+ # Provides information about specifications and dependencies to the resolver,
5
5
  # allowing the {Resolver} class to remain generic while still providing power
6
6
  # and flexibility.
7
7
  #
@@ -45,6 +45,17 @@ module Bundler::Molinillo
45
45
  true
46
46
  end
47
47
 
48
+ # Determines whether two arrays of dependencies are equal, and thus can be
49
+ # grouped.
50
+ #
51
+ # @param [Array<Object>] dependencies
52
+ # @param [Array<Object>] other_dependencies
53
+ # @return [Boolean] whether `dependencies` and `other_dependencies` should
54
+ # be considered equal.
55
+ def dependencies_equal?(dependencies, other_dependencies)
56
+ dependencies == other_dependencies
57
+ end
58
+
48
59
  # Returns the name for the given `dependency`.
49
60
  # @note This method should be 'pure', i.e. the return value should depend
50
61
  # only on the `dependency` parameter.
@@ -207,7 +207,7 @@ module Bundler::Molinillo
207
207
  def start_resolution
208
208
  @started_at = Time.now
209
209
 
210
- handle_missing_or_push_dependency_state(initial_state)
210
+ push_initial_state
211
211
 
212
212
  debug { "Starting resolution (#{@started_at})\nUser-requested dependencies: #{original_requested}" }
213
213
  resolver_ui.before_resolution
@@ -273,10 +273,10 @@ module Bundler::Molinillo
273
273
  states.last
274
274
  end
275
275
 
276
- # Creates the initial state for the resolution, based upon the
276
+ # Creates and pushes the initial state for the resolution, based upon the
277
277
  # {#requested} dependencies
278
- # @return [DependencyState] the initial state for the resolution
279
- def initial_state
278
+ # @return [void]
279
+ def push_initial_state
280
280
  graph = DependencyGraph.new.tap do |dg|
281
281
  original_requested.each do |requested|
282
282
  vertex = dg.add_vertex(name_for(requested), nil, true)
@@ -285,18 +285,7 @@ module Bundler::Molinillo
285
285
  dg.tag(:initial_state)
286
286
  end
287
287
 
288
- requirements = sort_dependencies(original_requested, graph, {})
289
- initial_requirement = requirements.shift
290
- DependencyState.new(
291
- initial_requirement && name_for(initial_requirement),
292
- requirements,
293
- graph,
294
- initial_requirement,
295
- possibilities_for_requirement(initial_requirement, graph),
296
- 0,
297
- {},
298
- []
299
- )
288
+ push_state_for_requirements(original_requested, true, graph)
300
289
  end
301
290
 
302
291
  # Unwinds the states stack because a conflict has been encountered
@@ -340,11 +329,11 @@ module Bundler::Molinillo
340
329
 
341
330
  # Look for past conflicts that could be unwound to affect the
342
331
  # requirement tree for the current conflict
332
+ all_reqs = last_detail_for_current_unwind.all_requirements
333
+ all_reqs_size = all_reqs.size
343
334
  relevant_unused_unwinds = unused_unwind_options.select do |alternative|
344
- intersecting_requirements =
345
- last_detail_for_current_unwind.all_requirements &
346
- alternative.requirements_unwound_to_instead
347
- next if intersecting_requirements.empty?
335
+ diff_reqs = all_reqs - alternative.requirements_unwound_to_instead
336
+ next if diff_reqs.size == all_reqs_size
348
337
  # Find the highest index unwind whilst looping through
349
338
  current_detail = alternative if alternative > current_detail
350
339
  alternative
@@ -355,13 +344,17 @@ module Bundler::Molinillo
355
344
  state.unused_unwind_options += unwind_details.reject { |detail| detail.state_index == -1 }
356
345
 
357
346
  # Update the requirements_unwound_to_instead on any relevant unused unwinds
358
- relevant_unused_unwinds.each { |d| d.requirements_unwound_to_instead << current_detail.state_requirement }
359
- unwind_details.each { |d| d.requirements_unwound_to_instead << current_detail.state_requirement }
347
+ relevant_unused_unwinds.each do |d|
348
+ (d.requirements_unwound_to_instead << current_detail.state_requirement).uniq!
349
+ end
350
+ unwind_details.each do |d|
351
+ (d.requirements_unwound_to_instead << current_detail.state_requirement).uniq!
352
+ end
360
353
 
361
354
  current_detail
362
355
  end
363
356
 
364
- # @param [Array<Object>] array of requirements that combine to create a conflict
357
+ # @param [Array<Object>] binding_requirements array of requirements that combine to create a conflict
365
358
  # @return [Array<UnwindDetails>] array of UnwindDetails that have a chance
366
359
  # of resolving the passed requirements
367
360
  def unwind_options_for_requirements(binding_requirements)
@@ -429,7 +422,7 @@ module Bundler::Molinillo
429
422
  end
430
423
 
431
424
  # @param [DependencyState] state
432
- # @param [Array] array of requirements
425
+ # @param [Array] binding_requirements array of requirements
433
426
  # @return [Boolean] whether or not the given state has any possibilities
434
427
  # that could satisfy the given requirements
435
428
  def conflict_fixing_possibilities?(state, binding_requirements)
@@ -444,7 +437,8 @@ module Bundler::Molinillo
444
437
 
445
438
  # Filter's a state's possibilities to remove any that would not fix the
446
439
  # conflict we've just rewound from
447
- # @param [UnwindDetails] details of the conflict just unwound from
440
+ # @param [UnwindDetails] unwind_details details of the conflict just
441
+ # unwound from
448
442
  # @return [void]
449
443
  def filter_possibilities_after_unwind(unwind_details)
450
444
  return unless state && !state.possibilities.empty?
@@ -458,7 +452,7 @@ module Bundler::Molinillo
458
452
 
459
453
  # Filter's a state's possibilities to remove any that would not satisfy
460
454
  # the requirements in the conflict we've just rewound from
461
- # @param [UnwindDetails] details of the conflict just unwound from
455
+ # @param [UnwindDetails] unwind_details details of the conflict just unwound from
462
456
  # @return [void]
463
457
  def filter_possibilities_for_primary_unwind(unwind_details)
464
458
  unwinds_to_state = unused_unwind_options.select { |uw| uw.state_index == unwind_details.state_index }
@@ -491,7 +485,7 @@ module Bundler::Molinillo
491
485
 
492
486
  # Filter's a state's possibilities to remove any that would (eventually)
493
487
  # create a requirement in the conflict we've just rewound from
494
- # @param [UnwindDetails] details of the conflict just unwound from
488
+ # @param [UnwindDetails] unwind_details details of the conflict just unwound from
495
489
  # @return [void]
496
490
  def filter_possibilities_for_parent_unwind(unwind_details)
497
491
  unwinds_to_state = unused_unwind_options.select { |uw| uw.state_index == unwind_details.state_index }
@@ -500,7 +494,7 @@ module Bundler::Molinillo
500
494
  primary_unwinds = unwinds_to_state.select(&:unwinding_to_primary_requirement?).uniq
501
495
  parent_unwinds = unwinds_to_state.uniq - primary_unwinds
502
496
 
503
- allowed_possibility_sets = Compatibility.flat_map(primary_unwinds) do |unwind|
497
+ allowed_possibility_sets = primary_unwinds.flat_map do |unwind|
504
498
  states[unwind.state_index].possibilities.select do |possibility_set|
505
499
  possibility_set.possibilities.any? do |poss|
506
500
  possibility_satisfies_requirements?(poss, unwind.conflicting_requirements)
@@ -508,7 +502,7 @@ module Bundler::Molinillo
508
502
  end
509
503
  end
510
504
 
511
- requirements_to_avoid = Compatibility.flat_map(parent_unwinds, &:sub_dependencies_to_avoid)
505
+ requirements_to_avoid = parent_unwinds.flat_map(&:sub_dependencies_to_avoid)
512
506
 
513
507
  state.possibilities.reject! do |possibility_set|
514
508
  !allowed_possibility_sets.include?(possibility_set) &&
@@ -524,12 +518,12 @@ module Bundler::Molinillo
524
518
 
525
519
  possible_binding_requirements = conflict.requirements.values.flatten(1).uniq
526
520
 
527
- # When theres a `CircularDependency` error the conflicting requirement
528
- # (the one causing the circular) wont be `conflict.requirement`
529
- # (which wont be for the right state, because we wont have created it,
530
- # because its circular).
531
- # We need to make sure we have that requirement in the conflicts list,
532
- # otherwise we wont be able to unwind properly, so we just return all
521
+ # When there's a `CircularDependency` error the conflicting requirement
522
+ # (the one causing the circular) won't be `conflict.requirement`
523
+ # (which won't be for the right state, because we won't have created it,
524
+ # because it's circular).
525
+ # We need to make sure we have that requirement in the conflict's list,
526
+ # otherwise we won't be able to unwind properly, so we just return all
533
527
  # the requirements for the conflict.
534
528
  return possible_binding_requirements if conflict.underlying_error
535
529
 
@@ -558,8 +552,8 @@ module Bundler::Molinillo
558
552
  end
559
553
 
560
554
  # @param [Object] requirement we wish to check
561
- # @param [Array] array of requirements
562
- # @param [Array] array of possibilities the requirements will be used to filter
555
+ # @param [Array] possible_binding_requirements array of requirements
556
+ # @param [Array] possibilities array of possibilities the requirements will be used to filter
563
557
  # @return [Boolean] whether or not the given requirement is required to filter
564
558
  # out all elements of the array of possibilities.
565
559
  def binding_requirement_in_set?(requirement, possible_binding_requirements, possibilities)
@@ -568,6 +562,7 @@ module Bundler::Molinillo
568
562
  end
569
563
  end
570
564
 
565
+ # @param [Object] requirement
571
566
  # @return [Object] the requirement that led to `requirement` being added
572
567
  # to the list of requirements.
573
568
  def parent_of(requirement)
@@ -577,6 +572,7 @@ module Bundler::Molinillo
577
572
  parent_state.requirement
578
573
  end
579
574
 
575
+ # @param [String] name
580
576
  # @return [Object] the requirement that led to a version of a possibility
581
577
  # with the given name being activated.
582
578
  def requirement_for_existing_name(name)
@@ -585,6 +581,7 @@ module Bundler::Molinillo
585
581
  states.find { |s| s.name == name }.requirement
586
582
  end
587
583
 
584
+ # @param [Object] requirement
588
585
  # @return [ResolutionState] the state whose `requirement` is the given
589
586
  # `requirement`.
590
587
  def find_state_for(requirement)
@@ -592,6 +589,7 @@ module Bundler::Molinillo
592
589
  states.find { |i| requirement == i.requirement }
593
590
  end
594
591
 
592
+ # @param [Object] underlying_error
595
593
  # @return [Conflict] a {Conflict} that reflects the failure to activate
596
594
  # the {#possibility} in conjunction with the current {#state}
597
595
  def create_conflict(underlying_error = nil)
@@ -628,6 +626,7 @@ module Bundler::Molinillo
628
626
  vertex.requirements.map { |r| requirement_tree_for(r) }
629
627
  end
630
628
 
629
+ # @param [Object] requirement
631
630
  # @return [Array<Object>] the list of requirements that led to
632
631
  # `requirement` being required.
633
632
  def requirement_tree_for(requirement)
@@ -673,9 +672,8 @@ module Bundler::Molinillo
673
672
  attempt_to_filter_existing_spec(existing_vertex)
674
673
  else
675
674
  latest = possibility.latest_version
676
- # use reject!(!satisfied) for 1.8.7 compatibility
677
- possibility.possibilities.reject! do |possibility|
678
- !requirement_satisfied_by?(requirement, activated, possibility)
675
+ possibility.possibilities.select! do |possibility|
676
+ requirement_satisfied_by?(requirement, activated, possibility)
679
677
  end
680
678
  if possibility.latest_version.nil?
681
679
  # ensure there's a possibility for better error messages
@@ -705,7 +703,7 @@ module Bundler::Molinillo
705
703
 
706
704
  # Generates a filtered version of the existing vertex's `PossibilitySet` using the
707
705
  # current state's `requirement`
708
- # @param [Object] existing vertex
706
+ # @param [Object] vertex existing vertex
709
707
  # @return [PossibilitySet] filtered possibility set
710
708
  def filtered_possibility_set(vertex)
711
709
  PossibilitySet.new(vertex.payload.dependencies, vertex.payload.possibilities & possibility.possibilities)
@@ -730,7 +728,7 @@ module Bundler::Molinillo
730
728
  end
731
729
 
732
730
  # Requires the dependencies that the recently activated spec has
733
- # @param [Object] activated_possibility the PossibilitySet that has just been
731
+ # @param [Object] possibility_set the PossibilitySet that has just been
734
732
  # activated
735
733
  # @return [void]
736
734
  def require_nested_dependencies_for(possibility_set)
@@ -749,6 +747,8 @@ module Bundler::Molinillo
749
747
  # Pushes a new {DependencyState} that encapsulates both existing and new
750
748
  # requirements
751
749
  # @param [Array] new_requirements
750
+ # @param [Boolean] requires_sort
751
+ # @param [Object] new_activated
752
752
  # @return [void]
753
753
  def push_state_for_requirements(new_requirements, requires_sort = true, new_activated = activated)
754
754
  new_requirements = sort_dependencies(new_requirements.uniq, new_activated, conflicts) if requires_sort
@@ -767,7 +767,8 @@ module Bundler::Molinillo
767
767
 
768
768
  # Checks a proposed requirement with any existing locked requirement
769
769
  # before generating an array of possibilities for it.
770
- # @param [Object] the proposed requirement
770
+ # @param [Object] requirement the proposed requirement
771
+ # @param [Object] activated
771
772
  # @return [Array] possibilities
772
773
  def possibilities_for_requirement(requirement, activated = self.activated)
773
774
  return [] unless requirement
@@ -778,7 +779,8 @@ module Bundler::Molinillo
778
779
  group_possibilities(search_for(requirement))
779
780
  end
780
781
 
781
- # @param [Object] the proposed requirement
782
+ # @param [Object] requirement the proposed requirement
783
+ # @param [Object] activated
782
784
  # @return [Array] possibility set containing only the locked requirement, if any
783
785
  def locked_requirement_possibility_set(requirement, activated = self.activated)
784
786
  all_possibilities = search_for(requirement)
@@ -797,15 +799,15 @@ module Bundler::Molinillo
797
799
  # Build an array of PossibilitySets, with each element representing a group of
798
800
  # dependency versions that all have the same sub-dependency version constraints
799
801
  # and are contiguous.
800
- # @param [Array] an array of possibilities
801
- # @return [Array] an array of possibility sets
802
+ # @param [Array] possibilities an array of possibilities
803
+ # @return [Array<PossibilitySet>] an array of possibility sets
802
804
  def group_possibilities(possibilities)
803
805
  possibility_sets = []
804
806
  current_possibility_set = nil
805
807
 
806
808
  possibilities.reverse_each do |possibility|
807
809
  dependencies = dependencies_for(possibility)
808
- if current_possibility_set && current_possibility_set.dependencies == dependencies
810
+ if current_possibility_set && dependencies_equal?(current_possibility_set.dependencies, dependencies)
809
811
  current_possibility_set.possibilities.unshift(possibility)
810
812
  else
811
813
  possibility_sets.unshift(PossibilitySet.new(dependencies, [possibility]))
@@ -12,15 +12,11 @@ autoload :OpenSSL, 'openssl'
12
12
  # servers you wish to talk to. For each host:port you communicate with a
13
13
  # single persistent connection is created.
14
14
  #
15
- # Multiple Bundler::Persistent::Net::HTTP::Persistent objects will share the same set of
16
- # connections.
15
+ # Connections will be shared across threads through a connection pool to
16
+ # increase reuse of connections.
17
17
  #
18
- # For each thread you start a new connection will be created. A
19
- # Bundler::Persistent::Net::HTTP::Persistent connection will not be shared across threads.
20
- #
21
- # You can shut down the HTTP connections when done by calling #shutdown. You
22
- # should name your Bundler::Persistent::Net::HTTP::Persistent object if you intend to call this
23
- # method.
18
+ # You can shut down any remaining HTTP connections when done by calling
19
+ # #shutdown.
24
20
  #
25
21
  # Example:
26
22
  #
@@ -28,7 +24,7 @@ autoload :OpenSSL, 'openssl'
28
24
  #
29
25
  # uri = Bundler::URI 'http://example.com/awesome/web/service'
30
26
  #
31
- # http = Bundler::Persistent::Net::HTTP::Persistent.new name: 'my_app_name'
27
+ # http = Bundler::Persistent::Net::HTTP::Persistent.new
32
28
  #
33
29
  # # perform a GET
34
30
  # response = http.request uri
@@ -50,14 +46,14 @@ autoload :OpenSSL, 'openssl'
50
46
  # to use Bundler::URI#request_uri not Bundler::URI#path. The request_uri contains the query
51
47
  # params which are sent in the body for other requests.
52
48
  #
53
- # == SSL
49
+ # == TLS/SSL
54
50
  #
55
- # SSL connections are automatically created depending upon the scheme of the
56
- # Bundler::URI. SSL connections are automatically verified against the default
51
+ # TLS connections are automatically created depending upon the scheme of the
52
+ # Bundler::URI. TLS connections are automatically verified against the default
57
53
  # certificate store for your computer. You can override this by changing
58
54
  # verify_mode or by specifying an alternate cert_store.
59
55
  #
60
- # Here are the SSL settings, see the individual methods for documentation:
56
+ # Here are the TLS settings, see the individual methods for documentation:
61
57
  #
62
58
  # #certificate :: This client's certificate
63
59
  # #ca_file :: The certificate-authorities
@@ -67,7 +63,7 @@ autoload :OpenSSL, 'openssl'
67
63
  # #private_key :: The client's SSL private key
68
64
  # #reuse_ssl_sessions :: Reuse a previously opened SSL session for a new
69
65
  # connection
70
- # #ssl_timeout :: SSL session lifetime
66
+ # #ssl_timeout :: Session lifetime
71
67
  # #ssl_version :: Which specific SSL version to use
72
68
  # #verify_callback :: For server certificate verification
73
69
  # #verify_depth :: Depth of certificate verification
@@ -96,14 +92,15 @@ autoload :OpenSSL, 'openssl'
96
92
  #
97
93
  # === Segregation
98
94
  #
99
- # By providing an application name to ::new you can separate your connections
100
- # from the connections of other applications.
95
+ # Each Bundler::Persistent::Net::HTTP::Persistent instance has its own pool of connections. There
96
+ # is no sharing with other instances (as was true in earlier versions).
101
97
  #
102
98
  # === Idle Timeout
103
99
  #
104
- # If a connection hasn't been used for this number of seconds it will automatically be
105
- # reset upon the next use to avoid attempting to send to a closed connection.
106
- # The default value is 5 seconds. nil means no timeout. Set through #idle_timeout.
100
+ # If a connection hasn't been used for this number of seconds it will
101
+ # automatically be reset upon the next use to avoid attempting to send to a
102
+ # closed connection. The default value is 5 seconds. nil means no timeout.
103
+ # Set through #idle_timeout.
107
104
  #
108
105
  # Reducing this value may help avoid the "too many connection resets" error
109
106
  # when sending non-idempotent requests while increasing this value will cause
@@ -118,8 +115,9 @@ autoload :OpenSSL, 'openssl'
118
115
  #
119
116
  # The number of requests that should be made before opening a new connection.
120
117
  # Typically many keep-alive capable servers tune this to 100 or less, so the
121
- # 101st request will fail with ECONNRESET. If unset (default), this value has no
122
- # effect, if set, connections will be reset on the request after max_requests.
118
+ # 101st request will fail with ECONNRESET. If unset (default), this value has
119
+ # no effect, if set, connections will be reset on the request after
120
+ # max_requests.
123
121
  #
124
122
  # === Open Timeout
125
123
  #
@@ -131,45 +129,6 @@ autoload :OpenSSL, 'openssl'
131
129
  # Socket options may be set on newly-created connections. See #socket_options
132
130
  # for details.
133
131
  #
134
- # === Non-Idempotent Requests
135
- #
136
- # By default non-idempotent requests will not be retried per RFC 2616. By
137
- # setting retry_change_requests to true requests will automatically be retried
138
- # once.
139
- #
140
- # Only do this when you know that retrying a POST or other non-idempotent
141
- # request is safe for your application and will not create duplicate
142
- # resources.
143
- #
144
- # The recommended way to handle non-idempotent requests is the following:
145
- #
146
- # require 'bundler/vendor/net-http-persistent/lib/net/http/persistent'
147
- #
148
- # uri = Bundler::URI 'http://example.com/awesome/web/service'
149
- # post_uri = uri + 'create'
150
- #
151
- # http = Bundler::Persistent::Net::HTTP::Persistent.new name: 'my_app_name'
152
- #
153
- # post = Net::HTTP::Post.new post_uri.path
154
- # # ... fill in POST request
155
- #
156
- # begin
157
- # response = http.request post_uri, post
158
- # rescue Bundler::Persistent::Net::HTTP::Persistent::Error
159
- #
160
- # # POST failed, make a new request to verify the server did not process
161
- # # the request
162
- # exists_uri = uri + '...'
163
- # response = http.get exists_uri
164
- #
165
- # # Retry if it failed
166
- # retry if response.code == '404'
167
- # end
168
- #
169
- # The method of determining if the resource was created or not is unique to
170
- # the particular service you are using. Of course, you will want to add
171
- # protection from infinite looping.
172
- #
173
132
  # === Connection Termination
174
133
  #
175
134
  # If you are done using the Bundler::Persistent::Net::HTTP::Persistent instance you may shut down
@@ -195,33 +154,27 @@ class Bundler::Persistent::Net::HTTP::Persistent
195
154
  HAVE_OPENSSL = defined? OpenSSL::SSL # :nodoc:
196
155
 
197
156
  ##
198
- # The default connection pool size is 1/4 the allowed open files.
157
+ # The default connection pool size is 1/4 the allowed open files
158
+ # (<code>ulimit -n</code>) or 256 if your OS does not support file handle
159
+ # limits (typically windows).
199
160
 
200
- if Gem.win_platform? then
201
- DEFAULT_POOL_SIZE = 256
161
+ if Process.const_defined? :RLIMIT_NOFILE
162
+ open_file_limits = Process.getrlimit(Process::RLIMIT_NOFILE)
163
+
164
+ # Under JRuby on Windows Process responds to `getrlimit` but returns something that does not match docs
165
+ if open_file_limits.respond_to?(:first)
166
+ DEFAULT_POOL_SIZE = open_file_limits.first / 4
167
+ else
168
+ DEFAULT_POOL_SIZE = 256
169
+ end
202
170
  else
203
- DEFAULT_POOL_SIZE = Process.getrlimit(Process::RLIMIT_NOFILE).first / 4
171
+ DEFAULT_POOL_SIZE = 256
204
172
  end
205
173
 
206
174
  ##
207
175
  # The version of Bundler::Persistent::Net::HTTP::Persistent you are using
208
176
 
209
- VERSION = '3.1.0'
210
-
211
- ##
212
- # Exceptions rescued for automatic retry on ruby 2.0.0. This overlaps with
213
- # the exception list for ruby 1.x.
214
-
215
- RETRIED_EXCEPTIONS = [ # :nodoc:
216
- (Net::ReadTimeout if Net.const_defined? :ReadTimeout),
217
- IOError,
218
- EOFError,
219
- Errno::ECONNRESET,
220
- Errno::ECONNABORTED,
221
- Errno::EPIPE,
222
- (OpenSSL::SSL::SSLError if HAVE_OPENSSL),
223
- Timeout::Error,
224
- ].compact
177
+ VERSION = '4.0.0'
225
178
 
226
179
  ##
227
180
  # Error class for errors raised by Bundler::Persistent::Net::HTTP::Persistent. Various
@@ -348,6 +301,13 @@ class Bundler::Persistent::Net::HTTP::Persistent
348
301
 
349
302
  attr_accessor :max_requests
350
303
 
304
+ ##
305
+ # Number of retries to perform if a request fails.
306
+ #
307
+ # See also #max_retries=, Net::HTTP#max_retries=.
308
+
309
+ attr_reader :max_retries
310
+
351
311
  ##
352
312
  # The value sent in the Keep-Alive header. Defaults to 30. Not needed for
353
313
  # HTTP/1.1 servers.
@@ -360,8 +320,7 @@ class Bundler::Persistent::Net::HTTP::Persistent
360
320
  attr_accessor :keep_alive
361
321
 
362
322
  ##
363
- # A name for this connection. Allows you to keep your connections apart
364
- # from everybody else's.
323
+ # The name for this collection of persistent connections.
365
324
 
366
325
  attr_reader :name
367
326
 
@@ -490,23 +449,11 @@ class Bundler::Persistent::Net::HTTP::Persistent
490
449
 
491
450
  attr_reader :verify_mode
492
451
 
493
- ##
494
- # Enable retries of non-idempotent requests that change data (e.g. POST
495
- # requests) when the server has disconnected.
496
- #
497
- # This will in the worst case lead to multiple requests with the same data,
498
- # but it may be useful for some applications. Take care when enabling
499
- # this option to ensure it is safe to POST or perform other non-idempotent
500
- # requests to the server.
501
-
502
- attr_accessor :retry_change_requests
503
-
504
452
  ##
505
453
  # Creates a new Bundler::Persistent::Net::HTTP::Persistent.
506
454
  #
507
- # Set +name+ to keep your connections apart from everybody else's. Not
508
- # required currently, but highly recommended. Your library name should be
509
- # good enough. This parameter will be required in a future version.
455
+ # Set a +name+ for fun. Your library name should be good enough, but this
456
+ # otherwise has no purpose.
510
457
  #
511
458
  # +proxy+ may be set to a Bundler::URI::HTTP or :ENV to pick up proxy options from
512
459
  # the environment. See proxy_from_env for details.
@@ -519,8 +466,9 @@ class Bundler::Persistent::Net::HTTP::Persistent
519
466
  # proxy.password = 'hunter2'
520
467
  #
521
468
  # Set +pool_size+ to limit the maximum number of connections allowed.
522
- # Defaults to 1/4 the number of allowed file handles. You can have no more
523
- # than this many threads with active HTTP transactions.
469
+ # Defaults to 1/4 the number of allowed file handles or 256 if your OS does
470
+ # not support a limit on allowed file handles. You can have no more than
471
+ # this many threads with active HTTP transactions.
524
472
 
525
473
  def initialize name: nil, proxy: nil, pool_size: DEFAULT_POOL_SIZE
526
474
  @name = name
@@ -537,6 +485,7 @@ class Bundler::Persistent::Net::HTTP::Persistent
537
485
  @write_timeout = nil
538
486
  @idle_timeout = 5
539
487
  @max_requests = nil
488
+ @max_retries = 1
540
489
  @socket_options = []
541
490
  @ssl_generation = 0 # incremented when SSL session variables change
542
491
 
@@ -568,8 +517,6 @@ class Bundler::Persistent::Net::HTTP::Persistent
568
517
  @reuse_ssl_sessions = OpenSSL::SSL.const_defined? :Session
569
518
  end
570
519
 
571
- @retry_change_requests = false
572
-
573
520
  self.proxy = proxy if proxy
574
521
  end
575
522
 
@@ -630,7 +577,9 @@ class Bundler::Persistent::Net::HTTP::Persistent
630
577
 
631
578
  net_http_args = [uri.hostname, uri.port]
632
579
 
633
- if @proxy_uri and not proxy_bypass? uri.hostname, uri.port then
580
+ # I'm unsure if uri.host or uri.hostname should be checked against
581
+ # the proxy bypass list.
582
+ if @proxy_uri and not proxy_bypass? uri.host, uri.port then
634
583
  net_http_args.concat @proxy_args
635
584
  else
636
585
  net_http_args.concat [nil, nil, nil, nil]
@@ -650,9 +599,11 @@ class Bundler::Persistent::Net::HTTP::Persistent
650
599
  reset connection
651
600
  end
652
601
 
653
- http.read_timeout = @read_timeout if @read_timeout
654
- http.write_timeout = @write_timeout if @write_timeout && http.respond_to?(:write_timeout=)
655
- http.keep_alive_timeout = @idle_timeout if @idle_timeout
602
+ http.keep_alive_timeout = @idle_timeout if @idle_timeout
603
+ http.max_retries = @max_retries if http.respond_to?(:max_retries=)
604
+ http.read_timeout = @read_timeout if @read_timeout
605
+ http.write_timeout = @write_timeout if
606
+ @write_timeout && http.respond_to?(:write_timeout=)
656
607
 
657
608
  return yield connection
658
609
  rescue Errno::ECONNREFUSED
@@ -670,27 +621,14 @@ class Bundler::Persistent::Net::HTTP::Persistent
670
621
  end
671
622
 
672
623
  ##
673
- # Returns an error message containing the number of requests performed on
674
- # this connection
675
-
676
- def error_message connection
677
- connection.requests -= 1 # fixup
678
-
679
- age = Time.now - connection.last_use
680
-
681
- "after #{connection.requests} requests on #{connection.http.object_id}, " \
682
- "last used #{age} seconds ago"
683
- end
684
-
685
- ##
686
- # Bundler::URI::escape wrapper
624
+ # CGI::escape wrapper
687
625
 
688
626
  def escape str
689
627
  CGI.escape str if str
690
628
  end
691
629
 
692
630
  ##
693
- # Bundler::URI::unescape wrapper
631
+ # CGI::unescape wrapper
694
632
 
695
633
  def unescape str
696
634
  CGI.unescape str if str
@@ -733,6 +671,7 @@ class Bundler::Persistent::Net::HTTP::Persistent
733
671
  def finish connection
734
672
  connection.finish
735
673
 
674
+ connection.http.instance_variable_set :@last_communicated, nil
736
675
  connection.http.instance_variable_set :@ssl_session, nil unless
737
676
  @reuse_ssl_sessions
738
677
  end
@@ -741,31 +680,31 @@ class Bundler::Persistent::Net::HTTP::Persistent
741
680
  # Returns the HTTP protocol version for +uri+
742
681
 
743
682
  def http_version uri
744
- @http_versions["#{uri.host}:#{uri.port}"]
683
+ @http_versions["#{uri.hostname}:#{uri.port}"]
745
684
  end
746
685
 
747
686
  ##
748
- # Is +req+ idempotent according to RFC 2616?
687
+ # Adds "http://" to the String +uri+ if it is missing.
749
688
 
750
- def idempotent? req
751
- case req.method
752
- when 'DELETE', 'GET', 'HEAD', 'OPTIONS', 'PUT', 'TRACE' then
753
- true
754
- end
689
+ def normalize_uri uri
690
+ (uri =~ /^https?:/) ? uri : "http://#{uri}"
755
691
  end
756
692
 
757
693
  ##
758
- # Is the request +req+ idempotent or is retry_change_requests allowed.
694
+ # Set the maximum number of retries for a request.
695
+ #
696
+ # Defaults to one retry.
697
+ #
698
+ # Set this to 0 to disable retries.
759
699
 
760
- def can_retry? req
761
- @retry_change_requests && !idempotent?(req)
762
- end
700
+ def max_retries= retries
701
+ retries = retries.to_int
763
702
 
764
- ##
765
- # Adds "http://" to the String +uri+ if it is missing.
703
+ raise ArgumentError, "max_retries must be positive" if retries < 0
766
704
 
767
- def normalize_uri uri
768
- (uri =~ /^https?:/) ? uri : "http://#{uri}"
705
+ @max_retries = retries
706
+
707
+ reconnect
769
708
  end
770
709
 
771
710
  ##
@@ -806,7 +745,7 @@ class Bundler::Persistent::Net::HTTP::Persistent
806
745
 
807
746
  if @proxy_uri then
808
747
  @proxy_args = [
809
- @proxy_uri.host,
748
+ @proxy_uri.hostname,
810
749
  @proxy_uri.port,
811
750
  unescape(@proxy_uri.user),
812
751
  unescape(@proxy_uri.password),
@@ -881,14 +820,15 @@ class Bundler::Persistent::Net::HTTP::Persistent
881
820
  end
882
821
 
883
822
  ##
884
- # Forces reconnection of HTTP connections.
823
+ # Forces reconnection of all HTTP connections, including TLS/SSL
824
+ # connections.
885
825
 
886
826
  def reconnect
887
827
  @generation += 1
888
828
  end
889
829
 
890
830
  ##
891
- # Forces reconnection of SSL connections.
831
+ # Forces reconnection of only TLS/SSL connections.
892
832
 
893
833
  def reconnect_ssl
894
834
  @ssl_generation += 1
@@ -921,14 +861,8 @@ class Bundler::Persistent::Net::HTTP::Persistent
921
861
  # the response will not have been read).
922
862
  #
923
863
  # +req+ must be a Net::HTTPGenericRequest subclass (see Net::HTTP for a list).
924
- #
925
- # If there is an error and the request is idempotent according to RFC 2616
926
- # it will be retried automatically.
927
864
 
928
865
  def request uri, req = nil, &block
929
- retried = false
930
- bad_response = false
931
-
932
866
  uri = Bundler::URI uri
933
867
  req = request_setup req || uri
934
868
  response = nil
@@ -942,37 +876,12 @@ class Bundler::Persistent::Net::HTTP::Persistent
942
876
  response = http.request req, &block
943
877
 
944
878
  if req.connection_close? or
945
- (response.http_version <= '1.0' and
879
+ (response.http_version <= '1.0' and
946
880
  not response.connection_keep_alive?) or
947
- response.connection_close? then
881
+ response.connection_close? then
948
882
  finish connection
949
883
  end
950
- rescue Net::HTTPBadResponse => e
951
- message = error_message connection
952
-
953
- finish connection
954
-
955
- raise Error, "too many bad responses #{message}" if
956
- bad_response or not can_retry? req
957
-
958
- bad_response = true
959
- retry
960
- rescue *RETRIED_EXCEPTIONS => e
961
- request_failed e, req, connection if
962
- retried or not can_retry? req
963
-
964
- reset connection
965
-
966
- retried = true
967
- retry
968
- rescue Errno::EINVAL, Errno::ETIMEDOUT => e # not retried on ruby 2
969
- request_failed e, req, connection if retried or not can_retry? req
970
-
971
- reset connection
972
-
973
- retried = true
974
- retry
975
- rescue Exception => e
884
+ rescue Exception # make sure to close the connection when it was interrupted
976
885
  finish connection
977
886
 
978
887
  raise
@@ -981,26 +890,11 @@ class Bundler::Persistent::Net::HTTP::Persistent
981
890
  end
982
891
  end
983
892
 
984
- @http_versions["#{uri.host}:#{uri.port}"] ||= response.http_version
893
+ @http_versions["#{uri.hostname}:#{uri.port}"] ||= response.http_version
985
894
 
986
895
  response
987
896
  end
988
897
 
989
- ##
990
- # Raises an Error for +exception+ which resulted from attempting the request
991
- # +req+ on the +connection+.
992
- #
993
- # Finishes the +connection+.
994
-
995
- def request_failed exception, req, connection # :nodoc:
996
- due_to = "(due to #{exception.message} - #{exception.class})"
997
- message = "too many connection resets #{due_to} #{error_message connection}"
998
-
999
- finish connection
1000
-
1001
- raise Error, message, exception.backtrace
1002
- end
1003
-
1004
898
  ##
1005
899
  # Creates a GET request if +req_or_uri+ is a Bundler::URI and adds headers to the
1006
900
  # request.
@@ -1008,7 +902,7 @@ class Bundler::Persistent::Net::HTTP::Persistent
1008
902
  # Returns the request.
1009
903
 
1010
904
  def request_setup req_or_uri # :nodoc:
1011
- req = if Bundler::URI === req_or_uri then
905
+ req = if req_or_uri.respond_to? 'request_uri' then
1012
906
  Net::HTTP::Get.new req_or_uri.request_uri
1013
907
  else
1014
908
  req_or_uri
@@ -1172,7 +1066,6 @@ application:
1172
1066
 
1173
1067
  reconnect_ssl
1174
1068
  end
1175
-
1176
1069
  end
1177
1070
 
1178
1071
  require_relative 'persistent/connection'