rubygems-update 3.5.3 → 3.7.1

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 (437) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1410 -686
  3. data/CODE_OF_CONDUCT.md +79 -28
  4. data/CONTRIBUTING.md +4 -226
  5. data/Manifest.txt +107 -83
  6. data/README.md +16 -11
  7. data/SECURITY.md +7 -0
  8. data/bundler/CHANGELOG.md +1525 -931
  9. data/bundler/README.md +9 -9
  10. data/bundler/bundler.gemspec +2 -2
  11. data/bundler/lib/bundler/build_metadata.rb +10 -11
  12. data/bundler/lib/bundler/checksum.rb +22 -12
  13. data/bundler/lib/bundler/cli/add.rb +3 -1
  14. data/bundler/lib/bundler/cli/binstubs.rb +1 -1
  15. data/bundler/lib/bundler/cli/check.rb +3 -3
  16. data/bundler/lib/bundler/cli/common.rb +1 -1
  17. data/bundler/lib/bundler/cli/config.rb +2 -2
  18. data/bundler/lib/bundler/cli/console.rb +8 -10
  19. data/bundler/lib/bundler/cli/doctor/diagnose.rb +167 -0
  20. data/bundler/lib/bundler/cli/doctor/ssl.rb +249 -0
  21. data/bundler/lib/bundler/cli/doctor.rb +27 -151
  22. data/bundler/lib/bundler/cli/exec.rb +1 -0
  23. data/bundler/lib/bundler/cli/fund.rb +1 -1
  24. data/bundler/lib/bundler/cli/gem.rb +74 -46
  25. data/bundler/lib/bundler/cli/info.rb +6 -6
  26. data/bundler/lib/bundler/cli/inject.rb +3 -3
  27. data/bundler/lib/bundler/cli/install.rb +19 -10
  28. data/bundler/lib/bundler/cli/issue.rb +3 -3
  29. data/bundler/lib/bundler/cli/lock.rb +32 -11
  30. data/bundler/lib/bundler/cli/outdated.rb +23 -23
  31. data/bundler/lib/bundler/cli/plugin.rb +3 -2
  32. data/bundler/lib/bundler/cli/pristine.rb +1 -1
  33. data/bundler/lib/bundler/cli/show.rb +3 -3
  34. data/bundler/lib/bundler/cli/update.rb +3 -3
  35. data/bundler/lib/bundler/cli.rb +75 -145
  36. data/bundler/lib/bundler/compact_index_client/cache.rb +48 -73
  37. data/bundler/lib/bundler/compact_index_client/cache_file.rb +0 -5
  38. data/bundler/lib/bundler/compact_index_client/parser.rb +84 -0
  39. data/bundler/lib/bundler/compact_index_client/updater.rb +6 -16
  40. data/bundler/lib/bundler/compact_index_client.rb +52 -85
  41. data/bundler/lib/bundler/constants.rb +8 -1
  42. data/bundler/lib/bundler/current_ruby.rb +48 -34
  43. data/bundler/lib/bundler/definition.rb +501 -328
  44. data/bundler/lib/bundler/dependency.rb +93 -47
  45. data/bundler/lib/bundler/dsl.rb +147 -103
  46. data/bundler/lib/bundler/endpoint_specification.rb +30 -3
  47. data/bundler/lib/bundler/env.rb +1 -1
  48. data/bundler/lib/bundler/environment_preserver.rb +5 -23
  49. data/bundler/lib/bundler/errors.rb +53 -5
  50. data/bundler/lib/bundler/feature_flag.rb +18 -18
  51. data/bundler/lib/bundler/fetcher/compact_index.rb +16 -25
  52. data/bundler/lib/bundler/fetcher/dependency.rb +2 -1
  53. data/bundler/lib/bundler/fetcher/downloader.rb +34 -8
  54. data/bundler/lib/bundler/fetcher.rb +63 -26
  55. data/bundler/lib/bundler/force_platform.rb +0 -2
  56. data/bundler/lib/bundler/friendly_errors.rb +3 -2
  57. data/bundler/lib/bundler/gem_helper.rb +1 -1
  58. data/bundler/lib/bundler/gem_version_promoter.rb +42 -40
  59. data/bundler/lib/bundler/index.rb +7 -2
  60. data/bundler/lib/bundler/injector.rb +14 -16
  61. data/bundler/lib/bundler/inline.rb +42 -17
  62. data/bundler/lib/bundler/installer/gem_installer.rb +4 -3
  63. data/bundler/lib/bundler/installer/parallel_installer.rb +3 -2
  64. data/bundler/lib/bundler/installer/standalone.rb +2 -5
  65. data/bundler/lib/bundler/installer.rb +22 -45
  66. data/bundler/lib/bundler/lazy_specification.rb +121 -48
  67. data/bundler/lib/bundler/lockfile_generator.rb +1 -1
  68. data/bundler/lib/bundler/lockfile_parser.rb +36 -9
  69. data/bundler/lib/bundler/man/bundle-add.1 +44 -27
  70. data/bundler/lib/bundler/man/bundle-add.1.ronn +52 -23
  71. data/bundler/lib/bundler/man/bundle-binstubs.1 +9 -6
  72. data/bundler/lib/bundler/man/bundle-binstubs.1.ronn +6 -3
  73. data/bundler/lib/bundler/man/bundle-cache.1 +32 -4
  74. data/bundler/lib/bundler/man/bundle-cache.1.ronn +31 -2
  75. data/bundler/lib/bundler/man/bundle-check.1 +7 -5
  76. data/bundler/lib/bundler/man/bundle-check.1.ronn +7 -2
  77. data/bundler/lib/bundler/man/bundle-clean.1 +3 -3
  78. data/bundler/lib/bundler/man/bundle-config.1 +180 -138
  79. data/bundler/lib/bundler/man/bundle-config.1.ronn +96 -99
  80. data/bundler/lib/bundler/man/bundle-console.1 +4 -6
  81. data/bundler/lib/bundler/man/bundle-console.1.ronn +2 -7
  82. data/bundler/lib/bundler/man/bundle-doctor.1 +46 -7
  83. data/bundler/lib/bundler/man/bundle-doctor.1.ronn +49 -5
  84. data/bundler/lib/bundler/man/bundle-env.1 +9 -0
  85. data/bundler/lib/bundler/man/bundle-env.1.ronn +10 -0
  86. data/bundler/lib/bundler/man/bundle-exec.1 +9 -6
  87. data/bundler/lib/bundler/man/bundle-exec.1.ronn +6 -3
  88. data/bundler/lib/bundler/man/bundle-fund.1 +22 -0
  89. data/bundler/lib/bundler/man/bundle-fund.1.ronn +25 -0
  90. data/bundler/lib/bundler/man/bundle-gem.1 +69 -28
  91. data/bundler/lib/bundler/man/bundle-gem.1.ronn +42 -6
  92. data/bundler/lib/bundler/man/bundle-help.1 +3 -3
  93. data/bundler/lib/bundler/man/bundle-info.1 +7 -4
  94. data/bundler/lib/bundler/man/bundle-info.1.ronn +6 -2
  95. data/bundler/lib/bundler/man/bundle-init.1 +5 -5
  96. data/bundler/lib/bundler/man/bundle-init.1.ronn +3 -2
  97. data/bundler/lib/bundler/man/bundle-inject.1 +13 -5
  98. data/bundler/lib/bundler/man/bundle-inject.1.ronn +10 -2
  99. data/bundler/lib/bundler/man/bundle-install.1 +20 -17
  100. data/bundler/lib/bundler/man/bundle-install.1.ronn +26 -23
  101. data/bundler/lib/bundler/man/bundle-issue.1 +45 -0
  102. data/bundler/lib/bundler/man/bundle-issue.1.ronn +37 -0
  103. data/bundler/lib/bundler/man/bundle-licenses.1 +9 -0
  104. data/bundler/lib/bundler/man/bundle-licenses.1.ronn +10 -0
  105. data/bundler/lib/bundler/man/bundle-list.1 +3 -3
  106. data/bundler/lib/bundler/man/bundle-list.1.ronn +4 -1
  107. data/bundler/lib/bundler/man/bundle-lock.1 +23 -8
  108. data/bundler/lib/bundler/man/bundle-lock.1.ronn +25 -4
  109. data/bundler/lib/bundler/man/bundle-open.1 +4 -4
  110. data/bundler/lib/bundler/man/bundle-open.1.ronn +2 -1
  111. data/bundler/lib/bundler/man/bundle-outdated.1 +10 -7
  112. data/bundler/lib/bundler/man/bundle-outdated.1.ronn +8 -4
  113. data/bundler/lib/bundler/man/bundle-platform.1 +3 -3
  114. data/bundler/lib/bundler/man/bundle-plugin.1 +9 -6
  115. data/bundler/lib/bundler/man/bundle-plugin.1.ronn +7 -3
  116. data/bundler/lib/bundler/man/bundle-pristine.1 +3 -3
  117. data/bundler/lib/bundler/man/bundle-pristine.1.ronn +1 -1
  118. data/bundler/lib/bundler/man/bundle-remove.1 +3 -3
  119. data/bundler/lib/bundler/man/bundle-remove.1.ronn +1 -1
  120. data/bundler/lib/bundler/man/bundle-show.1 +7 -4
  121. data/bundler/lib/bundler/man/bundle-show.1.ronn +4 -0
  122. data/bundler/lib/bundler/man/bundle-update.1 +17 -11
  123. data/bundler/lib/bundler/man/bundle-update.1.ronn +17 -9
  124. data/bundler/lib/bundler/man/bundle-version.1 +3 -3
  125. data/bundler/lib/bundler/man/bundle-viz.1 +6 -6
  126. data/bundler/lib/bundler/man/bundle-viz.1.ronn +7 -3
  127. data/bundler/lib/bundler/man/bundle.1 +3 -3
  128. data/bundler/lib/bundler/man/gemfile.5 +7 -5
  129. data/bundler/lib/bundler/man/gemfile.5.ronn +8 -2
  130. data/bundler/lib/bundler/man/index.txt +4 -0
  131. data/bundler/lib/bundler/match_metadata.rb +13 -0
  132. data/bundler/lib/bundler/match_platform.rb +31 -12
  133. data/bundler/lib/bundler/materialization.rb +59 -0
  134. data/bundler/lib/bundler/mirror.rb +3 -3
  135. data/bundler/lib/bundler/plugin/api/source.rb +5 -4
  136. data/bundler/lib/bundler/plugin/events.rb +24 -0
  137. data/bundler/lib/bundler/plugin/index.rb +5 -1
  138. data/bundler/lib/bundler/plugin/installer/path.rb +26 -0
  139. data/bundler/lib/bundler/plugin/installer.rb +37 -17
  140. data/bundler/lib/bundler/plugin/source_list.rb +4 -4
  141. data/bundler/lib/bundler/plugin.rb +21 -2
  142. data/bundler/lib/bundler/process_lock.rb +10 -14
  143. data/bundler/lib/bundler/remote_specification.rb +6 -1
  144. data/bundler/lib/bundler/resolver/base.rb +14 -3
  145. data/bundler/lib/bundler/resolver/candidate.rb +18 -27
  146. data/bundler/lib/bundler/resolver/package.rb +20 -3
  147. data/bundler/lib/bundler/resolver/spec_group.rb +22 -27
  148. data/bundler/lib/bundler/resolver/strategy.rb +40 -0
  149. data/bundler/lib/bundler/resolver.rb +114 -52
  150. data/bundler/lib/bundler/retry.rb +1 -1
  151. data/bundler/lib/bundler/ruby_dsl.rb +12 -3
  152. data/bundler/lib/bundler/ruby_version.rb +7 -1
  153. data/bundler/lib/bundler/rubygems_ext.rb +303 -150
  154. data/bundler/lib/bundler/rubygems_gem_installer.rb +40 -5
  155. data/bundler/lib/bundler/rubygems_integration.rb +40 -73
  156. data/bundler/lib/bundler/runtime.rb +48 -35
  157. data/bundler/lib/bundler/self_manager.rb +36 -26
  158. data/bundler/lib/bundler/settings/validator.rb +0 -23
  159. data/bundler/lib/bundler/settings.rb +36 -27
  160. data/bundler/lib/bundler/setup.rb +6 -0
  161. data/bundler/lib/bundler/shared_helpers.rb +45 -25
  162. data/bundler/lib/bundler/source/gemspec.rb +1 -4
  163. data/bundler/lib/bundler/source/git/git_proxy.rb +26 -9
  164. data/bundler/lib/bundler/source/git.rb +113 -41
  165. data/bundler/lib/bundler/source/metadata.rb +4 -3
  166. data/bundler/lib/bundler/source/path.rb +14 -18
  167. data/bundler/lib/bundler/source/rubygems/remote.rb +12 -4
  168. data/bundler/lib/bundler/source/rubygems.rb +54 -48
  169. data/bundler/lib/bundler/source.rb +2 -0
  170. data/bundler/lib/bundler/source_list.rb +54 -12
  171. data/bundler/lib/bundler/source_map.rb +1 -1
  172. data/bundler/lib/bundler/spec_set.rb +227 -103
  173. data/bundler/lib/bundler/stub_specification.rb +29 -2
  174. data/bundler/lib/bundler/templates/Executable +0 -11
  175. data/bundler/lib/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt +77 -29
  176. data/bundler/lib/bundler/templates/newgem/Gemfile.tt +1 -3
  177. data/bundler/lib/bundler/templates/newgem/README.md.tt +7 -3
  178. data/bundler/lib/bundler/templates/newgem/github/workflows/main.yml.tt +17 -15
  179. data/bundler/lib/bundler/templates/newgem/newgem.gemspec.tt +14 -12
  180. data/bundler/lib/bundler/templates/newgem/rubocop.yml.tt +0 -5
  181. data/bundler/lib/bundler/ui/shell.rb +26 -4
  182. data/bundler/lib/bundler/ui/silent.rb +12 -1
  183. data/bundler/lib/bundler/uri_credentials_filter.rb +3 -3
  184. data/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb +53 -3
  185. data/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool/version.rb +1 -1
  186. data/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool.rb +11 -0
  187. data/bundler/lib/bundler/vendor/fileutils/lib/fileutils.rb +15 -13
  188. data/bundler/lib/bundler/vendor/net-http-persistent/README.rdoc +1 -1
  189. data/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/timed_stack_multi.rb +2 -1
  190. data/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb +134 -57
  191. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/basic_package_source.rb +4 -24
  192. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/static_package_source.rb +1 -0
  193. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/strategy.rb +42 -0
  194. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/version_range.rb +20 -8
  195. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/version_solver.rb +17 -29
  196. data/bundler/lib/bundler/vendor/securerandom/COPYING +56 -0
  197. data/bundler/lib/bundler/vendor/securerandom/lib/securerandom.rb +102 -0
  198. data/bundler/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb +3 -5
  199. data/bundler/lib/bundler/vendor/thor/lib/thor/group.rb +11 -0
  200. data/bundler/lib/bundler/vendor/thor/lib/thor/parser/argument.rb +1 -4
  201. data/bundler/lib/bundler/vendor/thor/lib/thor/parser/option.rb +2 -2
  202. data/bundler/lib/bundler/vendor/thor/lib/thor/parser/options.rb +2 -1
  203. data/bundler/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +9 -9
  204. data/bundler/lib/bundler/vendor/thor/lib/thor/shell/html.rb +1 -1
  205. data/bundler/lib/bundler/vendor/thor/lib/thor/shell/table_printer.rb +5 -21
  206. data/bundler/lib/bundler/vendor/thor/lib/thor/util.rb +1 -1
  207. data/bundler/lib/bundler/vendor/thor/lib/thor/version.rb +1 -1
  208. data/bundler/lib/bundler/vendor/thor/lib/thor.rb +11 -0
  209. data/bundler/lib/bundler/vendor/uri/COPYING +56 -0
  210. data/bundler/lib/bundler/vendor/uri/lib/uri/common.rb +43 -16
  211. data/bundler/lib/bundler/vendor/uri/lib/uri/file.rb +3 -3
  212. data/bundler/lib/bundler/vendor/uri/lib/uri/ftp.rb +1 -1
  213. data/bundler/lib/bundler/vendor/uri/lib/uri/generic.rb +28 -37
  214. data/bundler/lib/bundler/vendor/uri/lib/uri/http.rb +2 -2
  215. data/bundler/lib/bundler/vendor/uri/lib/uri/rfc2396_parser.rb +16 -9
  216. data/bundler/lib/bundler/vendor/uri/lib/uri/rfc3986_parser.rb +26 -3
  217. data/bundler/lib/bundler/vendor/uri/lib/uri/version.rb +1 -1
  218. data/bundler/lib/bundler/vendor/uri/lib/uri.rb +9 -9
  219. data/bundler/lib/bundler/vendored_net_http.rb +20 -5
  220. data/bundler/lib/bundler/vendored_securerandom.rb +12 -0
  221. data/bundler/lib/bundler/vendored_timeout.rb +7 -3
  222. data/bundler/lib/bundler/vendored_uri.rb +18 -1
  223. data/bundler/lib/bundler/version.rb +10 -2
  224. data/bundler/lib/bundler/worker.rb +1 -1
  225. data/bundler/lib/bundler/yaml_serializer.rb +12 -7
  226. data/bundler/lib/bundler.rb +101 -61
  227. data/{bundler → doc/bundler}/UPGRADING.md +132 -127
  228. data/doc/rubygems/CONTRIBUTING.md +227 -0
  229. data/{POLICIES.md → doc/rubygems/POLICIES.md} +86 -17
  230. data/exe/update_rubygems +1 -1
  231. data/lib/rubygems/basic_specification.rb +50 -10
  232. data/lib/rubygems/bundler_version_finder.rb +1 -1
  233. data/lib/rubygems/command.rb +1 -4
  234. data/lib/rubygems/command_manager.rb +5 -6
  235. data/lib/rubygems/commands/build_command.rb +2 -11
  236. data/lib/rubygems/commands/cleanup_command.rb +3 -13
  237. data/lib/rubygems/commands/contents_command.rb +17 -10
  238. data/lib/rubygems/commands/environment_command.rb +5 -0
  239. data/lib/rubygems/commands/exec_command.rb +18 -11
  240. data/lib/rubygems/commands/fetch_command.rb +14 -0
  241. data/lib/rubygems/commands/help_command.rb +2 -2
  242. data/lib/rubygems/commands/install_command.rb +0 -4
  243. data/lib/rubygems/commands/pristine_command.rb +29 -19
  244. data/lib/rubygems/commands/push_command.rb +31 -6
  245. data/lib/rubygems/commands/rdoc_command.rb +3 -10
  246. data/lib/rubygems/commands/rebuild_command.rb +262 -0
  247. data/lib/rubygems/commands/setup_command.rb +13 -18
  248. data/lib/rubygems/commands/sources_command.rb +2 -2
  249. data/lib/rubygems/commands/uninstall_command.rb +9 -4
  250. data/lib/rubygems/commands/unpack_command.rb +0 -6
  251. data/lib/rubygems/commands/update_command.rb +13 -22
  252. data/lib/rubygems/config_file.rb +45 -16
  253. data/lib/rubygems/core_ext/kernel_require.rb +15 -3
  254. data/lib/rubygems/core_ext/kernel_warn.rb +2 -6
  255. data/lib/rubygems/defaults.rb +7 -7
  256. data/lib/rubygems/dependency.rb +12 -16
  257. data/lib/rubygems/dependency_list.rb +1 -1
  258. data/lib/rubygems/deprecate.rb +79 -77
  259. data/lib/rubygems/errors.rb +2 -1
  260. data/lib/rubygems/exceptions.rb +2 -9
  261. data/lib/rubygems/ext/builder.rb +21 -8
  262. data/lib/rubygems/ext/cargo_builder.rb +16 -26
  263. data/lib/rubygems/ext/cmake_builder.rb +7 -2
  264. data/lib/rubygems/ext/configure_builder.rb +7 -2
  265. data/lib/rubygems/ext/ext_conf_builder.rb +9 -5
  266. data/lib/rubygems/ext/rake_builder.rb +7 -4
  267. data/lib/rubygems/gem_runner.rb +9 -0
  268. data/lib/rubygems/gemcutter_utilities/webauthn_listener.rb +11 -4
  269. data/lib/rubygems/gemcutter_utilities/webauthn_poller.rb +3 -1
  270. data/lib/rubygems/gemcutter_utilities.rb +52 -26
  271. data/lib/rubygems/gemspec_helpers.rb +19 -0
  272. data/lib/rubygems/install_update_options.rb +5 -0
  273. data/lib/rubygems/installer.rb +76 -90
  274. data/lib/rubygems/local_remote_options.rb +8 -8
  275. data/lib/rubygems/package/tar_header.rb +31 -4
  276. data/lib/rubygems/package/tar_reader/entry.rb +1 -5
  277. data/lib/rubygems/package/tar_writer.rb +5 -4
  278. data/lib/rubygems/package.rb +13 -8
  279. data/lib/rubygems/platform.rb +148 -43
  280. data/lib/rubygems/psych_tree.rb +4 -0
  281. data/lib/rubygems/query_utils.rb +2 -2
  282. data/lib/rubygems/rdoc.rb +16 -3
  283. data/lib/rubygems/remote_fetcher.rb +6 -7
  284. data/lib/rubygems/request.rb +5 -5
  285. data/lib/rubygems/request_set/gem_dependency_api.rb +1 -1
  286. data/lib/rubygems/request_set.rb +4 -7
  287. data/lib/rubygems/requirement.rb +16 -12
  288. data/lib/rubygems/resolver/activation_request.rb +1 -1
  289. data/lib/rubygems/resolver/api_set/gem_parser.rb +2 -5
  290. data/lib/rubygems/resolver/api_set.rb +13 -8
  291. data/lib/rubygems/resolver/best_set.rb +1 -29
  292. data/lib/rubygems/resolver/composed_set.rb +3 -3
  293. data/lib/rubygems/resolver/git_set.rb +0 -1
  294. data/lib/rubygems/resolver/index_set.rb +2 -2
  295. data/lib/rubygems/resolver/source_set.rb +1 -1
  296. data/lib/rubygems/resolver/spec_specification.rb +7 -0
  297. data/lib/rubygems/resolver.rb +8 -8
  298. data/lib/rubygems/s3_uri_signer.rb +8 -6
  299. data/lib/rubygems/safe_marshal/reader.rb +31 -14
  300. data/lib/rubygems/safe_marshal/visitors/to_ruby.rb +29 -16
  301. data/lib/rubygems/safe_yaml.rb +10 -1
  302. data/lib/rubygems/security.rb +1 -1
  303. data/lib/rubygems/source/git.rb +22 -17
  304. data/lib/rubygems/source/installed.rb +3 -1
  305. data/lib/rubygems/source/local.rb +8 -4
  306. data/lib/rubygems/source/specific_file.rb +5 -3
  307. data/lib/rubygems/source.rb +37 -29
  308. data/lib/rubygems/source_list.rb +1 -1
  309. data/lib/rubygems/spec_fetcher.rb +47 -15
  310. data/lib/rubygems/specification.rb +110 -183
  311. data/lib/rubygems/specification_policy.rb +33 -13
  312. data/lib/rubygems/specification_record.rb +212 -0
  313. data/lib/rubygems/stub_specification.rb +32 -10
  314. data/lib/rubygems/target_rbconfig.rb +50 -0
  315. data/lib/rubygems/uninstaller.rb +42 -22
  316. data/lib/rubygems/uri.rb +6 -6
  317. data/lib/rubygems/uri_formatter.rb +2 -1
  318. data/lib/rubygems/util/licenses.rb +118 -1
  319. data/lib/rubygems/util.rb +1 -1
  320. data/lib/rubygems/vendor/molinillo/lib/molinillo/delegates/resolution_state.rb +57 -0
  321. data/lib/rubygems/{resolver → vendor}/molinillo/lib/molinillo/delegates/specification_provider.rb +11 -11
  322. data/lib/rubygems/{resolver → vendor}/molinillo/lib/molinillo/dependency_graph/action.rb +1 -1
  323. data/lib/rubygems/{resolver → vendor}/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb +1 -1
  324. data/lib/rubygems/{resolver → vendor}/molinillo/lib/molinillo/dependency_graph/add_vertex.rb +1 -1
  325. data/lib/rubygems/{resolver → vendor}/molinillo/lib/molinillo/dependency_graph/delete_edge.rb +1 -1
  326. data/lib/rubygems/{resolver → vendor}/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb +1 -1
  327. data/lib/rubygems/{resolver → vendor}/molinillo/lib/molinillo/dependency_graph/log.rb +1 -1
  328. data/lib/rubygems/{resolver → vendor}/molinillo/lib/molinillo/dependency_graph/set_payload.rb +1 -1
  329. data/lib/rubygems/{resolver → vendor}/molinillo/lib/molinillo/dependency_graph/tag.rb +1 -1
  330. data/lib/rubygems/{resolver → vendor}/molinillo/lib/molinillo/dependency_graph/vertex.rb +1 -1
  331. data/lib/rubygems/{resolver → vendor}/molinillo/lib/molinillo/dependency_graph.rb +2 -2
  332. data/lib/rubygems/{resolver → vendor}/molinillo/lib/molinillo/errors.rb +1 -1
  333. data/lib/rubygems/vendor/molinillo/lib/molinillo/gem_metadata.rb +6 -0
  334. data/lib/rubygems/{resolver → vendor}/molinillo/lib/molinillo/modules/specification_provider.rb +2 -2
  335. data/lib/rubygems/{resolver → vendor}/molinillo/lib/molinillo/modules/ui.rb +1 -1
  336. data/lib/rubygems/{resolver → vendor}/molinillo/lib/molinillo/resolution.rb +4 -4
  337. data/lib/rubygems/{resolver → vendor}/molinillo/lib/molinillo/resolver.rb +1 -1
  338. data/lib/rubygems/{resolver → vendor}/molinillo/lib/molinillo/state.rb +1 -1
  339. data/lib/rubygems/{resolver → vendor}/molinillo/lib/molinillo.rb +2 -2
  340. data/lib/rubygems/vendor/net-http/COPYING +56 -0
  341. data/lib/rubygems/{net-http → vendor/net-http}/lib/net/http/generic_request.rb +9 -9
  342. data/lib/rubygems/{net-http → vendor/net-http}/lib/net/http/header.rb +3 -3
  343. data/lib/rubygems/{net-http → vendor/net-http}/lib/net/http/request.rb +3 -3
  344. data/lib/rubygems/{net-http → vendor/net-http}/lib/net/http/requests.rb +35 -30
  345. data/lib/rubygems/{net-http → vendor/net-http}/lib/net/http/response.rb +2 -2
  346. data/lib/rubygems/{net-http → vendor/net-http}/lib/net/http/responses.rb +6 -6
  347. data/lib/rubygems/{net-http → vendor/net-http}/lib/net/http/status.rb +1 -1
  348. data/lib/rubygems/{net-http → vendor/net-http}/lib/net/http.rb +149 -70
  349. data/lib/rubygems/{net-http → vendor/net-http}/lib/net/https.rb +1 -1
  350. data/lib/rubygems/vendor/optparse/COPYING +56 -0
  351. data/lib/rubygems/{optparse → vendor/optparse}/lib/optparse/ac.rb +16 -0
  352. data/lib/rubygems/{optparse → vendor/optparse}/lib/optparse/kwargs.rb +8 -3
  353. data/lib/rubygems/vendor/optparse/lib/optparse/uri.rb +7 -0
  354. data/lib/rubygems/{optparse → vendor/optparse}/lib/optparse/version.rb +9 -0
  355. data/lib/rubygems/{optparse → vendor/optparse}/lib/optparse.rb +158 -62
  356. data/lib/rubygems/vendor/resolv/COPYING +56 -0
  357. data/lib/rubygems/{resolv → vendor/resolv}/lib/resolv.rb +165 -69
  358. data/lib/rubygems/vendor/securerandom/COPYING +56 -0
  359. data/lib/rubygems/vendor/securerandom/lib/securerandom.rb +102 -0
  360. data/lib/rubygems/vendor/timeout/COPYING +56 -0
  361. data/lib/rubygems/{timeout → vendor/timeout}/lib/timeout.rb +10 -11
  362. data/lib/rubygems/{tsort → vendor/tsort}/lib/tsort.rb +2 -2
  363. data/lib/rubygems/vendor/uri/COPYING +56 -0
  364. data/lib/rubygems/vendor/uri/lib/uri/common.rb +880 -0
  365. data/lib/rubygems/vendor/uri/lib/uri/file.rb +100 -0
  366. data/lib/rubygems/vendor/uri/lib/uri/ftp.rb +267 -0
  367. data/lib/rubygems/vendor/uri/lib/uri/generic.rb +1579 -0
  368. data/lib/rubygems/vendor/uri/lib/uri/http.rb +125 -0
  369. data/lib/rubygems/vendor/uri/lib/uri/https.rb +23 -0
  370. data/lib/rubygems/vendor/uri/lib/uri/ldap.rb +261 -0
  371. data/lib/rubygems/vendor/uri/lib/uri/ldaps.rb +22 -0
  372. data/lib/rubygems/vendor/uri/lib/uri/mailto.rb +293 -0
  373. data/lib/rubygems/vendor/uri/lib/uri/rfc2396_parser.rb +546 -0
  374. data/lib/rubygems/vendor/uri/lib/uri/rfc3986_parser.rb +206 -0
  375. data/lib/rubygems/vendor/uri/lib/uri/version.rb +6 -0
  376. data/lib/rubygems/vendor/uri/lib/uri/ws.rb +83 -0
  377. data/lib/rubygems/vendor/uri/lib/uri/wss.rb +23 -0
  378. data/lib/rubygems/vendor/uri/lib/uri.rb +104 -0
  379. data/lib/rubygems/vendored_molinillo.rb +3 -0
  380. data/lib/rubygems/vendored_net_http.rb +5 -0
  381. data/lib/rubygems/vendored_optparse.rb +3 -0
  382. data/lib/rubygems/vendored_securerandom.rb +3 -0
  383. data/lib/rubygems/vendored_timeout.rb +5 -0
  384. data/lib/rubygems/vendored_tsort.rb +3 -0
  385. data/lib/rubygems/version.rb +26 -9
  386. data/lib/rubygems/yaml_serializer.rb +12 -7
  387. data/lib/rubygems.rb +160 -53
  388. data/rubygems-update.gemspec +11 -6
  389. data/setup.rb +1 -1
  390. metadata +124 -96
  391. data/bundler/lib/bundler/compact_index_client/gem_parser.rb +0 -32
  392. data/bundler/lib/bundler/gem_helpers.rb +0 -127
  393. data/bundler/lib/bundler/templates/Executable.bundler +0 -109
  394. data/bundler/lib/bundler/vendor/fileutils/.document +0 -1
  395. data/bundler/lib/bundler/vendor/net-http-persistent/.document +0 -1
  396. data/bundler/lib/bundler/vendor/pub_grub/.document +0 -1
  397. data/bundler/lib/bundler/vendor/thor/.document +0 -1
  398. data/bundler/lib/bundler/vendor/tsort/.document +0 -1
  399. data/bundler/lib/bundler/vendor/uri/.document +0 -1
  400. data/lib/rubygems/net/http.rb +0 -3
  401. data/lib/rubygems/net-http/.document +0 -1
  402. data/lib/rubygems/net-http/LICENSE.txt +0 -22
  403. data/lib/rubygems/net-http/lib/net/http/backward.rb +0 -40
  404. data/lib/rubygems/net-protocol/.document +0 -1
  405. data/lib/rubygems/net-protocol/LICENSE.txt +0 -22
  406. data/lib/rubygems/optparse/.document +0 -1
  407. data/lib/rubygems/optparse/lib/optparse/uri.rb +0 -7
  408. data/lib/rubygems/optparse.rb +0 -3
  409. data/lib/rubygems/resolv/.document +0 -1
  410. data/lib/rubygems/resolv/LICENSE.txt +0 -22
  411. data/lib/rubygems/resolver/molinillo/.document +0 -1
  412. data/lib/rubygems/resolver/molinillo/lib/molinillo/delegates/resolution_state.rb +0 -57
  413. data/lib/rubygems/resolver/molinillo/lib/molinillo/gem_metadata.rb +0 -6
  414. data/lib/rubygems/resolver/molinillo.rb +0 -3
  415. data/lib/rubygems/shellwords.rb +0 -3
  416. data/lib/rubygems/ssl_certs/rubygems.org/GlobalSignRootCA.pem +0 -21
  417. data/lib/rubygems/timeout/.document +0 -1
  418. data/lib/rubygems/timeout/LICENSE.txt +0 -22
  419. data/lib/rubygems/timeout.rb +0 -3
  420. data/lib/rubygems/tsort/.document +0 -1
  421. data/lib/rubygems/tsort/LICENSE.txt +0 -22
  422. data/lib/rubygems/tsort.rb +0 -3
  423. /data/{lib/rubygems/optparse → bundler/lib/bundler/vendor/fileutils}/COPYING +0 -0
  424. /data/{MAINTAINERS.txt → doc/MAINTAINERS.txt} +0 -0
  425. /data/{UPGRADING.md → doc/rubygems/UPGRADING.md} +0 -0
  426. /data/lib/rubygems/ssl_certs/rubygems.org/{GlobalSignRootCA_R3.pem → GlobalSign.pem} +0 -0
  427. /data/{bundler/lib/bundler/vendor/connection_pool → lib/rubygems/vendor}/.document +0 -0
  428. /data/lib/rubygems/{resolver → vendor}/molinillo/LICENSE +0 -0
  429. /data/lib/rubygems/{net-http → vendor/net-http}/lib/net/http/exceptions.rb +0 -0
  430. /data/lib/rubygems/{net-http → vendor/net-http}/lib/net/http/proxy_delta.rb +0 -0
  431. /data/{bundler/lib/bundler/vendor/fileutils → lib/rubygems/vendor/net-protocol}/LICENSE.txt +0 -0
  432. /data/lib/rubygems/{net-protocol → vendor/net-protocol}/lib/net/protocol.rb +0 -0
  433. /data/lib/rubygems/{optparse → vendor/optparse}/lib/optionparser.rb +0 -0
  434. /data/lib/rubygems/{optparse → vendor/optparse}/lib/optparse/date.rb +0 -0
  435. /data/lib/rubygems/{optparse → vendor/optparse}/lib/optparse/shellwords.rb +0 -0
  436. /data/lib/rubygems/{optparse → vendor/optparse}/lib/optparse/time.rb +0 -0
  437. /data/{bundler/lib/bundler/vendor/uri → lib/rubygems/vendor/tsort}/LICENSE.txt +0 -0
@@ -15,6 +15,7 @@ class Gem::Commands::EnvironmentCommand < Gem::Command
15
15
  version display the gem format version
16
16
  remotesources display the remote gem servers
17
17
  platform display the supported gem platforms
18
+ credentials display the path where credentials are stored
18
19
  <omitted> display everything
19
20
  EOF
20
21
  args.gsub(/^\s+/, "")
@@ -88,6 +89,8 @@ lib/rubygems/defaults/operating_system.rb
88
89
  Gem.sources.to_a.join("\n")
89
90
  when /^platform/ then
90
91
  Gem.platforms.join(File::PATH_SEPARATOR)
92
+ when /^credentials/, /^creds/ then
93
+ Gem.configuration.credentials_path
91
94
  when nil then
92
95
  show_environment
93
96
  else
@@ -114,6 +117,8 @@ lib/rubygems/defaults/operating_system.rb
114
117
 
115
118
  out << " - USER INSTALLATION DIRECTORY: #{Gem.user_dir}\n"
116
119
 
120
+ out << " - CREDENTIALS FILE: #{Gem.configuration.credentials_path}\n"
121
+
117
122
  out << " - RUBYGEMS PREFIX: #{Gem.prefix}\n" unless Gem.prefix.nil?
118
123
 
119
124
  out << " - RUBY EXECUTABLE: #{Gem.ruby}\n"
@@ -57,8 +57,6 @@ to the same gem path as user-installed gems.
57
57
  end
58
58
 
59
59
  def execute
60
- gem_paths = { "GEM_HOME" => Gem.paths.home, "GEM_PATH" => Gem.paths.path.join(File::PATH_SEPARATOR), "GEM_SPEC_CACHE" => Gem.paths.spec_cache_dir }.compact
61
-
62
60
  check_executable
63
61
 
64
62
  print_command
@@ -74,9 +72,6 @@ to the same gem path as user-installed gems.
74
72
  end
75
73
 
76
74
  load!
77
- ensure
78
- ENV.update(gem_paths) if gem_paths
79
- Gem.clear_paths
80
75
  end
81
76
 
82
77
  private
@@ -143,7 +138,7 @@ to the same gem path as user-installed gems.
143
138
  end
144
139
 
145
140
  def set_gem_exec_install_paths
146
- home = File.join(Gem.dir, "gem_exec")
141
+ home = Gem.dir
147
142
 
148
143
  ENV["GEM_PATH"] = ([home] + Gem.path).join(File::PATH_SEPARATOR)
149
144
  ENV["GEM_HOME"] = home
@@ -200,7 +195,7 @@ to the same gem path as user-installed gems.
200
195
  argv = ARGV.clone
201
196
  ARGV.replace options[:args]
202
197
 
203
- exe = executable = options[:executable]
198
+ executable = options[:executable]
204
199
 
205
200
  contains_executable = Gem.loaded_specs.values.select do |spec|
206
201
  spec.executables.include?(executable)
@@ -211,13 +206,22 @@ to the same gem path as user-installed gems.
211
206
  end
212
207
 
213
208
  if contains_executable.empty?
214
- if (spec = Gem.loaded_specs[executable]) && (exe = spec.executable)
215
- contains_executable << spec
216
- else
209
+ spec = Gem.loaded_specs[executable]
210
+
211
+ if spec.nil? || spec.executables.empty?
217
212
  alert_error "Failed to load executable `#{executable}`," \
218
213
  " are you sure the gem `#{options[:gem_name]}` contains it?"
219
214
  terminate_interaction 1
220
215
  end
216
+
217
+ if spec.executables.size > 1
218
+ alert_error "Ambiguous which executable from gem `#{executable}` should be run: " \
219
+ "the options are #{spec.executables.sort}, specify one via COMMAND, and use `-g` and `-v` to specify gem and version"
220
+ terminate_interaction 1
221
+ end
222
+
223
+ contains_executable << spec
224
+ executable = spec.executable
221
225
  end
222
226
 
223
227
  if contains_executable.size > 1
@@ -227,8 +231,11 @@ to the same gem path as user-installed gems.
227
231
  terminate_interaction 1
228
232
  end
229
233
 
230
- load Gem.activate_bin_path(contains_executable.first.name, exe, ">= 0.a")
234
+ old_exe = $0
235
+ $0 = executable
236
+ load Gem.activate_bin_path(contains_executable.first.name, executable, ">= 0.a")
231
237
  ensure
238
+ $0 = old_exe if old_exe
232
239
  ARGV.replace argv
233
240
  end
234
241
 
@@ -63,6 +63,17 @@ then repackaging it.
63
63
 
64
64
  def execute
65
65
  check_version
66
+
67
+ exit_code = fetch_gems
68
+
69
+ terminate_interaction exit_code
70
+ end
71
+
72
+ private
73
+
74
+ def fetch_gems
75
+ exit_code = 0
76
+
66
77
  version = options[:version]
67
78
 
68
79
  platform = Gem.platforms.last
@@ -86,10 +97,13 @@ then repackaging it.
86
97
 
87
98
  if spec.nil?
88
99
  show_lookup_failure gem_name, gem_version, errors, suppress_suggestions, options[:domain]
100
+ exit_code |= 2
89
101
  next
90
102
  end
91
103
  source.download spec
92
104
  say "Downloaded #{spec.full_name}"
93
105
  end
106
+
107
+ exit_code
94
108
  end
95
109
  end
@@ -59,7 +59,7 @@ multiple environments. The RubyGems implementation is designed to be
59
59
  compatible with Bundler's Gemfile format. You can see additional
60
60
  documentation on the format at:
61
61
 
62
- http://bundler.io
62
+ https://bundler.io
63
63
 
64
64
  RubyGems automatically looks for these gem dependencies files:
65
65
 
@@ -172,7 +172,7 @@ and #platforms methods:
172
172
  See the bundler Gemfile manual page for a list of platforms supported in a gem
173
173
  dependencies file.:
174
174
 
175
- http://bundler.io/v1.6/man/gemfile.5.html
175
+ https://bundler.io/v2.5/man/gemfile.5.html
176
176
 
177
177
  Ruby Version and Engine Dependency
178
178
  ==================================
@@ -224,10 +224,6 @@ You can use `i` command instead of `install`.
224
224
  rescue Gem::InstallError => e
225
225
  alert_error "Error installing #{gem_name}:\n\t#{e.message}"
226
226
  exit_code |= 1
227
- rescue Gem::GemNotFoundException => e
228
- show_lookup_failure e.name, e.version, e.errors, suppress_suggestions
229
-
230
- exit_code |= 2
231
227
  rescue Gem::UnsatisfiableDependencyError => e
232
228
  show_lookup_failure e.name, e.version, e.errors, suppress_suggestions,
233
229
  "'#{gem_name}' (#{gem_version})"
@@ -57,7 +57,7 @@ class Gem::Commands::PristineCommand < Gem::Command
57
57
  end
58
58
 
59
59
  add_option("-i", "--install-dir DIR",
60
- "Gem repository to get binstubs and plugins installed") do |value, options|
60
+ "Gem repository to get gems restored") do |value, options|
61
61
  options[:install_dir] = File.expand_path(value)
62
62
  end
63
63
 
@@ -103,22 +103,26 @@ extensions will be restored.
103
103
  end
104
104
 
105
105
  def execute
106
+ install_dir = options[:install_dir]
107
+
108
+ specification_record = install_dir ? Gem::SpecificationRecord.from_path(install_dir) : Gem::Specification.specification_record
109
+
106
110
  specs = if options[:all]
107
- Gem::Specification.map
111
+ specification_record.map
108
112
 
109
113
  # `--extensions` must be explicitly given to pristine only gems
110
114
  # with extensions.
111
115
  elsif options[:extensions_set] &&
112
116
  options[:extensions] && options[:args].empty?
113
- Gem::Specification.select do |spec|
117
+ specification_record.select do |spec|
114
118
  spec.extensions && !spec.extensions.empty?
115
119
  end
116
120
  elsif options[:only_missing_extensions]
117
- Gem::Specification.select(&:missing_extensions?)
121
+ specification_record.select(&:missing_extensions?)
118
122
  else
119
- get_all_gem_names.sort.map do |gem_name|
120
- Gem::Specification.find_all_by_name(gem_name, options[:version]).reverse
121
- end.flatten
123
+ get_all_gem_names.sort.flat_map do |gem_name|
124
+ specification_record.find_all_by_name(gem_name, options[:version]).reverse
125
+ end
122
126
  end
123
127
 
124
128
  specs = specs.select {|spec| spec.platform == RUBY_ENGINE || Gem::Platform.local === spec.platform || spec.platform == Gem::Platform::RUBY }
@@ -130,10 +134,17 @@ extensions will be restored.
130
134
 
131
135
  say "Restoring gems to pristine condition..."
132
136
 
133
- specs.each do |spec|
134
- if spec.default_gem?
135
- say "Skipped #{spec.full_name}, it is a default gem"
136
- next
137
+ specs.group_by(&:full_name_with_location).values.each do |grouped_specs|
138
+ spec = grouped_specs.find {|s| !s.default_gem? } || grouped_specs.first
139
+
140
+ only_executables = options[:only_executables]
141
+ only_plugins = options[:only_plugins]
142
+
143
+ unless only_executables || only_plugins
144
+ # Default gemspecs include changes provided by ruby-core installer that
145
+ # can't currently be pristined (inclusion of compiled extension targets in
146
+ # the file list). So stick to resetting executables if it's a default gem.
147
+ only_executables = true if spec.default_gem?
137
148
  end
138
149
 
139
150
  if options.key? :skip
@@ -143,17 +154,17 @@ extensions will be restored.
143
154
  end
144
155
  end
145
156
 
146
- unless spec.extensions.empty? || options[:extensions] || options[:only_executables] || options[:only_plugins]
147
- say "Skipped #{spec.full_name}, it needs to compile an extension"
157
+ unless spec.extensions.empty? || options[:extensions] || only_executables || only_plugins
158
+ say "Skipped #{spec.full_name_with_location}, it needs to compile an extension"
148
159
  next
149
160
  end
150
161
 
151
162
  gem = spec.cache_file
152
163
 
153
- unless File.exist?(gem) || options[:only_executables] || options[:only_plugins]
164
+ unless File.exist?(gem) || only_executables || only_plugins
154
165
  require_relative "../remote_fetcher"
155
166
 
156
- say "Cached gem for #{spec.full_name} not found, attempting to fetch..."
167
+ say "Cached gem for #{spec.full_name_with_location} not found, attempting to fetch..."
157
168
 
158
169
  dep = Gem::Dependency.new spec.name, spec.version
159
170
  found, _ = Gem::SpecFetcher.fetcher.spec_for_dependency dep
@@ -176,7 +187,6 @@ extensions will be restored.
176
187
  end
177
188
 
178
189
  bin_dir = options[:bin_dir] if options[:bin_dir]
179
- install_dir = options[:install_dir] if options[:install_dir]
180
190
 
181
191
  installer_options = {
182
192
  wrappers: true,
@@ -187,10 +197,10 @@ extensions will be restored.
187
197
  bin_dir: bin_dir,
188
198
  }
189
199
 
190
- if options[:only_executables]
200
+ if only_executables
191
201
  installer = Gem::Installer.for_spec(spec, installer_options)
192
202
  installer.generate_bin
193
- elsif options[:only_plugins]
203
+ elsif only_plugins
194
204
  installer = Gem::Installer.for_spec(spec, installer_options)
195
205
  installer.generate_plugins
196
206
  else
@@ -198,7 +208,7 @@ extensions will be restored.
198
208
  installer.install
199
209
  end
200
210
 
201
- say "Restored #{spec.full_name}"
211
+ say "Restored #{spec.full_name_with_location}"
202
212
  end
203
213
  end
204
214
  end
@@ -30,7 +30,7 @@ The push command will use ~/.gem/credentials to authenticate to a server, but yo
30
30
  end
31
31
 
32
32
  def initialize
33
- super "push", "Push a gem up to the gem server", host: host
33
+ super "push", "Push a gem up to the gem server", host: host, attestations: []
34
34
 
35
35
  @user_defined_host = false
36
36
 
@@ -45,6 +45,11 @@ The push command will use ~/.gem/credentials to authenticate to a server, but yo
45
45
  @user_defined_host = true
46
46
  end
47
47
 
48
+ add_option("--attestation FILE",
49
+ "Push with sigstore attestations") do |value, options|
50
+ options[:attestations] << value
51
+ end
52
+
48
53
  @host = nil
49
54
  end
50
55
 
@@ -87,11 +92,20 @@ The push command will use ~/.gem/credentials to authenticate to a server, but yo
87
92
  private
88
93
 
89
94
  def send_push_request(name, args)
90
- rubygems_api_request(*args, scope: get_push_scope) do |request|
91
- request.body = Gem.read_binary name
92
- request.add_field "Content-Length", request.body.size
93
- request.add_field "Content-Type", "application/octet-stream"
94
- request.add_field "Authorization", api_key
95
+ scope = get_push_scope
96
+ rubygems_api_request(*args, scope: scope) do |request|
97
+ body = Gem.read_binary name
98
+ if options[:attestations].any?
99
+ request.set_form([
100
+ ["gem", body, { filename: name, content_type: "application/octet-stream" }],
101
+ get_attestations_part,
102
+ ], "multipart/form-data")
103
+ else
104
+ request.body = body
105
+ request.add_field "Content-Type", "application/octet-stream"
106
+ request.add_field "Content-Length", request.body.size
107
+ end
108
+ request.add_field "Authorization", api_key
95
109
  end
96
110
  end
97
111
 
@@ -107,4 +121,15 @@ The push command will use ~/.gem/credentials to authenticate to a server, but yo
107
121
  def get_push_scope
108
122
  :push_rubygem
109
123
  end
124
+
125
+ def get_attestations_part
126
+ bundles = "[" + options[:attestations].map do |attestation|
127
+ Gem.read_binary(attestation)
128
+ end.join(",") + "]"
129
+ [
130
+ "attestations",
131
+ bundles,
132
+ { content_type: "application/json" },
133
+ ]
134
+ end
110
135
  end
@@ -64,9 +64,9 @@ Use --overwrite to force rebuilding of documentation.
64
64
  specs = if options[:all]
65
65
  Gem::Specification.to_a
66
66
  else
67
- get_all_gem_names.map do |name|
67
+ get_all_gem_names.flat_map do |name|
68
68
  Gem::Specification.find_by_name name, options[:version]
69
- end.flatten.uniq
69
+ end.uniq
70
70
  end
71
71
 
72
72
  if specs.empty?
@@ -84,14 +84,7 @@ Use --overwrite to force rebuilding of documentation.
84
84
  FileUtils.rm_rf File.join(spec.doc_dir, "rdoc")
85
85
  end
86
86
 
87
- begin
88
- doc.generate
89
- rescue Errno::ENOENT => e
90
- match = / - /.match(e.message)
91
- alert_error "Unable to document #{spec.full_name}, " \
92
- " #{match.post_match} is missing, skipping"
93
- terminate_interaction 1 if specs.length == 1
94
- end
87
+ doc.generate
95
88
  end
96
89
  end
97
90
  end
@@ -0,0 +1,262 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "date"
4
+ require "digest"
5
+ require "fileutils"
6
+ require "tmpdir"
7
+ require_relative "../gemspec_helpers"
8
+ require_relative "../package"
9
+
10
+ class Gem::Commands::RebuildCommand < Gem::Command
11
+ include Gem::GemspecHelpers
12
+
13
+ def initialize
14
+ super "rebuild", "Attempt to reproduce a build of a gem."
15
+
16
+ add_option "--diff", "If the files don't match, compare them using diffoscope." do |_value, options|
17
+ options[:diff] = true
18
+ end
19
+
20
+ add_option "--force", "Skip validation of the spec." do |_value, options|
21
+ options[:force] = true
22
+ end
23
+
24
+ add_option "--strict", "Consider warnings as errors when validating the spec." do |_value, options|
25
+ options[:strict] = true
26
+ end
27
+
28
+ add_option "--source GEM_SOURCE", "Specify the source to download the gem from." do |value, options|
29
+ options[:source] = value
30
+ end
31
+
32
+ add_option "--original GEM_FILE", "Specify a local file to compare against (instead of downloading it)." do |value, options|
33
+ options[:original_gem_file] = value
34
+ end
35
+
36
+ add_option "--gemspec GEMSPEC_FILE", "Specify the name of the gemspec file." do |value, options|
37
+ options[:gemspec_file] = value
38
+ end
39
+
40
+ add_option "-C PATH", "Run as if gem build was started in <PATH> instead of the current working directory." do |value, options|
41
+ options[:build_path] = value
42
+ end
43
+ end
44
+
45
+ def arguments # :nodoc:
46
+ "GEM_NAME gem name on gem server\n" \
47
+ "GEM_VERSION gem version you are attempting to rebuild"
48
+ end
49
+
50
+ def description # :nodoc:
51
+ <<-EOF
52
+ The rebuild command allows you to (attempt to) reproduce a build of a gem
53
+ from a ruby gemspec.
54
+
55
+ This command assumes the gemspec can be built with the `gem build` command.
56
+ If you use any of `gem build`, `rake build`, or`rake release` in the
57
+ build/release process for a gem, it is a potential candidate.
58
+
59
+ You will need to match the RubyGems version used, since this is included in
60
+ the Gem metadata.
61
+
62
+ If the gem includes lockfiles (e.g. Gemfile.lock) and similar, it will
63
+ require more effort to reproduce a build. For example, it might require
64
+ more precisely matched versions of Ruby and/or Bundler to be used.
65
+ EOF
66
+ end
67
+
68
+ def usage # :nodoc:
69
+ "#{program_name} GEM_NAME GEM_VERSION"
70
+ end
71
+
72
+ def execute
73
+ gem_name, gem_version = get_gem_name_and_version
74
+
75
+ old_dir, new_dir = prep_dirs
76
+
77
+ gem_filename = "#{gem_name}-#{gem_version}.gem"
78
+ old_file = File.join(old_dir, gem_filename)
79
+ new_file = File.join(new_dir, gem_filename)
80
+
81
+ if options[:original_gem_file]
82
+ FileUtils.copy_file(options[:original_gem_file], old_file)
83
+ else
84
+ download_gem(gem_name, gem_version, old_file)
85
+ end
86
+
87
+ rg_version = rubygems_version(old_file)
88
+ unless rg_version == Gem::VERSION
89
+ alert_error <<-EOF
90
+ You need to use the same RubyGems version #{gem_name} v#{gem_version} was built with.
91
+
92
+ #{gem_name} v#{gem_version} was built using RubyGems v#{rg_version}.
93
+ Gem files include the version of RubyGems used to build them.
94
+ This means in order to reproduce #{gem_filename}, you must also use RubyGems v#{rg_version}.
95
+
96
+ You're using RubyGems v#{Gem::VERSION}.
97
+
98
+ Please install RubyGems v#{rg_version} and try again.
99
+ EOF
100
+ terminate_interaction 1
101
+ end
102
+
103
+ source_date_epoch = get_timestamp(old_file).to_s
104
+
105
+ if build_path = options[:build_path]
106
+ Dir.chdir(build_path) { build_gem(gem_name, source_date_epoch, new_file) }
107
+ else
108
+ build_gem(gem_name, source_date_epoch, new_file)
109
+ end
110
+
111
+ compare(source_date_epoch, old_file, new_file)
112
+ end
113
+
114
+ private
115
+
116
+ def sha256(file)
117
+ Digest::SHA256.hexdigest(Gem.read_binary(file))
118
+ end
119
+
120
+ def get_timestamp(file)
121
+ mtime = nil
122
+ File.open(file, Gem.binary_mode) do |f|
123
+ Gem::Package::TarReader.new(f) do |tar|
124
+ mtime = tar.seek("metadata.gz") {|tf| tf.header.mtime }
125
+ end
126
+ end
127
+
128
+ mtime
129
+ end
130
+
131
+ def compare(source_date_epoch, old_file, new_file)
132
+ date = Time.at(source_date_epoch.to_i).strftime("%F %T %Z")
133
+
134
+ old_hash = sha256(old_file)
135
+ new_hash = sha256(new_file)
136
+
137
+ say
138
+ say "Built at: #{date} (#{source_date_epoch})"
139
+ say "Original build saved to: #{old_file}"
140
+ say "Reproduced build saved to: #{new_file}"
141
+ say "Working directory: #{options[:build_path] || Dir.pwd}"
142
+ say
143
+ say "Hash comparison:"
144
+ say " #{old_hash}\t#{old_file}"
145
+ say " #{new_hash}\t#{new_file}"
146
+ say
147
+
148
+ if old_hash == new_hash
149
+ say "SUCCESS - original and rebuild hashes matched"
150
+ else
151
+ say "FAILURE - original and rebuild hashes did not match"
152
+ say
153
+
154
+ if options[:diff]
155
+ if system("diffoscope", old_file, new_file).nil?
156
+ alert_error "error: could not find `diffoscope` executable"
157
+ end
158
+ else
159
+ say "Pass --diff for more details (requires diffoscope to be installed)."
160
+ end
161
+
162
+ terminate_interaction 1
163
+ end
164
+ end
165
+
166
+ def prep_dirs
167
+ rebuild_dir = Dir.mktmpdir("gem_rebuild")
168
+ old_dir = File.join(rebuild_dir, "old")
169
+ new_dir = File.join(rebuild_dir, "new")
170
+
171
+ FileUtils.mkdir_p(old_dir)
172
+ FileUtils.mkdir_p(new_dir)
173
+
174
+ [old_dir, new_dir]
175
+ end
176
+
177
+ def get_gem_name_and_version
178
+ args = options[:args] || []
179
+ if args.length == 2
180
+ gem_name, gem_version = args
181
+ elsif args.length > 2
182
+ raise Gem::CommandLineError, "Too many arguments"
183
+ else
184
+ raise Gem::CommandLineError, "Expected GEM_NAME and GEM_VERSION arguments (gem rebuild GEM_NAME GEM_VERSION)"
185
+ end
186
+
187
+ [gem_name, gem_version]
188
+ end
189
+
190
+ def build_gem(gem_name, source_date_epoch, output_file)
191
+ gemspec = options[:gemspec_file] || find_gemspec("#{gem_name}.gemspec")
192
+
193
+ if gemspec
194
+ build_package(gemspec, source_date_epoch, output_file)
195
+ else
196
+ alert_error error_message(gem_name)
197
+ terminate_interaction(1)
198
+ end
199
+ end
200
+
201
+ def build_package(gemspec, source_date_epoch, output_file)
202
+ with_source_date_epoch(source_date_epoch) do
203
+ spec = Gem::Specification.load(gemspec)
204
+ if spec
205
+ Gem::Package.build(
206
+ spec,
207
+ options[:force],
208
+ options[:strict],
209
+ output_file
210
+ )
211
+ else
212
+ alert_error "Error loading gemspec. Aborting."
213
+ terminate_interaction 1
214
+ end
215
+ end
216
+ end
217
+
218
+ def with_source_date_epoch(source_date_epoch)
219
+ old_sde = ENV["SOURCE_DATE_EPOCH"]
220
+ ENV["SOURCE_DATE_EPOCH"] = source_date_epoch.to_s
221
+
222
+ yield
223
+ ensure
224
+ ENV["SOURCE_DATE_EPOCH"] = old_sde
225
+ end
226
+
227
+ def error_message(gem_name)
228
+ if gem_name
229
+ "Couldn't find a gemspec file matching '#{gem_name}' in #{Dir.pwd}"
230
+ else
231
+ "Couldn't find a gemspec file in #{Dir.pwd}"
232
+ end
233
+ end
234
+
235
+ def download_gem(gem_name, gem_version, old_file)
236
+ # This code was based loosely off the `gem fetch` command.
237
+ version = "= #{gem_version}"
238
+ dep = Gem::Dependency.new gem_name, version
239
+
240
+ specs_and_sources, errors =
241
+ Gem::SpecFetcher.fetcher.spec_for_dependency dep
242
+
243
+ # There should never be more than one item in specs_and_sources,
244
+ # since we search for an exact version.
245
+ spec, source = specs_and_sources[0]
246
+
247
+ if spec.nil?
248
+ show_lookup_failure gem_name, version, errors, options[:domain]
249
+ terminate_interaction 1
250
+ end
251
+
252
+ download_path = source.download spec
253
+
254
+ FileUtils.move(download_path, old_file)
255
+
256
+ say "Downloaded #{gem_name} version #{gem_version} as #{old_file}."
257
+ end
258
+
259
+ def rubygems_version(gem_file)
260
+ Gem::Package.new(gem_file).spec.rubygems_version
261
+ end
262
+ end