bundler 2.1.4 → 2.3.12

Sign up to get free protection for your applications and to get access to all the features.
Files changed (277) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +2164 -1430
  3. data/README.md +7 -9
  4. data/bundler.gemspec +5 -6
  5. data/exe/bundle +10 -8
  6. data/exe/bundler +1 -1
  7. data/lib/bundler/.document +1 -0
  8. data/lib/bundler/build_metadata.rb +3 -11
  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 +3 -8
  12. data/lib/bundler/cli/check.rb +4 -2
  13. data/lib/bundler/cli/clean.rb +1 -1
  14. data/lib/bundler/cli/common.rb +30 -3
  15. data/lib/bundler/cli/config.rb +10 -1
  16. data/lib/bundler/cli/console.rb +1 -1
  17. data/lib/bundler/cli/doctor.rb +25 -6
  18. data/lib/bundler/cli/exec.rb +5 -10
  19. data/lib/bundler/cli/fund.rb +36 -0
  20. data/lib/bundler/cli/gem.rb +219 -28
  21. data/lib/bundler/cli/info.rb +38 -6
  22. data/lib/bundler/cli/init.rb +3 -3
  23. data/lib/bundler/cli/inject.rb +1 -1
  24. data/lib/bundler/cli/install.rb +20 -52
  25. data/lib/bundler/cli/issue.rb +5 -4
  26. data/lib/bundler/cli/list.rb +19 -11
  27. data/lib/bundler/cli/lock.rb +5 -1
  28. data/lib/bundler/cli/open.rb +1 -2
  29. data/lib/bundler/cli/outdated.rb +95 -75
  30. data/lib/bundler/cli/platform.rb +1 -1
  31. data/lib/bundler/cli/plugin.rb +10 -0
  32. data/lib/bundler/cli/pristine.rb +5 -0
  33. data/lib/bundler/cli/remove.rb +1 -2
  34. data/lib/bundler/cli/show.rb +2 -2
  35. data/lib/bundler/cli/update.rb +20 -9
  36. data/lib/bundler/cli.rb +101 -81
  37. data/lib/bundler/compact_index_client/cache.rb +6 -23
  38. data/lib/bundler/compact_index_client/gem_parser.rb +28 -0
  39. data/lib/bundler/compact_index_client/updater.rb +13 -22
  40. data/lib/bundler/compact_index_client.rb +3 -9
  41. data/lib/bundler/current_ruby.rb +6 -4
  42. data/lib/bundler/definition.rb +201 -385
  43. data/lib/bundler/dep_proxy.rb +16 -9
  44. data/lib/bundler/dependency.rb +23 -14
  45. data/lib/bundler/digest.rb +71 -0
  46. data/lib/bundler/dsl.rb +71 -74
  47. data/lib/bundler/endpoint_specification.rb +22 -12
  48. data/lib/bundler/env.rb +2 -2
  49. data/lib/bundler/environment_preserver.rb +29 -2
  50. data/lib/bundler/errors.rb +20 -3
  51. data/lib/bundler/feature_flag.rb +0 -8
  52. data/lib/bundler/fetcher/base.rb +1 -1
  53. data/lib/bundler/fetcher/compact_index.rb +11 -16
  54. data/lib/bundler/fetcher/downloader.rb +10 -7
  55. data/lib/bundler/fetcher/index.rb +2 -30
  56. data/lib/bundler/fetcher.rb +18 -23
  57. data/lib/bundler/friendly_errors.rb +25 -43
  58. data/lib/bundler/gem_helper.rb +53 -31
  59. data/lib/bundler/gem_helpers.rb +36 -25
  60. data/lib/bundler/gem_version_promoter.rb +4 -4
  61. data/lib/bundler/graph.rb +1 -1
  62. data/lib/bundler/index.rb +9 -9
  63. data/lib/bundler/injector.rb +33 -6
  64. data/lib/bundler/inline.rb +3 -2
  65. data/lib/bundler/installer/gem_installer.rb +7 -25
  66. data/lib/bundler/installer/parallel_installer.rb +46 -25
  67. data/lib/bundler/installer/standalone.rb +30 -10
  68. data/lib/bundler/installer.rb +36 -59
  69. data/lib/bundler/lazy_specification.rb +62 -26
  70. data/lib/bundler/lockfile_generator.rb +2 -2
  71. data/lib/bundler/lockfile_parser.rb +17 -46
  72. data/lib/bundler/man/.document +1 -0
  73. data/{man → lib/bundler/man}/bundle-add.1 +10 -2
  74. data/{man/bundle-add.ronn → lib/bundler/man/bundle-add.1.ronn} +7 -1
  75. data/{man → lib/bundler/man}/bundle-binstubs.1 +5 -3
  76. data/{man/bundle-binstubs.ronn → lib/bundler/man/bundle-binstubs.1.ronn} +2 -4
  77. data/{man → lib/bundler/man}/bundle-cache.1 +1 -1
  78. data/{man → lib/bundler/man}/bundle-check.1 +1 -1
  79. data/{man → lib/bundler/man}/bundle-clean.1 +1 -1
  80. data/{man → lib/bundler/man}/bundle-config.1 +44 -45
  81. data/{man/bundle-config.ronn → lib/bundler/man/bundle-config.1.ronn} +59 -60
  82. data/{man → lib/bundler/man}/bundle-doctor.1 +1 -1
  83. data/{man → lib/bundler/man}/bundle-exec.1 +1 -1
  84. data/{man → lib/bundler/man}/bundle-gem.1 +38 -3
  85. data/{man/bundle-gem.ronn → lib/bundler/man/bundle-gem.1.ronn} +46 -7
  86. data/{man → lib/bundler/man}/bundle-info.1 +1 -1
  87. data/{man → lib/bundler/man}/bundle-init.1 +1 -1
  88. data/{man → lib/bundler/man}/bundle-inject.1 +1 -1
  89. data/{man → lib/bundler/man}/bundle-install.1 +31 -4
  90. data/{man/bundle-install.ronn → lib/bundler/man/bundle-install.1.ronn} +27 -5
  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 → lib/bundler/man}/bundle-open.1 +1 -1
  95. data/{man → lib/bundler/man}/bundle-outdated.1 +3 -10
  96. data/{man/bundle-outdated.ronn → lib/bundler/man/bundle-outdated.1.ronn} +1 -10
  97. data/{man → lib/bundler/man}/bundle-platform.1 +1 -1
  98. data/{man → lib/bundler/man}/bundle-pristine.1 +1 -1
  99. data/{man → lib/bundler/man}/bundle-remove.1 +1 -1
  100. data/{man → lib/bundler/man}/bundle-show.1 +1 -1
  101. data/{man → lib/bundler/man}/bundle-update.1 +5 -5
  102. data/{man/bundle-update.ronn → lib/bundler/man/bundle-update.1.ronn} +5 -4
  103. data/{man → lib/bundler/man}/bundle-viz.1 +1 -1
  104. data/{man → lib/bundler/man}/bundle.1 +1 -1
  105. data/{man → lib/bundler/man}/gemfile.5 +31 -5
  106. data/{man → lib/bundler/man}/gemfile.5.ronn +13 -5
  107. data/lib/bundler/mirror.rb +2 -2
  108. data/lib/bundler/plugin/api/source.rb +23 -7
  109. data/lib/bundler/plugin/dsl.rb +1 -1
  110. data/lib/bundler/plugin/index.rb +13 -1
  111. data/lib/bundler/plugin/installer/rubygems.rb +1 -1
  112. data/lib/bundler/plugin/installer.rb +11 -11
  113. data/lib/bundler/plugin/source_list.rb +5 -1
  114. data/lib/bundler/plugin.rb +56 -11
  115. data/lib/bundler/process_lock.rb +1 -1
  116. data/lib/bundler/remote_specification.rb +12 -2
  117. data/lib/bundler/resolver/spec_group.rb +58 -55
  118. data/lib/bundler/resolver.rb +176 -177
  119. data/lib/bundler/retry.rb +2 -2
  120. data/lib/bundler/ruby_version.rb +2 -15
  121. data/lib/bundler/rubygems_ext.rb +137 -28
  122. data/lib/bundler/rubygems_gem_installer.rb +69 -8
  123. data/lib/bundler/rubygems_integration.rb +69 -133
  124. data/lib/bundler/runtime.rb +22 -25
  125. data/lib/bundler/self_manager.rb +168 -0
  126. data/lib/bundler/settings.rb +144 -65
  127. data/lib/bundler/setup.rb +2 -2
  128. data/lib/bundler/shared_helpers.rb +12 -27
  129. data/lib/bundler/similarity_detector.rb +1 -1
  130. data/lib/bundler/source/git/git_proxy.rb +88 -84
  131. data/lib/bundler/source/git.rb +43 -23
  132. data/lib/bundler/source/metadata.rb +3 -7
  133. data/lib/bundler/source/path/installer.rb +10 -10
  134. data/lib/bundler/source/path.rb +10 -4
  135. data/lib/bundler/source/rubygems/remote.rb +1 -1
  136. data/lib/bundler/source/rubygems.rb +126 -116
  137. data/lib/bundler/source/rubygems_aggregate.rb +68 -0
  138. data/lib/bundler/source.rb +22 -1
  139. data/lib/bundler/source_list.rb +101 -63
  140. data/lib/bundler/source_map.rb +71 -0
  141. data/lib/bundler/spec_set.rb +26 -41
  142. data/lib/bundler/stub_specification.rb +25 -7
  143. data/lib/bundler/templates/Executable +2 -4
  144. data/lib/bundler/templates/Executable.bundler +8 -8
  145. data/lib/bundler/templates/Executable.standalone +2 -4
  146. data/lib/bundler/templates/Gemfile +0 -2
  147. data/lib/bundler/templates/gems.rb +0 -3
  148. data/lib/bundler/templates/newgem/CHANGELOG.md.tt +5 -0
  149. data/lib/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt +57 -47
  150. data/lib/bundler/templates/newgem/Gemfile.tt +12 -1
  151. data/lib/bundler/templates/newgem/README.md.tt +9 -14
  152. data/lib/bundler/templates/newgem/Rakefile.tt +32 -5
  153. data/lib/bundler/templates/newgem/bin/console.tt +1 -0
  154. data/lib/bundler/templates/newgem/circleci/config.yml.tt +13 -0
  155. data/lib/bundler/templates/newgem/ext/newgem/extconf.rb.tt +2 -0
  156. data/lib/bundler/templates/newgem/github/workflows/main.yml.tt +27 -0
  157. data/lib/bundler/templates/newgem/gitlab-ci.yml.tt +9 -0
  158. data/lib/bundler/templates/newgem/lib/newgem/version.rb.tt +2 -0
  159. data/lib/bundler/templates/newgem/lib/newgem.rb.tt +4 -2
  160. data/lib/bundler/templates/newgem/newgem.gemspec.tt +27 -17
  161. data/lib/bundler/templates/newgem/rubocop.yml.tt +13 -0
  162. data/lib/bundler/templates/newgem/sig/newgem.rbs.tt +8 -0
  163. data/lib/bundler/templates/newgem/spec/newgem_spec.rb.tt +2 -0
  164. data/lib/bundler/templates/newgem/spec/spec_helper.rb.tt +2 -1
  165. data/lib/bundler/templates/newgem/standard.yml.tt +3 -0
  166. data/lib/bundler/templates/newgem/test/{test_helper.rb.tt → minitest/test_helper.rb.tt} +2 -0
  167. data/lib/bundler/templates/newgem/test/{newgem_test.rb.tt → minitest/test_newgem.rb.tt} +3 -1
  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 +6 -6
  171. data/lib/bundler/uri_credentials_filter.rb +3 -1
  172. data/lib/bundler/vendor/.document +1 -0
  173. data/lib/bundler/vendor/connection_pool/LICENSE +20 -0
  174. data/lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb +19 -21
  175. data/lib/bundler/vendor/connection_pool/lib/connection_pool/version.rb +1 -1
  176. data/lib/bundler/vendor/connection_pool/lib/connection_pool/wrapper.rb +57 -0
  177. data/lib/bundler/vendor/connection_pool/lib/connection_pool.rb +39 -74
  178. data/lib/bundler/vendor/fileutils/LICENSE.txt +22 -0
  179. data/lib/bundler/vendor/molinillo/LICENSE +9 -0
  180. data/lib/bundler/vendor/molinillo/lib/molinillo/delegates/specification_provider.rb +7 -0
  181. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/tag.rb +2 -2
  182. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb +11 -5
  183. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb +37 -5
  184. data/lib/bundler/vendor/molinillo/lib/molinillo/errors.rb +34 -28
  185. data/lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb +1 -1
  186. data/lib/bundler/vendor/molinillo/lib/molinillo/modules/specification_provider.rb +12 -1
  187. data/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb +49 -47
  188. data/lib/bundler/vendor/molinillo/lib/molinillo.rb +0 -1
  189. data/lib/bundler/vendor/net-http-persistent/README.rdoc +82 -0
  190. data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb +82 -189
  191. data/lib/bundler/vendor/thor/LICENSE.md +20 -0
  192. data/lib/bundler/vendor/thor/lib/thor/actions/create_link.rb +2 -1
  193. data/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb +9 -7
  194. data/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb +1 -2
  195. data/lib/bundler/vendor/thor/lib/thor/actions.rb +7 -3
  196. data/lib/bundler/vendor/thor/lib/thor/base.rb +9 -0
  197. data/lib/bundler/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb +6 -0
  198. data/lib/bundler/vendor/thor/lib/thor/error.rb +10 -5
  199. data/lib/bundler/vendor/thor/lib/thor/parser/arguments.rb +5 -1
  200. data/lib/bundler/vendor/thor/lib/thor/parser/options.rb +28 -9
  201. data/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +27 -6
  202. data/lib/bundler/vendor/thor/lib/thor/shell/color.rb +5 -1
  203. data/lib/bundler/vendor/thor/lib/thor/shell.rb +1 -1
  204. data/lib/bundler/vendor/thor/lib/thor/util.rb +1 -1
  205. data/lib/bundler/vendor/thor/lib/thor/version.rb +1 -1
  206. data/lib/bundler/vendor/thor/lib/thor.rb +5 -13
  207. data/lib/bundler/vendor/tmpdir/lib/tmpdir.rb +154 -0
  208. data/lib/bundler/vendor/tsort/LICENSE.txt +22 -0
  209. data/lib/bundler/vendor/tsort/lib/tsort.rb +452 -0
  210. data/lib/bundler/vendor/uri/LICENSE.txt +22 -0
  211. data/lib/bundler/vendor/uri/lib/uri/common.rb +17 -80
  212. data/lib/bundler/vendor/uri/lib/uri/ftp.rb +0 -1
  213. data/lib/bundler/vendor/uri/lib/uri/generic.rb +5 -6
  214. data/lib/bundler/vendor/uri/lib/uri/http.rb +0 -1
  215. data/lib/bundler/vendor/uri/lib/uri/https.rb +0 -1
  216. data/lib/bundler/vendor/uri/lib/uri/ldap.rb +1 -1
  217. data/lib/bundler/vendor/uri/lib/uri/mailto.rb +0 -1
  218. data/lib/bundler/vendor/uri/lib/uri/rfc2396_parser.rb +1 -14
  219. data/lib/bundler/vendor/uri/lib/uri/rfc3986_parser.rb +1 -12
  220. data/lib/bundler/vendor/uri/lib/uri/version.rb +1 -1
  221. data/lib/bundler/vendor/uri/lib/uri/ws.rb +84 -0
  222. data/lib/bundler/vendor/uri/lib/uri/wss.rb +22 -0
  223. data/lib/bundler/vendor/uri/lib/uri.rb +0 -1
  224. data/lib/bundler/vendored_persistent.rb +0 -7
  225. data/lib/bundler/vendored_tmpdir.rb +4 -0
  226. data/lib/bundler/vendored_tsort.rb +4 -0
  227. data/lib/bundler/version.rb +1 -1
  228. data/lib/bundler/worker.rb +20 -5
  229. data/lib/bundler/yaml_serializer.rb +1 -1
  230. data/lib/bundler.rb +64 -43
  231. metadata +94 -91
  232. data/lib/bundler/gemdeps.rb +0 -29
  233. data/lib/bundler/psyched_yaml.rb +0 -37
  234. data/lib/bundler/vendor/connection_pool/lib/connection_pool/monotonic_time.rb +0 -66
  235. data/lib/bundler/vendor/molinillo/lib/molinillo/compatibility.rb +0 -26
  236. data/man/bundle-add.1.txt +0 -58
  237. data/man/bundle-binstubs.1.txt +0 -48
  238. data/man/bundle-cache.1.txt +0 -78
  239. data/man/bundle-check.1.txt +0 -33
  240. data/man/bundle-clean.1.txt +0 -26
  241. data/man/bundle-config.1.txt +0 -528
  242. data/man/bundle-doctor.1.txt +0 -44
  243. data/man/bundle-exec.1.txt +0 -178
  244. data/man/bundle-gem.1.txt +0 -91
  245. data/man/bundle-info.1.txt +0 -21
  246. data/man/bundle-init.1.txt +0 -34
  247. data/man/bundle-inject.1.txt +0 -32
  248. data/man/bundle-install.1.txt +0 -401
  249. data/man/bundle-list.1.txt +0 -43
  250. data/man/bundle-lock.1.txt +0 -93
  251. data/man/bundle-open.1.txt +0 -29
  252. data/man/bundle-outdated.1.txt +0 -131
  253. data/man/bundle-platform.1.txt +0 -57
  254. data/man/bundle-pristine.1.txt +0 -44
  255. data/man/bundle-remove.1.txt +0 -34
  256. data/man/bundle-show.1.txt +0 -27
  257. data/man/bundle-update.1.txt +0 -390
  258. data/man/bundle-viz.1.txt +0 -39
  259. data/man/bundle.1.txt +0 -116
  260. data/man/gemfile.5.txt +0 -649
  261. /data/{man/bundle-cache.ronn → lib/bundler/man/bundle-cache.1.ronn} +0 -0
  262. /data/{man/bundle-check.ronn → lib/bundler/man/bundle-check.1.ronn} +0 -0
  263. /data/{man/bundle-clean.ronn → lib/bundler/man/bundle-clean.1.ronn} +0 -0
  264. /data/{man/bundle-doctor.ronn → lib/bundler/man/bundle-doctor.1.ronn} +0 -0
  265. /data/{man/bundle-exec.ronn → lib/bundler/man/bundle-exec.1.ronn} +0 -0
  266. /data/{man/bundle-info.ronn → lib/bundler/man/bundle-info.1.ronn} +0 -0
  267. /data/{man/bundle-init.ronn → lib/bundler/man/bundle-init.1.ronn} +0 -0
  268. /data/{man/bundle-inject.ronn → lib/bundler/man/bundle-inject.1.ronn} +0 -0
  269. /data/{man/bundle-lock.ronn → lib/bundler/man/bundle-lock.1.ronn} +0 -0
  270. /data/{man/bundle-open.ronn → lib/bundler/man/bundle-open.1.ronn} +0 -0
  271. /data/{man/bundle-platform.ronn → lib/bundler/man/bundle-platform.1.ronn} +0 -0
  272. /data/{man/bundle-pristine.ronn → lib/bundler/man/bundle-pristine.1.ronn} +0 -0
  273. /data/{man/bundle-remove.ronn → lib/bundler/man/bundle-remove.1.ronn} +0 -0
  274. /data/{man/bundle-show.ronn → lib/bundler/man/bundle-show.1.ronn} +0 -0
  275. /data/{man/bundle-viz.ronn → lib/bundler/man/bundle-viz.1.ronn} +0 -0
  276. /data/{man/bundle.ronn → lib/bundler/man/bundle.1.ronn} +0 -0
  277. /data/{man → lib/bundler/man}/index.txt +0 -0
@@ -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'
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 Yehuda Katz, Eric Hodel, et al.
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -33,7 +33,8 @@ class Bundler::Thor
33
33
  # Boolean:: true if it is identical, false otherwise.
34
34
  #
35
35
  def identical?
36
- exists? && File.identical?(render, destination)
36
+ source = File.expand_path(render, File.dirname(destination))
37
+ exists? && File.identical?(source, destination)
37
38
  end
38
39
 
39
40
  def invoke!
@@ -210,9 +210,9 @@ class Bundler::Thor
210
210
  #
211
211
  # ==== Examples
212
212
  #
213
- # inject_into_class "app/controllers/application_controller.rb", ApplicationController, " filter_parameter :password\n"
213
+ # inject_into_class "app/controllers/application_controller.rb", "ApplicationController", " filter_parameter :password\n"
214
214
  #
215
- # inject_into_class "app/controllers/application_controller.rb", ApplicationController do
215
+ # inject_into_class "app/controllers/application_controller.rb", "ApplicationController" do
216
216
  # " filter_parameter :password\n"
217
217
  # end
218
218
  #
@@ -233,9 +233,9 @@ class Bundler::Thor
233
233
  #
234
234
  # ==== Examples
235
235
  #
236
- # inject_into_module "app/helpers/application_helper.rb", ApplicationHelper, " def help; 'help'; end\n"
236
+ # inject_into_module "app/helpers/application_helper.rb", "ApplicationHelper", " def help; 'help'; end\n"
237
237
  #
238
- # inject_into_module "app/helpers/application_helper.rb", ApplicationHelper do
238
+ # inject_into_module "app/helpers/application_helper.rb", "ApplicationHelper" do
239
239
  # " def help; 'help'; end\n"
240
240
  # end
241
241
  #
@@ -251,7 +251,8 @@ class Bundler::Thor
251
251
  # path<String>:: path of the file to be changed
252
252
  # flag<Regexp|String>:: the regexp or string to be replaced
253
253
  # replacement<String>:: the replacement, can be also given as a block
254
- # config<Hash>:: give :verbose => false to not log the status.
254
+ # config<Hash>:: give :verbose => false to not log the status, and
255
+ # :force => true, to force the replacement regardles of runner behavior.
255
256
  #
256
257
  # ==== Example
257
258
  #
@@ -262,9 +263,10 @@ class Bundler::Thor
262
263
  # end
263
264
  #
264
265
  def gsub_file(path, flag, *args, &block)
265
- return unless behavior == :invoke
266
266
  config = args.last.is_a?(Hash) ? args.pop : {}
267
267
 
268
+ return unless behavior == :invoke || config.fetch(:force, false)
269
+
268
270
  path = File.expand_path(path, destination_root)
269
271
  say_status :gsub, relative_to_original_destination_root(path), config.fetch(:verbose, true)
270
272
 
@@ -329,7 +331,7 @@ class Bundler::Thor
329
331
  path = File.expand_path(path, destination_root)
330
332
 
331
333
  say_status :remove, relative_to_original_destination_root(path), config.fetch(:verbose, true)
332
- if !options[:pretend] && File.exist?(path)
334
+ if !options[:pretend] && (File.exist?(path) || File.symlink?(path))
333
335
  require "fileutils"
334
336
  ::FileUtils.rm_rf(path)
335
337
  end
@@ -106,12 +106,11 @@ class Bundler::Thor
106
106
  # Adds the content to the file.
107
107
  #
108
108
  def replace!(regexp, string, force)
109
- return if pretend?
110
109
  content = File.read(destination)
111
110
  if force || !content.include?(replacement)
112
111
  success = content.gsub!(regexp, string)
113
112
 
114
- File.open(destination, "wb") { |file| file.write(content) }
113
+ File.open(destination, "wb") { |file| file.write(content) } unless pretend?
115
114
  success
116
115
  end
117
116
  end
@@ -161,6 +161,8 @@ class Bundler::Thor
161
161
  # to the block you provide. The path is set back to the previous path when
162
162
  # the method exits.
163
163
  #
164
+ # Returns the value yielded by the block.
165
+ #
164
166
  # ==== Parameters
165
167
  # dir<String>:: the directory to move to.
166
168
  # config<Hash>:: give :verbose => true to log and use padding.
@@ -179,16 +181,18 @@ class Bundler::Thor
179
181
  FileUtils.mkdir_p(destination_root)
180
182
  end
181
183
 
184
+ result = nil
182
185
  if pretend
183
186
  # In pretend mode, just yield down to the block
184
- block.arity == 1 ? yield(destination_root) : yield
187
+ result = block.arity == 1 ? yield(destination_root) : yield
185
188
  else
186
189
  require "fileutils"
187
- FileUtils.cd(destination_root) { block.arity == 1 ? yield(destination_root) : yield }
190
+ FileUtils.cd(destination_root) { result = block.arity == 1 ? yield(destination_root) : yield }
188
191
  end
189
192
 
190
193
  @destination_stack.pop
191
194
  shell.padding -= 1 if verbose
195
+ result
192
196
  end
193
197
 
194
198
  # Goes to the root and execute the given block.
@@ -219,7 +223,7 @@ class Bundler::Thor
219
223
 
220
224
  contents = if is_uri
221
225
  require "open-uri"
222
- open(path, "Accept" => "application/x-thor-template", &:read)
226
+ URI.open(path, "Accept" => "application/x-thor-template", &:read)
223
227
  else
224
228
  open(path, &:read)
225
229
  end
@@ -22,6 +22,15 @@ class Bundler::Thor
22
22
 
23
23
  TEMPLATE_EXTNAME = ".tt"
24
24
 
25
+ class << self
26
+ def deprecation_warning(message) #:nodoc:
27
+ unless ENV['THOR_SILENCE_DEPRECATION']
28
+ warn "Deprecation warning: #{message}\n" +
29
+ 'You can silence deprecations warning by setting the environment variable THOR_SILENCE_DEPRECATION.'
30
+ end
31
+ end
32
+ end
33
+
25
34
  module Base
26
35
  attr_accessor :options, :parent_options, :args
27
36
 
@@ -28,6 +28,12 @@ class Bundler::Thor
28
28
  super(convert_key(key))
29
29
  end
30
30
 
31
+ def except(*keys)
32
+ dup.tap do |hash|
33
+ keys.each { |key| hash.delete(convert_key(key)) }
34
+ end
35
+ end
36
+
31
37
  def fetch(key, *args)
32
38
  super(convert_key(key), *args)
33
39
  end