rubygems-update 3.3.18 → 3.4.19

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 (615) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1429 -1064
  3. data/CONTRIBUTING.md +31 -8
  4. data/Manifest.txt +61 -36
  5. data/POLICIES.md +55 -20
  6. data/README.md +19 -6
  7. data/bundler/CHANGELOG.md +457 -1
  8. data/bundler/README.md +3 -6
  9. data/bundler/UPGRADING.md +11 -4
  10. data/bundler/bundler.gemspec +8 -10
  11. data/bundler/exe/bundle +5 -16
  12. data/bundler/lib/bundler/build_metadata.rb +2 -2
  13. data/bundler/lib/bundler/cli/add.rb +1 -1
  14. data/bundler/lib/bundler/cli/binstubs.rb +6 -2
  15. data/bundler/lib/bundler/cli/check.rb +1 -1
  16. data/bundler/lib/bundler/cli/common.rb +2 -0
  17. data/bundler/lib/bundler/cli/console.rb +2 -2
  18. data/bundler/lib/bundler/cli/doctor.rb +4 -6
  19. data/bundler/lib/bundler/cli/gem.rb +62 -40
  20. data/bundler/lib/bundler/cli/info.rb +1 -1
  21. data/bundler/lib/bundler/cli/init.rb +6 -2
  22. data/bundler/lib/bundler/cli/install.rb +8 -6
  23. data/bundler/lib/bundler/cli/lock.rb +8 -5
  24. data/bundler/lib/bundler/cli/open.rb +6 -4
  25. data/bundler/lib/bundler/cli/outdated.rb +14 -7
  26. data/bundler/lib/bundler/cli/platform.rb +7 -5
  27. data/bundler/lib/bundler/cli/viz.rb +1 -1
  28. data/bundler/lib/bundler/cli.rb +53 -7
  29. data/bundler/lib/bundler/compact_index_client/cache.rb +1 -1
  30. data/bundler/lib/bundler/compact_index_client/updater.rb +40 -39
  31. data/bundler/lib/bundler/constants.rb +1 -1
  32. data/bundler/lib/bundler/current_ruby.rb +16 -5
  33. data/bundler/lib/bundler/definition.rb +262 -133
  34. data/bundler/lib/bundler/dependency.rb +20 -86
  35. data/bundler/lib/bundler/digest.rb +1 -1
  36. data/bundler/lib/bundler/dsl.rb +6 -7
  37. data/bundler/lib/bundler/endpoint_specification.rb +2 -13
  38. data/bundler/lib/bundler/env.rb +2 -2
  39. data/bundler/lib/bundler/environment_preserver.rb +3 -2
  40. data/bundler/lib/bundler/errors.rb +1 -11
  41. data/bundler/lib/bundler/feature_flag.rb +0 -2
  42. data/bundler/lib/bundler/fetcher/compact_index.rb +11 -13
  43. data/bundler/lib/bundler/fetcher/dependency.rb +2 -6
  44. data/bundler/lib/bundler/fetcher/downloader.rb +4 -5
  45. data/bundler/lib/bundler/fetcher/index.rb +1 -2
  46. data/bundler/lib/bundler/fetcher.rb +21 -15
  47. data/bundler/lib/bundler/force_platform.rb +18 -0
  48. data/bundler/lib/bundler/friendly_errors.rb +1 -4
  49. data/bundler/lib/bundler/gem_helper.rb +3 -4
  50. data/bundler/lib/bundler/gem_helpers.rb +7 -2
  51. data/bundler/lib/bundler/gem_version_promoter.rb +53 -98
  52. data/bundler/lib/bundler/graph.rb +3 -3
  53. data/bundler/lib/bundler/index.rb +13 -47
  54. data/bundler/lib/bundler/injector.rb +5 -4
  55. data/bundler/lib/bundler/inline.rb +9 -11
  56. data/bundler/lib/bundler/installer/parallel_installer.rb +4 -34
  57. data/bundler/lib/bundler/installer/standalone.rb +13 -9
  58. data/bundler/lib/bundler/installer.rb +17 -29
  59. data/bundler/lib/bundler/lazy_specification.rb +54 -53
  60. data/bundler/lib/bundler/lockfile_generator.rb +3 -3
  61. data/bundler/lib/bundler/lockfile_parser.rb +17 -16
  62. data/bundler/lib/bundler/man/bundle-add.1 +6 -2
  63. data/bundler/lib/bundler/man/bundle-add.1.ronn +4 -1
  64. data/bundler/lib/bundler/man/bundle-binstubs.1 +1 -1
  65. data/bundler/lib/bundler/man/bundle-cache.1 +9 -3
  66. data/bundler/lib/bundler/man/bundle-cache.1.ronn +9 -2
  67. data/bundler/lib/bundler/man/bundle-check.1 +1 -1
  68. data/bundler/lib/bundler/man/bundle-clean.1 +2 -2
  69. data/bundler/lib/bundler/man/bundle-clean.1.ronn +1 -1
  70. data/bundler/lib/bundler/man/bundle-config.1 +26 -10
  71. data/bundler/lib/bundler/man/bundle-config.1.ronn +17 -10
  72. data/bundler/lib/bundler/man/bundle-console.1 +53 -0
  73. data/bundler/lib/bundler/man/bundle-console.1.ronn +44 -0
  74. data/bundler/lib/bundler/man/bundle-doctor.1 +1 -1
  75. data/bundler/lib/bundler/man/bundle-exec.1 +6 -6
  76. data/bundler/lib/bundler/man/bundle-exec.1.ronn +6 -6
  77. data/bundler/lib/bundler/man/bundle-gem.1 +27 -37
  78. data/bundler/lib/bundler/man/bundle-gem.1.ronn +5 -5
  79. data/bundler/lib/bundler/man/bundle-help.1 +13 -0
  80. data/bundler/lib/bundler/man/bundle-help.1.ronn +12 -0
  81. data/bundler/lib/bundler/man/bundle-info.1 +3 -3
  82. data/bundler/lib/bundler/man/bundle-info.1.ronn +3 -3
  83. data/bundler/lib/bundler/man/bundle-init.1 +5 -1
  84. data/bundler/lib/bundler/man/bundle-init.1.ronn +2 -0
  85. data/bundler/lib/bundler/man/bundle-inject.1 +5 -2
  86. data/bundler/lib/bundler/man/bundle-inject.1.ronn +3 -1
  87. data/bundler/lib/bundler/man/bundle-install.1 +5 -30
  88. data/bundler/lib/bundler/man/bundle-install.1.ronn +6 -29
  89. data/bundler/lib/bundler/man/bundle-list.1 +1 -1
  90. data/bundler/lib/bundler/man/bundle-lock.1 +1 -1
  91. data/bundler/lib/bundler/man/bundle-open.1 +22 -2
  92. data/bundler/lib/bundler/man/bundle-open.1.ronn +9 -1
  93. data/bundler/lib/bundler/man/bundle-outdated.1 +13 -9
  94. data/bundler/lib/bundler/man/bundle-outdated.1.ronn +12 -9
  95. data/bundler/lib/bundler/man/bundle-platform.1 +16 -6
  96. data/bundler/lib/bundler/man/bundle-platform.1.ronn +14 -7
  97. data/bundler/lib/bundler/man/bundle-plugin.1 +81 -0
  98. data/bundler/lib/bundler/man/bundle-plugin.1.ronn +59 -0
  99. data/bundler/lib/bundler/man/bundle-pristine.1 +1 -1
  100. data/bundler/lib/bundler/man/bundle-remove.1 +1 -1
  101. data/bundler/lib/bundler/man/bundle-show.1 +1 -1
  102. data/bundler/lib/bundler/man/bundle-update.1 +1 -1
  103. data/bundler/lib/bundler/man/bundle-version.1 +35 -0
  104. data/bundler/lib/bundler/man/bundle-version.1.ronn +24 -0
  105. data/bundler/lib/bundler/man/bundle-viz.1 +4 -1
  106. data/bundler/lib/bundler/man/bundle-viz.1.ronn +2 -0
  107. data/bundler/lib/bundler/man/bundle.1 +15 -10
  108. data/bundler/lib/bundler/man/bundle.1.ronn +12 -7
  109. data/bundler/lib/bundler/man/gemfile.5 +55 -55
  110. data/bundler/lib/bundler/man/gemfile.5.ronn +57 -53
  111. data/bundler/lib/bundler/man/index.txt +4 -0
  112. data/bundler/lib/bundler/match_metadata.rb +13 -0
  113. data/bundler/lib/bundler/match_remote_metadata.rb +29 -0
  114. data/bundler/lib/bundler/mirror.rb +5 -7
  115. data/bundler/lib/bundler/plugin/index.rb +5 -5
  116. data/bundler/lib/bundler/plugin/installer/rubygems.rb +0 -4
  117. data/bundler/lib/bundler/plugin/installer.rb +5 -2
  118. data/bundler/lib/bundler/plugin.rb +3 -1
  119. data/bundler/lib/bundler/remote_specification.rb +7 -12
  120. data/bundler/lib/bundler/resolver/base.rb +107 -0
  121. data/bundler/lib/bundler/resolver/candidate.rb +94 -0
  122. data/bundler/lib/bundler/resolver/incompatibility.rb +15 -0
  123. data/bundler/lib/bundler/resolver/package.rb +72 -0
  124. data/bundler/lib/bundler/resolver/root.rb +25 -0
  125. data/bundler/lib/bundler/resolver/spec_group.rb +42 -71
  126. data/bundler/lib/bundler/resolver.rb +335 -328
  127. data/bundler/lib/bundler/ruby_dsl.rb +7 -1
  128. data/bundler/lib/bundler/ruby_version.rb +8 -8
  129. data/bundler/lib/bundler/rubygems_ext.rb +100 -9
  130. data/bundler/lib/bundler/rubygems_gem_installer.rb +23 -14
  131. data/bundler/lib/bundler/rubygems_integration.rb +11 -15
  132. data/bundler/lib/bundler/runtime.rb +2 -6
  133. data/bundler/lib/bundler/safe_marshal.rb +31 -0
  134. data/bundler/lib/bundler/settings.rb +5 -11
  135. data/bundler/lib/bundler/setup.rb +4 -1
  136. data/bundler/lib/bundler/shared_helpers.rb +3 -3
  137. data/bundler/lib/bundler/source/git/git_proxy.rb +237 -74
  138. data/bundler/lib/bundler/source/git.rb +55 -30
  139. data/bundler/lib/bundler/source/metadata.rb +1 -2
  140. data/bundler/lib/bundler/source/path/installer.rb +1 -22
  141. data/bundler/lib/bundler/source/path.rb +6 -6
  142. data/bundler/lib/bundler/source/rubygems.rb +26 -81
  143. data/bundler/lib/bundler/source.rb +1 -1
  144. data/bundler/lib/bundler/source_list.rb +8 -2
  145. data/bundler/lib/bundler/spec_set.rb +60 -37
  146. data/bundler/lib/bundler/templates/Executable +1 -1
  147. data/bundler/lib/bundler/templates/Executable.bundler +5 -10
  148. data/bundler/lib/bundler/templates/Executable.standalone +2 -0
  149. data/bundler/lib/bundler/templates/newgem/Cargo.toml.tt +7 -0
  150. data/bundler/lib/bundler/templates/newgem/Gemfile.tt +3 -0
  151. data/bundler/lib/bundler/templates/newgem/README.md.tt +6 -4
  152. data/bundler/lib/bundler/templates/newgem/Rakefile.tt +12 -1
  153. data/bundler/lib/bundler/templates/newgem/bin/console.tt +0 -4
  154. data/bundler/lib/bundler/templates/newgem/circleci/config.yml.tt +12 -0
  155. data/bundler/lib/bundler/templates/newgem/ext/newgem/Cargo.toml.tt +15 -0
  156. data/bundler/lib/bundler/templates/newgem/ext/newgem/extconf-c.rb.tt +10 -0
  157. data/bundler/lib/bundler/templates/newgem/ext/newgem/extconf-rust.rb.tt +6 -0
  158. data/bundler/lib/bundler/templates/newgem/ext/newgem/newgem.c.tt +1 -1
  159. data/bundler/lib/bundler/templates/newgem/ext/newgem/src/lib.rs.tt +12 -0
  160. data/bundler/lib/bundler/templates/newgem/github/workflows/main.yml.tt +10 -0
  161. data/bundler/lib/bundler/templates/newgem/gitignore.tt +3 -0
  162. data/bundler/lib/bundler/templates/newgem/gitlab-ci.yml.tt +13 -4
  163. data/bundler/lib/bundler/templates/newgem/newgem.gemspec.tt +9 -2
  164. data/bundler/lib/bundler/ui/rg_proxy.rb +1 -1
  165. data/bundler/lib/bundler/ui/shell.rb +35 -12
  166. data/bundler/lib/bundler/ui/silent.rb +21 -5
  167. data/bundler/lib/bundler/uri_normalizer.rb +23 -0
  168. data/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb +3 -3
  169. data/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool/wrapper.rb +0 -1
  170. data/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool.rb +3 -1
  171. data/bundler/lib/bundler/vendor/fileutils/lib/fileutils.rb +1351 -409
  172. data/bundler/lib/bundler/vendor/net-http-persistent/README.rdoc +1 -1
  173. data/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb +1 -1
  174. data/bundler/lib/bundler/vendor/pub_grub/LICENSE.txt +21 -0
  175. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/assignment.rb +20 -0
  176. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/basic_package_source.rb +189 -0
  177. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/failure_writer.rb +182 -0
  178. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/incompatibility.rb +150 -0
  179. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/package.rb +43 -0
  180. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/partial_solution.rb +121 -0
  181. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/rubygems.rb +45 -0
  182. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/solve_failure.rb +19 -0
  183. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/static_package_source.rb +60 -0
  184. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/term.rb +105 -0
  185. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/version.rb +3 -0
  186. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/version_constraint.rb +129 -0
  187. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/version_range.rb +411 -0
  188. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/version_solver.rb +248 -0
  189. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/version_union.rb +178 -0
  190. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub.rb +31 -0
  191. data/bundler/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +1 -1
  192. data/bundler/lib/bundler/vendor/uri/lib/uri/common.rb +64 -16
  193. data/bundler/lib/bundler/vendor/uri/lib/uri/file.rb +7 -1
  194. data/bundler/lib/bundler/vendor/uri/lib/uri/ftp.rb +2 -1
  195. data/bundler/lib/bundler/vendor/uri/lib/uri/generic.rb +27 -7
  196. data/bundler/lib/bundler/vendor/uri/lib/uri/http.rb +40 -2
  197. data/bundler/lib/bundler/vendor/uri/lib/uri/https.rb +2 -1
  198. data/bundler/lib/bundler/vendor/uri/lib/uri/ldap.rb +1 -1
  199. data/bundler/lib/bundler/vendor/uri/lib/uri/ldaps.rb +2 -1
  200. data/bundler/lib/bundler/vendor/uri/lib/uri/mailto.rb +2 -2
  201. data/bundler/lib/bundler/vendor/uri/lib/uri/rfc2396_parser.rb +15 -9
  202. data/bundler/lib/bundler/vendor/uri/lib/uri/rfc3986_parser.rb +11 -6
  203. data/bundler/lib/bundler/vendor/uri/lib/uri/version.rb +1 -1
  204. data/bundler/lib/bundler/vendor/uri/lib/uri/ws.rb +1 -2
  205. data/bundler/lib/bundler/vendor/uri/lib/uri/wss.rb +2 -1
  206. data/bundler/lib/bundler/vendor/uri/lib/uri.rb +3 -2
  207. data/bundler/lib/bundler/vendored_persistent.rb +1 -33
  208. data/bundler/lib/bundler/{vendored_tmpdir.rb → vendored_pub_grub.rb} +1 -1
  209. data/bundler/lib/bundler/version.rb +5 -1
  210. data/bundler/lib/bundler/worker.rb +5 -7
  211. data/bundler/lib/bundler.rb +25 -77
  212. data/{bin → exe}/gem +4 -5
  213. data/{bin → exe}/update_rubygems +12 -10
  214. data/lib/rubygems/available_set.rb +4 -3
  215. data/lib/rubygems/basic_specification.rb +5 -4
  216. data/lib/rubygems/bundler_version_finder.rb +2 -2
  217. data/lib/rubygems/command.rb +41 -32
  218. data/lib/rubygems/command_manager.rb +30 -15
  219. data/lib/rubygems/commands/build_command.rb +12 -8
  220. data/lib/rubygems/commands/cert_command.rb +34 -33
  221. data/lib/rubygems/commands/check_command.rb +21 -20
  222. data/lib/rubygems/commands/cleanup_command.rb +18 -17
  223. data/lib/rubygems/commands/contents_command.rb +14 -13
  224. data/lib/rubygems/commands/dependency_command.rb +17 -16
  225. data/lib/rubygems/commands/environment_command.rb +6 -5
  226. data/lib/rubygems/commands/exec_command.rb +249 -0
  227. data/lib/rubygems/commands/fetch_command.rb +10 -9
  228. data/lib/rubygems/commands/generate_index_command.rb +18 -17
  229. data/lib/rubygems/commands/help_command.rb +7 -6
  230. data/lib/rubygems/commands/info_command.rb +3 -3
  231. data/lib/rubygems/commands/install_command.rb +28 -23
  232. data/lib/rubygems/commands/list_command.rb +4 -3
  233. data/lib/rubygems/commands/lock_command.rb +5 -4
  234. data/lib/rubygems/commands/mirror_command.rb +4 -3
  235. data/lib/rubygems/commands/open_command.rb +10 -9
  236. data/lib/rubygems/commands/outdated_command.rb +6 -5
  237. data/lib/rubygems/commands/owner_command.rb +17 -14
  238. data/lib/rubygems/commands/pristine_command.rb +46 -36
  239. data/lib/rubygems/commands/push_command.rb +9 -8
  240. data/lib/rubygems/commands/query_command.rb +9 -8
  241. data/lib/rubygems/commands/rdoc_command.rb +21 -19
  242. data/lib/rubygems/commands/search_command.rb +4 -3
  243. data/lib/rubygems/commands/server_command.rb +4 -3
  244. data/lib/rubygems/commands/setup_command.rb +97 -106
  245. data/lib/rubygems/commands/signin_command.rb +10 -9
  246. data/lib/rubygems/commands/signout_command.rb +8 -7
  247. data/lib/rubygems/commands/sources_command.rb +22 -21
  248. data/lib/rubygems/commands/specification_command.rb +14 -13
  249. data/lib/rubygems/commands/stale_command.rb +3 -2
  250. data/lib/rubygems/commands/uninstall_command.rb +44 -40
  251. data/lib/rubygems/commands/unpack_command.rb +14 -13
  252. data/lib/rubygems/commands/update_command.rb +42 -63
  253. data/lib/rubygems/commands/which_command.rb +8 -7
  254. data/lib/rubygems/commands/yank_command.rb +12 -11
  255. data/lib/rubygems/config_file.rb +55 -21
  256. data/lib/rubygems/core_ext/kernel_gem.rb +1 -6
  257. data/lib/rubygems/core_ext/kernel_require.rb +109 -115
  258. data/lib/rubygems/core_ext/kernel_warn.rb +33 -37
  259. data/lib/rubygems/core_ext/tcpsocket_init.rb +3 -1
  260. data/lib/rubygems/defaults.rb +33 -18
  261. data/lib/rubygems/dependency.rb +15 -11
  262. data/lib/rubygems/dependency_installer.rb +38 -37
  263. data/lib/rubygems/dependency_list.rb +7 -6
  264. data/lib/rubygems/deprecate.rb +3 -2
  265. data/lib/rubygems/doctor.rb +19 -18
  266. data/lib/rubygems/errors.rb +3 -2
  267. data/lib/rubygems/exceptions.rb +16 -8
  268. data/lib/rubygems/ext/build_error.rb +2 -1
  269. data/lib/rubygems/ext/builder.rb +37 -21
  270. data/lib/rubygems/ext/cargo_builder/link_flag_converter.rb +9 -5
  271. data/lib/rubygems/ext/cargo_builder.rb +150 -111
  272. data/lib/rubygems/ext/cmake_builder.rb +2 -2
  273. data/lib/rubygems/ext/configure_builder.rb +2 -1
  274. data/lib/rubygems/ext/ext_conf_builder.rb +11 -9
  275. data/lib/rubygems/ext/rake_builder.rb +7 -5
  276. data/lib/rubygems/ext.rb +8 -7
  277. data/lib/rubygems/gem_runner.rb +6 -5
  278. data/lib/rubygems/gemcutter_utilities/webauthn_listener/response.rb +163 -0
  279. data/lib/rubygems/gemcutter_utilities/webauthn_listener.rb +105 -0
  280. data/lib/rubygems/gemcutter_utilities/webauthn_poller.rb +78 -0
  281. data/lib/rubygems/gemcutter_utilities.rb +90 -34
  282. data/lib/rubygems/indexer.rb +29 -28
  283. data/lib/rubygems/install_default_message.rb +3 -2
  284. data/lib/rubygems/install_message.rb +3 -2
  285. data/lib/rubygems/install_update_options.rb +56 -55
  286. data/lib/rubygems/installer.rb +54 -46
  287. data/lib/rubygems/installer_uninstaller_utils.rb +2 -2
  288. data/lib/rubygems/local_remote_options.rb +19 -20
  289. data/lib/rubygems/mock_gem_ui.rb +3 -2
  290. data/lib/rubygems/name_tuple.rb +5 -4
  291. data/lib/rubygems/optparse/lib/optparse.rb +20 -15
  292. data/lib/rubygems/optparse.rb +1 -1
  293. data/lib/rubygems/package/digest_io.rb +1 -0
  294. data/lib/rubygems/package/file_source.rb +3 -2
  295. data/lib/rubygems/package/io_source.rb +1 -0
  296. data/lib/rubygems/package/old.rb +9 -8
  297. data/lib/rubygems/package/source.rb +1 -0
  298. data/lib/rubygems/package/tar_header.rb +63 -62
  299. data/lib/rubygems/package/tar_reader/entry.rb +91 -9
  300. data/lib/rubygems/package/tar_reader.rb +2 -29
  301. data/lib/rubygems/package/tar_writer.rb +8 -7
  302. data/lib/rubygems/package.rb +64 -48
  303. data/lib/rubygems/package_task.rb +5 -4
  304. data/lib/rubygems/path_support.rb +1 -0
  305. data/lib/rubygems/platform.rb +79 -53
  306. data/lib/rubygems/psych_tree.rb +2 -1
  307. data/lib/rubygems/query_utils.rb +35 -35
  308. data/lib/rubygems/rdoc.rb +3 -2
  309. data/lib/rubygems/remote_fetcher.rb +23 -22
  310. data/lib/rubygems/request/connection_pools.rb +4 -4
  311. data/lib/rubygems/request/http_pool.rb +2 -1
  312. data/lib/rubygems/request/https_pool.rb +1 -0
  313. data/lib/rubygems/request.rb +23 -22
  314. data/lib/rubygems/request_set/gem_dependency_api.rb +123 -123
  315. data/lib/rubygems/request_set/lockfile/parser.rb +28 -27
  316. data/lib/rubygems/request_set/lockfile/tokenizer.rb +5 -3
  317. data/lib/rubygems/request_set/lockfile.rb +6 -5
  318. data/lib/rubygems/request_set.rb +20 -19
  319. data/lib/rubygems/requirement.rb +15 -14
  320. data/lib/rubygems/resolver/activation_request.rb +4 -3
  321. data/lib/rubygems/resolver/api_set.rb +5 -4
  322. data/lib/rubygems/resolver/api_specification.rb +7 -6
  323. data/lib/rubygems/resolver/best_set.rb +6 -5
  324. data/lib/rubygems/resolver/composed_set.rb +1 -0
  325. data/lib/rubygems/resolver/conflict.rb +11 -10
  326. data/lib/rubygems/resolver/current_set.rb +1 -0
  327. data/lib/rubygems/resolver/dependency_request.rb +3 -2
  328. data/lib/rubygems/resolver/git_set.rb +3 -2
  329. data/lib/rubygems/resolver/git_specification.rb +7 -6
  330. data/lib/rubygems/resolver/index_set.rb +4 -3
  331. data/lib/rubygems/resolver/index_specification.rb +7 -5
  332. data/lib/rubygems/resolver/installed_specification.rb +5 -4
  333. data/lib/rubygems/resolver/installer_set.rb +15 -17
  334. data/lib/rubygems/resolver/local_specification.rb +3 -2
  335. data/lib/rubygems/resolver/lock_set.rb +5 -4
  336. data/lib/rubygems/resolver/lock_specification.rb +5 -4
  337. data/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph.rb +1 -1
  338. data/lib/rubygems/resolver/molinillo/lib/molinillo/errors.rb +32 -26
  339. data/lib/rubygems/resolver/molinillo/lib/molinillo/gem_metadata.rb +1 -1
  340. data/lib/rubygems/resolver/molinillo.rb +2 -1
  341. data/lib/rubygems/resolver/requirement_list.rb +1 -0
  342. data/lib/rubygems/resolver/set.rb +1 -0
  343. data/lib/rubygems/resolver/source_set.rb +2 -0
  344. data/lib/rubygems/resolver/spec_specification.rb +1 -0
  345. data/lib/rubygems/resolver/specification.rb +2 -1
  346. data/lib/rubygems/resolver/stats.rb +2 -1
  347. data/lib/rubygems/resolver/vendor_set.rb +2 -1
  348. data/lib/rubygems/resolver/vendor_specification.rb +4 -3
  349. data/lib/rubygems/resolver.rb +41 -40
  350. data/lib/rubygems/s3_uri_signer.rb +10 -8
  351. data/lib/rubygems/safe_yaml.rb +4 -2
  352. data/lib/rubygems/security/policies.rb +48 -47
  353. data/lib/rubygems/security/policy.rb +19 -18
  354. data/lib/rubygems/security/signer.rb +6 -5
  355. data/lib/rubygems/security/trust_dir.rb +5 -4
  356. data/lib/rubygems/security.rb +30 -42
  357. data/lib/rubygems/security_option.rb +6 -5
  358. data/lib/rubygems/shellwords.rb +3 -0
  359. data/lib/rubygems/source/git.rb +22 -22
  360. data/lib/rubygems/source/installed.rb +2 -1
  361. data/lib/rubygems/source/local.rb +3 -2
  362. data/lib/rubygems/source/lock.rb +1 -0
  363. data/lib/rubygems/source/specific_file.rb +2 -1
  364. data/lib/rubygems/source/vendor.rb +1 -0
  365. data/lib/rubygems/source.rb +16 -16
  366. data/lib/rubygems/spec_fetcher.rb +10 -9
  367. data/lib/rubygems/specification.rb +121 -114
  368. data/lib/rubygems/specification_policy.rb +36 -15
  369. data/lib/rubygems/stub_specification.rb +11 -9
  370. data/lib/rubygems/text.rb +2 -2
  371. data/lib/rubygems/tsort/lib/tsort.rb +308 -310
  372. data/lib/rubygems/tsort.rb +1 -1
  373. data/lib/rubygems/uninstaller.rb +19 -18
  374. data/lib/rubygems/update_suggestion.rb +69 -0
  375. data/lib/rubygems/uri.rb +4 -4
  376. data/lib/rubygems/uri_formatter.rb +1 -1
  377. data/lib/rubygems/user_interaction.rb +37 -21
  378. data/lib/rubygems/util/licenses.rb +4 -3
  379. data/lib/rubygems/util/list.rb +1 -0
  380. data/lib/rubygems/util.rb +12 -15
  381. data/lib/rubygems/validator.rb +7 -6
  382. data/lib/rubygems/version.rb +17 -11
  383. data/lib/rubygems/version_option.rb +4 -3
  384. data/lib/rubygems.rb +89 -68
  385. data/rubygems-update.gemspec +10 -8
  386. data/setup.rb +10 -9
  387. data/test/rubygems/alternate_cert.pem +14 -14
  388. data/test/rubygems/alternate_cert_32.pem +15 -15
  389. data/test/rubygems/alternate_key.pem +25 -25
  390. data/test/rubygems/bad_rake.rb +1 -0
  391. data/test/rubygems/bundler_test_gem.rb +421 -0
  392. data/test/rubygems/child_cert.pem +15 -16
  393. data/test/rubygems/child_cert_32.pem +15 -16
  394. data/test/rubygems/child_key.pem +25 -25
  395. data/test/rubygems/encrypted_private_key.pem +26 -26
  396. data/test/rubygems/expired_cert.pem +15 -15
  397. data/test/rubygems/fake_certlib/openssl.rb +1 -0
  398. data/test/rubygems/future_cert.pem +15 -15
  399. data/test/rubygems/future_cert_32.pem +15 -15
  400. data/test/rubygems/good_rake.rb +1 -0
  401. data/test/rubygems/grandchild_cert.pem +15 -16
  402. data/test/rubygems/grandchild_cert_32.pem +15 -16
  403. data/test/rubygems/grandchild_key.pem +25 -25
  404. data/test/rubygems/helper.rb +172 -151
  405. data/test/rubygems/installer_test_case.rb +14 -13
  406. data/test/rubygems/invalid_issuer_cert.pem +16 -16
  407. data/test/rubygems/invalid_issuer_cert_32.pem +16 -16
  408. data/test/rubygems/invalid_key.pem +25 -25
  409. data/test/rubygems/invalid_signer_cert.pem +15 -15
  410. data/test/rubygems/invalid_signer_cert_32.pem +15 -15
  411. data/test/rubygems/invalidchild_cert.pem +15 -16
  412. data/test/rubygems/invalidchild_cert_32.pem +15 -16
  413. data/test/rubygems/invalidchild_key.pem +25 -25
  414. data/test/rubygems/multifactor_auth_utilities.rb +111 -0
  415. data/test/rubygems/package/tar_test_case.rb +53 -17
  416. data/test/rubygems/packages/Bluebie-legs-0.6.2.gem +0 -0
  417. data/test/rubygems/plugin/exception/rubygems_plugin.rb +2 -1
  418. data/test/rubygems/plugin/load/rubygems_plugin.rb +1 -0
  419. data/test/rubygems/plugin/standarderror/rubygems_plugin.rb +2 -1
  420. data/test/rubygems/private_key.pem +25 -25
  421. data/test/rubygems/public_cert.pem +16 -16
  422. data/test/rubygems/public_cert_32.pem +15 -15
  423. data/test/rubygems/public_key.pem +7 -7
  424. data/test/rubygems/rubygems/commands/crash_command.rb +1 -0
  425. data/test/rubygems/rubygems_plugin.rb +3 -2
  426. data/test/rubygems/simple_gem.rb +2 -1
  427. data/test/rubygems/specifications/bar-0.0.2.gemspec +2 -0
  428. data/test/rubygems/specifications/rubyforge-0.0.1.gemspec +6 -4
  429. data/test/rubygems/test_bundled_ca.rb +13 -12
  430. data/test/rubygems/test_config.rb +5 -4
  431. data/test/rubygems/test_deprecate.rb +5 -4
  432. data/test/rubygems/test_exit.rb +9 -3
  433. data/test/rubygems/test_gem.rb +339 -677
  434. data/test/rubygems/test_gem_available_set.rb +22 -21
  435. data/test/rubygems/test_gem_bundler_version_finder.rb +6 -4
  436. data/test/rubygems/test_gem_command.rb +45 -44
  437. data/test/rubygems/test_gem_command_manager.rb +96 -30
  438. data/test/rubygems/test_gem_commands_build_command.rb +74 -63
  439. data/test/rubygems/test_gem_commands_cert_command.rb +98 -99
  440. data/test/rubygems/test_gem_commands_check_command.rb +5 -4
  441. data/test/rubygems/test_gem_commands_cleanup_command.rb +41 -40
  442. data/test/rubygems/test_gem_commands_contents_command.rb +28 -27
  443. data/test/rubygems/test_gem_commands_dependency_command.rb +37 -36
  444. data/test/rubygems/test_gem_commands_environment_command.rb +17 -16
  445. data/test/rubygems/test_gem_commands_exec_command.rb +853 -0
  446. data/test/rubygems/test_gem_commands_fetch_command.rb +38 -37
  447. data/test/rubygems/test_gem_commands_generate_index_command.rb +8 -7
  448. data/test/rubygems/test_gem_commands_help_command.rb +14 -13
  449. data/test/rubygems/test_gem_commands_info_command.rb +29 -2
  450. data/test/rubygems/test_gem_commands_install_command.rb +152 -132
  451. data/test/rubygems/test_gem_commands_list_command.rb +5 -4
  452. data/test/rubygems/test_gem_commands_lock_command.rb +11 -10
  453. data/test/rubygems/test_gem_commands_mirror.rb +3 -2
  454. data/test/rubygems/test_gem_commands_open_command.rb +5 -4
  455. data/test/rubygems/test_gem_commands_outdated_command.rb +10 -9
  456. data/test/rubygems/test_gem_commands_owner_command.rb +227 -50
  457. data/test/rubygems/test_gem_commands_pristine_command.rb +142 -93
  458. data/test/rubygems/test_gem_commands_push_command.rb +189 -64
  459. data/test/rubygems/test_gem_commands_query_command.rb +74 -73
  460. data/test/rubygems/test_gem_commands_search_command.rb +3 -2
  461. data/test/rubygems/test_gem_commands_server_command.rb +3 -2
  462. data/test/rubygems/test_gem_commands_setup_command.rb +123 -96
  463. data/test/rubygems/test_gem_commands_signin_command.rb +71 -31
  464. data/test/rubygems/test_gem_commands_signout_command.rb +3 -3
  465. data/test/rubygems/test_gem_commands_sources_command.rb +29 -29
  466. data/test/rubygems/test_gem_commands_specification_command.rb +33 -32
  467. data/test/rubygems/test_gem_commands_stale_command.rb +5 -4
  468. data/test/rubygems/test_gem_commands_uninstall_command.rb +99 -81
  469. data/test/rubygems/test_gem_commands_unpack_command.rb +32 -31
  470. data/test/rubygems/test_gem_commands_update_command.rb +96 -95
  471. data/test/rubygems/test_gem_commands_which_command.rb +7 -6
  472. data/test/rubygems/test_gem_commands_yank_command.rb +162 -43
  473. data/test/rubygems/test_gem_config_file.rb +94 -81
  474. data/test/rubygems/test_gem_dependency.rb +76 -73
  475. data/test/rubygems/test_gem_dependency_installer.rb +200 -165
  476. data/test/rubygems/test_gem_dependency_list.rb +48 -47
  477. data/test/rubygems/test_gem_dependency_resolution_error.rb +5 -4
  478. data/test/rubygems/test_gem_doctor.rb +27 -26
  479. data/test/rubygems/test_gem_ext_builder.rb +60 -61
  480. data/test/rubygems/test_gem_ext_cargo_builder/custom_name/custom_name.gemspec +4 -4
  481. data/test/rubygems/test_gem_ext_cargo_builder/custom_name/{Cargo.lock → ext/custom_name_lib/Cargo.lock} +23 -33
  482. data/test/rubygems/test_gem_ext_cargo_builder/custom_name/{Cargo.toml → ext/custom_name_lib/Cargo.toml} +1 -1
  483. data/test/rubygems/test_gem_ext_cargo_builder/custom_name/{src → ext/custom_name_lib/src}/lib.rs +1 -1
  484. data/test/rubygems/test_gem_ext_cargo_builder/custom_name/lib/custom_name.rb +3 -0
  485. data/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.lock +37 -33
  486. data/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.toml +1 -1
  487. data/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/rust_ruby_example.gemspec +2 -0
  488. data/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/src/lib.rs +12 -0
  489. data/test/rubygems/test_gem_ext_cargo_builder.rb +48 -59
  490. data/test/rubygems/test_gem_ext_cargo_builder_link_flag_converter.rb +20 -19
  491. data/test/rubygems/test_gem_ext_cargo_builder_unit.rb +21 -36
  492. data/test/rubygems/test_gem_ext_cmake_builder.rb +16 -15
  493. data/test/rubygems/test_gem_ext_configure_builder.rb +14 -13
  494. data/test/rubygems/test_gem_ext_ext_conf_builder.rb +51 -52
  495. data/test/rubygems/test_gem_ext_rake_builder.rb +16 -15
  496. data/test/rubygems/test_gem_gem_runner.rb +15 -9
  497. data/test/rubygems/test_gem_gemcutter_utilities.rb +170 -84
  498. data/test/rubygems/test_gem_impossible_dependencies_error.rb +5 -4
  499. data/test/rubygems/test_gem_indexer.rb +87 -67
  500. data/test/rubygems/test_gem_install_update_options.rb +17 -16
  501. data/test/rubygems/test_gem_installer.rb +422 -304
  502. data/test/rubygems/test_gem_local_remote_options.rb +11 -10
  503. data/test/rubygems/test_gem_name_tuple.rb +5 -4
  504. data/test/rubygems/test_gem_package.rb +243 -231
  505. data/test/rubygems/test_gem_package_old.rb +14 -13
  506. data/test/rubygems/test_gem_package_tar_header.rb +48 -47
  507. data/test/rubygems/test_gem_package_tar_reader.rb +56 -8
  508. data/test/rubygems/test_gem_package_tar_reader_entry.rb +162 -16
  509. data/test/rubygems/test_gem_package_tar_writer.rb +77 -76
  510. data/test/rubygems/test_gem_package_task.rb +19 -18
  511. data/test/rubygems/test_gem_path_support.rb +15 -14
  512. data/test/rubygems/test_gem_platform.rb +333 -227
  513. data/test/rubygems/test_gem_rdoc.rb +15 -14
  514. data/test/rubygems/test_gem_remote_fetcher.rb +155 -154
  515. data/test/rubygems/test_gem_request.rb +64 -58
  516. data/test/rubygems/test_gem_request_connection_pools.rb +30 -29
  517. data/test/rubygems/test_gem_request_set.rb +101 -100
  518. data/test/rubygems/test_gem_request_set_gem_dependency_api.rb +210 -211
  519. data/test/rubygems/test_gem_request_set_lockfile.rb +87 -86
  520. data/test/rubygems/test_gem_request_set_lockfile_parser.rb +58 -57
  521. data/test/rubygems/test_gem_request_set_lockfile_tokenizer.rb +63 -62
  522. data/test/rubygems/test_gem_requirement.rb +48 -41
  523. data/test/rubygems/test_gem_resolver.rb +167 -99
  524. data/test/rubygems/test_gem_resolver_activation_request.rb +7 -6
  525. data/test/rubygems/test_gem_resolver_api_set.rb +34 -33
  526. data/test/rubygems/test_gem_resolver_api_specification.rb +48 -47
  527. data/test/rubygems/test_gem_resolver_best_set.rb +23 -22
  528. data/test/rubygems/test_gem_resolver_composed_set.rb +2 -1
  529. data/test/rubygems/test_gem_resolver_conflict.rb +13 -12
  530. data/test/rubygems/test_gem_resolver_dependency_request.rb +16 -15
  531. data/test/rubygems/test_gem_resolver_git_set.rb +22 -21
  532. data/test/rubygems/test_gem_resolver_git_specification.rb +22 -21
  533. data/test/rubygems/test_gem_resolver_index_set.rb +13 -12
  534. data/test/rubygems/test_gem_resolver_index_specification.rb +17 -16
  535. data/test/rubygems/test_gem_resolver_installed_specification.rb +6 -5
  536. data/test/rubygems/test_gem_resolver_installer_set.rb +79 -34
  537. data/test/rubygems/test_gem_resolver_local_specification.rb +8 -7
  538. data/test/rubygems/test_gem_resolver_lock_set.rb +13 -12
  539. data/test/rubygems/test_gem_resolver_lock_specification.rb +18 -17
  540. data/test/rubygems/test_gem_resolver_requirement_list.rb +2 -1
  541. data/test/rubygems/test_gem_resolver_specification.rb +9 -8
  542. data/test/rubygems/test_gem_resolver_vendor_set.rb +7 -6
  543. data/test/rubygems/test_gem_resolver_vendor_specification.rb +11 -10
  544. data/test/rubygems/test_gem_security.rb +69 -68
  545. data/test/rubygems/test_gem_security_policy.rb +72 -72
  546. data/test/rubygems/test_gem_security_signer.rb +35 -34
  547. data/test/rubygems/test_gem_security_trust_dir.rb +7 -6
  548. data/test/rubygems/test_gem_silent_ui.rb +39 -32
  549. data/test/rubygems/test_gem_source.rb +45 -44
  550. data/test/rubygems/test_gem_source_fetch_problem.rb +10 -9
  551. data/test/rubygems/test_gem_source_git.rb +69 -62
  552. data/test/rubygems/test_gem_source_installed.rb +17 -16
  553. data/test/rubygems/test_gem_source_list.rb +6 -5
  554. data/test/rubygems/test_gem_source_local.rb +15 -14
  555. data/test/rubygems/test_gem_source_lock.rb +32 -31
  556. data/test/rubygems/test_gem_source_specific_file.rb +18 -17
  557. data/test/rubygems/test_gem_source_subpath_problem.rb +8 -7
  558. data/test/rubygems/test_gem_source_vendor.rb +14 -13
  559. data/test/rubygems/test_gem_spec_fetcher.rb +73 -72
  560. data/test/rubygems/test_gem_specification.rb +533 -469
  561. data/test/rubygems/test_gem_stream_ui.rb +53 -22
  562. data/test/rubygems/test_gem_stub_specification.rb +33 -32
  563. data/test/rubygems/test_gem_text.rb +2 -1
  564. data/test/rubygems/test_gem_uninstaller.rb +118 -117
  565. data/test/rubygems/test_gem_unsatisfiable_dependency_error.rb +4 -3
  566. data/test/rubygems/test_gem_update_suggestion.rb +209 -0
  567. data/test/rubygems/test_gem_uri.rb +6 -4
  568. data/test/rubygems/test_gem_uri_formatter.rb +15 -14
  569. data/test/rubygems/test_gem_util.rb +24 -23
  570. data/test/rubygems/test_gem_validator.rb +8 -8
  571. data/test/rubygems/test_gem_version.rb +24 -16
  572. data/test/rubygems/test_gem_version_option.rb +16 -15
  573. data/test/rubygems/test_kernel.rb +43 -48
  574. data/test/rubygems/test_project_sanity.rb +32 -3
  575. data/test/rubygems/test_remote_fetch_error.rb +8 -7
  576. data/test/rubygems/test_require.rb +118 -103
  577. data/test/rubygems/test_rubygems.rb +10 -8
  578. data/test/rubygems/test_webauthn_listener.rb +143 -0
  579. data/test/rubygems/test_webauthn_listener_response.rb +93 -0
  580. data/test/rubygems/test_webauthn_poller.rb +124 -0
  581. data/test/rubygems/utilities.rb +98 -34
  582. data/test/rubygems/wrong_key_cert.pem +15 -15
  583. data/test/rubygems/wrong_key_cert_32.pem +15 -15
  584. data/test/test_changelog_generator.rb +1 -1
  585. metadata +99 -46
  586. data/bundler/lib/bundler/dep_proxy.rb +0 -55
  587. data/bundler/lib/bundler/templates/gems.rb +0 -5
  588. data/bundler/lib/bundler/templates/newgem/ext/newgem/extconf.rb.tt +0 -5
  589. data/bundler/lib/bundler/templates/newgem/travis.yml.tt +0 -6
  590. data/bundler/lib/bundler/vendor/molinillo/LICENSE +0 -9
  591. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/delegates/resolution_state.rb +0 -57
  592. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/delegates/specification_provider.rb +0 -88
  593. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/action.rb +0 -36
  594. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb +0 -66
  595. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_vertex.rb +0 -62
  596. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/delete_edge.rb +0 -63
  597. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb +0 -61
  598. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/log.rb +0 -126
  599. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/set_payload.rb +0 -46
  600. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/tag.rb +0 -36
  601. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb +0 -164
  602. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb +0 -255
  603. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/errors.rb +0 -149
  604. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb +0 -6
  605. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/modules/specification_provider.rb +0 -112
  606. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/modules/ui.rb +0 -67
  607. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb +0 -839
  608. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/resolver.rb +0 -46
  609. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/state.rb +0 -58
  610. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo.rb +0 -11
  611. data/bundler/lib/bundler/vendor/tmpdir/lib/tmpdir.rb +0 -154
  612. data/bundler/lib/bundler/vendored_molinillo.rb +0 -4
  613. data/bundler/lib/bundler/version_ranges.rb +0 -122
  614. data/test/rubygems/test_gem_ext_cargo_builder/custom_name/build.rb +0 -21
  615. data/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/build.rb +0 -21
@@ -1,29 +1,32 @@
1
1
  # frozen_string_literal: true
2
- require_relative 'helper'
3
- require 'rubygems'
4
- require 'rubygems/command'
5
- require 'rubygems/gemcutter_utilities'
2
+
3
+ require_relative "helper"
4
+ require_relative "multifactor_auth_utilities"
5
+ require "rubygems"
6
+ require "rubygems/command"
7
+ require "rubygems/gemcutter_utilities"
6
8
 
7
9
  class TestGemGemcutterUtilities < Gem::TestCase
8
10
  def setup
9
11
  super
10
12
 
11
13
  credential_setup
14
+ @fetcher = SignInFetcher.new
12
15
 
13
16
  # below needed for random testing, class property
14
17
  Gem.configuration.disable_default_gem_server = nil
15
18
 
16
- ENV['RUBYGEMS_HOST'] = nil
17
- ENV['GEM_HOST_OTP_CODE'] = nil
19
+ ENV["RUBYGEMS_HOST"] = nil
20
+ ENV["GEM_HOST_OTP_CODE"] = nil
18
21
  Gem.configuration.rubygems_api_key = nil
19
22
 
20
- @cmd = Gem::Command.new '', 'summary'
23
+ @cmd = Gem::Command.new "", "summary"
21
24
  @cmd.extend Gem::GemcutterUtilities
22
25
  end
23
26
 
24
27
  def teardown
25
- ENV['RUBYGEMS_HOST'] = nil
26
- ENV['GEM_HOST_OTP_CODE'] = nil
28
+ ENV["RUBYGEMS_HOST"] = nil
29
+ ENV["GEM_HOST_OTP_CODE"] = nil
27
30
  Gem.configuration.rubygems_api_key = nil
28
31
 
29
32
  credential_teardown
@@ -33,11 +36,11 @@ class TestGemGemcutterUtilities < Gem::TestCase
33
36
 
34
37
  def test_alternate_key_alternate_host
35
38
  keys = {
36
- :rubygems_api_key => 'KEY',
39
+ :rubygems_api_key => "KEY",
37
40
  "http://rubygems.engineyard.com" => "EYKEY",
38
41
  }
39
42
 
40
- File.open Gem.configuration.credentials_path, 'w' do |f|
43
+ File.open Gem.configuration.credentials_path, "w" do |f|
41
44
  f.write keys.to_yaml
42
45
  end
43
46
 
@@ -45,25 +48,25 @@ class TestGemGemcutterUtilities < Gem::TestCase
45
48
 
46
49
  Gem.configuration.load_api_keys
47
50
 
48
- assert_equal 'EYKEY', @cmd.api_key
51
+ assert_equal "EYKEY", @cmd.api_key
49
52
  end
50
53
 
51
54
  def test_api_key
52
- keys = { :rubygems_api_key => 'KEY' }
55
+ keys = { :rubygems_api_key => "KEY" }
53
56
 
54
- File.open Gem.configuration.credentials_path, 'w' do |f|
57
+ File.open Gem.configuration.credentials_path, "w" do |f|
55
58
  f.write keys.to_yaml
56
59
  end
57
60
 
58
61
  Gem.configuration.load_api_keys
59
62
 
60
- assert_equal 'KEY', @cmd.api_key
63
+ assert_equal "KEY", @cmd.api_key
61
64
  end
62
65
 
63
66
  def test_api_key_override
64
- keys = { :rubygems_api_key => 'KEY', :other => 'OTHER' }
67
+ keys = { :rubygems_api_key => "KEY", :other => "OTHER" }
65
68
 
66
- File.open Gem.configuration.credentials_path, 'w' do |f|
69
+ File.open Gem.configuration.credentials_path, "w" do |f|
67
70
  f.write keys.to_yaml
68
71
  end
69
72
 
@@ -72,41 +75,39 @@ class TestGemGemcutterUtilities < Gem::TestCase
72
75
  @cmd.add_key_option
73
76
  @cmd.handle_options %w[--key other]
74
77
 
75
- assert_equal 'OTHER', @cmd.api_key
78
+ assert_equal "OTHER", @cmd.api_key
76
79
  end
77
80
 
78
81
  def test_host
79
- assert_equal 'https://rubygems.org', @cmd.host
82
+ assert_equal "https://rubygems.org", @cmd.host
80
83
  end
81
84
 
82
85
  def test_host_RUBYGEMS_HOST
83
- ENV['RUBYGEMS_HOST'] = 'https://other.example'
86
+ ENV["RUBYGEMS_HOST"] = "https://other.example"
84
87
 
85
- assert_equal 'https://other.example', @cmd.host
88
+ assert_equal "https://other.example", @cmd.host
86
89
  end
87
90
 
88
91
  def test_host_RUBYGEMS_HOST_empty
89
- ENV['RUBYGEMS_HOST'] = ''
92
+ ENV["RUBYGEMS_HOST"] = ""
90
93
 
91
- assert_equal 'https://rubygems.org', @cmd.host
94
+ assert_equal "https://rubygems.org", @cmd.host
92
95
  end
93
96
 
94
97
  def test_sign_in
95
- api_key = 'a5fdbb6ba150cbb83aad2bb2fede64cf040453903'
96
- util_sign_in [api_key, 200, 'OK']
98
+ util_sign_in
97
99
 
98
100
  assert_match %r{Enter your RubyGems.org credentials.}, @sign_in_ui.output
99
101
  assert @fetcher.last_request["authorization"]
100
102
  assert_match %r{Signed in.}, @sign_in_ui.output
101
103
 
102
104
  credentials = load_yaml_file Gem.configuration.credentials_path
103
- assert_equal api_key, credentials[:rubygems_api_key]
105
+ assert_equal @fetcher.api_key, credentials[:rubygems_api_key]
104
106
  end
105
107
 
106
108
  def test_sign_in_with_host
107
- api_key = 'a5fdbb6ba150cbb83aad2bb2fede64cf040453903'
108
-
109
- util_sign_in [api_key, 200, 'OK'], 'http://example.com', ['http://example.com']
109
+ @fetcher = SignInFetcher.new(host: "http://example.com")
110
+ util_sign_in
110
111
 
111
112
  assert_match "Enter your http://example.com credentials.",
112
113
  @sign_in_ui.output
@@ -114,13 +115,12 @@ class TestGemGemcutterUtilities < Gem::TestCase
114
115
  assert_match %r{Signed in.}, @sign_in_ui.output
115
116
 
116
117
  credentials = load_yaml_file Gem.configuration.credentials_path
117
- assert_equal api_key, credentials['http://example.com']
118
+ assert_equal @fetcher.api_key, credentials["http://example.com"]
118
119
  end
119
120
 
120
121
  def test_sign_in_with_host_nil
121
- api_key = 'a5fdbb6ba150cbb83aad2bb2fede64cf040453903'
122
-
123
- util_sign_in [api_key, 200, 'OK'], nil, [nil]
122
+ @fetcher = SignInFetcher.new(host: nil)
123
+ util_sign_in(args: [nil])
124
124
 
125
125
  assert_match "Enter your RubyGems.org credentials.",
126
126
  @sign_in_ui.output
@@ -128,12 +128,12 @@ class TestGemGemcutterUtilities < Gem::TestCase
128
128
  assert_match %r{Signed in.}, @sign_in_ui.output
129
129
 
130
130
  credentials = load_yaml_file Gem.configuration.credentials_path
131
- assert_equal api_key, credentials[:rubygems_api_key]
131
+ assert_equal @fetcher.api_key, credentials[:rubygems_api_key]
132
132
  end
133
133
 
134
134
  def test_sign_in_with_host_ENV
135
- api_key = 'a5fdbb6ba150cbb83aad2bb2fede64cf040453903'
136
- util_sign_in [api_key, 200, 'OK'], 'http://example.com'
135
+ @fetcher = SignInFetcher.new(host: "http://example.com")
136
+ util_sign_in
137
137
 
138
138
  assert_match "Enter your http://example.com credentials.",
139
139
  @sign_in_ui.output
@@ -141,47 +141,45 @@ class TestGemGemcutterUtilities < Gem::TestCase
141
141
  assert_match %r{Signed in.}, @sign_in_ui.output
142
142
 
143
143
  credentials = load_yaml_file Gem.configuration.credentials_path
144
- assert_equal api_key, credentials['http://example.com']
144
+ assert_equal @fetcher.api_key, credentials["http://example.com"]
145
145
  end
146
146
 
147
147
  def test_sign_in_skips_with_existing_credentials
148
- api_key = 'a5fdbb6ba150cbb83aad2bb2fede64cf040453903'
149
- Gem.configuration.rubygems_api_key = api_key
148
+ Gem.configuration.rubygems_api_key = @fetcher.api_key
150
149
 
151
- util_sign_in [api_key, 200, 'OK']
150
+ util_sign_in
152
151
 
153
152
  assert_equal "", @sign_in_ui.output
154
153
  end
155
154
 
156
155
  def test_sign_in_skips_with_key_override
157
- api_key = 'a5fdbb6ba150cbb83aad2bb2fede64cf040453903'
158
- Gem.configuration.api_keys[:KEY] = 'other'
156
+ Gem.configuration.api_keys[:KEY] = "other"
159
157
  @cmd.options[:key] = :KEY
160
- util_sign_in [api_key, 200, 'OK']
158
+ util_sign_in
161
159
 
162
160
  assert_equal "", @sign_in_ui.output
163
161
  end
164
162
 
165
163
  def test_sign_in_with_other_credentials_doesnt_overwrite_other_keys
166
- api_key = 'a5fdbb6ba150cbb83aad2bb2fede64cf040453903'
167
- other_api_key = 'f46dbb18bb6a9c97cdc61b5b85c186a17403cdcbf'
164
+ other_api_key = "f46dbb18bb6a9c97cdc61b5b85c186a17403cdcbf"
168
165
 
169
- File.open Gem.configuration.credentials_path, 'w' do |f|
166
+ File.open Gem.configuration.credentials_path, "w" do |f|
170
167
  f.write Hash[:other_api_key, other_api_key].to_yaml
171
168
  end
172
- util_sign_in [api_key, 200, 'OK']
169
+ util_sign_in
173
170
 
174
171
  assert_match %r{Enter your RubyGems.org credentials.}, @sign_in_ui.output
175
172
  assert_match %r{Signed in.}, @sign_in_ui.output
176
173
 
177
174
  credentials = load_yaml_file Gem.configuration.credentials_path
178
- assert_equal api_key, credentials[:rubygems_api_key]
175
+ assert_equal @fetcher.api_key, credentials[:rubygems_api_key]
179
176
  assert_equal other_api_key, credentials[:other_api_key]
180
177
  end
181
178
 
182
179
  def test_sign_in_with_bad_credentials
180
+ @fetcher.respond_with_forbidden_api_key_response
183
181
  assert_raise Gem::MockGemUi::TermError do
184
- util_sign_in ['Access Denied.', 403, 'Forbidden']
182
+ util_sign_in
185
183
  end
186
184
 
187
185
  assert_match %r{Enter your RubyGems.org credentials.}, @sign_in_ui.output
@@ -189,57 +187,120 @@ class TestGemGemcutterUtilities < Gem::TestCase
189
187
  end
190
188
 
191
189
  def test_signin_with_env_otp_code
192
- ENV['GEM_HOST_OTP_CODE'] = '111111'
193
- api_key = 'a5fdbb6ba150cbb83aad2bb2fede64cf040453903'
190
+ ENV["GEM_HOST_OTP_CODE"] = "111111"
194
191
 
195
- util_sign_in [api_key, 200, 'OK']
192
+ util_sign_in
196
193
 
197
- assert_match 'Signed in with API key:', @sign_in_ui.output
198
- assert_equal '111111', @fetcher.last_request['OTP']
194
+ assert_match "Signed in with API key:", @sign_in_ui.output
195
+ assert_equal "111111", @fetcher.last_request["OTP"]
199
196
  end
200
197
 
201
198
  def test_sign_in_with_correct_otp_code
202
- api_key = 'a5fdbb6ba150cbb83aad2bb2fede64cf040453903'
203
- response_fail = "You have enabled multifactor authentication but your request doesn't have the correct OTP code. Please check it and retry."
204
-
205
- util_sign_in(proc do
206
- @call_count ||= 0
207
- (@call_count += 1).odd? ? [response_fail, 401, 'Unauthorized'] : [api_key, 200, 'OK']
208
- end, nil, [], "111111\n")
209
-
210
- assert_match 'You have enabled multi-factor authentication. Please enter OTP code.', @sign_in_ui.output
211
- assert_match 'Code: ', @sign_in_ui.output
212
- assert_match 'Signed in with API key:', @sign_in_ui.output
213
- assert_equal '111111', @fetcher.last_request['OTP']
199
+ @fetcher.respond_with_require_otp
200
+ util_sign_in(extra_input: "111111\n")
201
+
202
+ assert_match "You have enabled multi-factor authentication. Please enter OTP code.", @sign_in_ui.output
203
+ assert_match "Code: ", @sign_in_ui.output
204
+ assert_match "Signed in with API key:", @sign_in_ui.output
205
+ assert_equal "111111", @fetcher.last_request["OTP"]
214
206
  end
215
207
 
216
208
  def test_sign_in_with_incorrect_otp_code
217
209
  response = "You have enabled multifactor authentication but your request doesn't have the correct OTP code. Please check it and retry."
218
210
 
211
+ @fetcher.respond_with_unauthorized_api_key_response
219
212
  assert_raise Gem::MockGemUi::TermError do
220
- util_sign_in [response, 401, 'Unauthorized'], nil, [], "111111\n"
213
+ util_sign_in(extra_input: "111111\n")
221
214
  end
222
215
 
223
- assert_match 'You have enabled multi-factor authentication. Please enter OTP code.', @sign_in_ui.output
224
- assert_match 'Code: ', @sign_in_ui.output
216
+ assert_match "You have enabled multi-factor authentication. Please enter OTP code.", @sign_in_ui.output
217
+ assert_match "Code: ", @sign_in_ui.output
225
218
  assert_match response, @sign_in_ui.output
226
- assert_equal '111111', @fetcher.last_request['OTP']
219
+ assert_equal "111111", @fetcher.last_request["OTP"]
220
+ end
221
+
222
+ def test_sign_in_with_webauthn_enabled
223
+ server = Gem::MockTCPServer.new
224
+
225
+ @fetcher.respond_with_require_otp
226
+ @fetcher.respond_with_webauthn_url
227
+ TCPServer.stub(:new, server) do
228
+ Gem::GemcutterUtilities::WebauthnListener.stub(:listener_thread, Thread.new { Thread.current[:otp] = "Uvh6T57tkWuUnWYo" }) do
229
+ util_sign_in
230
+ end
231
+ end
232
+
233
+ assert_match "You have enabled multi-factor authentication. Please visit #{@fetcher.webauthn_url_with_port(server.port)} " \
234
+ "to authenticate via security device. If you can't verify using WebAuthn but have OTP enabled, " \
235
+ "you can re-run the gem signin command with the `--otp [your_code]` option.", @sign_in_ui.output
236
+ assert_match "You are verified with a security device. You may close the browser window.", @sign_in_ui.output
237
+ assert_equal "Uvh6T57tkWuUnWYo", @fetcher.last_request["OTP"]
238
+ end
239
+
240
+ def test_sign_in_with_webauthn_enabled_with_error
241
+ server = Gem::MockTCPServer.new
242
+ error = Gem::WebauthnVerificationError.new("Something went wrong")
243
+
244
+ @fetcher.respond_with_require_otp
245
+ @fetcher.respond_with_webauthn_url
246
+ error = assert_raise Gem::MockGemUi::TermError do
247
+ TCPServer.stub(:new, server) do
248
+ Gem::GemcutterUtilities::WebauthnListener.stub(:listener_thread, Thread.new { Thread.current[:error] = error }) do
249
+ util_sign_in
250
+ end
251
+ end
252
+ end
253
+ assert_equal 1, error.exit_code
254
+
255
+ assert_match "You have enabled multi-factor authentication. Please visit #{@fetcher.webauthn_url_with_port(server.port)} " \
256
+ "to authenticate via security device. If you can't verify using WebAuthn but have OTP enabled, " \
257
+ "you can re-run the gem signin command with the `--otp [your_code]` option.", @sign_in_ui.output
258
+ assert_match "ERROR: Security device verification failed: Something went wrong", @sign_in_ui.error
259
+ refute_match "You are verified with a security device. You may close the browser window.", @sign_in_ui.output
260
+ refute_match "Signed in with API key:", @sign_in_ui.output
227
261
  end
228
262
 
229
- def util_sign_in(response, host = nil, args = [], extra_input = '')
230
- email = 'you@example.com'
231
- password = 'secret'
232
- profile_response = [ "mfa: disabled\n" , 200, 'OK']
263
+ def test_sign_in_with_webauthn_enabled_with_polling
264
+ server = Gem::MockTCPServer.new
265
+ @fetcher.respond_with_require_otp
266
+ @fetcher.respond_with_webauthn_url
267
+ @fetcher.respond_with_webauthn_polling("Uvh6T57tkWuUnWYo")
233
268
 
234
- if host
235
- ENV['RUBYGEMS_HOST'] = host
236
- else
237
- host = Gem.host
269
+ TCPServer.stub(:new, server) do
270
+ util_sign_in
238
271
  end
239
272
 
240
- @fetcher = Gem::FakeFetcher.new
241
- @fetcher.data["#{host}/api/v1/api_key"] = response
242
- @fetcher.data["#{host}/api/v1/profile/me.yaml"] = profile_response
273
+ assert_match "You have enabled multi-factor authentication. Please visit #{@fetcher.webauthn_url_with_port(server.port)} " \
274
+ "to authenticate via security device. If you can't verify using WebAuthn but have OTP enabled, " \
275
+ "you can re-run the gem signin command with the `--otp [your_code]` option.", @sign_in_ui.output
276
+ assert_match "You are verified with a security device. You may close the browser window.", @sign_in_ui.output
277
+ assert_equal "Uvh6T57tkWuUnWYo", @fetcher.last_request["OTP"]
278
+ end
279
+
280
+ def test_sign_in_with_webauthn_enabled_with_polling_failure
281
+ server = Gem::MockTCPServer.new
282
+ @fetcher.respond_with_require_otp
283
+ @fetcher.respond_with_webauthn_url
284
+ @fetcher.respond_with_webauthn_polling_failure
285
+
286
+ assert_raise Gem::MockGemUi::TermError do
287
+ TCPServer.stub(:new, server) do
288
+ util_sign_in
289
+ end
290
+ end
291
+
292
+ assert_match "You have enabled multi-factor authentication. Please visit #{@fetcher.webauthn_url_with_port(server.port)} " \
293
+ "to authenticate via security device. If you can't verify using WebAuthn but have OTP enabled, " \
294
+ "you can re-run the gem signin command with the `--otp [your_code]` option.", @sign_in_ui.output
295
+ assert_match "ERROR: Security device verification failed: " \
296
+ "The token in the link you used has either expired or been used already.", @sign_in_ui.error
297
+ end
298
+
299
+ def util_sign_in(args: [], extra_input: "")
300
+ email = "you@example.com"
301
+ password = "secret"
302
+
303
+ ENV["RUBYGEMS_HOST"] = @fetcher.host
243
304
  Gem::RemoteFetcher.fetcher = @fetcher
244
305
 
245
306
  @sign_in_ui = Gem::MockGemUi.new("#{email}\n#{password}\n\n\n\n\n\n\n\n\n" + extra_input)
@@ -254,13 +315,13 @@ class TestGemGemcutterUtilities < Gem::TestCase
254
315
  end
255
316
 
256
317
  def test_verify_api_key
257
- keys = { :other => 'a5fdbb6ba150cbb83aad2bb2fede64cf040453903' }
258
- File.open Gem.configuration.credentials_path, 'w' do |f|
318
+ keys = { :other => "a5fdbb6ba150cbb83aad2bb2fede64cf040453903" }
319
+ File.open Gem.configuration.credentials_path, "w" do |f|
259
320
  f.write keys.to_yaml
260
321
  end
261
322
  Gem.configuration.load_api_keys
262
323
 
263
- assert_equal 'a5fdbb6ba150cbb83aad2bb2fede64cf040453903',
324
+ assert_equal "a5fdbb6ba150cbb83aad2bb2fede64cf040453903",
264
325
  @cmd.verify_api_key(:other)
265
326
  end
266
327
 
@@ -269,4 +330,29 @@ class TestGemGemcutterUtilities < Gem::TestCase
269
330
  @cmd.verify_api_key :missing
270
331
  end
271
332
  end
333
+
334
+ class SignInFetcher < Gem::MultifactorAuthFetcher
335
+ attr_reader :api_key
336
+
337
+ def initialize(host: nil)
338
+ super(host: host)
339
+ @api_key = "a5fdbb6ba150cbb83aad2bb2fede64cf040453903"
340
+ @data["#{@host}/api/v1/api_key"] = Gem::HTTPResponseFactory.create(body: @api_key, code: 200, msg: "OK")
341
+ @data["#{@host}/api/v1/profile/me.yaml"] = Gem::HTTPResponseFactory.create(body: "mfa: disabled\n", code: 200, msg: "OK")
342
+ end
343
+
344
+ def respond_with_require_otp
345
+ super("#{host}/api/v1/api_key", @api_key)
346
+ end
347
+
348
+ def respond_with_forbidden_api_key_response
349
+ @data["#{host}/api/v1/api_key"] = Gem::HTTPResponseFactory.create(body: "Access Denied.", code: 403, msg: "Forbidden")
350
+ end
351
+
352
+ def respond_with_unauthorized_api_key_response
353
+ response = "You have enabled multifactor authentication but your request doesn't have the correct OTP code. Please check it and retry."
354
+
355
+ @data["#{host}/api/v1/api_key"] = Gem::HTTPResponseFactory.create(body: response, code: 401, msg: "Unauthorized")
356
+ end
357
+ end
272
358
  end
@@ -1,9 +1,10 @@
1
1
  # frozen_string_literal: true
2
- require_relative 'helper'
2
+
3
+ require_relative "helper"
3
4
 
4
5
  class TestGemImpossibleDependenciesError < Gem::TestCase
5
6
  def test_message_conflict
6
- request = dependency_request dep('net-ssh', '>= 2.0.13'), 'rye', '0.9.8'
7
+ request = dependency_request dep("net-ssh", ">= 2.0.13"), "rye", "0.9.8"
7
8
 
8
9
  conflicts = []
9
10
 
@@ -11,9 +12,9 @@ class TestGemImpossibleDependenciesError < Gem::TestCase
11
12
  # requested-by entries, but they are suitable for testing the message.
12
13
  # See #485 to construct a correct conflict.
13
14
  net_ssh_2_2_2 =
14
- dependency_request dep('net-ssh', '>= 2.6.5'), 'net-ssh', '2.2.2', request
15
+ dependency_request dep("net-ssh", ">= 2.6.5"), "net-ssh", "2.2.2", request
15
16
  net_ssh_2_6_5 =
16
- dependency_request dep('net-ssh', '~> 2.2.2'), 'net-ssh', '2.6.5', request
17
+ dependency_request dep("net-ssh", "~> 2.2.2"), "net-ssh", "2.6.5", request
17
18
 
18
19
  conflict1 = Gem::Resolver::Conflict.new \
19
20
  net_ssh_2_6_5, net_ssh_2_6_5.requester