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,6 +1,8 @@
1
1
  # frozen_string_literal: true
2
- require_relative 'helper'
3
- require 'rubygems/commands/push_command'
2
+
3
+ require_relative "helper"
4
+ require_relative "multifactor_auth_utilities"
5
+ require "rubygems/commands/push_command"
4
6
 
5
7
  class TestGemCommandsPushCommand < Gem::TestCase
6
8
  def setup
@@ -12,7 +14,7 @@ class TestGemCommandsPushCommand < Gem::TestCase
12
14
  Gem.host = Gem::DEFAULT_HOST
13
15
  Gem.configuration.disable_default_gem_server = false
14
16
 
15
- @gems_dir = File.join @tempdir, 'gems'
17
+ @gems_dir = File.join @tempdir, "gems"
16
18
  @cache_dir = File.join @gemhome, "cache"
17
19
 
18
20
  FileUtils.mkdir @gems_dir
@@ -21,10 +23,10 @@ class TestGemCommandsPushCommand < Gem::TestCase
21
23
  "ed244fbf2b1a52e012da8616c512fa47f9aa5250"
22
24
 
23
25
  @spec, @path = util_gem "freewill", "1.0.0"
24
- @host = 'https://rubygems.example'
26
+ @host = "https://rubygems.example"
25
27
  @api_key = Gem.configuration.rubygems_api_key
26
28
 
27
- @fetcher = Gem::FakeFetcher.new
29
+ @fetcher = Gem::MultifactorAuthFetcher.new
28
30
  Gem::RemoteFetcher.fetcher = @fetcher
29
31
 
30
32
  @cmd = Gem::Commands::PushCommand.new
@@ -68,7 +70,7 @@ class TestGemCommandsPushCommand < Gem::TestCase
68
70
 
69
71
  def test_execute
70
72
  @response = "Successfully registered gem: freewill (1.0.0)"
71
- @fetcher.data["#{Gem.host}/api/v1/gems"] = [@response, 200, 'OK']
73
+ @fetcher.data["#{Gem.host}/api/v1/gems"] = HTTPResponseFactory.create(body: @response, code: 200, msg: "OK")
72
74
 
73
75
  @cmd.options[:args] = [@path]
74
76
 
@@ -81,12 +83,12 @@ class TestGemCommandsPushCommand < Gem::TestCase
81
83
  end
82
84
 
83
85
  def test_execute_host
84
- host = 'https://other.example'
86
+ host = "https://other.example"
85
87
 
86
88
  @response = "Successfully registered gem: freewill (1.0.0)"
87
- @fetcher.data["#{host}/api/v1/gems"] = [@response, 200, 'OK']
89
+ @fetcher.data["#{host}/api/v1/gems"] = HTTPResponseFactory.create(body: @response, code: 200, msg: "OK")
88
90
  @fetcher.data["#{Gem.host}/api/v1/gems"] =
89
- ['fail', 500, 'Internal Server Error']
91
+ ["fail", 500, "Internal Server Error"]
90
92
 
91
93
  @cmd.options[:host] = host
92
94
  @cmd.options[:args] = [@path]
@@ -101,13 +103,13 @@ class TestGemCommandsPushCommand < Gem::TestCase
101
103
 
102
104
  def test_execute_allowed_push_host
103
105
  @spec, @path = util_gem "freebird", "1.0.1" do |spec|
104
- spec.metadata['allowed_push_host'] = "https://privategemserver.example"
106
+ spec.metadata["allowed_push_host"] = "https://privategemserver.example"
105
107
  end
106
108
 
107
109
  @response = "Successfully registered gem: freewill (1.0.0)"
108
- @fetcher.data["#{@spec.metadata['allowed_push_host']}/api/v1/gems"] = [@response, 200, 'OK']
110
+ @fetcher.data["#{@spec.metadata['allowed_push_host']}/api/v1/gems"] = HTTPResponseFactory.create(body: @response, code: 200, msg: "OK")
109
111
  @fetcher.data["#{Gem.host}/api/v1/gems"] =
110
- ['fail', 500, 'Internal Server Error']
112
+ ["fail", 500, "Internal Server Error"]
111
113
 
112
114
  @cmd.options[:args] = [@path]
113
115
 
@@ -136,7 +138,7 @@ class TestGemCommandsPushCommand < Gem::TestCase
136
138
  ENV["RUBYGEMS_HOST"] = @host
137
139
  Gem.configuration.disable_default_gem_server = true
138
140
  @response = "Successfully registered gem: freewill (1.0.0)"
139
- @fetcher.data["#{@host}/api/v1/gems"] = [@response, 200, 'OK']
141
+ @fetcher.data["#{@host}/api/v1/gems"] = HTTPResponseFactory.create(body: @response, code: 200, msg: "OK")
140
142
 
141
143
  send_battery
142
144
  end
@@ -145,17 +147,17 @@ class TestGemCommandsPushCommand < Gem::TestCase
145
147
  @host = "http://privategemserver.example"
146
148
 
147
149
  @spec, @path = util_gem "freebird", "1.0.1" do |spec|
148
- spec.metadata['default_gem_server'] = @host
150
+ spec.metadata["default_gem_server"] = @host
149
151
  end
150
152
 
151
153
  @api_key = "EYKEY"
152
154
 
153
155
  keys = {
154
- :rubygems_api_key => 'KEY',
156
+ :rubygems_api_key => "KEY",
155
157
  @host => @api_key,
156
158
  }
157
159
 
158
- File.open Gem.configuration.credentials_path, 'w' do |f|
160
+ File.open Gem.configuration.credentials_path, "w" do |f|
159
161
  f.write keys.to_yaml
160
162
  end
161
163
  Gem.configuration.load_api_keys
@@ -163,14 +165,14 @@ class TestGemCommandsPushCommand < Gem::TestCase
163
165
  FileUtils.rm Gem.configuration.credentials_path
164
166
 
165
167
  @response = "Successfully registered gem: freebird (1.0.1)"
166
- @fetcher.data["#{@host}/api/v1/gems"] = [@response, 200, 'OK']
168
+ @fetcher.data["#{@host}/api/v1/gems"] = HTTPResponseFactory.create(body: @response, code: 200, msg: "OK")
167
169
 
168
170
  send_battery
169
171
  end
170
172
 
171
173
  def test_sending_gem
172
174
  @response = "Successfully registered gem: freewill (1.0.0)"
173
- @fetcher.data["#{@host}/api/v1/gems"] = [@response, 200, 'OK']
175
+ @fetcher.data["#{@host}/api/v1/gems"] = HTTPResponseFactory.create(body: @response, code: 200, msg: "OK")
174
176
 
175
177
  send_battery
176
178
  end
@@ -179,17 +181,17 @@ class TestGemCommandsPushCommand < Gem::TestCase
179
181
  @host = "http://privategemserver.example"
180
182
 
181
183
  @spec, @path = util_gem "freebird", "1.0.1" do |spec|
182
- spec.metadata['allowed_push_host'] = @host
184
+ spec.metadata["allowed_push_host"] = @host
183
185
  end
184
186
 
185
187
  @api_key = "PRIVKEY"
186
188
 
187
189
  keys = {
188
- :rubygems_api_key => 'KEY',
190
+ :rubygems_api_key => "KEY",
189
191
  @host => @api_key,
190
192
  }
191
193
 
192
- File.open Gem.configuration.credentials_path, 'w' do |f|
194
+ File.open Gem.configuration.credentials_path, "w" do |f|
193
195
  f.write keys.to_yaml
194
196
  end
195
197
  Gem.configuration.load_api_keys
@@ -197,7 +199,7 @@ class TestGemCommandsPushCommand < Gem::TestCase
197
199
  FileUtils.rm Gem.configuration.credentials_path
198
200
 
199
201
  @response = "Successfully registered gem: freebird (1.0.1)"
200
- @fetcher.data["#{@host}/api/v1/gems"] = [@response, 200, 'OK']
202
+ @fetcher.data["#{@host}/api/v1/gems"] = HTTPResponseFactory.create(body: @response, code: 200, msg: "OK")
201
203
  send_battery
202
204
  end
203
205
 
@@ -205,14 +207,14 @@ class TestGemCommandsPushCommand < Gem::TestCase
205
207
  @host = "http://privategemserver.example"
206
208
 
207
209
  @spec, @path = util_gem "freebird", "1.0.1" do |spec|
208
- spec.metadata['allowed_push_host'] = @host
210
+ spec.metadata["allowed_push_host"] = @host
209
211
  end
210
212
 
211
213
  @api_key = "PRIVKEY"
212
214
  ENV["GEM_HOST_API_KEY"] = "PRIVKEY"
213
215
 
214
216
  @response = "Successfully registered gem: freebird (1.0.1)"
215
- @fetcher.data["#{@host}/api/v1/gems"] = [@response, 200, 'OK']
217
+ @fetcher.data["#{@host}/api/v1/gems"] = HTTPResponseFactory.create(body: @response, code: 200, msg: "OK")
216
218
  send_battery
217
219
  end
218
220
 
@@ -221,7 +223,7 @@ class TestGemCommandsPushCommand < Gem::TestCase
221
223
  @host = "http://user:password@privategemserver.example"
222
224
 
223
225
  @spec, @path = util_gem "freebird", "1.0.1" do |spec|
224
- spec.metadata['allowed_push_host'] = @sanitized_host
226
+ spec.metadata["allowed_push_host"] = @sanitized_host
225
227
  end
226
228
 
227
229
  @api_key = "DOESNTMATTER"
@@ -230,7 +232,7 @@ class TestGemCommandsPushCommand < Gem::TestCase
230
232
  :rubygems_api_key => @api_key,
231
233
  }
232
234
 
233
- File.open Gem.configuration.credentials_path, 'w' do |f|
235
+ File.open Gem.configuration.credentials_path, "w" do |f|
234
236
  f.write keys.to_yaml
235
237
  end
236
238
  Gem.configuration.load_api_keys
@@ -238,13 +240,13 @@ class TestGemCommandsPushCommand < Gem::TestCase
238
240
  FileUtils.rm Gem.configuration.credentials_path
239
241
 
240
242
  @response = "Successfully registered gem: freebird (1.0.1)"
241
- @fetcher.data["#{@host}/api/v1/gems"] = [@response, 200, 'OK']
243
+ @fetcher.data["#{@host}/api/v1/gems"] = HTTPResponseFactory.create(body: @response, code: 200, msg: "OK")
242
244
  send_battery
243
245
  end
244
246
 
245
247
  def test_sending_gem_to_disallowed_default_host
246
248
  @spec, @path = util_gem "freebird", "1.0.1" do |spec|
247
- spec.metadata['allowed_push_host'] = "https://privategemserver.example"
249
+ spec.metadata["allowed_push_host"] = "https://privategemserver.example"
248
250
  end
249
251
 
250
252
  response = %(ERROR: "#{@host}" is not allowed by the gemspec, which only allows "https://privategemserver.example")
@@ -261,17 +263,17 @@ class TestGemCommandsPushCommand < Gem::TestCase
261
263
  push_host = "https://privategemserver.example"
262
264
 
263
265
  @spec, @path = util_gem "freebird", "1.0.1" do |spec|
264
- spec.metadata['allowed_push_host'] = push_host
266
+ spec.metadata["allowed_push_host"] = push_host
265
267
  end
266
268
 
267
269
  @api_key = "PRIVKEY"
268
270
 
269
271
  keys = {
270
- :rubygems_api_key => 'KEY',
272
+ :rubygems_api_key => "KEY",
271
273
  @host => @api_key,
272
274
  }
273
275
 
274
- File.open Gem.configuration.credentials_path, 'w' do |f|
276
+ File.open Gem.configuration.credentials_path, "w" do |f|
275
277
  f.write keys.to_yaml
276
278
  end
277
279
  Gem.configuration.load_api_keys
@@ -291,8 +293,8 @@ class TestGemCommandsPushCommand < Gem::TestCase
291
293
  host = "http://privategemserver.example"
292
294
 
293
295
  @spec, @path = util_gem "freebird", "1.0.1" do |spec|
294
- spec.metadata.delete('default_gem_server')
295
- spec.metadata['allowed_push_host'] = host
296
+ spec.metadata.delete("default_gem_server")
297
+ spec.metadata["allowed_push_host"] = host
296
298
  end
297
299
 
298
300
  api_key = "PRIVKEY"
@@ -301,7 +303,7 @@ class TestGemCommandsPushCommand < Gem::TestCase
301
303
  host => api_key,
302
304
  }
303
305
 
304
- File.open Gem.configuration.credentials_path, 'w' do |f|
306
+ File.open Gem.configuration.credentials_path, "w" do |f|
305
307
  f.write keys.to_yaml
306
308
  end
307
309
  Gem.configuration.load_api_keys
@@ -309,7 +311,7 @@ class TestGemCommandsPushCommand < Gem::TestCase
309
311
  FileUtils.rm Gem.configuration.credentials_path
310
312
 
311
313
  @response = "Successfully registered gem: freebird (1.0.1)"
312
- @fetcher.data["#{host}/api/v1/gems"] = [@response, 200, 'OK']
314
+ @fetcher.data["#{host}/api/v1/gems"] = HTTPResponseFactory.create(body: @response, code: 200, msg: "OK")
313
315
 
314
316
  # do not set @host
315
317
  use_ui(@ui) { @cmd.send_gem(@path) }
@@ -325,6 +327,27 @@ class TestGemCommandsPushCommand < Gem::TestCase
325
327
  assert_match @response, @ui.output
326
328
  end
327
329
 
330
+ def test_sending_gem_to_host_permanent_redirect
331
+ @host = "http://rubygems.example"
332
+ redirected_uri = "https://rubygems.example/api/v1/gems"
333
+ @fetcher.data["#{@host}/api/v1/gems"] = HTTPResponseFactory.create(
334
+ body: "",
335
+ code: 308,
336
+ msg: "Permanent Redirect",
337
+ headers: { "Location" => redirected_uri }
338
+ )
339
+
340
+ assert_raise Gem::MockGemUi::TermError do
341
+ use_ui @ui do
342
+ @cmd.instance_variable_set :@host, @host
343
+ @cmd.send_gem(@path)
344
+ end
345
+ end
346
+
347
+ response = "The request has redirected permanently to #{redirected_uri}. Please check your defined push host URL."
348
+ assert_match response, @ui.output
349
+ end
350
+
328
351
  def test_raises_error_with_no_arguments
329
352
  def @cmd.sign_in(*); end
330
353
  assert_raise Gem::CommandLineError do
@@ -334,7 +357,7 @@ class TestGemCommandsPushCommand < Gem::TestCase
334
357
 
335
358
  def test_sending_gem_denied
336
359
  response = "You don't have permission to push to this gem"
337
- @fetcher.data["#{@host}/api/v1/gems"] = [response, 403, 'Forbidden']
360
+ @fetcher.data["#{@host}/api/v1/gems"] = HTTPResponseFactory.create(body: response, code: 403, msg: "Forbidden")
338
361
  @cmd.instance_variable_set :@host, @host
339
362
 
340
363
  assert_raise Gem::MockGemUi::TermError do
@@ -348,9 +371,9 @@ class TestGemCommandsPushCommand < Gem::TestCase
348
371
 
349
372
  def test_sending_gem_key
350
373
  @response = "Successfully registered gem: freewill (1.0.0)"
351
- @fetcher.data["#{@host}/api/v1/gems"] = [@response, 200, "OK"]
352
- File.open Gem.configuration.credentials_path, 'a' do |f|
353
- f.write ':other: 701229f217cdf23b1344c7b4b54ca97'
374
+ @fetcher.data["#{@host}/api/v1/gems"] = HTTPResponseFactory.create(body: @response, code: 200, msg: "OK")
375
+ File.open Gem.configuration.credentials_path, "a" do |f|
376
+ f.write ":other: 701229f217cdf23b1344c7b4b54ca97"
354
377
  end
355
378
  Gem.configuration.load_api_keys
356
379
 
@@ -363,28 +386,26 @@ class TestGemCommandsPushCommand < Gem::TestCase
363
386
  end
364
387
 
365
388
  def test_otp_verified_success
366
- response_fail = "You have enabled multifactor authentication but your request doesn't have the correct OTP code. Please check it and retry."
367
- response_success = 'Successfully registered gem: freewill (1.0.0)'
389
+ response_success = "Successfully registered gem: freewill (1.0.0)"
368
390
 
369
- @fetcher.data["#{Gem.host}/api/v1/gems"] = [
370
- [response_fail, 401, 'Unauthorized'],
371
- [response_success, 200, 'OK'],
372
- ]
391
+ @fetcher.respond_with_require_otp("#{Gem.host}/api/v1/gems", response_success)
373
392
 
374
393
  @otp_ui = Gem::MockGemUi.new "111111\n"
375
394
  use_ui @otp_ui do
376
395
  @cmd.send_gem(@path)
377
396
  end
378
397
 
379
- assert_match 'You have enabled multi-factor authentication. Please enter OTP code.', @otp_ui.output
380
- assert_match 'Code: ', @otp_ui.output
398
+ assert_match "You have enabled multi-factor authentication. Please enter OTP code.", @otp_ui.output
399
+ assert_match "Code: ", @otp_ui.output
381
400
  assert_match response_success, @otp_ui.output
382
- assert_equal '111111', @fetcher.last_request['OTP']
401
+ assert_equal "111111", @fetcher.last_request["OTP"]
383
402
  end
384
403
 
385
404
  def test_otp_verified_failure
386
405
  response = "You have enabled multifactor authentication but your request doesn't have the correct OTP code. Please check it and retry."
387
- @fetcher.data["#{Gem.host}/api/v1/gems"] = [response, 401, 'Unauthorized']
406
+ @fetcher.data["#{Gem.host}/api/v1/gems"] = HTTPResponseFactory.create(body: response, code: 401, msg: "Unauthorized")
407
+ @fetcher.data["#{Gem.host}/api/v1/webauthn_verification"] =
408
+ HTTPResponseFactory.create(body: "You don't have any security devices", code: 422, msg: "Unprocessable Entity")
388
409
 
389
410
  @otp_ui = Gem::MockGemUi.new "111111\n"
390
411
  assert_raise Gem::MockGemUi::TermError do
@@ -394,23 +415,125 @@ class TestGemCommandsPushCommand < Gem::TestCase
394
415
  end
395
416
 
396
417
  assert_match response, @otp_ui.output
397
- assert_match 'You have enabled multi-factor authentication. Please enter OTP code.', @otp_ui.output
398
- assert_match 'Code: ', @otp_ui.output
399
- assert_equal '111111', @fetcher.last_request['OTP']
418
+ assert_match "You have enabled multi-factor authentication. Please enter OTP code.", @otp_ui.output
419
+ assert_match "Code: ", @otp_ui.output
420
+ assert_equal "111111", @fetcher.last_request["OTP"]
421
+ end
422
+
423
+ def test_with_webauthn_enabled_success
424
+ response_success = "Successfully registered gem: freewill (1.0.0)"
425
+ server = Gem::MockTCPServer.new
426
+
427
+ @fetcher.respond_with_require_otp("#{Gem.host}/api/v1/gems", response_success)
428
+ @fetcher.respond_with_webauthn_url
429
+
430
+ TCPServer.stub(:new, server) do
431
+ Gem::GemcutterUtilities::WebauthnListener.stub(:listener_thread, Thread.new { Thread.current[:otp] = "Uvh6T57tkWuUnWYo" }) do
432
+ use_ui @ui do
433
+ @cmd.send_gem(@path)
434
+ end
435
+ end
436
+ end
437
+
438
+ assert_match "You have enabled multi-factor authentication. Please visit #{@fetcher.webauthn_url_with_port(server.port)} " \
439
+ "to authenticate via security device. If you can't verify using WebAuthn but have OTP enabled, " \
440
+ "you can re-run the gem signin command with the `--otp [your_code]` option.", @ui.output
441
+ assert_match "You are verified with a security device. You may close the browser window.", @ui.output
442
+ assert_equal "Uvh6T57tkWuUnWYo", @fetcher.last_request["OTP"]
443
+ assert_match response_success, @ui.output
444
+ end
445
+
446
+ def test_with_webauthn_enabled_failure
447
+ response_success = "Successfully registered gem: freewill (1.0.0)"
448
+ server = Gem::MockTCPServer.new
449
+ error = Gem::WebauthnVerificationError.new("Something went wrong")
450
+
451
+ @fetcher.respond_with_require_otp("#{Gem.host}/api/v1/gems", response_success)
452
+ @fetcher.respond_with_webauthn_url
453
+
454
+ error = assert_raise Gem::MockGemUi::TermError do
455
+ TCPServer.stub(:new, server) do
456
+ Gem::GemcutterUtilities::WebauthnListener.stub(:listener_thread, Thread.new { Thread.current[:error] = error }) do
457
+ use_ui @ui do
458
+ @cmd.send_gem(@path)
459
+ end
460
+ end
461
+ end
462
+ end
463
+ assert_equal 1, error.exit_code
464
+
465
+ assert_match @fetcher.last_request["Authorization"], Gem.configuration.rubygems_api_key
466
+ assert_match "You have enabled multi-factor authentication. Please visit #{@fetcher.webauthn_url_with_port(server.port)} " \
467
+ "to authenticate via security device. If you can't verify using WebAuthn but have OTP enabled, " \
468
+ "you can re-run the gem signin command with the `--otp [your_code]` option.", @ui.output
469
+ assert_match "ERROR: Security device verification failed: Something went wrong", @ui.error
470
+ refute_match "You are verified with a security device. You may close the browser window.", @ui.output
471
+ refute_match response_success, @ui.output
472
+ end
473
+
474
+ def test_with_webauthn_enabled_success_with_polling
475
+ response_success = "Successfully registered gem: freewill (1.0.0)"
476
+ server = Gem::MockTCPServer.new
477
+
478
+ @fetcher.respond_with_require_otp("#{Gem.host}/api/v1/gems", response_success)
479
+ @fetcher.respond_with_webauthn_url
480
+ @fetcher.respond_with_webauthn_polling("Uvh6T57tkWuUnWYo")
481
+
482
+ TCPServer.stub(:new, server) do
483
+ use_ui @ui do
484
+ @cmd.send_gem(@path)
485
+ end
486
+ end
487
+
488
+ assert_match "You have enabled multi-factor authentication. Please visit #{@fetcher.webauthn_url_with_port(server.port)} " \
489
+ "to authenticate via security device. If you can't verify using WebAuthn but have OTP enabled, " \
490
+ "you can re-run the gem signin command with the `--otp [your_code]` option.", @ui.output
491
+ assert_match "You are verified with a security device. You may close the browser window.", @ui.output
492
+ assert_equal "Uvh6T57tkWuUnWYo", @fetcher.last_request["OTP"]
493
+ assert_match response_success, @ui.output
494
+ end
495
+
496
+ def test_with_webauthn_enabled_failure_with_polling
497
+ response_success = "Successfully registered gem: freewill (1.0.0)"
498
+ server = Gem::MockTCPServer.new
499
+
500
+ @fetcher.respond_with_require_otp("#{Gem.host}/api/v1/gems", response_success)
501
+ @fetcher.respond_with_webauthn_url
502
+ @fetcher.respond_with_webauthn_polling_failure
503
+
504
+ error = assert_raise Gem::MockGemUi::TermError do
505
+ TCPServer.stub(:new, server) do
506
+ use_ui @ui do
507
+ @cmd.send_gem(@path)
508
+ end
509
+ end
510
+ end
511
+ assert_equal 1, error.exit_code
512
+
513
+ assert_match @fetcher.last_request["Authorization"], Gem.configuration.rubygems_api_key
514
+ assert_match "You have enabled multi-factor authentication. Please visit #{@fetcher.webauthn_url_with_port(server.port)} " \
515
+ "to authenticate via security device. If you can't verify using WebAuthn but have OTP enabled, you can re-run the gem signin " \
516
+ "command with the `--otp [your_code]` option.", @ui.output
517
+ assert_match "ERROR: Security device verification failed: The token in the link you used has either expired " \
518
+ "or been used already.", @ui.error
519
+ refute_match "You are verified with a security device. You may close the browser window.", @ui.output
520
+ refute_match response_success, @ui.output
400
521
  end
401
522
 
402
523
  def test_sending_gem_unathorized_api_key_with_mfa_enabled
403
524
  response_mfa_enabled = "You have enabled multifactor authentication but your request doesn't have the correct OTP code. Please check it and retry."
404
525
  response_forbidden = "The API key doesn't have access"
405
- response_success = 'Successfully registered gem: freewill (1.0.0)'
526
+ response_success = "Successfully registered gem: freewill (1.0.0)"
406
527
 
407
528
  @fetcher.data["#{@host}/api/v1/gems"] = [
408
- [response_mfa_enabled, 401, 'Unauthorized'],
409
- [response_forbidden, 403, 'Forbidden'],
410
- [response_success, 200, "OK"],
529
+ HTTPResponseFactory.create(body: response_mfa_enabled, code: 401, msg: "Unauthorized"),
530
+ HTTPResponseFactory.create(body: response_forbidden, code: 403, msg: "Forbidden"),
531
+ HTTPResponseFactory.create(body: response_success, code: 200, msg: "OK"),
411
532
  ]
533
+ @fetcher.data["#{@host}/api/v1/webauthn_verification"] =
534
+ HTTPResponseFactory.create(body: "You don't have any security devices", code: 422, msg: "Unprocessable Entity")
412
535
 
413
- @fetcher.data["#{@host}/api/v1/api_key"] = ["", 200, "OK"]
536
+ @fetcher.data["#{@host}/api/v1/api_key"] = HTTPResponseFactory.create(body: "", code: 200, msg: "OK")
414
537
  @cmd.instance_variable_set :@host, @host
415
538
  @cmd.instance_variable_set :@scope, :push_rubygem
416
539
 
@@ -427,28 +550,30 @@ class TestGemCommandsPushCommand < Gem::TestCase
427
550
  assert_match "Password:", @ui.output
428
551
  assert_match "Added push_rubygem scope to the existing API key", @ui.output
429
552
  assert_match response_success, @ui.output
430
- assert_equal '11111', @fetcher.last_request['OTP']
553
+ assert_equal "11111", @fetcher.last_request["OTP"]
431
554
  end
432
555
 
433
556
  def test_sending_gem_with_no_local_creds
434
557
  Gem.configuration.rubygems_api_key = nil
435
558
 
436
559
  response_mfa_enabled = "You have enabled multifactor authentication but your request doesn't have the correct OTP code. Please check it and retry."
437
- response_success = 'Successfully registered gem: freewill (1.0.0)'
560
+ response_success = "Successfully registered gem: freewill (1.0.0)"
438
561
  response_profile = "mfa: disabled\n"
439
562
 
440
563
  @fetcher.data["#{@host}/api/v1/gems"] = [
441
- [response_success, 200, "OK"],
564
+ HTTPResponseFactory.create(body: response_success, code: 200, msg: "OK"),
442
565
  ]
443
566
 
444
567
  @fetcher.data["#{@host}/api/v1/api_key"] = [
445
- [response_mfa_enabled, 401, 'Unauthorized'],
446
- ["", 200, "OK"],
568
+ HTTPResponseFactory.create(body: response_mfa_enabled, code: 401, msg: "Unauthorized"),
569
+ HTTPResponseFactory.create(body: "", code: 200, msg: "OK"),
447
570
  ]
448
571
 
449
572
  @fetcher.data["#{@host}/api/v1/profile/me.yaml"] = [
450
- [response_profile, 200, "OK"],
573
+ HTTPResponseFactory.create(body: response_profile, code: 200, msg: "OK"),
451
574
  ]
575
+ @fetcher.data["#{@host}/api/v1/webauthn_verification"] =
576
+ HTTPResponseFactory.create(body: "You don't have any security devices", code: 422, msg: "Unprocessable Entity")
452
577
 
453
578
  @cmd.instance_variable_set :@scope, :push_rubygem
454
579
  @cmd.options[:args] = [@path]
@@ -466,7 +591,7 @@ class TestGemCommandsPushCommand < Gem::TestCase
466
591
  assert_match "Password:", @ui.output
467
592
  assert_match "Signed in with API key:", @ui.output
468
593
  assert_match response_success, @ui.output
469
- assert_equal '11111', @fetcher.last_request['OTP']
594
+ assert_equal "11111", @fetcher.last_request["OTP"]
470
595
  end
471
596
 
472
597
  private