rubygems-update 3.4.21 → 3.5.0

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 (564) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +132 -2
  3. data/Manifest.txt +39 -221
  4. data/README.md +1 -3
  5. data/bundler/CHANGELOG.md +74 -0
  6. data/bundler/README.md +1 -2
  7. data/bundler/bundler.gemspec +4 -2
  8. data/bundler/exe/bundle +1 -10
  9. data/bundler/lib/bundler/build_metadata.rb +3 -3
  10. data/bundler/lib/bundler/capistrano.rb +1 -1
  11. data/bundler/lib/bundler/checksum.rb +245 -0
  12. data/bundler/lib/bundler/ci_detector.rb +75 -0
  13. data/bundler/lib/bundler/cli/add.rb +3 -3
  14. data/bundler/lib/bundler/cli/binstubs.rb +4 -4
  15. data/bundler/lib/bundler/cli/cache.rb +1 -1
  16. data/bundler/lib/bundler/cli/check.rb +1 -1
  17. data/bundler/lib/bundler/cli/common.rb +9 -1
  18. data/bundler/lib/bundler/cli/config.rb +8 -7
  19. data/bundler/lib/bundler/cli/console.rb +3 -2
  20. data/bundler/lib/bundler/cli/doctor.rb +2 -2
  21. data/bundler/lib/bundler/cli/exec.rb +1 -1
  22. data/bundler/lib/bundler/cli/gem.rb +31 -23
  23. data/bundler/lib/bundler/cli/info.rb +2 -13
  24. data/bundler/lib/bundler/cli/install.rb +5 -4
  25. data/bundler/lib/bundler/cli/issue.rb +1 -1
  26. data/bundler/lib/bundler/cli/lock.rb +4 -4
  27. data/bundler/lib/bundler/cli/open.rb +1 -1
  28. data/bundler/lib/bundler/cli/outdated.rb +6 -6
  29. data/bundler/lib/bundler/cli/plugin.rb +7 -14
  30. data/bundler/lib/bundler/cli/pristine.rb +38 -30
  31. data/bundler/lib/bundler/cli/show.rb +2 -2
  32. data/bundler/lib/bundler/cli/update.rb +5 -5
  33. data/bundler/lib/bundler/cli.rb +215 -263
  34. data/bundler/lib/bundler/compact_index_client/cache.rb +29 -9
  35. data/bundler/lib/bundler/compact_index_client/cache_file.rb +153 -0
  36. data/bundler/lib/bundler/compact_index_client/gem_parser.rb +7 -3
  37. data/bundler/lib/bundler/compact_index_client/updater.rb +79 -81
  38. data/bundler/lib/bundler/compact_index_client.rb +14 -7
  39. data/bundler/lib/bundler/constants.rb +1 -1
  40. data/bundler/lib/bundler/current_ruby.rb +5 -21
  41. data/bundler/lib/bundler/definition.rb +43 -16
  42. data/bundler/lib/bundler/dependency.rb +16 -12
  43. data/bundler/lib/bundler/digest.rb +2 -2
  44. data/bundler/lib/bundler/dsl.rb +43 -25
  45. data/bundler/lib/bundler/endpoint_specification.rb +6 -2
  46. data/bundler/lib/bundler/env.rb +1 -3
  47. data/bundler/lib/bundler/errors.rb +58 -0
  48. data/bundler/lib/bundler/fetcher/base.rb +3 -1
  49. data/bundler/lib/bundler/fetcher/compact_index.rb +4 -4
  50. data/bundler/lib/bundler/fetcher/downloader.rb +13 -11
  51. data/bundler/lib/bundler/fetcher/gem_remote_fetcher.rb +16 -0
  52. data/bundler/lib/bundler/fetcher/index.rb +1 -1
  53. data/bundler/lib/bundler/fetcher.rb +28 -25
  54. data/bundler/lib/bundler/friendly_errors.rb +5 -5
  55. data/bundler/lib/bundler/gem_helper.rb +1 -1
  56. data/bundler/lib/bundler/gem_helpers.rb +12 -2
  57. data/bundler/lib/bundler/graph.rb +9 -9
  58. data/bundler/lib/bundler/index.rb +1 -2
  59. data/bundler/lib/bundler/injector.rb +1 -1
  60. data/bundler/lib/bundler/inline.rb +3 -3
  61. data/bundler/lib/bundler/installer/gem_installer.rb +10 -10
  62. data/bundler/lib/bundler/installer/parallel_installer.rb +16 -8
  63. data/bundler/lib/bundler/installer/standalone.rb +2 -3
  64. data/bundler/lib/bundler/installer.rb +9 -9
  65. data/bundler/lib/bundler/lazy_specification.rb +28 -17
  66. data/bundler/lib/bundler/lockfile_generator.rb +9 -0
  67. data/bundler/lib/bundler/lockfile_parser.rb +81 -10
  68. data/bundler/lib/bundler/man/bundle-add.1 +3 -26
  69. data/bundler/lib/bundler/man/bundle-binstubs.1 +4 -16
  70. data/bundler/lib/bundler/man/bundle-cache.1 +3 -24
  71. data/bundler/lib/bundler/man/bundle-check.1 +3 -12
  72. data/bundler/lib/bundler/man/bundle-clean.1 +3 -10
  73. data/bundler/lib/bundler/man/bundle-config.1 +20 -211
  74. data/bundler/lib/bundler/man/bundle-config.1.ronn +6 -0
  75. data/bundler/lib/bundler/man/bundle-console.1 +4 -22
  76. data/bundler/lib/bundler/man/bundle-doctor.1 +4 -18
  77. data/bundler/lib/bundler/man/bundle-exec.1 +12 -73
  78. data/bundler/lib/bundler/man/bundle-gem.1 +13 -49
  79. data/bundler/lib/bundler/man/bundle-help.1 +3 -7
  80. data/bundler/lib/bundler/man/bundle-info.1 +3 -9
  81. data/bundler/lib/bundler/man/bundle-init.1 +3 -12
  82. data/bundler/lib/bundler/man/bundle-inject.1 +6 -19
  83. data/bundler/lib/bundler/man/bundle-install.1 +27 -125
  84. data/bundler/lib/bundler/man/bundle-install.1.ronn +1 -0
  85. data/bundler/lib/bundler/man/bundle-list.1 +4 -19
  86. data/bundler/lib/bundler/man/bundle-lock.1 +5 -29
  87. data/bundler/lib/bundler/man/bundle-open.1 +7 -27
  88. data/bundler/lib/bundler/man/bundle-outdated.1 +3 -55
  89. data/bundler/lib/bundler/man/bundle-outdated.1.ronn +1 -0
  90. data/bundler/lib/bundler/man/bundle-platform.1 +5 -27
  91. data/bundler/lib/bundler/man/bundle-plugin.1 +3 -29
  92. data/bundler/lib/bundler/man/bundle-pristine.1 +5 -16
  93. data/bundler/lib/bundler/man/bundle-remove.1 +4 -14
  94. data/bundler/lib/bundler/man/bundle-show.1 +3 -10
  95. data/bundler/lib/bundler/man/bundle-update.1 +18 -137
  96. data/bundler/lib/bundler/man/bundle-version.1 +3 -16
  97. data/bundler/lib/bundler/man/bundle-viz.1 +4 -16
  98. data/bundler/lib/bundler/man/bundle.1 +5 -44
  99. data/bundler/lib/bundler/man/gemfile.5 +24 -301
  100. data/bundler/lib/bundler/man/gemfile.5.ronn +4 -0
  101. data/bundler/lib/bundler/match_metadata.rb +4 -0
  102. data/bundler/lib/bundler/match_platform.rb +1 -1
  103. data/bundler/lib/bundler/plugin/api/source.rb +3 -2
  104. data/bundler/lib/bundler/plugin/index.rb +8 -0
  105. data/bundler/lib/bundler/plugin/installer.rb +1 -1
  106. data/bundler/lib/bundler/plugin.rb +12 -5
  107. data/bundler/lib/bundler/resolver/base.rb +1 -1
  108. data/bundler/lib/bundler/resolver/incompatibility.rb +1 -1
  109. data/bundler/lib/bundler/resolver/spec_group.rb +1 -4
  110. data/bundler/lib/bundler/resolver.rb +16 -16
  111. data/bundler/lib/bundler/ruby_dsl.rb +20 -12
  112. data/bundler/lib/bundler/ruby_version.rb +1 -1
  113. data/bundler/lib/bundler/rubygems_ext.rb +27 -54
  114. data/bundler/lib/bundler/rubygems_gem_installer.rb +23 -58
  115. data/bundler/lib/bundler/rubygems_integration.rb +25 -94
  116. data/bundler/lib/bundler/runtime.rb +2 -2
  117. data/bundler/lib/bundler/self_manager.rb +23 -7
  118. data/bundler/lib/bundler/settings.rb +27 -7
  119. data/bundler/lib/bundler/setup.rb +4 -1
  120. data/bundler/lib/bundler/shared_helpers.rb +35 -13
  121. data/bundler/lib/bundler/source/git/git_proxy.rb +22 -14
  122. data/bundler/lib/bundler/source/git.rb +4 -3
  123. data/bundler/lib/bundler/source/metadata.rb +16 -16
  124. data/bundler/lib/bundler/source/path.rb +7 -6
  125. data/bundler/lib/bundler/source/rubygems.rb +21 -14
  126. data/bundler/lib/bundler/source.rb +2 -0
  127. data/bundler/lib/bundler/spec_set.rb +43 -12
  128. data/bundler/lib/bundler/stub_specification.rb +1 -0
  129. data/bundler/lib/bundler/templates/Executable.bundler +1 -1
  130. data/bundler/lib/bundler/templates/newgem/README.md.tt +3 -3
  131. data/bundler/lib/bundler/templates/newgem/Rakefile.tt +2 -6
  132. data/bundler/lib/bundler/templates/newgem/ext/newgem/Cargo.toml.tt +1 -1
  133. data/bundler/lib/bundler/templates/newgem/newgem.gemspec.tt +1 -1
  134. data/bundler/lib/bundler/templates/newgem/standard.yml.tt +1 -1
  135. data/bundler/lib/bundler/ui/shell.rb +2 -2
  136. data/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool/version.rb +1 -1
  137. data/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool.rb +53 -6
  138. data/bundler/lib/bundler/vendor/fileutils/lib/fileutils.rb +8 -20
  139. data/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/connection.rb +4 -3
  140. data/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/pool.rb +23 -11
  141. data/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/timed_stack_multi.rb +1 -1
  142. data/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb +36 -36
  143. data/bundler/lib/bundler/vendor/thor/lib/thor/actions/create_file.rb +3 -2
  144. data/bundler/lib/bundler/vendor/thor/lib/thor/actions/directory.rb +1 -1
  145. data/bundler/lib/bundler/vendor/thor/lib/thor/actions/empty_directory.rb +1 -1
  146. data/bundler/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb +8 -10
  147. data/bundler/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb +15 -4
  148. data/bundler/lib/bundler/vendor/thor/lib/thor/actions.rb +15 -15
  149. data/bundler/lib/bundler/vendor/thor/lib/thor/base.rb +140 -14
  150. data/bundler/lib/bundler/vendor/thor/lib/thor/command.rb +13 -4
  151. data/bundler/lib/bundler/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb +4 -0
  152. data/bundler/lib/bundler/vendor/thor/lib/thor/error.rb +16 -25
  153. data/bundler/lib/bundler/vendor/thor/lib/thor/group.rb +1 -1
  154. data/bundler/lib/bundler/vendor/thor/lib/thor/invocation.rb +1 -1
  155. data/bundler/lib/bundler/vendor/thor/lib/thor/nested_context.rb +2 -2
  156. data/bundler/lib/bundler/vendor/thor/lib/thor/parser/argument.rb +20 -1
  157. data/bundler/lib/bundler/vendor/thor/lib/thor/parser/arguments.rb +33 -17
  158. data/bundler/lib/bundler/vendor/thor/lib/thor/parser/option.rb +27 -8
  159. data/bundler/lib/bundler/vendor/thor/lib/thor/parser/options.rb +44 -6
  160. data/bundler/lib/bundler/vendor/thor/lib/thor/rake_compat.rb +2 -2
  161. data/bundler/lib/bundler/vendor/thor/lib/thor/runner.rb +40 -30
  162. data/bundler/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +26 -150
  163. data/bundler/lib/bundler/vendor/thor/lib/thor/shell/color.rb +4 -46
  164. data/bundler/lib/bundler/vendor/thor/lib/thor/shell/column_printer.rb +29 -0
  165. data/bundler/lib/bundler/vendor/thor/lib/thor/shell/html.rb +3 -45
  166. data/bundler/lib/bundler/vendor/thor/lib/thor/shell/lcs_diff.rb +49 -0
  167. data/bundler/lib/bundler/vendor/thor/lib/thor/shell/table_printer.rb +134 -0
  168. data/bundler/lib/bundler/vendor/thor/lib/thor/shell/terminal.rb +42 -0
  169. data/bundler/lib/bundler/vendor/thor/lib/thor/shell/wrapped_printer.rb +38 -0
  170. data/bundler/lib/bundler/vendor/thor/lib/thor/shell.rb +1 -1
  171. data/bundler/lib/bundler/vendor/thor/lib/thor/util.rb +8 -7
  172. data/bundler/lib/bundler/vendor/thor/lib/thor/version.rb +1 -1
  173. data/bundler/lib/bundler/vendor/thor/lib/thor.rb +155 -8
  174. data/bundler/lib/bundler/vendor/tsort/lib/tsort.rb +3 -0
  175. data/bundler/lib/bundler/vendor/uri/lib/uri/common.rb +256 -132
  176. data/bundler/lib/bundler/vendor/uri/lib/uri/generic.rb +1 -0
  177. data/bundler/lib/bundler/vendor/uri/lib/uri/rfc3986_parser.rb +95 -31
  178. data/bundler/lib/bundler/vendor/uri/lib/uri/version.rb +1 -1
  179. data/bundler/lib/bundler/vendored_net_http.rb +8 -0
  180. data/bundler/lib/bundler/vendored_persistent.rb +0 -4
  181. data/bundler/lib/bundler/vendored_timeout.rb +8 -0
  182. data/bundler/lib/bundler/version.rb +1 -1
  183. data/bundler/lib/bundler/vlad.rb +1 -1
  184. data/bundler/lib/bundler/yaml_serializer.rb +9 -4
  185. data/bundler/lib/bundler.rb +38 -35
  186. data/lib/rubygems/available_set.rb +4 -4
  187. data/lib/rubygems/basic_specification.rb +35 -37
  188. data/lib/rubygems/bundler_version_finder.rb +4 -4
  189. data/lib/rubygems/ci_detector.rb +75 -0
  190. data/lib/rubygems/command.rb +15 -17
  191. data/lib/rubygems/command_manager.rb +5 -4
  192. data/lib/rubygems/commands/build_command.rb +2 -2
  193. data/lib/rubygems/commands/cert_command.rb +2 -3
  194. data/lib/rubygems/commands/check_command.rb +4 -4
  195. data/lib/rubygems/commands/cleanup_command.rb +12 -14
  196. data/lib/rubygems/commands/contents_command.rb +5 -5
  197. data/lib/rubygems/commands/dependency_command.rb +4 -5
  198. data/lib/rubygems/commands/environment_command.rb +3 -5
  199. data/lib/rubygems/commands/exec_command.rb +1 -1
  200. data/lib/rubygems/commands/fetch_command.rb +2 -2
  201. data/lib/rubygems/commands/generate_index_command.rb +39 -74
  202. data/lib/rubygems/commands/help_command.rb +4 -4
  203. data/lib/rubygems/commands/info_command.rb +2 -2
  204. data/lib/rubygems/commands/install_command.rb +8 -16
  205. data/lib/rubygems/commands/list_command.rb +2 -2
  206. data/lib/rubygems/commands/lock_command.rb +1 -1
  207. data/lib/rubygems/commands/open_command.rb +1 -1
  208. data/lib/rubygems/commands/owner_command.rb +1 -1
  209. data/lib/rubygems/commands/pristine_command.rb +13 -15
  210. data/lib/rubygems/commands/push_command.rb +2 -2
  211. data/lib/rubygems/commands/query_command.rb +4 -5
  212. data/lib/rubygems/commands/rdoc_command.rb +2 -2
  213. data/lib/rubygems/commands/search_command.rb +2 -2
  214. data/lib/rubygems/commands/setup_command.rb +33 -36
  215. data/lib/rubygems/commands/sources_command.rb +12 -12
  216. data/lib/rubygems/commands/specification_command.rb +10 -10
  217. data/lib/rubygems/commands/stale_command.rb +1 -1
  218. data/lib/rubygems/commands/uninstall_command.rb +13 -14
  219. data/lib/rubygems/commands/unpack_command.rb +7 -7
  220. data/lib/rubygems/commands/update_command.rb +11 -13
  221. data/lib/rubygems/commands/which_command.rb +1 -1
  222. data/lib/rubygems/commands/yank_command.rb +1 -1
  223. data/lib/rubygems/compatibility.rb +5 -6
  224. data/lib/rubygems/config_file.rb +7 -7
  225. data/lib/rubygems/core_ext/kernel_gem.rb +0 -2
  226. data/lib/rubygems/core_ext/kernel_require.rb +20 -49
  227. data/lib/rubygems/core_ext/kernel_warn.rb +1 -1
  228. data/lib/rubygems/core_ext/tcpsocket_init.rb +1 -1
  229. data/lib/rubygems/defaults.rb +15 -3
  230. data/lib/rubygems/dependency.rb +12 -14
  231. data/lib/rubygems/dependency_installer.rb +30 -31
  232. data/lib/rubygems/dependency_list.rb +1 -1
  233. data/lib/rubygems/deprecate.rb +16 -15
  234. data/lib/rubygems/doctor.rb +6 -6
  235. data/lib/rubygems/errors.rb +2 -6
  236. data/lib/rubygems/exceptions.rb +2 -1
  237. data/lib/rubygems/ext/builder.rb +15 -10
  238. data/lib/rubygems/ext/cargo_builder.rb +5 -5
  239. data/lib/rubygems/ext/ext_conf_builder.rb +2 -4
  240. data/lib/rubygems/ext/rake_builder.rb +1 -1
  241. data/lib/rubygems/gem_runner.rb +4 -4
  242. data/lib/rubygems/gemcutter_utilities/webauthn_listener/response.rb +3 -3
  243. data/lib/rubygems/gemcutter_utilities/webauthn_poller.rb +3 -3
  244. data/lib/rubygems/gemcutter_utilities.rb +18 -19
  245. data/lib/rubygems/install_update_options.rb +18 -19
  246. data/lib/rubygems/installer.rb +66 -45
  247. data/lib/rubygems/installer_uninstaller_utils.rb +0 -2
  248. data/lib/rubygems/local_remote_options.rb +8 -11
  249. data/lib/rubygems/name_tuple.rb +7 -9
  250. data/lib/rubygems/net/http.rb +3 -0
  251. data/lib/rubygems/net-http/LICENSE.txt +22 -0
  252. data/lib/rubygems/net-http/lib/net/http/backward.rb +40 -0
  253. data/lib/rubygems/net-http/lib/net/http/exceptions.rb +34 -0
  254. data/lib/rubygems/net-http/lib/net/http/generic_request.rb +414 -0
  255. data/lib/rubygems/net-http/lib/net/http/header.rb +981 -0
  256. data/lib/rubygems/net-http/lib/net/http/proxy_delta.rb +17 -0
  257. data/lib/rubygems/net-http/lib/net/http/request.rb +88 -0
  258. data/lib/rubygems/net-http/lib/net/http/requests.rb +425 -0
  259. data/lib/rubygems/net-http/lib/net/http/response.rb +738 -0
  260. data/lib/rubygems/net-http/lib/net/http/responses.rb +1174 -0
  261. data/lib/rubygems/net-http/lib/net/http/status.rb +84 -0
  262. data/lib/rubygems/net-http/lib/net/http.rb +2496 -0
  263. data/lib/rubygems/net-http/lib/net/https.rb +23 -0
  264. data/lib/rubygems/net-protocol/LICENSE.txt +22 -0
  265. data/lib/rubygems/net-protocol/lib/net/protocol.rb +544 -0
  266. data/lib/rubygems/optparse/lib/optparse.rb +39 -17
  267. data/lib/rubygems/package/digest_io.rb +1 -1
  268. data/lib/rubygems/package/old.rb +2 -2
  269. data/lib/rubygems/package/tar_header.rb +45 -39
  270. data/lib/rubygems/package/tar_reader/entry.rb +5 -4
  271. data/lib/rubygems/package/tar_reader.rb +14 -5
  272. data/lib/rubygems/package/tar_writer.rb +20 -18
  273. data/lib/rubygems/package.rb +28 -27
  274. data/lib/rubygems/package_task.rb +2 -2
  275. data/lib/rubygems/path_support.rb +10 -11
  276. data/lib/rubygems/platform.rb +65 -48
  277. data/lib/rubygems/query_utils.rb +7 -9
  278. data/lib/rubygems/remote_fetcher.rb +17 -17
  279. data/lib/rubygems/request/connection_pools.rb +3 -3
  280. data/lib/rubygems/request.rb +20 -17
  281. data/lib/rubygems/request_set/gem_dependency_api.rb +120 -123
  282. data/lib/rubygems/request_set/lockfile/parser.rb +9 -9
  283. data/lib/rubygems/request_set/lockfile/tokenizer.rb +20 -12
  284. data/lib/rubygems/request_set/lockfile.rb +6 -11
  285. data/lib/rubygems/request_set.rb +5 -5
  286. data/lib/rubygems/requirement.rb +7 -7
  287. data/lib/rubygems/resolv/LICENSE.txt +22 -0
  288. data/lib/rubygems/resolv/lib/resolv.rb +3387 -0
  289. data/lib/rubygems/resolver/activation_request.rb +1 -3
  290. data/lib/rubygems/resolver/api_set/gem_parser.rb +7 -3
  291. data/lib/rubygems/resolver/best_set.rb +1 -1
  292. data/lib/rubygems/resolver/composed_set.rb +1 -1
  293. data/lib/rubygems/resolver/conflict.rb +4 -12
  294. data/lib/rubygems/resolver/index_set.rb +4 -4
  295. data/lib/rubygems/resolver/index_specification.rb +2 -2
  296. data/lib/rubygems/resolver/installer_set.rb +5 -6
  297. data/lib/rubygems/resolver/lock_set.rb +1 -1
  298. data/lib/rubygems/resolver.rb +6 -13
  299. data/lib/rubygems/s3_uri_signer.rb +6 -6
  300. data/lib/rubygems/safe_marshal/elements.rb +138 -0
  301. data/lib/rubygems/safe_marshal/reader.rb +306 -0
  302. data/lib/rubygems/safe_marshal/visitors/stream_printer.rb +31 -0
  303. data/lib/rubygems/safe_marshal/visitors/to_ruby.rb +385 -0
  304. data/lib/rubygems/safe_marshal/visitors/visitor.rb +74 -0
  305. data/lib/rubygems/safe_marshal.rb +74 -0
  306. data/lib/rubygems/safe_yaml.rb +5 -28
  307. data/lib/rubygems/security/policies.rb +36 -38
  308. data/lib/rubygems/security/policy.rb +7 -11
  309. data/lib/rubygems/security/signer.rb +1 -1
  310. data/lib/rubygems/security/trust_dir.rb +4 -4
  311. data/lib/rubygems/security.rb +8 -22
  312. data/lib/rubygems/source/git.rb +1 -3
  313. data/lib/rubygems/source/installed.rb +0 -2
  314. data/lib/rubygems/source/local.rb +7 -9
  315. data/lib/rubygems/source/lock.rb +1 -3
  316. data/lib/rubygems/source/specific_file.rb +0 -1
  317. data/lib/rubygems/source/vendor.rb +0 -2
  318. data/lib/rubygems/source.rb +12 -12
  319. data/lib/rubygems/source_list.rb +5 -5
  320. data/lib/rubygems/spec_fetcher.rb +31 -31
  321. data/lib/rubygems/specification.rb +145 -150
  322. data/lib/rubygems/specification_policy.rb +61 -31
  323. data/lib/rubygems/stub_specification.rb +4 -5
  324. data/lib/rubygems/text.rb +1 -2
  325. data/lib/rubygems/timeout/LICENSE.txt +22 -0
  326. data/lib/rubygems/timeout/lib/timeout.rb +199 -0
  327. data/lib/rubygems/timeout.rb +3 -0
  328. data/lib/rubygems/tsort/lib/tsort.rb +3 -0
  329. data/lib/rubygems/uninstaller.rb +9 -11
  330. data/lib/rubygems/update_suggestion.rb +5 -18
  331. data/lib/rubygems/uri_formatter.rb +1 -1
  332. data/lib/rubygems/user_interaction.rb +17 -23
  333. data/lib/rubygems/util/licenses.rb +113 -35
  334. data/lib/rubygems/util/list.rb +3 -1
  335. data/lib/rubygems/util.rb +2 -4
  336. data/lib/rubygems/validator.rb +6 -4
  337. data/lib/rubygems/version.rb +35 -29
  338. data/lib/rubygems/version_option.rb +2 -5
  339. data/lib/rubygems/yaml_serializer.rb +9 -4
  340. data/lib/rubygems.rb +42 -42
  341. data/rubygems-update.gemspec +4 -4
  342. data/setup.rb +2 -2
  343. metadata +43 -225
  344. data/lib/rubygems/indexer.rb +0 -428
  345. data/lib/rubygems/mock_gem_ui.rb +0 -86
  346. data/test/rubygems/alternate_cert.pem +0 -19
  347. data/test/rubygems/alternate_cert_32.pem +0 -19
  348. data/test/rubygems/alternate_key.pem +0 -27
  349. data/test/rubygems/bad_rake.rb +0 -3
  350. data/test/rubygems/bundler_test_gem.rb +0 -424
  351. data/test/rubygems/ca_cert.pem +0 -77
  352. data/test/rubygems/child_cert.pem +0 -19
  353. data/test/rubygems/child_cert_32.pem +0 -19
  354. data/test/rubygems/child_key.pem +0 -27
  355. data/test/rubygems/client.pem +0 -107
  356. data/test/rubygems/data/excon-0.7.7.gemspec.rz +0 -0
  357. data/test/rubygems/data/gem-private_key.pem +0 -27
  358. data/test/rubygems/data/gem-public_cert.pem +0 -20
  359. data/test/rubygems/data/null-required-ruby-version.gemspec.rz +0 -0
  360. data/test/rubygems/data/null-required-rubygems-version.gemspec.rz +0 -0
  361. data/test/rubygems/data/pry-0.4.7.gemspec.rz +0 -0
  362. data/test/rubygems/encrypted_private_key.pem +0 -30
  363. data/test/rubygems/expired_cert.pem +0 -19
  364. data/test/rubygems/fake_certlib/openssl.rb +0 -9
  365. data/test/rubygems/foo/discover.rb +0 -1
  366. data/test/rubygems/future_cert.pem +0 -19
  367. data/test/rubygems/future_cert_32.pem +0 -19
  368. data/test/rubygems/good_rake.rb +0 -3
  369. data/test/rubygems/grandchild_cert.pem +0 -19
  370. data/test/rubygems/grandchild_cert_32.pem +0 -19
  371. data/test/rubygems/grandchild_key.pem +0 -27
  372. data/test/rubygems/helper.rb +0 -1649
  373. data/test/rubygems/installer_test_case.rb +0 -248
  374. data/test/rubygems/invalid_client.pem +0 -49
  375. data/test/rubygems/invalid_issuer_cert.pem +0 -20
  376. data/test/rubygems/invalid_issuer_cert_32.pem +0 -20
  377. data/test/rubygems/invalid_key.pem +0 -27
  378. data/test/rubygems/invalid_signer_cert.pem +0 -19
  379. data/test/rubygems/invalid_signer_cert_32.pem +0 -19
  380. data/test/rubygems/invalidchild_cert.pem +0 -19
  381. data/test/rubygems/invalidchild_cert_32.pem +0 -19
  382. data/test/rubygems/invalidchild_key.pem +0 -27
  383. data/test/rubygems/multifactor_auth_utilities.rb +0 -111
  384. data/test/rubygems/package/tar_test_case.rb +0 -175
  385. data/test/rubygems/packages/Bluebie-legs-0.6.2.gem +0 -0
  386. data/test/rubygems/packages/ascii_binder-0.1.10.1.gem +0 -0
  387. data/test/rubygems/packages/ill-formatted-platform-1.0.0.10.gem +0 -0
  388. data/test/rubygems/plugin/exception/rubygems_plugin.rb +0 -4
  389. data/test/rubygems/plugin/load/rubygems_plugin.rb +0 -5
  390. data/test/rubygems/plugin/standarderror/rubygems_plugin.rb +0 -4
  391. data/test/rubygems/private3072_key.pem +0 -40
  392. data/test/rubygems/private_ec_key.pem +0 -9
  393. data/test/rubygems/private_key.pem +0 -27
  394. data/test/rubygems/public3072_cert.pem +0 -25
  395. data/test/rubygems/public_cert.pem +0 -20
  396. data/test/rubygems/public_cert_32.pem +0 -19
  397. data/test/rubygems/public_key.pem +0 -9
  398. data/test/rubygems/rubygems/commands/crash_command.rb +0 -5
  399. data/test/rubygems/rubygems_plugin.rb +0 -24
  400. data/test/rubygems/sff/discover.rb +0 -1
  401. data/test/rubygems/simple_gem.rb +0 -68
  402. data/test/rubygems/specifications/bar-0.0.2.gemspec +0 -9
  403. data/test/rubygems/specifications/foo-0.0.1-x86-mswin32.gemspec +0 -0
  404. data/test/rubygems/specifications/rubyforge-0.0.1.gemspec +0 -14
  405. data/test/rubygems/ssl_cert.pem +0 -80
  406. data/test/rubygems/ssl_key.pem +0 -27
  407. data/test/rubygems/test_bundled_ca.rb +0 -61
  408. data/test/rubygems/test_config.rb +0 -28
  409. data/test/rubygems/test_deprecate.rb +0 -158
  410. data/test/rubygems/test_exit.rb +0 -17
  411. data/test/rubygems/test_gem.rb +0 -1799
  412. data/test/rubygems/test_gem_available_set.rb +0 -130
  413. data/test/rubygems/test_gem_bundler_version_finder.rb +0 -127
  414. data/test/rubygems/test_gem_command.rb +0 -403
  415. data/test/rubygems/test_gem_command_manager.rb +0 -400
  416. data/test/rubygems/test_gem_commands_build_command.rb +0 -739
  417. data/test/rubygems/test_gem_commands_cert_command.rb +0 -866
  418. data/test/rubygems/test_gem_commands_check_command.rb +0 -68
  419. data/test/rubygems/test_gem_commands_cleanup_command.rb +0 -292
  420. data/test/rubygems/test_gem_commands_contents_command.rb +0 -271
  421. data/test/rubygems/test_gem_commands_dependency_command.rb +0 -228
  422. data/test/rubygems/test_gem_commands_environment_command.rb +0 -169
  423. data/test/rubygems/test_gem_commands_exec_command.rb +0 -857
  424. data/test/rubygems/test_gem_commands_fetch_command.rb +0 -258
  425. data/test/rubygems/test_gem_commands_generate_index_command.rb +0 -81
  426. data/test/rubygems/test_gem_commands_help_command.rb +0 -94
  427. data/test/rubygems/test_gem_commands_info_command.rb +0 -70
  428. data/test/rubygems/test_gem_commands_install_command.rb +0 -1573
  429. data/test/rubygems/test_gem_commands_list_command.rb +0 -33
  430. data/test/rubygems/test_gem_commands_lock_command.rb +0 -67
  431. data/test/rubygems/test_gem_commands_mirror.rb +0 -20
  432. data/test/rubygems/test_gem_commands_open_command.rb +0 -101
  433. data/test/rubygems/test_gem_commands_outdated_command.rb +0 -50
  434. data/test/rubygems/test_gem_commands_owner_command.rb +0 -503
  435. data/test/rubygems/test_gem_commands_pristine_command.rb +0 -708
  436. data/test/rubygems/test_gem_commands_push_command.rb +0 -603
  437. data/test/rubygems/test_gem_commands_query_command.rb +0 -858
  438. data/test/rubygems/test_gem_commands_search_command.rb +0 -16
  439. data/test/rubygems/test_gem_commands_server_command.rb +0 -20
  440. data/test/rubygems/test_gem_commands_setup_command.rb +0 -474
  441. data/test/rubygems/test_gem_commands_signin_command.rb +0 -259
  442. data/test/rubygems/test_gem_commands_signout_command.rb +0 -30
  443. data/test/rubygems/test_gem_commands_sources_command.rb +0 -534
  444. data/test/rubygems/test_gem_commands_specification_command.rb +0 -277
  445. data/test/rubygems/test_gem_commands_stale_command.rb +0 -43
  446. data/test/rubygems/test_gem_commands_uninstall_command.rb +0 -522
  447. data/test/rubygems/test_gem_commands_unpack_command.rb +0 -224
  448. data/test/rubygems/test_gem_commands_update_command.rb +0 -836
  449. data/test/rubygems/test_gem_commands_which_command.rb +0 -85
  450. data/test/rubygems/test_gem_commands_yank_command.rb +0 -299
  451. data/test/rubygems/test_gem_config_file.rb +0 -551
  452. data/test/rubygems/test_gem_dependency.rb +0 -398
  453. data/test/rubygems/test_gem_dependency_installer.rb +0 -1190
  454. data/test/rubygems/test_gem_dependency_list.rb +0 -265
  455. data/test/rubygems/test_gem_dependency_resolution_error.rb +0 -27
  456. data/test/rubygems/test_gem_doctor.rb +0 -195
  457. data/test/rubygems/test_gem_ext_builder.rb +0 -337
  458. data/test/rubygems/test_gem_ext_cargo_builder/custom_name/.gitignore +0 -1
  459. data/test/rubygems/test_gem_ext_cargo_builder/custom_name/custom_name.gemspec +0 -10
  460. data/test/rubygems/test_gem_ext_cargo_builder/custom_name/ext/custom_name_lib/Cargo.lock +0 -249
  461. data/test/rubygems/test_gem_ext_cargo_builder/custom_name/ext/custom_name_lib/Cargo.toml +0 -10
  462. data/test/rubygems/test_gem_ext_cargo_builder/custom_name/ext/custom_name_lib/src/lib.rs +0 -27
  463. data/test/rubygems/test_gem_ext_cargo_builder/custom_name/lib/custom_name.rb +0 -3
  464. data/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/.gitignore +0 -1
  465. data/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.lock +0 -249
  466. data/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.toml +0 -10
  467. data/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/rust_ruby_example.gemspec +0 -10
  468. data/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/src/lib.rs +0 -51
  469. data/test/rubygems/test_gem_ext_cargo_builder.rb +0 -167
  470. data/test/rubygems/test_gem_ext_cargo_builder_link_flag_converter.rb +0 -34
  471. data/test/rubygems/test_gem_ext_cargo_builder_unit.rb +0 -60
  472. data/test/rubygems/test_gem_ext_cmake_builder.rb +0 -84
  473. data/test/rubygems/test_gem_ext_configure_builder.rb +0 -80
  474. data/test/rubygems/test_gem_ext_ext_conf_builder.rb +0 -229
  475. data/test/rubygems/test_gem_ext_rake_builder.rb +0 -113
  476. data/test/rubygems/test_gem_gem_runner.rb +0 -119
  477. data/test/rubygems/test_gem_gemcutter_utilities.rb +0 -361
  478. data/test/rubygems/test_gem_impossible_dependencies_error.rb +0 -60
  479. data/test/rubygems/test_gem_indexer.rb +0 -381
  480. data/test/rubygems/test_gem_install_update_options.rb +0 -208
  481. data/test/rubygems/test_gem_installer.rb +0 -2512
  482. data/test/rubygems/test_gem_local_remote_options.rb +0 -133
  483. data/test/rubygems/test_gem_name_tuple.rb +0 -43
  484. data/test/rubygems/test_gem_package.rb +0 -1306
  485. data/test/rubygems/test_gem_package_old.rb +0 -91
  486. data/test/rubygems/test_gem_package_tar_header.rb +0 -226
  487. data/test/rubygems/test_gem_package_tar_reader.rb +0 -135
  488. data/test/rubygems/test_gem_package_tar_reader_entry.rb +0 -350
  489. data/test/rubygems/test_gem_package_tar_writer.rb +0 -331
  490. data/test/rubygems/test_gem_package_task.rb +0 -118
  491. data/test/rubygems/test_gem_path_support.rb +0 -139
  492. data/test/rubygems/test_gem_platform.rb +0 -497
  493. data/test/rubygems/test_gem_rdoc.rb +0 -137
  494. data/test/rubygems/test_gem_remote_fetcher.rb +0 -1227
  495. data/test/rubygems/test_gem_request.rb +0 -547
  496. data/test/rubygems/test_gem_request_connection_pools.rb +0 -152
  497. data/test/rubygems/test_gem_request_set.rb +0 -672
  498. data/test/rubygems/test_gem_request_set_gem_dependency_api.rb +0 -853
  499. data/test/rubygems/test_gem_request_set_lockfile.rb +0 -469
  500. data/test/rubygems/test_gem_request_set_lockfile_parser.rb +0 -544
  501. data/test/rubygems/test_gem_request_set_lockfile_tokenizer.rb +0 -307
  502. data/test/rubygems/test_gem_requirement.rb +0 -505
  503. data/test/rubygems/test_gem_resolver.rb +0 -859
  504. data/test/rubygems/test_gem_resolver_activation_request.rb +0 -43
  505. data/test/rubygems/test_gem_resolver_api_set.rb +0 -210
  506. data/test/rubygems/test_gem_resolver_api_specification.rb +0 -167
  507. data/test/rubygems/test_gem_resolver_best_set.rb +0 -159
  508. data/test/rubygems/test_gem_resolver_composed_set.rb +0 -44
  509. data/test/rubygems/test_gem_resolver_conflict.rb +0 -82
  510. data/test/rubygems/test_gem_resolver_dependency_request.rb +0 -83
  511. data/test/rubygems/test_gem_resolver_git_set.rb +0 -188
  512. data/test/rubygems/test_gem_resolver_git_specification.rb +0 -114
  513. data/test/rubygems/test_gem_resolver_index_set.rb +0 -88
  514. data/test/rubygems/test_gem_resolver_index_specification.rb +0 -93
  515. data/test/rubygems/test_gem_resolver_installed_specification.rb +0 -47
  516. data/test/rubygems/test_gem_resolver_installer_set.rb +0 -320
  517. data/test/rubygems/test_gem_resolver_local_specification.rb +0 -44
  518. data/test/rubygems/test_gem_resolver_lock_set.rb +0 -62
  519. data/test/rubygems/test_gem_resolver_lock_specification.rb +0 -98
  520. data/test/rubygems/test_gem_resolver_requirement_list.rb +0 -19
  521. data/test/rubygems/test_gem_resolver_specification.rb +0 -63
  522. data/test/rubygems/test_gem_resolver_vendor_set.rb +0 -82
  523. data/test/rubygems/test_gem_resolver_vendor_specification.rb +0 -82
  524. data/test/rubygems/test_gem_security.rb +0 -341
  525. data/test/rubygems/test_gem_security_policy.rb +0 -535
  526. data/test/rubygems/test_gem_security_signer.rb +0 -218
  527. data/test/rubygems/test_gem_security_trust_dir.rb +0 -99
  528. data/test/rubygems/test_gem_silent_ui.rb +0 -123
  529. data/test/rubygems/test_gem_source.rb +0 -254
  530. data/test/rubygems/test_gem_source_fetch_problem.rb +0 -37
  531. data/test/rubygems/test_gem_source_git.rb +0 -310
  532. data/test/rubygems/test_gem_source_installed.rb +0 -35
  533. data/test/rubygems/test_gem_source_list.rb +0 -119
  534. data/test/rubygems/test_gem_source_local.rb +0 -107
  535. data/test/rubygems/test_gem_source_lock.rb +0 -113
  536. data/test/rubygems/test_gem_source_specific_file.rb +0 -76
  537. data/test/rubygems/test_gem_source_subpath_problem.rb +0 -50
  538. data/test/rubygems/test_gem_source_vendor.rb +0 -30
  539. data/test/rubygems/test_gem_spec_fetcher.rb +0 -338
  540. data/test/rubygems/test_gem_specification.rb +0 -3856
  541. data/test/rubygems/test_gem_stream_ui.rb +0 -255
  542. data/test/rubygems/test_gem_stub_specification.rb +0 -278
  543. data/test/rubygems/test_gem_text.rb +0 -103
  544. data/test/rubygems/test_gem_uninstaller.rb +0 -675
  545. data/test/rubygems/test_gem_unsatisfiable_dependency_error.rb +0 -31
  546. data/test/rubygems/test_gem_update_suggestion.rb +0 -209
  547. data/test/rubygems/test_gem_uri.rb +0 -41
  548. data/test/rubygems/test_gem_uri_formatter.rb +0 -27
  549. data/test/rubygems/test_gem_util.rb +0 -91
  550. data/test/rubygems/test_gem_validator.rb +0 -42
  551. data/test/rubygems/test_gem_version.rb +0 -305
  552. data/test/rubygems/test_gem_version_option.rb +0 -165
  553. data/test/rubygems/test_kernel.rb +0 -124
  554. data/test/rubygems/test_project_sanity.rb +0 -49
  555. data/test/rubygems/test_remote_fetch_error.rb +0 -20
  556. data/test/rubygems/test_require.rb +0 -732
  557. data/test/rubygems/test_rubygems.rb +0 -76
  558. data/test/rubygems/test_webauthn_listener.rb +0 -143
  559. data/test/rubygems/test_webauthn_listener_response.rb +0 -93
  560. data/test/rubygems/test_webauthn_poller.rb +0 -124
  561. data/test/rubygems/utilities.rb +0 -436
  562. data/test/rubygems/wrong_key_cert.pem +0 -19
  563. data/test/rubygems/wrong_key_cert_32.pem +0 -19
  564. data/test/test_changelog_generator.rb +0 -17
@@ -1,603 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "helper"
4
- require_relative "multifactor_auth_utilities"
5
- require "rubygems/commands/push_command"
6
- require "rubygems/config_file"
7
-
8
- class TestGemCommandsPushCommand < Gem::TestCase
9
- def setup
10
- super
11
-
12
- credential_setup
13
-
14
- ENV["RUBYGEMS_HOST"] = nil
15
- Gem.host = Gem::DEFAULT_HOST
16
- Gem.configuration.disable_default_gem_server = false
17
-
18
- @gems_dir = File.join @tempdir, "gems"
19
- @cache_dir = File.join @gemhome, "cache"
20
-
21
- FileUtils.mkdir @gems_dir
22
-
23
- Gem.configuration.rubygems_api_key =
24
- "ed244fbf2b1a52e012da8616c512fa47f9aa5250"
25
-
26
- @spec, @path = util_gem "freewill", "1.0.0"
27
- @host = "https://rubygems.example"
28
- @api_key = Gem.configuration.rubygems_api_key
29
-
30
- @fetcher = Gem::MultifactorAuthFetcher.new
31
- Gem::RemoteFetcher.fetcher = @fetcher
32
-
33
- @cmd = Gem::Commands::PushCommand.new
34
-
35
- singleton_gem_class.class_eval do
36
- alias_method :orig_latest_rubygems_version, :latest_rubygems_version
37
-
38
- def latest_rubygems_version
39
- Gem.rubygems_version
40
- end
41
- end
42
- end
43
-
44
- def teardown
45
- credential_teardown
46
-
47
- super
48
-
49
- singleton_gem_class.class_eval do
50
- remove_method :latest_rubygems_version
51
- alias_method :latest_rubygems_version, :orig_latest_rubygems_version
52
- end
53
- end
54
-
55
- def send_battery
56
- use_ui @ui do
57
- @cmd.instance_variable_set :@host, @host
58
- @cmd.send_gem(@path)
59
- end
60
-
61
- assert_match %r{Pushing gem to #{@host}...}, @ui.output
62
-
63
- assert_equal Net::HTTP::Post, @fetcher.last_request.class
64
- assert_equal Gem.read_binary(@path), @fetcher.last_request.body
65
- assert_equal File.size(@path), @fetcher.last_request["Content-Length"].to_i
66
- assert_equal "application/octet-stream", @fetcher.last_request["Content-Type"]
67
- assert_equal @api_key, @fetcher.last_request["Authorization"]
68
-
69
- assert_match @response, @ui.output
70
- end
71
-
72
- def test_execute
73
- @response = "Successfully registered gem: freewill (1.0.0)"
74
- @fetcher.data["#{Gem.host}/api/v1/gems"] = HTTPResponseFactory.create(body: @response, code: 200, msg: "OK")
75
-
76
- @cmd.options[:args] = [@path]
77
-
78
- @cmd.execute
79
-
80
- assert_equal Net::HTTP::Post, @fetcher.last_request.class
81
- assert_equal Gem.read_binary(@path), @fetcher.last_request.body
82
- assert_equal "application/octet-stream",
83
- @fetcher.last_request["Content-Type"]
84
- end
85
-
86
- def test_execute_host
87
- host = "https://other.example"
88
-
89
- @response = "Successfully registered gem: freewill (1.0.0)"
90
- @fetcher.data["#{host}/api/v1/gems"] = HTTPResponseFactory.create(body: @response, code: 200, msg: "OK")
91
- @fetcher.data["#{Gem.host}/api/v1/gems"] =
92
- ["fail", 500, "Internal Server Error"]
93
-
94
- @cmd.options[:host] = host
95
- @cmd.options[:args] = [@path]
96
-
97
- @cmd.execute
98
-
99
- assert_equal Net::HTTP::Post, @fetcher.last_request.class
100
- assert_equal Gem.read_binary(@path), @fetcher.last_request.body
101
- assert_equal "application/octet-stream",
102
- @fetcher.last_request["Content-Type"]
103
- end
104
-
105
- def test_execute_allowed_push_host
106
- @spec, @path = util_gem "freebird", "1.0.1" do |spec|
107
- spec.metadata["allowed_push_host"] = "https://privategemserver.example"
108
- end
109
-
110
- @response = "Successfully registered gem: freewill (1.0.0)"
111
- @fetcher.data["#{@spec.metadata["allowed_push_host"]}/api/v1/gems"] = HTTPResponseFactory.create(body: @response, code: 200, msg: "OK")
112
- @fetcher.data["#{Gem.host}/api/v1/gems"] =
113
- ["fail", 500, "Internal Server Error"]
114
-
115
- @cmd.options[:args] = [@path]
116
-
117
- @cmd.execute
118
-
119
- assert_equal Net::HTTP::Post, @fetcher.last_request.class
120
- assert_equal Gem.read_binary(@path), @fetcher.last_request.body
121
- assert_equal "application/octet-stream",
122
- @fetcher.last_request["Content-Type"]
123
- end
124
-
125
- def test_sending_when_default_host_disabled
126
- Gem.configuration.disable_default_gem_server = true
127
- response = "You must specify a gem server"
128
-
129
- assert_raise Gem::MockGemUi::TermError do
130
- use_ui @ui do
131
- @cmd.send_gem(@path)
132
- end
133
- end
134
-
135
- assert_match response, @ui.error
136
- end
137
-
138
- def test_sending_when_default_host_disabled_with_override
139
- ENV["RUBYGEMS_HOST"] = @host
140
- Gem.configuration.disable_default_gem_server = true
141
- @response = "Successfully registered gem: freewill (1.0.0)"
142
- @fetcher.data["#{@host}/api/v1/gems"] = HTTPResponseFactory.create(body: @response, code: 200, msg: "OK")
143
-
144
- send_battery
145
- end
146
-
147
- def test_sending_gem_to_metadata_host
148
- @host = "http://privategemserver.example"
149
-
150
- @spec, @path = util_gem "freebird", "1.0.1" do |spec|
151
- spec.metadata["default_gem_server"] = @host
152
- end
153
-
154
- @api_key = "EYKEY"
155
-
156
- keys = {
157
- :rubygems_api_key => "KEY",
158
- @host => @api_key,
159
- }
160
-
161
- File.open Gem.configuration.credentials_path, "w" do |f|
162
- f.write Gem::ConfigFile.dump_with_rubygems_yaml(keys)
163
- end
164
- Gem.configuration.load_api_keys
165
-
166
- FileUtils.rm Gem.configuration.credentials_path
167
-
168
- @response = "Successfully registered gem: freebird (1.0.1)"
169
- @fetcher.data["#{@host}/api/v1/gems"] = HTTPResponseFactory.create(body: @response, code: 200, msg: "OK")
170
-
171
- send_battery
172
- end
173
-
174
- def test_sending_gem
175
- @response = "Successfully registered gem: freewill (1.0.0)"
176
- @fetcher.data["#{@host}/api/v1/gems"] = HTTPResponseFactory.create(body: @response, code: 200, msg: "OK")
177
-
178
- send_battery
179
- end
180
-
181
- def test_sending_gem_to_allowed_push_host
182
- @host = "http://privategemserver.example"
183
-
184
- @spec, @path = util_gem "freebird", "1.0.1" do |spec|
185
- spec.metadata["allowed_push_host"] = @host
186
- end
187
-
188
- @api_key = "PRIVKEY"
189
-
190
- keys = {
191
- :rubygems_api_key => "KEY",
192
- @host => @api_key,
193
- }
194
-
195
- File.open Gem.configuration.credentials_path, "w" do |f|
196
- f.write Gem::ConfigFile.dump_with_rubygems_yaml(keys)
197
- end
198
- Gem.configuration.load_api_keys
199
-
200
- FileUtils.rm Gem.configuration.credentials_path
201
-
202
- @response = "Successfully registered gem: freebird (1.0.1)"
203
- @fetcher.data["#{@host}/api/v1/gems"] = HTTPResponseFactory.create(body: @response, code: 200, msg: "OK")
204
- send_battery
205
- end
206
-
207
- def test_sending_gem_with_env_var_api_key
208
- @host = "http://privategemserver.example"
209
-
210
- @spec, @path = util_gem "freebird", "1.0.1" do |spec|
211
- spec.metadata["allowed_push_host"] = @host
212
- end
213
-
214
- @api_key = "PRIVKEY"
215
- ENV["GEM_HOST_API_KEY"] = "PRIVKEY"
216
-
217
- @response = "Successfully registered gem: freebird (1.0.1)"
218
- @fetcher.data["#{@host}/api/v1/gems"] = HTTPResponseFactory.create(body: @response, code: 200, msg: "OK")
219
- send_battery
220
- end
221
-
222
- def test_sending_gem_to_allowed_push_host_with_basic_credentials
223
- @sanitized_host = "http://privategemserver.example"
224
- @host = "http://user:password@privategemserver.example"
225
-
226
- @spec, @path = util_gem "freebird", "1.0.1" do |spec|
227
- spec.metadata["allowed_push_host"] = @sanitized_host
228
- end
229
-
230
- @api_key = "DOESNTMATTER"
231
-
232
- keys = {
233
- :rubygems_api_key => @api_key,
234
- }
235
-
236
- File.open Gem.configuration.credentials_path, "w" do |f|
237
- f.write Gem::ConfigFile.dump_with_rubygems_yaml(keys)
238
- end
239
- Gem.configuration.load_api_keys
240
-
241
- FileUtils.rm Gem.configuration.credentials_path
242
-
243
- @response = "Successfully registered gem: freebird (1.0.1)"
244
- @fetcher.data["#{@host}/api/v1/gems"] = HTTPResponseFactory.create(body: @response, code: 200, msg: "OK")
245
- send_battery
246
- end
247
-
248
- def test_sending_gem_to_disallowed_default_host
249
- @spec, @path = util_gem "freebird", "1.0.1" do |spec|
250
- spec.metadata["allowed_push_host"] = "https://privategemserver.example"
251
- end
252
-
253
- response = %(ERROR: "#{@host}" is not allowed by the gemspec, which only allows "https://privategemserver.example")
254
-
255
- assert_raise Gem::MockGemUi::TermError do
256
- send_battery
257
- end
258
-
259
- assert_match response, @ui.error
260
- end
261
-
262
- def test_sending_gem_to_disallowed_push_host
263
- @host = "https://anotherprivategemserver.example"
264
- push_host = "https://privategemserver.example"
265
-
266
- @spec, @path = util_gem "freebird", "1.0.1" do |spec|
267
- spec.metadata["allowed_push_host"] = push_host
268
- end
269
-
270
- @api_key = "PRIVKEY"
271
-
272
- keys = {
273
- :rubygems_api_key => "KEY",
274
- @host => @api_key,
275
- }
276
-
277
- File.open Gem.configuration.credentials_path, "w" do |f|
278
- f.write Gem::ConfigFile.dump_with_rubygems_yaml(keys)
279
- end
280
- Gem.configuration.load_api_keys
281
-
282
- FileUtils.rm Gem.configuration.credentials_path
283
-
284
- response = "ERROR: \"#{@host}\" is not allowed by the gemspec, which only allows \"#{push_host}\""
285
-
286
- assert_raise Gem::MockGemUi::TermError do
287
- send_battery
288
- end
289
-
290
- assert_match response, @ui.error
291
- end
292
-
293
- def test_sending_gem_defaulting_to_allowed_push_host
294
- host = "http://privategemserver.example"
295
-
296
- @spec, @path = util_gem "freebird", "1.0.1" do |spec|
297
- spec.metadata.delete("default_gem_server")
298
- spec.metadata["allowed_push_host"] = host
299
- end
300
-
301
- api_key = "PRIVKEY"
302
-
303
- keys = {
304
- host => api_key,
305
- }
306
-
307
- File.open Gem.configuration.credentials_path, "w" do |f|
308
- f.write Gem::ConfigFile.dump_with_rubygems_yaml(keys)
309
- end
310
- Gem.configuration.load_api_keys
311
-
312
- FileUtils.rm Gem.configuration.credentials_path
313
-
314
- @response = "Successfully registered gem: freebird (1.0.1)"
315
- @fetcher.data["#{host}/api/v1/gems"] = HTTPResponseFactory.create(body: @response, code: 200, msg: "OK")
316
-
317
- # do not set @host
318
- use_ui(@ui) { @cmd.send_gem(@path) }
319
-
320
- assert_match %r{Pushing gem to #{host}...}, @ui.output
321
-
322
- assert_equal Net::HTTP::Post, @fetcher.last_request.class
323
- assert_equal Gem.read_binary(@path), @fetcher.last_request.body
324
- assert_equal File.size(@path), @fetcher.last_request["Content-Length"].to_i
325
- assert_equal "application/octet-stream", @fetcher.last_request["Content-Type"]
326
- assert_equal api_key, @fetcher.last_request["Authorization"]
327
-
328
- assert_match @response, @ui.output
329
- end
330
-
331
- def test_sending_gem_to_host_permanent_redirect
332
- @host = "http://rubygems.example"
333
- redirected_uri = "https://rubygems.example/api/v1/gems"
334
- @fetcher.data["#{@host}/api/v1/gems"] = HTTPResponseFactory.create(
335
- body: "",
336
- code: 308,
337
- msg: "Permanent Redirect",
338
- headers: { "Location" => redirected_uri }
339
- )
340
-
341
- assert_raise Gem::MockGemUi::TermError do
342
- use_ui @ui do
343
- @cmd.instance_variable_set :@host, @host
344
- @cmd.send_gem(@path)
345
- end
346
- end
347
-
348
- response = "The request has redirected permanently to #{redirected_uri}. Please check your defined push host URL."
349
- assert_match response, @ui.output
350
- end
351
-
352
- def test_raises_error_with_no_arguments
353
- def @cmd.sign_in(*); end
354
- assert_raise Gem::CommandLineError do
355
- @cmd.execute
356
- end
357
- end
358
-
359
- def test_sending_gem_denied
360
- response = "You don't have permission to push to this gem"
361
- @fetcher.data["#{@host}/api/v1/gems"] = HTTPResponseFactory.create(body: response, code: 403, msg: "Forbidden")
362
- @cmd.instance_variable_set :@host, @host
363
-
364
- assert_raise Gem::MockGemUi::TermError do
365
- use_ui @ui do
366
- @cmd.send_gem(@path)
367
- end
368
- end
369
-
370
- assert_match response, @ui.output
371
- end
372
-
373
- def test_sending_gem_key
374
- @response = "Successfully registered gem: freewill (1.0.0)"
375
- @fetcher.data["#{@host}/api/v1/gems"] = HTTPResponseFactory.create(body: @response, code: 200, msg: "OK")
376
- File.open Gem.configuration.credentials_path, "a" do |f|
377
- f.write ":other: 701229f217cdf23b1344c7b4b54ca97"
378
- end
379
- Gem.configuration.load_api_keys
380
-
381
- @cmd.handle_options %w[-k other]
382
- @cmd.instance_variable_set :@host, @host
383
- @cmd.send_gem(@path)
384
-
385
- assert_equal Gem.configuration.api_keys[:other],
386
- @fetcher.last_request["Authorization"]
387
- end
388
-
389
- def test_otp_verified_success
390
- response_success = "Successfully registered gem: freewill (1.0.0)"
391
-
392
- @fetcher.respond_with_require_otp("#{Gem.host}/api/v1/gems", response_success)
393
-
394
- @otp_ui = Gem::MockGemUi.new "111111\n"
395
- use_ui @otp_ui do
396
- @cmd.send_gem(@path)
397
- end
398
-
399
- assert_match "You have enabled multi-factor authentication. Please enter OTP code.", @otp_ui.output
400
- assert_match "Code: ", @otp_ui.output
401
- assert_match response_success, @otp_ui.output
402
- assert_equal "111111", @fetcher.last_request["OTP"]
403
- end
404
-
405
- def test_otp_verified_failure
406
- response = "You have enabled multifactor authentication but your request doesn't have the correct OTP code. Please check it and retry."
407
- @fetcher.data["#{Gem.host}/api/v1/gems"] = HTTPResponseFactory.create(body: response, code: 401, msg: "Unauthorized")
408
- @fetcher.data["#{Gem.host}/api/v1/webauthn_verification"] =
409
- HTTPResponseFactory.create(body: "You don't have any security devices", code: 422, msg: "Unprocessable Entity")
410
-
411
- @otp_ui = Gem::MockGemUi.new "111111\n"
412
- assert_raise Gem::MockGemUi::TermError do
413
- use_ui @otp_ui do
414
- @cmd.send_gem(@path)
415
- end
416
- end
417
-
418
- assert_match response, @otp_ui.output
419
- assert_match "You have enabled multi-factor authentication. Please enter OTP code.", @otp_ui.output
420
- assert_match "Code: ", @otp_ui.output
421
- assert_equal "111111", @fetcher.last_request["OTP"]
422
- end
423
-
424
- def test_with_webauthn_enabled_success
425
- response_success = "Successfully registered gem: freewill (1.0.0)"
426
- server = Gem::MockTCPServer.new
427
-
428
- @fetcher.respond_with_require_otp("#{Gem.host}/api/v1/gems", response_success)
429
- @fetcher.respond_with_webauthn_url
430
-
431
- TCPServer.stub(:new, server) do
432
- Gem::GemcutterUtilities::WebauthnListener.stub(:listener_thread, Thread.new { Thread.current[:otp] = "Uvh6T57tkWuUnWYo" }) do
433
- use_ui @ui do
434
- @cmd.send_gem(@path)
435
- end
436
- end
437
- end
438
-
439
- assert_match "You have enabled multi-factor authentication. Please visit #{@fetcher.webauthn_url_with_port(server.port)} " \
440
- "to authenticate via security device. If you can't verify using WebAuthn but have OTP enabled, " \
441
- "you can re-run the gem signin command with the `--otp [your_code]` option.", @ui.output
442
- assert_match "You are verified with a security device. You may close the browser window.", @ui.output
443
- assert_equal "Uvh6T57tkWuUnWYo", @fetcher.last_request["OTP"]
444
- assert_match response_success, @ui.output
445
- end
446
-
447
- def test_with_webauthn_enabled_failure
448
- response_success = "Successfully registered gem: freewill (1.0.0)"
449
- server = Gem::MockTCPServer.new
450
- error = Gem::WebauthnVerificationError.new("Something went wrong")
451
-
452
- @fetcher.respond_with_require_otp("#{Gem.host}/api/v1/gems", response_success)
453
- @fetcher.respond_with_webauthn_url
454
-
455
- error = assert_raise Gem::MockGemUi::TermError do
456
- TCPServer.stub(:new, server) do
457
- Gem::GemcutterUtilities::WebauthnListener.stub(:listener_thread, Thread.new { Thread.current[:error] = error }) do
458
- use_ui @ui do
459
- @cmd.send_gem(@path)
460
- end
461
- end
462
- end
463
- end
464
- assert_equal 1, error.exit_code
465
-
466
- assert_match @fetcher.last_request["Authorization"], Gem.configuration.rubygems_api_key
467
- assert_match "You have enabled multi-factor authentication. Please visit #{@fetcher.webauthn_url_with_port(server.port)} " \
468
- "to authenticate via security device. If you can't verify using WebAuthn but have OTP enabled, " \
469
- "you can re-run the gem signin command with the `--otp [your_code]` option.", @ui.output
470
- assert_match "ERROR: Security device verification failed: Something went wrong", @ui.error
471
- refute_match "You are verified with a security device. You may close the browser window.", @ui.output
472
- refute_match response_success, @ui.output
473
- end
474
-
475
- def test_with_webauthn_enabled_success_with_polling
476
- response_success = "Successfully registered gem: freewill (1.0.0)"
477
- server = Gem::MockTCPServer.new
478
-
479
- @fetcher.respond_with_require_otp("#{Gem.host}/api/v1/gems", response_success)
480
- @fetcher.respond_with_webauthn_url
481
- @fetcher.respond_with_webauthn_polling("Uvh6T57tkWuUnWYo")
482
-
483
- TCPServer.stub(:new, server) do
484
- use_ui @ui do
485
- @cmd.send_gem(@path)
486
- end
487
- end
488
-
489
- assert_match "You have enabled multi-factor authentication. Please visit #{@fetcher.webauthn_url_with_port(server.port)} " \
490
- "to authenticate via security device. If you can't verify using WebAuthn but have OTP enabled, " \
491
- "you can re-run the gem signin command with the `--otp [your_code]` option.", @ui.output
492
- assert_match "You are verified with a security device. You may close the browser window.", @ui.output
493
- assert_equal "Uvh6T57tkWuUnWYo", @fetcher.last_request["OTP"]
494
- assert_match response_success, @ui.output
495
- end
496
-
497
- def test_with_webauthn_enabled_failure_with_polling
498
- response_success = "Successfully registered gem: freewill (1.0.0)"
499
- server = Gem::MockTCPServer.new
500
-
501
- @fetcher.respond_with_require_otp("#{Gem.host}/api/v1/gems", response_success)
502
- @fetcher.respond_with_webauthn_url
503
- @fetcher.respond_with_webauthn_polling_failure
504
-
505
- error = assert_raise Gem::MockGemUi::TermError do
506
- TCPServer.stub(:new, server) do
507
- use_ui @ui do
508
- @cmd.send_gem(@path)
509
- end
510
- end
511
- end
512
- assert_equal 1, error.exit_code
513
-
514
- assert_match @fetcher.last_request["Authorization"], Gem.configuration.rubygems_api_key
515
- assert_match "You have enabled multi-factor authentication. Please visit #{@fetcher.webauthn_url_with_port(server.port)} " \
516
- "to authenticate via security device. If you can't verify using WebAuthn but have OTP enabled, you can re-run the gem signin " \
517
- "command with the `--otp [your_code]` option.", @ui.output
518
- assert_match "ERROR: Security device verification failed: The token in the link you used has either expired " \
519
- "or been used already.", @ui.error
520
- refute_match "You are verified with a security device. You may close the browser window.", @ui.output
521
- refute_match response_success, @ui.output
522
- end
523
-
524
- def test_sending_gem_unathorized_api_key_with_mfa_enabled
525
- response_mfa_enabled = "You have enabled multifactor authentication but your request doesn't have the correct OTP code. Please check it and retry."
526
- response_forbidden = "The API key doesn't have access"
527
- response_success = "Successfully registered gem: freewill (1.0.0)"
528
-
529
- @fetcher.data["#{@host}/api/v1/gems"] = [
530
- HTTPResponseFactory.create(body: response_mfa_enabled, code: 401, msg: "Unauthorized"),
531
- HTTPResponseFactory.create(body: response_forbidden, code: 403, msg: "Forbidden"),
532
- HTTPResponseFactory.create(body: response_success, code: 200, msg: "OK"),
533
- ]
534
- @fetcher.data["#{@host}/api/v1/webauthn_verification"] =
535
- HTTPResponseFactory.create(body: "You don't have any security devices", code: 422, msg: "Unprocessable Entity")
536
-
537
- @fetcher.data["#{@host}/api/v1/api_key"] = HTTPResponseFactory.create(body: "", code: 200, msg: "OK")
538
- @cmd.instance_variable_set :@host, @host
539
- @cmd.instance_variable_set :@scope, :push_rubygem
540
-
541
- @ui = Gem::MockGemUi.new "11111\nsome@mail.com\npass\n"
542
- use_ui @ui do
543
- @cmd.send_gem(@path)
544
- end
545
-
546
- mfa_notice = "You have enabled multi-factor authentication. Please enter OTP code."
547
- access_notice = "The existing key doesn't have access of push_rubygem on https://rubygems.example. Please sign in to update access."
548
- assert_match mfa_notice, @ui.output
549
- assert_match access_notice, @ui.output
550
- assert_match "Email:", @ui.output
551
- assert_match "Password:", @ui.output
552
- assert_match "Added push_rubygem scope to the existing API key", @ui.output
553
- assert_match response_success, @ui.output
554
- assert_equal "11111", @fetcher.last_request["OTP"]
555
- end
556
-
557
- def test_sending_gem_with_no_local_creds
558
- Gem.configuration.rubygems_api_key = nil
559
-
560
- response_mfa_enabled = "You have enabled multifactor authentication but your request doesn't have the correct OTP code. Please check it and retry."
561
- response_success = "Successfully registered gem: freewill (1.0.0)"
562
- response_profile = "mfa: disabled\n"
563
-
564
- @fetcher.data["#{@host}/api/v1/gems"] = [
565
- HTTPResponseFactory.create(body: response_success, code: 200, msg: "OK"),
566
- ]
567
-
568
- @fetcher.data["#{@host}/api/v1/api_key"] = [
569
- HTTPResponseFactory.create(body: response_mfa_enabled, code: 401, msg: "Unauthorized"),
570
- HTTPResponseFactory.create(body: "", code: 200, msg: "OK"),
571
- ]
572
-
573
- @fetcher.data["#{@host}/api/v1/profile/me.yaml"] = [
574
- HTTPResponseFactory.create(body: response_profile, code: 200, msg: "OK"),
575
- ]
576
- @fetcher.data["#{@host}/api/v1/webauthn_verification"] =
577
- HTTPResponseFactory.create(body: "You don't have any security devices", code: 422, msg: "Unprocessable Entity")
578
-
579
- @cmd.instance_variable_set :@scope, :push_rubygem
580
- @cmd.options[:args] = [@path]
581
- @cmd.options[:host] = @host
582
-
583
- @ui = Gem::MockGemUi.new "some@mail.com\npass\n11111\n"
584
- use_ui @ui do
585
- @cmd.execute
586
- end
587
-
588
- mfa_notice = "You have enabled multi-factor authentication. Please enter OTP code."
589
- assert_match mfa_notice, @ui.output
590
- assert_match "Enter your https://rubygems.example credentials.", @ui.output
591
- assert_match "Email:", @ui.output
592
- assert_match "Password:", @ui.output
593
- assert_match "Signed in with API key:", @ui.output
594
- assert_match response_success, @ui.output
595
- assert_equal "11111", @fetcher.last_request["OTP"]
596
- end
597
-
598
- private
599
-
600
- def singleton_gem_class
601
- class << Gem; self; end
602
- end
603
- end