rubygems-update 4.0.21 → 4.1.0.beta1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (496) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +590 -53
  3. data/CONTRIBUTING.md +66 -5
  4. data/MIT.txt +4 -3
  5. data/Manifest.txt +332 -375
  6. data/README.md +26 -6
  7. data/bundler.gemspec +63 -0
  8. data/doc/POLICIES.md +147 -0
  9. data/doc/UPGRADING.md +4 -4
  10. data/{bundler/lib → lib}/bundler/build_metadata.rb +2 -2
  11. data/{bundler/lib → lib}/bundler/checksum.rb +40 -25
  12. data/{bundler/lib → lib}/bundler/ci_detector.rb +1 -1
  13. data/{bundler/lib → lib}/bundler/cli/add.rb +3 -4
  14. data/{bundler/lib → lib}/bundler/cli/cache.rb +4 -0
  15. data/{bundler/lib → lib}/bundler/cli/clean.rb +5 -0
  16. data/{bundler/lib → lib}/bundler/cli/common.rb +37 -1
  17. data/{bundler/lib → lib}/bundler/cli/config.rb +4 -2
  18. data/{bundler/lib → lib}/bundler/cli/gem.rb +0 -17
  19. data/{bundler/lib → lib}/bundler/cli/install.rb +4 -5
  20. data/{bundler/lib → lib}/bundler/cli/lock.rb +1 -2
  21. data/{bundler/lib → lib}/bundler/cli/outdated.rb +8 -3
  22. data/{bundler/lib → lib}/bundler/cli/pristine.rb +2 -1
  23. data/{bundler/lib → lib}/bundler/cli/update.rb +21 -12
  24. data/{bundler/lib → lib}/bundler/cli.rb +14 -11
  25. data/{bundler/lib → lib}/bundler/definition.rb +61 -24
  26. data/{bundler/lib → lib}/bundler/dependency.rb +4 -0
  27. data/{bundler/lib → lib}/bundler/dsl.rb +77 -11
  28. data/{bundler/lib → lib}/bundler/endpoint_specification.rb +51 -14
  29. data/{bundler/lib → lib}/bundler/env.rb +7 -24
  30. data/{bundler/lib → lib}/bundler/errors.rb +34 -5
  31. data/{bundler/lib → lib}/bundler/fetcher/compact_index.rb +14 -5
  32. data/lib/bundler/fetcher/connection_pools.rb +150 -0
  33. data/{bundler/lib → lib}/bundler/fetcher/downloader.rb +31 -16
  34. data/{bundler/lib → lib}/bundler/fetcher.rb +8 -47
  35. data/{bundler/lib → lib}/bundler/injector.rb +3 -3
  36. data/{bundler/lib → lib}/bundler/inline.rb +44 -4
  37. data/{bundler/lib → lib}/bundler/installer/parallel_installer.rb +25 -30
  38. data/{bundler/lib → lib}/bundler/installer.rb +20 -6
  39. data/{bundler/lib → lib}/bundler/lazy_specification.rb +44 -17
  40. data/{bundler/lib → lib}/bundler/lockfile_generator.rb +24 -2
  41. data/{bundler/lib → lib}/bundler/lockfile_parser.rb +43 -5
  42. data/{bundler/lib → lib}/bundler/man/bundle-add.1 +7 -4
  43. data/{bundler/lib → lib}/bundler/man/bundle-add.1.ronn +8 -4
  44. data/{bundler/lib → lib}/bundler/man/bundle-binstubs.1 +1 -1
  45. data/{bundler/lib → lib}/bundler/man/bundle-cache.1 +2 -2
  46. data/{bundler/lib → lib}/bundler/man/bundle-cache.1.ronn +2 -2
  47. data/{bundler/lib → lib}/bundler/man/bundle-check.1 +1 -1
  48. data/{bundler/lib → lib}/bundler/man/bundle-clean.1 +1 -1
  49. data/{bundler/lib → lib}/bundler/man/bundle-config.1 +38 -6
  50. data/{bundler/lib → lib}/bundler/man/bundle-config.1.ronn +143 -10
  51. data/{bundler/lib → lib}/bundler/man/bundle-console.1 +1 -1
  52. data/{bundler/lib → lib}/bundler/man/bundle-doctor.1 +1 -1
  53. data/{bundler/lib → lib}/bundler/man/bundle-env.1 +1 -1
  54. data/{bundler/lib → lib}/bundler/man/bundle-exec.1 +1 -1
  55. data/{bundler/lib → lib}/bundler/man/bundle-fund.1 +1 -1
  56. data/{bundler/lib → lib}/bundler/man/bundle-gem.1 +1 -1
  57. data/{bundler/lib → lib}/bundler/man/bundle-help.1 +1 -1
  58. data/{bundler/lib → lib}/bundler/man/bundle-info.1 +1 -1
  59. data/{bundler/lib → lib}/bundler/man/bundle-init.1 +1 -1
  60. data/{bundler/lib → lib}/bundler/man/bundle-install.1 +2 -2
  61. data/{bundler/lib → lib}/bundler/man/bundle-install.1.ronn +4 -4
  62. data/{bundler/lib → lib}/bundler/man/bundle-issue.1 +1 -1
  63. data/{bundler/lib → lib}/bundler/man/bundle-licenses.1 +1 -1
  64. data/{bundler/lib → lib}/bundler/man/bundle-list.1 +1 -1
  65. data/{bundler/lib → lib}/bundler/man/bundle-lock.1 +3 -3
  66. data/{bundler/lib → lib}/bundler/man/bundle-lock.1.ronn +5 -5
  67. data/{bundler/lib → lib}/bundler/man/bundle-open.1 +1 -1
  68. data/{bundler/lib → lib}/bundler/man/bundle-outdated.1 +1 -1
  69. data/{bundler/lib → lib}/bundler/man/bundle-platform.1 +1 -1
  70. data/{bundler/lib → lib}/bundler/man/bundle-plugin.1 +1 -1
  71. data/{bundler/lib → lib}/bundler/man/bundle-pristine.1 +1 -1
  72. data/{bundler/lib → lib}/bundler/man/bundle-remove.1 +1 -1
  73. data/{bundler/lib → lib}/bundler/man/bundle-show.1 +1 -1
  74. data/{bundler/lib → lib}/bundler/man/bundle-update.1 +3 -3
  75. data/{bundler/lib → lib}/bundler/man/bundle-update.1.ronn +3 -5
  76. data/{bundler/lib → lib}/bundler/man/bundle-version.1 +1 -1
  77. data/{bundler/lib → lib}/bundler/man/bundle.1 +1 -1
  78. data/{bundler/lib → lib}/bundler/man/gemfile.5 +45 -1
  79. data/{bundler/lib → lib}/bundler/man/gemfile.5.ronn +53 -0
  80. data/lib/bundler/match_metadata.rb +50 -0
  81. data/{bundler/lib → lib}/bundler/match_platform.rb +25 -2
  82. data/lib/bundler/match_remote_metadata.rb +44 -0
  83. data/{bundler/lib → lib}/bundler/materialization.rb +2 -1
  84. data/lib/bundler/override.rb +69 -0
  85. data/{bundler/lib → lib}/bundler/plugin/dsl.rb +3 -5
  86. data/{bundler/lib → lib}/bundler/plugin/events.rb +55 -13
  87. data/{bundler/lib → lib}/bundler/plugin/index.rb +87 -11
  88. data/{bundler/lib → lib}/bundler/plugin/installer/path.rb +1 -1
  89. data/{bundler/lib → lib}/bundler/plugin/installer.rb +13 -5
  90. data/{bundler/lib → lib}/bundler/plugin.rb +58 -30
  91. data/{bundler/lib → lib}/bundler/remote_specification.rb +6 -3
  92. data/{bundler/lib → lib}/bundler/resolver/base.rb +2 -1
  93. data/{bundler/lib → lib}/bundler/resolver/incompatibility.rb +1 -1
  94. data/{bundler/lib → lib}/bundler/resolver.rb +73 -23
  95. data/{bundler/lib → lib}/bundler/ruby_version.rb +0 -2
  96. data/{bundler/lib → lib}/bundler/rubygems_ext.rb +71 -1
  97. data/{bundler/lib → lib}/bundler/rubygems_gem_installer.rb +41 -2
  98. data/{bundler/lib → lib}/bundler/rubygems_integration.rb +7 -2
  99. data/{bundler/lib → lib}/bundler/runtime.rb +69 -2
  100. data/{bundler/lib → lib}/bundler/self_manager.rb +9 -15
  101. data/{bundler/lib → lib}/bundler/settings.rb +373 -30
  102. data/{bundler/lib → lib}/bundler/shared_helpers.rb +2 -1
  103. data/{bundler/lib → lib}/bundler/source/git/git_proxy.rb +2 -10
  104. data/{bundler/lib → lib}/bundler/source/git.rb +15 -6
  105. data/{bundler/lib → lib}/bundler/source/path/installer.rb +1 -1
  106. data/{bundler/lib → lib}/bundler/source/rubygems/remote.rb +10 -5
  107. data/{bundler/lib → lib}/bundler/source/rubygems.rb +48 -12
  108. data/{bundler/lib → lib}/bundler/spec_set.rb +16 -4
  109. data/{bundler/lib → lib}/bundler/stub_specification.rb +2 -1
  110. data/{bundler/lib → lib}/bundler/templates/newgem/Gemfile.tt +4 -4
  111. data/{bundler/lib → lib}/bundler/templates/newgem/newgem.gemspec.tt +3 -3
  112. data/{bundler/lib → lib}/bundler/templates/newgem/spec/newgem_spec.rb.tt +1 -1
  113. data/{bundler/lib → lib}/bundler/templates/newgem/test/minitest/test_newgem.rb.tt +1 -1
  114. data/{bundler/lib → lib}/bundler/ui/shell.rb +0 -4
  115. data/{bundler/lib → lib}/bundler/ui/silent.rb +0 -4
  116. data/{bundler/lib → lib}/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb +35 -2
  117. data/{bundler/lib → lib}/bundler/vendor/thor/lib/thor/base.rb +2 -1
  118. data/{bundler/lib → lib}/bundler/vendor/thor/lib/thor/shell/basic.rb +14 -6
  119. data/{bundler/lib → lib}/bundler/vendor/thor/lib/thor/shell/color.rb +2 -0
  120. data/{bundler/lib → lib}/bundler/vendor/thor/lib/thor/version.rb +1 -1
  121. data/{bundler/lib → lib}/bundler/vendor/thor/lib/thor.rb +34 -1
  122. data/lib/bundler/vendored_pub_grub.rb +7 -0
  123. data/lib/bundler/vendored_securerandom.rb +15 -0
  124. data/lib/bundler/vendored_uri.rb +21 -0
  125. data/{bundler/lib → lib}/bundler/version.rb +1 -1
  126. data/{bundler/lib → lib}/bundler/worker.rb +3 -2
  127. data/{bundler/lib → lib}/bundler.rb +1 -1
  128. data/lib/rubygems/basic_specification.rb +15 -14
  129. data/lib/rubygems/bundler_settings.rb +137 -0
  130. data/lib/rubygems/bundler_version_finder.rb +13 -55
  131. data/lib/rubygems/ci_detector.rb +1 -1
  132. data/lib/rubygems/commands/build_command.rb +8 -1
  133. data/lib/rubygems/commands/cert_command.rb +9 -7
  134. data/lib/rubygems/commands/contents_command.rb +1 -1
  135. data/lib/rubygems/commands/dependency_command.rb +15 -3
  136. data/lib/rubygems/commands/environment_command.rb +1 -0
  137. data/lib/rubygems/commands/exec_command.rb +3 -0
  138. data/lib/rubygems/commands/fetch_command.rb +1 -1
  139. data/lib/rubygems/commands/help_command.rb +3 -1
  140. data/lib/rubygems/commands/install_command.rb +13 -3
  141. data/lib/rubygems/commands/lock_command.rb +2 -2
  142. data/lib/rubygems/commands/outdated_command.rb +77 -2
  143. data/lib/rubygems/commands/owner_command.rb +1 -1
  144. data/lib/rubygems/commands/push_command.rb +159 -21
  145. data/lib/rubygems/commands/setup_command.rb +20 -23
  146. data/lib/rubygems/commands/signin_command.rb +3 -1
  147. data/lib/rubygems/commands/signout_command.rb +26 -6
  148. data/lib/rubygems/commands/specification_command.rb +1 -1
  149. data/lib/rubygems/commands/uninstall_command.rb +1 -1
  150. data/lib/rubygems/commands/update_command.rb +84 -2
  151. data/lib/rubygems/commands/yank_command.rb +10 -7
  152. data/lib/rubygems/compact_index_client/cache.rb +122 -0
  153. data/lib/rubygems/compact_index_client/cache_file.rb +147 -0
  154. data/lib/rubygems/compact_index_client/http_fetcher.rb +88 -0
  155. data/lib/rubygems/compact_index_client/parser.rb +90 -0
  156. data/lib/rubygems/compact_index_client/updater.rb +113 -0
  157. data/lib/rubygems/compact_index_client.rb +111 -0
  158. data/lib/rubygems/config_file.rb +304 -22
  159. data/lib/rubygems/content_address.rb +194 -0
  160. data/lib/rubygems/cooldown.rb +173 -0
  161. data/lib/rubygems/cooldown_option.rb +27 -0
  162. data/lib/rubygems/cooldown_settings.rb +57 -0
  163. data/lib/rubygems/credential_store/native/linux.rb +97 -0
  164. data/lib/rubygems/credential_store/native/macos.rb +88 -0
  165. data/lib/rubygems/credential_store/native/windows.rb +130 -0
  166. data/lib/rubygems/credential_store.rb +332 -0
  167. data/lib/rubygems/defaults.rb +9 -0
  168. data/lib/rubygems/dependency_installer.rb +15 -0
  169. data/lib/rubygems/doctor.rb +23 -6
  170. data/lib/rubygems/exceptions.rb +11 -43
  171. data/lib/rubygems/ext/builder.rb +70 -5
  172. data/lib/rubygems/ext/cargo_builder.rb +0 -9
  173. data/lib/rubygems/ext/ext_conf_builder.rb +8 -15
  174. data/lib/rubygems/gemcutter_utilities.rb +44 -2
  175. data/lib/rubygems/install_update_options.rb +16 -0
  176. data/lib/rubygems/installer.rb +90 -11
  177. data/lib/rubygems/installer_uninstaller_utils.rb +24 -3
  178. data/lib/rubygems/name_tuple.rb +55 -18
  179. data/lib/rubygems/package/old.rb +1 -1
  180. data/lib/rubygems/package.rb +200 -47
  181. data/lib/rubygems/package_task.rb +2 -2
  182. data/lib/rubygems/platform.rb +2 -2
  183. data/lib/rubygems/query_utils.rb +84 -24
  184. data/lib/rubygems/remote_fetcher.rb +65 -17
  185. data/lib/rubygems/request/connection_pools.rb +3 -0
  186. data/lib/rubygems/request_set/gem_dependency_api.rb +1 -1
  187. data/lib/rubygems/request_set/lockfile.rb +0 -2
  188. data/lib/rubygems/request_set.rb +105 -17
  189. data/lib/rubygems/resolver/api_set.rb +14 -26
  190. data/lib/rubygems/resolver/api_specification.rb +56 -15
  191. data/lib/rubygems/resolver/incompatibility.rb +10 -0
  192. data/lib/rubygems/resolver/index_specification.rb +6 -4
  193. data/lib/rubygems/resolver/installer_set.rb +2 -2
  194. data/lib/rubygems/resolver/lock_specification.rb +5 -1
  195. data/lib/rubygems/resolver/spec_specification.rb +4 -0
  196. data/lib/rubygems/resolver/specification.rb +16 -1
  197. data/lib/rubygems/resolver/strategy.rb +44 -0
  198. data/lib/rubygems/resolver.rb +471 -145
  199. data/lib/rubygems/safe_marshal.rb +2 -1
  200. data/lib/rubygems/safe_yaml.rb +20 -3
  201. data/lib/rubygems/security/policy.rb +11 -3
  202. data/lib/rubygems/security/signer.rb +15 -7
  203. data/lib/rubygems/security.rb +111 -17
  204. data/lib/rubygems/source/local.rb +7 -2
  205. data/lib/rubygems/source.rb +270 -23
  206. data/lib/rubygems/spec_fetcher.rb +47 -12
  207. data/lib/rubygems/specification.rb +76 -32
  208. data/lib/rubygems/specification_policy.rb +33 -6
  209. data/lib/rubygems/specification_record.rb +41 -2
  210. data/lib/rubygems/stub_specification.rb +39 -16
  211. data/lib/rubygems/uninstaller.rb +2 -0
  212. data/lib/rubygems/util/atomic_file_writer.rb +109 -0
  213. data/lib/rubygems/vendor/net-http/lib/net/http/exceptions.rb +2 -1
  214. data/lib/rubygems/vendor/net-http/lib/net/http/generic_request.rb +5 -6
  215. data/lib/rubygems/vendor/net-http/lib/net/http/header.rb +8 -4
  216. data/lib/rubygems/vendor/net-http/lib/net/http/requests.rb +15 -1
  217. data/lib/rubygems/vendor/net-http/lib/net/http/response.rb +2 -1
  218. data/lib/rubygems/vendor/net-http/lib/net/http/responses.rb +68 -0
  219. data/lib/rubygems/vendor/net-http/lib/net/http.rb +60 -49
  220. data/lib/rubygems/vendor/optparse/lib/optparse.rb +23 -30
  221. data/{bundler/lib/bundler → lib/rubygems}/vendor/pub_grub/lib/pub_grub/assignment.rb +1 -1
  222. data/{bundler/lib/bundler → lib/rubygems}/vendor/pub_grub/lib/pub_grub/basic_package_source.rb +7 -7
  223. data/{bundler/lib/bundler → lib/rubygems}/vendor/pub_grub/lib/pub_grub/failure_writer.rb +1 -1
  224. data/{bundler/lib/bundler → lib/rubygems}/vendor/pub_grub/lib/pub_grub/incompatibility.rb +4 -4
  225. data/{bundler/lib/bundler → lib/rubygems}/vendor/pub_grub/lib/pub_grub/package.rb +1 -1
  226. data/{bundler/lib/bundler → lib/rubygems}/vendor/pub_grub/lib/pub_grub/partial_solution.rb +1 -1
  227. data/{bundler/lib/bundler → lib/rubygems}/vendor/pub_grub/lib/pub_grub/rubygems.rb +3 -3
  228. data/{bundler/lib/bundler → lib/rubygems}/vendor/pub_grub/lib/pub_grub/solve_failure.rb +1 -1
  229. data/{bundler/lib/bundler → lib/rubygems}/vendor/pub_grub/lib/pub_grub/static_package_source.rb +3 -3
  230. data/{bundler/lib/bundler → lib/rubygems}/vendor/pub_grub/lib/pub_grub/strategy.rb +2 -2
  231. data/{bundler/lib/bundler → lib/rubygems}/vendor/pub_grub/lib/pub_grub/term.rb +1 -1
  232. data/{bundler/lib/bundler → lib/rubygems}/vendor/pub_grub/lib/pub_grub/version.rb +1 -1
  233. data/{bundler/lib/bundler → lib/rubygems}/vendor/pub_grub/lib/pub_grub/version_constraint.rb +3 -3
  234. data/{bundler/lib/bundler → lib/rubygems}/vendor/pub_grub/lib/pub_grub/version_range.rb +1 -1
  235. data/{bundler/lib/bundler → lib/rubygems}/vendor/pub_grub/lib/pub_grub/version_solver.rb +2 -2
  236. data/{bundler/lib/bundler → lib/rubygems}/vendor/pub_grub/lib/pub_grub/version_union.rb +1 -1
  237. data/lib/rubygems/vendor/pub_grub/lib/pub_grub.rb +57 -0
  238. data/lib/rubygems/vendor/resolv/lib/resolv.rb +3508 -0
  239. data/lib/rubygems/vendor/securerandom/lib/securerandom.rb +4 -0
  240. data/lib/rubygems/vendor/timeout/lib/timeout.rb +190 -77
  241. data/lib/rubygems/vendor/uri/lib/uri.rb +4 -0
  242. data/{bundler/lib/bundler → lib/rubygems}/vendored_pub_grub.rb +0 -1
  243. data/lib/rubygems/version.rb +129 -111
  244. data/lib/rubygems/version_option.rb +14 -0
  245. data/lib/rubygems/yaml_serializer.rb +853 -71
  246. data/lib/rubygems.rb +45 -11
  247. data/rubygems-update.gemspec +3 -4
  248. data/setup.rb +1 -0
  249. metadata +365 -410
  250. data/bundler/CHANGELOG.md +0 -5784
  251. data/bundler/LICENSE.md +0 -22
  252. data/bundler/README.md +0 -58
  253. data/bundler/bundler.gemspec +0 -46
  254. data/bundler/lib/bundler/compact_index_client/cache.rb +0 -107
  255. data/bundler/lib/bundler/compact_index_client/cache_file.rb +0 -148
  256. data/bundler/lib/bundler/compact_index_client/parser.rb +0 -87
  257. data/bundler/lib/bundler/compact_index_client/updater.rb +0 -105
  258. data/bundler/lib/bundler/compact_index_client.rb +0 -92
  259. data/bundler/lib/bundler/match_metadata.rb +0 -30
  260. data/bundler/lib/bundler/match_remote_metadata.rb +0 -29
  261. data/bundler/lib/bundler/vendor/connection_pool/LICENSE +0 -20
  262. data/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb +0 -227
  263. data/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool/version.rb +0 -3
  264. data/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool/wrapper.rb +0 -56
  265. data/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool.rb +0 -230
  266. data/bundler/lib/bundler/vendor/net-http-persistent/README.rdoc +0 -82
  267. data/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/connection.rb +0 -41
  268. data/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/pool.rb +0 -65
  269. data/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/timed_stack_multi.rb +0 -80
  270. data/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb +0 -1153
  271. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub.rb +0 -31
  272. data/bundler/lib/bundler/vendor/securerandom/lib/securerandom.rb +0 -102
  273. data/bundler/lib/bundler/vendor/uri/COPYING +0 -56
  274. data/bundler/lib/bundler/vendor/uri/lib/uri/common.rb +0 -922
  275. data/bundler/lib/bundler/vendor/uri/lib/uri/file.rb +0 -100
  276. data/bundler/lib/bundler/vendor/uri/lib/uri/ftp.rb +0 -267
  277. data/bundler/lib/bundler/vendor/uri/lib/uri/generic.rb +0 -1592
  278. data/bundler/lib/bundler/vendor/uri/lib/uri/http.rb +0 -137
  279. data/bundler/lib/bundler/vendor/uri/lib/uri/https.rb +0 -23
  280. data/bundler/lib/bundler/vendor/uri/lib/uri/ldap.rb +0 -261
  281. data/bundler/lib/bundler/vendor/uri/lib/uri/ldaps.rb +0 -22
  282. data/bundler/lib/bundler/vendor/uri/lib/uri/mailto.rb +0 -293
  283. data/bundler/lib/bundler/vendor/uri/lib/uri/rfc2396_parser.rb +0 -547
  284. data/bundler/lib/bundler/vendor/uri/lib/uri/rfc3986_parser.rb +0 -206
  285. data/bundler/lib/bundler/vendor/uri/lib/uri/version.rb +0 -6
  286. data/bundler/lib/bundler/vendor/uri/lib/uri/ws.rb +0 -83
  287. data/bundler/lib/bundler/vendor/uri/lib/uri/wss.rb +0 -23
  288. data/bundler/lib/bundler/vendor/uri/lib/uri.rb +0 -104
  289. data/bundler/lib/bundler/vendored_persistent.rb +0 -11
  290. data/bundler/lib/bundler/vendored_securerandom.rb +0 -12
  291. data/bundler/lib/bundler/vendored_uri.rb +0 -21
  292. data/bundler/lib/bundler/yaml_serializer.rb +0 -98
  293. data/doc/rubygems/CONTRIBUTING.md +0 -231
  294. data/doc/rubygems/POLICIES.md +0 -60
  295. data/lib/rubygems/request_set/lockfile/parser.rb +0 -344
  296. data/lib/rubygems/request_set/lockfile/tokenizer.rb +0 -122
  297. data/lib/rubygems/resolver/conflict.rb +0 -146
  298. data/lib/rubygems/resolver/stats.rb +0 -46
  299. data/lib/rubygems/util/list.rb +0 -40
  300. data/lib/rubygems/vendor/molinillo/LICENSE +0 -9
  301. data/lib/rubygems/vendor/molinillo/lib/molinillo/delegates/resolution_state.rb +0 -57
  302. data/lib/rubygems/vendor/molinillo/lib/molinillo/delegates/specification_provider.rb +0 -88
  303. data/lib/rubygems/vendor/molinillo/lib/molinillo/dependency_graph/action.rb +0 -36
  304. data/lib/rubygems/vendor/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb +0 -66
  305. data/lib/rubygems/vendor/molinillo/lib/molinillo/dependency_graph/add_vertex.rb +0 -62
  306. data/lib/rubygems/vendor/molinillo/lib/molinillo/dependency_graph/delete_edge.rb +0 -63
  307. data/lib/rubygems/vendor/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb +0 -61
  308. data/lib/rubygems/vendor/molinillo/lib/molinillo/dependency_graph/log.rb +0 -126
  309. data/lib/rubygems/vendor/molinillo/lib/molinillo/dependency_graph/set_payload.rb +0 -46
  310. data/lib/rubygems/vendor/molinillo/lib/molinillo/dependency_graph/tag.rb +0 -36
  311. data/lib/rubygems/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb +0 -164
  312. data/lib/rubygems/vendor/molinillo/lib/molinillo/dependency_graph.rb +0 -255
  313. data/lib/rubygems/vendor/molinillo/lib/molinillo/errors.rb +0 -149
  314. data/lib/rubygems/vendor/molinillo/lib/molinillo/gem_metadata.rb +0 -6
  315. data/lib/rubygems/vendor/molinillo/lib/molinillo/modules/specification_provider.rb +0 -112
  316. data/lib/rubygems/vendor/molinillo/lib/molinillo/modules/ui.rb +0 -67
  317. data/lib/rubygems/vendor/molinillo/lib/molinillo/resolution.rb +0 -839
  318. data/lib/rubygems/vendor/molinillo/lib/molinillo/resolver.rb +0 -46
  319. data/lib/rubygems/vendor/molinillo/lib/molinillo/state.rb +0 -58
  320. data/lib/rubygems/vendor/molinillo/lib/molinillo.rb +0 -11
  321. data/lib/rubygems/vendored_molinillo.rb +0 -3
  322. /data/{bundler/exe → exe}/bundle +0 -0
  323. /data/{bundler/exe → exe}/bundler +0 -0
  324. /data/{bundler/lib → lib}/bundler/.document +0 -0
  325. /data/{bundler/lib → lib}/bundler/capistrano.rb +0 -0
  326. /data/{bundler/lib → lib}/bundler/cli/binstubs.rb +0 -0
  327. /data/{bundler/lib → lib}/bundler/cli/check.rb +0 -0
  328. /data/{bundler/lib → lib}/bundler/cli/console.rb +0 -0
  329. /data/{bundler/lib → lib}/bundler/cli/doctor/diagnose.rb +0 -0
  330. /data/{bundler/lib → lib}/bundler/cli/doctor/ssl.rb +0 -0
  331. /data/{bundler/lib → lib}/bundler/cli/doctor.rb +0 -0
  332. /data/{bundler/lib → lib}/bundler/cli/exec.rb +0 -0
  333. /data/{bundler/lib → lib}/bundler/cli/fund.rb +0 -0
  334. /data/{bundler/lib → lib}/bundler/cli/info.rb +0 -0
  335. /data/{bundler/lib → lib}/bundler/cli/init.rb +0 -0
  336. /data/{bundler/lib → lib}/bundler/cli/issue.rb +0 -0
  337. /data/{bundler/lib → lib}/bundler/cli/list.rb +0 -0
  338. /data/{bundler/lib → lib}/bundler/cli/open.rb +0 -0
  339. /data/{bundler/lib → lib}/bundler/cli/platform.rb +0 -0
  340. /data/{bundler/lib → lib}/bundler/cli/plugin.rb +0 -0
  341. /data/{bundler/lib → lib}/bundler/cli/remove.rb +0 -0
  342. /data/{bundler/lib → lib}/bundler/cli/show.rb +0 -0
  343. /data/{bundler/lib → lib}/bundler/constants.rb +0 -0
  344. /data/{bundler/lib → lib}/bundler/current_ruby.rb +0 -0
  345. /data/{bundler/lib → lib}/bundler/deployment.rb +0 -0
  346. /data/{bundler/lib → lib}/bundler/deprecate.rb +0 -0
  347. /data/{bundler/lib → lib}/bundler/digest.rb +0 -0
  348. /data/{bundler/lib → lib}/bundler/environment_preserver.rb +0 -0
  349. /data/{bundler/lib → lib}/bundler/feature_flag.rb +0 -0
  350. /data/{bundler/lib → lib}/bundler/fetcher/base.rb +0 -0
  351. /data/{bundler/lib → lib}/bundler/fetcher/dependency.rb +0 -0
  352. /data/{bundler/lib → lib}/bundler/fetcher/gem_remote_fetcher.rb +0 -0
  353. /data/{bundler/lib → lib}/bundler/fetcher/index.rb +0 -0
  354. /data/{bundler/lib → lib}/bundler/force_platform.rb +0 -0
  355. /data/{bundler/lib → lib}/bundler/friendly_errors.rb +0 -0
  356. /data/{bundler/lib → lib}/bundler/gem_helper.rb +0 -0
  357. /data/{bundler/lib → lib}/bundler/gem_tasks.rb +0 -0
  358. /data/{bundler/lib → lib}/bundler/gem_version_promoter.rb +0 -0
  359. /data/{bundler/lib → lib}/bundler/index.rb +0 -0
  360. /data/{bundler/lib → lib}/bundler/installer/gem_installer.rb +0 -0
  361. /data/{bundler/lib → lib}/bundler/installer/standalone.rb +0 -0
  362. /data/{bundler/lib → lib}/bundler/man/.document +0 -0
  363. /data/{bundler/lib → lib}/bundler/man/bundle-binstubs.1.ronn +0 -0
  364. /data/{bundler/lib → lib}/bundler/man/bundle-check.1.ronn +0 -0
  365. /data/{bundler/lib → lib}/bundler/man/bundle-clean.1.ronn +0 -0
  366. /data/{bundler/lib → lib}/bundler/man/bundle-console.1.ronn +0 -0
  367. /data/{bundler/lib → lib}/bundler/man/bundle-doctor.1.ronn +0 -0
  368. /data/{bundler/lib → lib}/bundler/man/bundle-env.1.ronn +0 -0
  369. /data/{bundler/lib → lib}/bundler/man/bundle-exec.1.ronn +0 -0
  370. /data/{bundler/lib → lib}/bundler/man/bundle-fund.1.ronn +0 -0
  371. /data/{bundler/lib → lib}/bundler/man/bundle-gem.1.ronn +0 -0
  372. /data/{bundler/lib → lib}/bundler/man/bundle-help.1.ronn +0 -0
  373. /data/{bundler/lib → lib}/bundler/man/bundle-info.1.ronn +0 -0
  374. /data/{bundler/lib → lib}/bundler/man/bundle-init.1.ronn +0 -0
  375. /data/{bundler/lib → lib}/bundler/man/bundle-issue.1.ronn +0 -0
  376. /data/{bundler/lib → lib}/bundler/man/bundle-licenses.1.ronn +0 -0
  377. /data/{bundler/lib → lib}/bundler/man/bundle-list.1.ronn +0 -0
  378. /data/{bundler/lib → lib}/bundler/man/bundle-open.1.ronn +0 -0
  379. /data/{bundler/lib → lib}/bundler/man/bundle-outdated.1.ronn +0 -0
  380. /data/{bundler/lib → lib}/bundler/man/bundle-platform.1.ronn +0 -0
  381. /data/{bundler/lib → lib}/bundler/man/bundle-plugin.1.ronn +0 -0
  382. /data/{bundler/lib → lib}/bundler/man/bundle-pristine.1.ronn +0 -0
  383. /data/{bundler/lib → lib}/bundler/man/bundle-remove.1.ronn +0 -0
  384. /data/{bundler/lib → lib}/bundler/man/bundle-show.1.ronn +0 -0
  385. /data/{bundler/lib → lib}/bundler/man/bundle-version.1.ronn +0 -0
  386. /data/{bundler/lib → lib}/bundler/man/bundle.1.ronn +0 -0
  387. /data/{bundler/lib → lib}/bundler/man/index.txt +0 -0
  388. /data/{bundler/lib → lib}/bundler/mirror.rb +0 -0
  389. /data/{bundler/lib → lib}/bundler/plugin/api/source.rb +0 -0
  390. /data/{bundler/lib → lib}/bundler/plugin/api.rb +0 -0
  391. /data/{bundler/lib → lib}/bundler/plugin/installer/git.rb +0 -0
  392. /data/{bundler/lib → lib}/bundler/plugin/installer/rubygems.rb +0 -0
  393. /data/{bundler/lib → lib}/bundler/plugin/source_list.rb +0 -0
  394. /data/{bundler/lib → lib}/bundler/plugin/unloaded_source.rb +0 -0
  395. /data/{bundler/lib → lib}/bundler/process_lock.rb +0 -0
  396. /data/{bundler/lib → lib}/bundler/resolver/candidate.rb +0 -0
  397. /data/{bundler/lib → lib}/bundler/resolver/package.rb +0 -0
  398. /data/{bundler/lib → lib}/bundler/resolver/root.rb +0 -0
  399. /data/{bundler/lib → lib}/bundler/resolver/spec_group.rb +0 -0
  400. /data/{bundler/lib → lib}/bundler/resolver/strategy.rb +0 -0
  401. /data/{bundler/lib → lib}/bundler/retry.rb +0 -0
  402. /data/{bundler/lib → lib}/bundler/ruby_dsl.rb +0 -0
  403. /data/{bundler/lib → lib}/bundler/safe_marshal.rb +0 -0
  404. /data/{bundler/lib → lib}/bundler/settings/validator.rb +0 -0
  405. /data/{bundler/lib → lib}/bundler/setup.rb +0 -0
  406. /data/{bundler/lib → lib}/bundler/source/gemspec.rb +0 -0
  407. /data/{bundler/lib → lib}/bundler/source/metadata.rb +0 -0
  408. /data/{bundler/lib → lib}/bundler/source/path.rb +0 -0
  409. /data/{bundler/lib → lib}/bundler/source/rubygems_aggregate.rb +0 -0
  410. /data/{bundler/lib → lib}/bundler/source.rb +0 -0
  411. /data/{bundler/lib → lib}/bundler/source_list.rb +0 -0
  412. /data/{bundler/lib → lib}/bundler/source_map.rb +0 -0
  413. /data/{bundler/lib → lib}/bundler/templates/.document +0 -0
  414. /data/{bundler/lib → lib}/bundler/templates/Executable +0 -0
  415. /data/{bundler/lib → lib}/bundler/templates/Executable.standalone +0 -0
  416. /data/{bundler/lib → lib}/bundler/templates/Gemfile +0 -0
  417. /data/{bundler/lib → lib}/bundler/templates/newgem/CHANGELOG.md.tt +0 -0
  418. /data/{bundler/lib → lib}/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt +0 -0
  419. /data/{bundler/lib → lib}/bundler/templates/newgem/Cargo.toml.tt +0 -0
  420. /data/{bundler/lib → lib}/bundler/templates/newgem/LICENSE.txt.tt +0 -0
  421. /data/{bundler/lib → lib}/bundler/templates/newgem/README.md.tt +0 -0
  422. /data/{bundler/lib → lib}/bundler/templates/newgem/Rakefile.tt +0 -0
  423. /data/{bundler/lib → lib}/bundler/templates/newgem/bin/console.tt +0 -0
  424. /data/{bundler/lib → lib}/bundler/templates/newgem/bin/setup.tt +0 -0
  425. /data/{bundler/lib → lib}/bundler/templates/newgem/circleci/config.yml.tt +0 -0
  426. /data/{bundler/lib → lib}/bundler/templates/newgem/exe/newgem.tt +0 -0
  427. /data/{bundler/lib → lib}/bundler/templates/newgem/ext/newgem/Cargo.toml.tt +0 -0
  428. /data/{bundler/lib → lib}/bundler/templates/newgem/ext/newgem/build.rs.tt +0 -0
  429. /data/{bundler/lib → lib}/bundler/templates/newgem/ext/newgem/extconf-c.rb.tt +0 -0
  430. /data/{bundler/lib → lib}/bundler/templates/newgem/ext/newgem/extconf-go.rb.tt +0 -0
  431. /data/{bundler/lib → lib}/bundler/templates/newgem/ext/newgem/extconf-rust.rb.tt +0 -0
  432. /data/{bundler/lib → lib}/bundler/templates/newgem/ext/newgem/go.mod.tt +0 -0
  433. /data/{bundler/lib → lib}/bundler/templates/newgem/ext/newgem/newgem-go.c.tt +0 -0
  434. /data/{bundler/lib → lib}/bundler/templates/newgem/ext/newgem/newgem.c.tt +0 -0
  435. /data/{bundler/lib → lib}/bundler/templates/newgem/ext/newgem/newgem.go.tt +0 -0
  436. /data/{bundler/lib → lib}/bundler/templates/newgem/ext/newgem/newgem.h.tt +0 -0
  437. /data/{bundler/lib → lib}/bundler/templates/newgem/ext/newgem/src/lib.rs.tt +0 -0
  438. /data/{bundler/lib → lib}/bundler/templates/newgem/github/workflows/build-gems.yml.tt +0 -0
  439. /data/{bundler/lib → lib}/bundler/templates/newgem/github/workflows/main.yml.tt +0 -0
  440. /data/{bundler/lib → lib}/bundler/templates/newgem/gitignore.tt +0 -0
  441. /data/{bundler/lib → lib}/bundler/templates/newgem/gitlab-ci.yml.tt +0 -0
  442. /data/{bundler/lib → lib}/bundler/templates/newgem/lib/newgem/version.rb.tt +0 -0
  443. /data/{bundler/lib → lib}/bundler/templates/newgem/lib/newgem.rb.tt +0 -0
  444. /data/{bundler/lib → lib}/bundler/templates/newgem/rspec.tt +0 -0
  445. /data/{bundler/lib → lib}/bundler/templates/newgem/rubocop.yml.tt +0 -0
  446. /data/{bundler/lib → lib}/bundler/templates/newgem/sig/newgem.rbs.tt +0 -0
  447. /data/{bundler/lib → lib}/bundler/templates/newgem/spec/spec_helper.rb.tt +0 -0
  448. /data/{bundler/lib → lib}/bundler/templates/newgem/standard.yml.tt +0 -0
  449. /data/{bundler/lib → lib}/bundler/templates/newgem/test/minitest/test_helper.rb.tt +0 -0
  450. /data/{bundler/lib → lib}/bundler/templates/newgem/test/test-unit/newgem_test.rb.tt +0 -0
  451. /data/{bundler/lib → lib}/bundler/templates/newgem/test/test-unit/test_helper.rb.tt +0 -0
  452. /data/{bundler/lib → lib}/bundler/ui/rg_proxy.rb +0 -0
  453. /data/{bundler/lib → lib}/bundler/ui.rb +0 -0
  454. /data/{bundler/lib → lib}/bundler/uri_credentials_filter.rb +0 -0
  455. /data/{bundler/lib → lib}/bundler/uri_normalizer.rb +0 -0
  456. /data/{bundler/lib → lib}/bundler/vendor/.document +0 -0
  457. /data/{bundler/lib → lib}/bundler/vendor/fileutils/COPYING +0 -0
  458. /data/{bundler/lib → lib}/bundler/vendor/fileutils/lib/fileutils.rb +0 -0
  459. /data/{bundler/lib → lib}/bundler/vendor/thor/LICENSE.md +0 -0
  460. /data/{bundler/lib → lib}/bundler/vendor/thor/lib/thor/actions/create_file.rb +0 -0
  461. /data/{bundler/lib → lib}/bundler/vendor/thor/lib/thor/actions/create_link.rb +0 -0
  462. /data/{bundler/lib → lib}/bundler/vendor/thor/lib/thor/actions/directory.rb +0 -0
  463. /data/{bundler/lib → lib}/bundler/vendor/thor/lib/thor/actions/empty_directory.rb +0 -0
  464. /data/{bundler/lib → lib}/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb +0 -0
  465. /data/{bundler/lib → lib}/bundler/vendor/thor/lib/thor/actions.rb +0 -0
  466. /data/{bundler/lib → lib}/bundler/vendor/thor/lib/thor/command.rb +0 -0
  467. /data/{bundler/lib → lib}/bundler/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb +0 -0
  468. /data/{bundler/lib → lib}/bundler/vendor/thor/lib/thor/error.rb +0 -0
  469. /data/{bundler/lib → lib}/bundler/vendor/thor/lib/thor/group.rb +0 -0
  470. /data/{bundler/lib → lib}/bundler/vendor/thor/lib/thor/invocation.rb +0 -0
  471. /data/{bundler/lib → lib}/bundler/vendor/thor/lib/thor/line_editor/basic.rb +0 -0
  472. /data/{bundler/lib → lib}/bundler/vendor/thor/lib/thor/line_editor/readline.rb +0 -0
  473. /data/{bundler/lib → lib}/bundler/vendor/thor/lib/thor/line_editor.rb +0 -0
  474. /data/{bundler/lib → lib}/bundler/vendor/thor/lib/thor/nested_context.rb +0 -0
  475. /data/{bundler/lib → lib}/bundler/vendor/thor/lib/thor/parser/argument.rb +0 -0
  476. /data/{bundler/lib → lib}/bundler/vendor/thor/lib/thor/parser/arguments.rb +0 -0
  477. /data/{bundler/lib → lib}/bundler/vendor/thor/lib/thor/parser/option.rb +0 -0
  478. /data/{bundler/lib → lib}/bundler/vendor/thor/lib/thor/parser/options.rb +0 -0
  479. /data/{bundler/lib → lib}/bundler/vendor/thor/lib/thor/parser.rb +0 -0
  480. /data/{bundler/lib → lib}/bundler/vendor/thor/lib/thor/rake_compat.rb +0 -0
  481. /data/{bundler/lib → lib}/bundler/vendor/thor/lib/thor/runner.rb +0 -0
  482. /data/{bundler/lib → lib}/bundler/vendor/thor/lib/thor/shell/column_printer.rb +0 -0
  483. /data/{bundler/lib → lib}/bundler/vendor/thor/lib/thor/shell/html.rb +0 -0
  484. /data/{bundler/lib → lib}/bundler/vendor/thor/lib/thor/shell/table_printer.rb +0 -0
  485. /data/{bundler/lib → lib}/bundler/vendor/thor/lib/thor/shell/terminal.rb +0 -0
  486. /data/{bundler/lib → lib}/bundler/vendor/thor/lib/thor/shell/wrapped_printer.rb +0 -0
  487. /data/{bundler/lib → lib}/bundler/vendor/thor/lib/thor/shell.rb +0 -0
  488. /data/{bundler/lib → lib}/bundler/vendor/thor/lib/thor/util.rb +0 -0
  489. /data/{bundler/lib → lib}/bundler/vendored_fileutils.rb +0 -0
  490. /data/{bundler/lib → lib}/bundler/vendored_net_http.rb +0 -0
  491. /data/{bundler/lib → lib}/bundler/vendored_thor.rb +0 -0
  492. /data/{bundler/lib → lib}/bundler/vendored_timeout.rb +0 -0
  493. /data/{bundler/lib → lib}/bundler/vendored_tsort.rb +0 -0
  494. /data/{bundler/lib → lib}/bundler/vlad.rb +0 -0
  495. /data/{bundler/lib/bundler → lib/rubygems}/vendor/pub_grub/LICENSE.txt +0 -0
  496. /data/{bundler/lib/bundler/vendor/securerandom → lib/rubygems/vendor/resolv}/COPYING +0 -0
@@ -0,0 +1,122 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "digest"
4
+ require "fileutils"
5
+ require "pathname" unless defined?(Pathname)
6
+ require "set"
7
+
8
+ class Gem::CompactIndexClient
9
+ # Calls the Updater to update the cached files on disk, reads the
10
+ # cached files and returns their contents.
11
+ class Cache
12
+ attr_reader :directory
13
+
14
+ def initialize(directory, fetcher = nil)
15
+ @directory = Pathname.new(directory).expand_path
16
+ @updater = Updater.new(fetcher) if fetcher
17
+ @mutex = Thread::Mutex.new
18
+ @endpoints = Set.new
19
+
20
+ @info_root = mkdir("info")
21
+ @special_characters_info_root = mkdir("info-special-characters")
22
+ @info_etag_root = mkdir("info-etags")
23
+ end
24
+
25
+ def names
26
+ fetch("names", names_path, names_etag_path)
27
+ end
28
+
29
+ def versions
30
+ fetch("versions", versions_path, versions_etag_path)
31
+ end
32
+
33
+ def info(name, remote_checksum = nil)
34
+ path = info_path(name)
35
+
36
+ if remote_checksum && remote_checksum != checksum_for_file(path)
37
+ fetch("info/#{name}", path, info_etag_path(name))
38
+ else
39
+ Gem::CompactIndexClient.debug { "update skipped info/#{name} (#{remote_checksum ? "versions index checksum matches local" : "versions index checksum is nil"})" }
40
+ read(path)
41
+ end
42
+ end
43
+
44
+ # Fetch a single gem's info file without consulting the versions
45
+ # index, refreshing the cached file with a conditional request.
46
+ def fetch_info(name)
47
+ fetch("info/#{name}", info_path(name), info_etag_path(name))
48
+ end
49
+
50
+ def reset!
51
+ @mutex.synchronize { @endpoints.clear }
52
+ end
53
+
54
+ private
55
+
56
+ def names_path = directory.join("names")
57
+ def names_etag_path = directory.join("names.etag")
58
+ def versions_path = directory.join("versions")
59
+ def versions_etag_path = directory.join("versions.etag")
60
+
61
+ def info_path(name)
62
+ name = name.to_s
63
+ validate_name!(name)
64
+ if /[^a-z0-9_-]/.match?(name)
65
+ name += "-#{Digest::MD5.hexdigest(name).downcase}"
66
+ @special_characters_info_root.join(name)
67
+ else
68
+ @info_root.join(name)
69
+ end
70
+ end
71
+
72
+ def info_etag_path(name)
73
+ name = name.to_s
74
+ validate_name!(name)
75
+ @info_etag_root.join("#{name}-#{Digest::MD5.hexdigest(name).downcase}")
76
+ end
77
+
78
+ # Gem names come from the remote index and are not otherwise
79
+ # validated, so refuse anything that would escape the cache
80
+ # directory when used as a path component.
81
+ def validate_name!(name)
82
+ return unless name.empty? || name.include?("\0") || name == "." || name == ".." || File.basename(name) != name
83
+
84
+ raise Gem::Exception, "malformed gem name: #{name.inspect}"
85
+ end
86
+
87
+ def checksum_for_file(path)
88
+ return unless path.file?
89
+ Gem::CompactIndexClient.filesystem_access(path, :read) do
90
+ Digest::MD5.file(path).hexdigest
91
+ end
92
+ end
93
+
94
+ def mkdir(name)
95
+ directory.join(name).tap do |dir|
96
+ Gem::CompactIndexClient.filesystem_access(dir) do
97
+ FileUtils.mkdir_p(dir)
98
+ end
99
+ end
100
+ end
101
+
102
+ def fetch(remote_path, path, etag_path)
103
+ if already_fetched?(remote_path)
104
+ Gem::CompactIndexClient.debug { "already fetched #{remote_path}" }
105
+ else
106
+ Gem::CompactIndexClient.debug { "fetching #{remote_path}" }
107
+ @updater&.update(remote_path, path, etag_path)
108
+ end
109
+
110
+ read(path)
111
+ end
112
+
113
+ def already_fetched?(remote_path)
114
+ @mutex.synchronize { !@endpoints.add?(remote_path) }
115
+ end
116
+
117
+ def read(path)
118
+ return unless path.file?
119
+ Gem::CompactIndexClient.filesystem_access(path, :read, &:read)
120
+ end
121
+ end
122
+ end
@@ -0,0 +1,147 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "digest"
4
+ require "fileutils"
5
+ require "rubygems/package"
6
+
7
+ class Gem::CompactIndexClient
8
+ # write cache files in a way that is robust to concurrent modifications
9
+ # if digests are given, the checksums will be verified
10
+ class CacheFile
11
+ DEFAULT_FILE_MODE = 0o644
12
+ private_constant :DEFAULT_FILE_MODE
13
+
14
+ class Error < RuntimeError; end
15
+ class ClosedError < Error; end
16
+
17
+ class DigestMismatchError < Error
18
+ def initialize(digests, expected_digests)
19
+ super "Calculated checksums #{digests.inspect} did not match expected #{expected_digests.inspect}."
20
+ end
21
+ end
22
+
23
+ # Initialize with a copy of the original file, then yield the instance.
24
+ def self.copy(path, &block)
25
+ new(path) do |file|
26
+ file.initialize_digests
27
+
28
+ Gem::CompactIndexClient.filesystem_access(path, :read) do
29
+ path.open("rb") do |s|
30
+ file.open {|f| IO.copy_stream(s, f) }
31
+ end
32
+ end
33
+
34
+ yield file
35
+ end
36
+ end
37
+
38
+ # Write data to a temp file, then replace the original file with it verifying the digests if given.
39
+ def self.write(path, data, digests = nil)
40
+ return unless data
41
+ new(path) do |file|
42
+ file.digests = digests
43
+ file.write(data)
44
+ end
45
+ end
46
+
47
+ attr_reader :original_path, :path
48
+
49
+ def initialize(original_path, &block)
50
+ @original_path = original_path
51
+ @perm = original_path.file? ? original_path.stat.mode : DEFAULT_FILE_MODE
52
+ @path = original_path.sub(/$/, ".#{$$}.tmp")
53
+ return unless block_given?
54
+ begin
55
+ yield self
56
+ ensure
57
+ close
58
+ end
59
+ end
60
+
61
+ def size
62
+ path.size
63
+ end
64
+
65
+ # initialize the digests using CompactIndexClient::SUPPORTED_DIGESTS, or a subset based on keys.
66
+ def initialize_digests(keys = nil)
67
+ @digests = keys ? SUPPORTED_DIGESTS.slice(*keys) : SUPPORTED_DIGESTS.dup
68
+ @digests.transform_values! {|algo_class| Digest(algo_class).new }
69
+ end
70
+
71
+ # reset the digests so they don't contain any previously read data
72
+ def reset_digests
73
+ @digests&.each_value(&:reset)
74
+ end
75
+
76
+ # set the digests that will be verified at the end
77
+ def digests=(expected_digests)
78
+ @expected_digests = expected_digests
79
+
80
+ if @expected_digests.nil?
81
+ @digests = nil
82
+ elsif @digests
83
+ @digests = @digests.slice(*@expected_digests.keys)
84
+ else
85
+ initialize_digests(@expected_digests.keys)
86
+ end
87
+ end
88
+
89
+ def digests?
90
+ @digests&.any?
91
+ end
92
+
93
+ # Open the temp file for writing, reusing original permissions, yielding the IO object.
94
+ def open(write_mode = "wb", perm = @perm, &block)
95
+ raise ClosedError, "Cannot reopen closed file" if @closed
96
+ Gem::CompactIndexClient.filesystem_access(path, :write) do
97
+ path.open(write_mode, perm) do |f|
98
+ yield digests? ? Gem::Package::DigestIO.new(f, @digests) : f
99
+ end
100
+ end
101
+ end
102
+
103
+ # Returns false without appending when no digests since appending is too error prone to do without digests.
104
+ def append(data)
105
+ return false unless digests?
106
+ open("ab") {|f| f.write data }
107
+ verify && commit
108
+ end
109
+
110
+ def write(data)
111
+ reset_digests
112
+ open {|f| f.write data }
113
+ commit!
114
+ end
115
+
116
+ def commit!
117
+ verify || raise(DigestMismatchError.new(@base64digests, @expected_digests))
118
+ commit
119
+ end
120
+
121
+ # Verify the digests, returning true on match, false on mismatch.
122
+ def verify
123
+ return true unless @expected_digests && digests?
124
+ @base64digests = @digests.transform_values!(&:base64digest)
125
+ @digests = nil
126
+ @base64digests.all? {|algo, digest| @expected_digests[algo] == digest }
127
+ end
128
+
129
+ # Replace the original file with the temp file without verifying digests.
130
+ # The file is permanently closed.
131
+ def commit
132
+ raise ClosedError, "Cannot commit closed file" if @closed
133
+ Gem::CompactIndexClient.filesystem_access(original_path, :write) do
134
+ FileUtils.mv(path, original_path)
135
+ end
136
+ @closed = true
137
+ end
138
+
139
+ # Remove the temp file without replacing the original file.
140
+ # The file is permanently closed.
141
+ def close
142
+ return if @closed
143
+ FileUtils.remove_file(path) if @path&.file?
144
+ @closed = true
145
+ end
146
+ end
147
+ end
@@ -0,0 +1,88 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rubygems/remote_fetcher"
4
+
5
+ class Gem::CompactIndexClient
6
+ # Fetches compact index files relative to +base_uri+ using
7
+ # Gem::RemoteFetcher's connection infrastructure (proxy, TLS,
8
+ # connection pooling). Implements the fetcher interface expected by
9
+ # Gem::CompactIndexClient: #call(path, headers) returning a
10
+ # Gem::Net::HTTP response.
11
+ class HTTPFetcher
12
+ REDIRECT_LIMIT = 10
13
+ private_constant :REDIRECT_LIMIT
14
+
15
+ def initialize(base_uri, remote_fetcher = Gem::RemoteFetcher.fetcher)
16
+ base_uri = base_uri.to_s
17
+ base_uri += "/" unless base_uri.end_with?("/")
18
+ @base_uri = Gem::URI(base_uri)
19
+ @remote_fetcher = remote_fetcher
20
+ end
21
+
22
+ def call(path, headers = {})
23
+ fetch(@base_uri + path, headers, REDIRECT_LIMIT)
24
+ end
25
+
26
+ private
27
+
28
+ def fetch(uri, headers, redirects_remaining)
29
+ response = request(uri, headers)
30
+
31
+ case response
32
+ when Gem::Net::HTTPNotModified
33
+ response
34
+ when Gem::Net::HTTPSuccess
35
+ # The callers write the body into the cache, so a body-less success
36
+ # such as 204 would truncate the cached file.
37
+ raise bad_response(response, uri) unless response.class.body_permitted?
38
+
39
+ response
40
+ when Gem::Net::HTTPMovedPermanently, Gem::Net::HTTPFound, Gem::Net::HTTPSeeOther,
41
+ Gem::Net::HTTPTemporaryRedirect, Gem::Net::HTTPPermanentRedirect
42
+ raise Gem::RemoteFetcher::FetchError.new("too many redirects", uri) if redirects_remaining.zero?
43
+
44
+ location = response["Location"]
45
+ raise Gem::RemoteFetcher::FetchError.new("redirecting but no redirect location was given", uri) unless location
46
+
47
+ redirect = uri + location
48
+ if https?(uri) && !https?(redirect)
49
+ raise Gem::RemoteFetcher::FetchError.new("redirecting to non-https resource: #{Gem::Uri.redact(redirect)}", uri)
50
+ end
51
+ # An absolute Location on the same host drops the credentials that a
52
+ # relative one would have kept.
53
+ redirect.userinfo = uri.userinfo if redirect.host == uri.host && !redirect.userinfo
54
+
55
+ fetch(redirect, headers, redirects_remaining - 1)
56
+ when Gem::Net::HTTPRangeNotSatisfiable
57
+ raise bad_response(response, uri) unless headers.key?("Range")
58
+
59
+ # The local cache is longer than the remote file, refetch it whole. A
60
+ # matching ETag would otherwise turn the retry into a 304 and keep the
61
+ # oversized cache.
62
+ fetch(uri, headers.except("Range", "If-None-Match"), redirects_remaining)
63
+ else
64
+ raise bad_response(response, uri)
65
+ end
66
+ end
67
+
68
+ # The callers fall back to the Marshal index when a fetch fails, and they
69
+ # only recognize a failure that arrives as a FetchError.
70
+ def request(uri, headers)
71
+ @remote_fetcher.request(uri, Gem::Net::HTTP::Get) do |req|
72
+ headers.each {|name, value| req[name] = value }
73
+ end
74
+ rescue Gem::Timeout::Error, IOError, SocketError, SystemCallError,
75
+ *(OpenSSL::SSL::SSLError if Gem::HAVE_OPENSSL) => e
76
+ raise Gem::RemoteFetcher::FetchError.new("#{e.class}: #{e}", uri)
77
+ end
78
+
79
+ def bad_response(response, uri)
80
+ detail = response["X-Error-Message"] || response.message
81
+ Gem::RemoteFetcher::FetchError.new("bad response #{detail} #{response.code}", uri)
82
+ end
83
+
84
+ def https?(uri)
85
+ uri.scheme == "https"
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rubygems/resolver/api_set/gem_parser"
4
+
5
+ class Gem::CompactIndexClient
6
+ class Parser
7
+ # `compact_index` - an object responding to #names, #versions, #info(name, checksum),
8
+ # returning the file contents as a string
9
+ def initialize(compact_index)
10
+ @compact_index = compact_index
11
+ @info_checksums = nil
12
+ @versions_by_name = nil
13
+ @available = nil
14
+ @gem_parser = nil
15
+ end
16
+
17
+ def names
18
+ lines(@compact_index.names)
19
+ end
20
+
21
+ def versions
22
+ @versions_by_name ||= Hash.new {|hash, key| hash[key] = [] }
23
+ @info_checksums = {}
24
+
25
+ lines(@compact_index.versions).each do |line|
26
+ name, versions_string, checksum = line.split(" ", 3)
27
+ @info_checksums[name] = checksum || ""
28
+ versions_string.split(",") do |version|
29
+ delete = version.delete_prefix!("-")
30
+ version = version.split("-", 2).unshift(name)
31
+ if delete
32
+ @versions_by_name[name].delete(version)
33
+ else
34
+ @versions_by_name[name] << version
35
+ end
36
+ end
37
+ end
38
+
39
+ @versions_by_name
40
+ end
41
+
42
+ def info(name)
43
+ parse_info(@compact_index.info(name, info_checksums[name]), name)
44
+ end
45
+
46
+ def parse_info(data, name)
47
+ lines(data).map {|line| gem_parser.parse(line).unshift(name) }
48
+ end
49
+
50
+ def available?
51
+ return @available unless @available.nil?
52
+ @available = !info_checksums.empty?
53
+ end
54
+
55
+ private
56
+
57
+ def info_checksums
58
+ @info_checksums ||= lines(@compact_index.versions).each_with_object({}) do |line, checksums|
59
+ parse_version_checksum(line, checksums)
60
+ end
61
+ end
62
+
63
+ def lines(data)
64
+ return [] if data.nil? || data.empty?
65
+ lines = data.split("\n")
66
+ header = lines.index("---")
67
+ header ? lines[header + 1..-1] : lines
68
+ end
69
+
70
+ def gem_parser
71
+ @gem_parser ||= Gem::Resolver::APISet::GemParser.new
72
+ end
73
+
74
+ # This is mostly the same as `split(" ", 3)` but it avoids allocating extra objects.
75
+ # This method gets called at least once for every gem when parsing versions.
76
+ def parse_version_checksum(line, checksums)
77
+ return unless (name_end = line.index(" ")) # Artifactory bug causes blank lines in artifactory index files
78
+ checksum_start = line.index(" ", name_end + 1)
79
+ return unless checksum_start
80
+ checksum_start += 1
81
+
82
+ checksum_end = line.size - checksum_start
83
+
84
+ line.freeze # allows slicing into the string to not allocate a copy of the line
85
+ name = line[0, name_end]
86
+ checksum = line[checksum_start, checksum_end]
87
+ checksums[name.freeze] = checksum # freeze name since it is used as a hash key
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,113 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "zlib"
4
+
5
+ # On RubyGems versions too old to vendor Gem::Net (when this file is loaded
6
+ # from the copy shipped inside the Bundler gem), Bundler's own
7
+ # vendored_net_http shim has already defined it before this file is loaded.
8
+ begin
9
+ require "rubygems/vendored_net_http" unless defined?(Gem::Net::HTTP)
10
+ rescue LoadError
11
+ require "net/http"
12
+ end
13
+
14
+ class Gem::CompactIndexClient
15
+ # Updates the cached files on disk, keeping them in sync with the server
16
+ # using conditional requests (ETag) and ranged requests where possible.
17
+ class Updater
18
+ class MismatchedChecksumError < Error
19
+ def initialize(path, message)
20
+ super "The checksum of /#{path} does not match the checksum provided by the server! Something is wrong. #{message}"
21
+ end
22
+ end
23
+
24
+ def initialize(fetcher)
25
+ @fetcher = fetcher
26
+ end
27
+
28
+ def update(remote_path, local_path, etag_path)
29
+ append(remote_path, local_path, etag_path) || replace(remote_path, local_path, etag_path)
30
+ rescue CacheFile::DigestMismatchError => e
31
+ raise MismatchedChecksumError.new(remote_path, e.message)
32
+ rescue Zlib::GzipFile::Error
33
+ raise Error, "invalid gzip response while fetching /#{remote_path}"
34
+ end
35
+
36
+ private
37
+
38
+ def append(remote_path, local_path, etag_path)
39
+ return false unless local_path.file? && local_path.size.nonzero?
40
+
41
+ CacheFile.copy(local_path) do |file|
42
+ etag = etag_path.read.tap(&:chomp!) if etag_path.file?
43
+
44
+ # Subtract a byte to ensure the range won't be empty.
45
+ # Avoids 416 (Range Not Satisfiable) responses.
46
+ response = @fetcher.call(remote_path, request_headers(etag, file.size - 1))
47
+ break true if response.is_a?(Gem::Net::HTTPNotModified)
48
+
49
+ file.digests = parse_digests(response)
50
+ # server may ignore Range and return the full response
51
+ if response.is_a?(Gem::Net::HTTPPartialContent)
52
+ tail = response.body.byteslice(1..-1)
53
+ break false unless tail && file.append(tail)
54
+ else
55
+ file.write(response.body)
56
+ end
57
+ CacheFile.write(etag_path, etag_from_response(response))
58
+ true
59
+ end
60
+ end
61
+
62
+ # request without range header to get the full file or a 304 Not Modified
63
+ def replace(remote_path, local_path, etag_path)
64
+ etag = etag_path.read.tap(&:chomp!) if etag_path.file?
65
+ response = @fetcher.call(remote_path, request_headers(etag))
66
+ return true if response.is_a?(Gem::Net::HTTPNotModified)
67
+ CacheFile.write(local_path, response.body, parse_digests(response))
68
+ CacheFile.write(etag_path, etag_from_response(response))
69
+ end
70
+
71
+ def request_headers(etag, range_start = nil)
72
+ headers = {}
73
+ headers["Range"] = "bytes=#{range_start}-" if range_start
74
+ headers["If-None-Match"] = %("#{etag}") if etag
75
+ headers
76
+ end
77
+
78
+ def etag_from_response(response)
79
+ return unless response["ETag"]
80
+ etag = response["ETag"].delete_prefix("W/")
81
+ return if etag.delete_prefix!('"') && !etag.delete_suffix!('"')
82
+ etag
83
+ end
84
+
85
+ # Unwraps and returns a Hash of digest algorithms and base64 values
86
+ # according to RFC 8941 Structured Field Values for HTTP.
87
+ # https://www.rfc-editor.org/rfc/rfc8941#name-parsing-a-byte-sequence
88
+ # Ignores unsupported algorithms.
89
+ def parse_digests(response)
90
+ return unless header = response["Repr-Digest"] || response["Digest"]
91
+ digests = {}
92
+ header.split(",") do |param|
93
+ algorithm, value = param.split("=", 2)
94
+ algorithm.strip!
95
+ algorithm.downcase!
96
+ next unless SUPPORTED_DIGESTS.key?(algorithm)
97
+ next unless value
98
+ next unless value = byte_sequence(value)
99
+ digests[algorithm] = value
100
+ end
101
+ digests.empty? ? nil : digests
102
+ end
103
+
104
+ # Unwrap surrounding colons (byte sequence)
105
+ # The wrapping characters must be matched or we return nil.
106
+ # Also handles quotes because right now rubygems.org sends them.
107
+ def byte_sequence(value)
108
+ return if value.delete_prefix!(":") && !value.delete_suffix!(":")
109
+ return if value.delete_prefix!('"') && !value.delete_suffix!('"')
110
+ value
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,111 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Skip reloading when an identical copy (e.g. the one shipped inside the Bundler
4
+ # gem) was already required from a different path, to avoid redefinition warnings.
5
+ return if defined?(Gem::CompactIndexClient::INFO_REQS)
6
+
7
+ ##
8
+ # The CompactIndexClient fetches and parses the compact index files
9
+ # (names, versions and info/[gem]) served by a gem server, keeping a
10
+ # local cache so subsequent fetches only transfer what changed.
11
+ #
12
+ # This is the single shared client: Bundler ships a copy of it and uses
13
+ # it underneath its own fetcher orchestration, injecting its fetcher and
14
+ # filesystem access hook.
15
+
16
+ class Gem::CompactIndexClient
17
+ SUPPORTED_DIGESTS = { "sha-256" => :SHA256 }.freeze
18
+ DEBUG_MUTEX = Thread::Mutex.new
19
+
20
+ # info returns an Array of INFO Arrays. Each INFO Array has the following indices:
21
+ INFO_NAME = 0
22
+ INFO_VERSION = 1
23
+ INFO_SUFFIX = 2
24
+ INFO_DEPS = 3
25
+ INFO_REQS = 4
26
+
27
+ INFO_PLATFORM = INFO_SUFFIX
28
+ deprecate_constant :INFO_PLATFORM
29
+
30
+ def self.debug
31
+ return unless ENV["DEBUG_COMPACT_INDEX"]
32
+ DEBUG_MUTEX.synchronize { warn("[#{self}] #{yield}") }
33
+ end
34
+
35
+ class Error < StandardError; end
36
+
37
+ # Filesystem reads and writes funnel through this hook so that a host
38
+ # (e.g. Bundler) can translate low-level Errno exceptions into its own
39
+ # friendlier errors. The default just yields the path.
40
+ def self.filesystem_access(path, action = :write, &block)
41
+ if @filesystem_access
42
+ @filesystem_access.call(path, action, &block)
43
+ else
44
+ yield path
45
+ end
46
+ end
47
+
48
+ def self.filesystem_access=(hook)
49
+ @filesystem_access = hook
50
+ end
51
+
52
+ require_relative "compact_index_client/cache"
53
+ require_relative "compact_index_client/cache_file"
54
+ require_relative "compact_index_client/http_fetcher"
55
+ require_relative "compact_index_client/parser"
56
+ require_relative "compact_index_client/updater"
57
+
58
+ # The client is instantiated with:
59
+ # - `directory`: the root directory where the cache files are stored.
60
+ # - `fetcher`: (optional) an object that responds to #call(uri_path, headers)
61
+ # and returns a Gem::Net::HTTP response. When the fetcher is not provided,
62
+ # the client only reads cached files from disk.
63
+ def initialize(directory, fetcher = nil)
64
+ @cache = Cache.new(directory, fetcher)
65
+ @parser = Parser.new(@cache)
66
+ end
67
+
68
+ def names
69
+ Gem::CompactIndexClient.debug { "names" }
70
+ @parser.names
71
+ end
72
+
73
+ def versions
74
+ Gem::CompactIndexClient.debug { "versions" }
75
+ @parser.versions
76
+ end
77
+
78
+ def dependencies(names)
79
+ Gem::CompactIndexClient.debug { "dependencies(#{names})" }
80
+ names.map {|name| info(name) }
81
+ end
82
+
83
+ def info(name)
84
+ Gem::CompactIndexClient.debug { "info(#{name})" }
85
+ @parser.info(name)
86
+ end
87
+
88
+ # Fetches a single gem's info without consulting the versions index,
89
+ # using a conditional request to refresh the cached file. Useful when
90
+ # only a few gems are needed and the versions index download would
91
+ # dominate, as in gem install.
92
+ def fetch_info(name)
93
+ Gem::CompactIndexClient.debug { "fetch_info(#{name})" }
94
+ @parser.parse_info(@cache.fetch_info(name), name)
95
+ end
96
+
97
+ def latest_version(name)
98
+ Gem::CompactIndexClient.debug { "latest_version(#{name})" }
99
+ @parser.info(name).map {|d| Gem::Version.new(d[INFO_VERSION]) }.max
100
+ end
101
+
102
+ def available?
103
+ Gem::CompactIndexClient.debug { "available?" }
104
+ @parser.available?
105
+ end
106
+
107
+ def reset!
108
+ Gem::CompactIndexClient.debug { "reset!" }
109
+ @cache.reset!
110
+ end
111
+ end