rubygems-update 2.6.1 → 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 (801) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +5899 -0
  3. data/CODE_OF_CONDUCT.md +76 -35
  4. data/CONTRIBUTING.md +231 -0
  5. data/MAINTAINERS.txt +8 -0
  6. data/Manifest.txt +428 -216
  7. data/POLICIES.md +135 -0
  8. data/README.md +112 -0
  9. data/UPGRADING.md +15 -0
  10. data/bundler/CHANGELOG.md +4719 -0
  11. data/bundler/LICENSE.md +22 -0
  12. data/bundler/README.md +58 -0
  13. data/bundler/UPGRADING.md +222 -0
  14. data/bundler/bundler.gemspec +46 -0
  15. data/bundler/exe/bundle +29 -0
  16. data/bundler/exe/bundler +4 -0
  17. data/bundler/lib/bundler/.document +1 -0
  18. data/bundler/lib/bundler/build_metadata.rb +45 -0
  19. data/bundler/lib/bundler/capistrano.rb +22 -0
  20. data/bundler/lib/bundler/checksum.rb +245 -0
  21. data/bundler/lib/bundler/ci_detector.rb +75 -0
  22. data/bundler/lib/bundler/cli/add.rb +47 -0
  23. data/bundler/lib/bundler/cli/binstubs.rb +57 -0
  24. data/bundler/lib/bundler/cli/cache.rb +43 -0
  25. data/bundler/lib/bundler/cli/check.rb +40 -0
  26. data/bundler/lib/bundler/cli/clean.rb +25 -0
  27. data/bundler/lib/bundler/cli/common.rb +138 -0
  28. data/bundler/lib/bundler/cli/config.rb +204 -0
  29. data/bundler/lib/bundler/cli/console.rb +44 -0
  30. data/bundler/lib/bundler/cli/doctor.rb +157 -0
  31. data/bundler/lib/bundler/cli/exec.rb +88 -0
  32. data/bundler/lib/bundler/cli/fund.rb +36 -0
  33. data/bundler/lib/bundler/cli/gem.rb +471 -0
  34. data/bundler/lib/bundler/cli/info.rb +83 -0
  35. data/bundler/lib/bundler/cli/init.rb +51 -0
  36. data/bundler/lib/bundler/cli/inject.rb +60 -0
  37. data/bundler/lib/bundler/cli/install.rb +190 -0
  38. data/bundler/lib/bundler/cli/issue.rb +41 -0
  39. data/bundler/lib/bundler/cli/list.rb +66 -0
  40. data/bundler/lib/bundler/cli/lock.rb +73 -0
  41. data/bundler/lib/bundler/cli/open.rb +29 -0
  42. data/bundler/lib/bundler/cli/outdated.rb +297 -0
  43. data/bundler/lib/bundler/cli/platform.rb +48 -0
  44. data/bundler/lib/bundler/cli/plugin.rb +34 -0
  45. data/bundler/lib/bundler/cli/pristine.rb +60 -0
  46. data/bundler/lib/bundler/cli/remove.rb +17 -0
  47. data/bundler/lib/bundler/cli/show.rb +75 -0
  48. data/bundler/lib/bundler/cli/update.rb +123 -0
  49. data/bundler/lib/bundler/cli/viz.rb +31 -0
  50. data/bundler/lib/bundler/cli.rb +846 -0
  51. data/bundler/lib/bundler/compact_index_client/cache.rb +121 -0
  52. data/bundler/lib/bundler/compact_index_client/cache_file.rb +153 -0
  53. data/bundler/lib/bundler/compact_index_client/gem_parser.rb +32 -0
  54. data/bundler/lib/bundler/compact_index_client/updater.rb +115 -0
  55. data/bundler/lib/bundler/compact_index_client.rb +126 -0
  56. data/bundler/lib/bundler/constants.rb +7 -0
  57. data/bundler/lib/bundler/current_ruby.rb +92 -0
  58. data/bundler/lib/bundler/definition.rb +1005 -0
  59. data/bundler/lib/bundler/dependency.rb +101 -0
  60. data/bundler/lib/bundler/deployment.rb +69 -0
  61. data/bundler/lib/bundler/deprecate.rb +44 -0
  62. data/bundler/lib/bundler/digest.rb +71 -0
  63. data/bundler/lib/bundler/dsl.rb +601 -0
  64. data/bundler/lib/bundler/endpoint_specification.rb +147 -0
  65. data/bundler/lib/bundler/env.rb +148 -0
  66. data/bundler/lib/bundler/environment_preserver.rb +86 -0
  67. data/bundler/lib/bundler/errors.rb +233 -0
  68. data/bundler/lib/bundler/feature_flag.rb +53 -0
  69. data/bundler/lib/bundler/fetcher/base.rb +52 -0
  70. data/bundler/lib/bundler/fetcher/compact_index.rb +129 -0
  71. data/bundler/lib/bundler/fetcher/dependency.rb +78 -0
  72. data/bundler/lib/bundler/fetcher/downloader.rb +91 -0
  73. data/bundler/lib/bundler/fetcher/gem_remote_fetcher.rb +16 -0
  74. data/bundler/lib/bundler/fetcher/index.rb +25 -0
  75. data/bundler/lib/bundler/fetcher.rb +324 -0
  76. data/bundler/lib/bundler/force_platform.rb +18 -0
  77. data/bundler/lib/bundler/friendly_errors.rb +126 -0
  78. data/bundler/lib/bundler/gem_helper.rb +237 -0
  79. data/bundler/lib/bundler/gem_helpers.rb +127 -0
  80. data/bundler/lib/bundler/gem_tasks.rb +7 -0
  81. data/bundler/lib/bundler/gem_version_promoter.rb +145 -0
  82. data/bundler/lib/bundler/graph.rb +152 -0
  83. data/bundler/lib/bundler/index.rb +205 -0
  84. data/bundler/lib/bundler/injector.rb +287 -0
  85. data/bundler/lib/bundler/inline.rb +73 -0
  86. data/bundler/lib/bundler/installer/gem_installer.rb +84 -0
  87. data/bundler/lib/bundler/installer/parallel_installer.rb +202 -0
  88. data/bundler/lib/bundler/installer/standalone.rb +116 -0
  89. data/bundler/lib/bundler/installer.rb +267 -0
  90. data/bundler/lib/bundler/lazy_specification.rb +170 -0
  91. data/bundler/lib/bundler/lockfile_generator.rb +104 -0
  92. data/bundler/lib/bundler/lockfile_parser.rb +289 -0
  93. data/bundler/lib/bundler/man/.document +1 -0
  94. data/bundler/lib/bundler/man/bundle-add.1 +59 -0
  95. data/bundler/lib/bundler/man/bundle-add.1.ronn +58 -0
  96. data/bundler/lib/bundler/man/bundle-binstubs.1 +30 -0
  97. data/bundler/lib/bundler/man/bundle-binstubs.1.ronn +41 -0
  98. data/bundler/lib/bundler/man/bundle-cache.1 +40 -0
  99. data/bundler/lib/bundler/man/bundle-cache.1.ronn +79 -0
  100. data/bundler/lib/bundler/man/bundle-check.1 +22 -0
  101. data/bundler/lib/bundler/man/bundle-check.1.ronn +26 -0
  102. data/bundler/lib/bundler/man/bundle-clean.1 +17 -0
  103. data/bundler/lib/bundler/man/bundle-clean.1.ronn +18 -0
  104. data/bundler/lib/bundler/man/bundle-config.1 +321 -0
  105. data/bundler/lib/bundler/man/bundle-config.1.ronn +411 -0
  106. data/bundler/lib/bundler/man/bundle-console.1 +35 -0
  107. data/bundler/lib/bundler/man/bundle-console.1.ronn +44 -0
  108. data/bundler/lib/bundler/man/bundle-doctor.1 +30 -0
  109. data/bundler/lib/bundler/man/bundle-doctor.1.ronn +33 -0
  110. data/bundler/lib/bundler/man/bundle-exec.1 +104 -0
  111. data/bundler/lib/bundler/man/bundle-exec.1.ronn +151 -0
  112. data/bundler/lib/bundler/man/bundle-gem.1 +69 -0
  113. data/bundler/lib/bundler/man/bundle-gem.1.ronn +117 -0
  114. data/bundler/lib/bundler/man/bundle-help.1 +9 -0
  115. data/bundler/lib/bundler/man/bundle-help.1.ronn +12 -0
  116. data/bundler/lib/bundler/man/bundle-info.1 +14 -0
  117. data/bundler/lib/bundler/man/bundle-info.1.ronn +17 -0
  118. data/bundler/lib/bundler/man/bundle-init.1 +20 -0
  119. data/bundler/lib/bundler/man/bundle-init.1.ronn +31 -0
  120. data/bundler/lib/bundler/man/bundle-inject.1 +23 -0
  121. data/bundler/lib/bundler/man/bundle-inject.1.ronn +24 -0
  122. data/bundler/lib/bundler/man/bundle-install.1 +215 -0
  123. data/bundler/lib/bundler/man/bundle-install.1.ronn +383 -0
  124. data/bundler/lib/bundler/man/bundle-list.1 +35 -0
  125. data/bundler/lib/bundler/man/bundle-list.1.ronn +33 -0
  126. data/bundler/lib/bundler/man/bundle-lock.1 +60 -0
  127. data/bundler/lib/bundler/man/bundle-lock.1.ronn +94 -0
  128. data/bundler/lib/bundler/man/bundle-open.1 +32 -0
  129. data/bundler/lib/bundler/man/bundle-open.1.ronn +27 -0
  130. data/bundler/lib/bundler/man/bundle-outdated.1 +100 -0
  131. data/bundler/lib/bundler/man/bundle-outdated.1.ronn +106 -0
  132. data/bundler/lib/bundler/man/bundle-platform.1 +49 -0
  133. data/bundler/lib/bundler/man/bundle-platform.1.ronn +49 -0
  134. data/bundler/lib/bundler/man/bundle-plugin.1 +55 -0
  135. data/bundler/lib/bundler/man/bundle-plugin.1.ronn +59 -0
  136. data/bundler/lib/bundler/man/bundle-pristine.1 +23 -0
  137. data/bundler/lib/bundler/man/bundle-pristine.1.ronn +34 -0
  138. data/bundler/lib/bundler/man/bundle-remove.1 +21 -0
  139. data/bundler/lib/bundler/man/bundle-remove.1.ronn +23 -0
  140. data/bundler/lib/bundler/man/bundle-show.1 +16 -0
  141. data/bundler/lib/bundler/man/bundle-show.1.ronn +21 -0
  142. data/bundler/lib/bundler/man/bundle-update.1 +275 -0
  143. data/bundler/lib/bundler/man/bundle-update.1.ronn +351 -0
  144. data/bundler/lib/bundler/man/bundle-version.1 +22 -0
  145. data/bundler/lib/bundler/man/bundle-version.1.ronn +24 -0
  146. data/bundler/lib/bundler/man/bundle-viz.1 +30 -0
  147. data/bundler/lib/bundler/man/bundle-viz.1.ronn +32 -0
  148. data/bundler/lib/bundler/man/bundle.1 +102 -0
  149. data/bundler/lib/bundler/man/bundle.1.ronn +116 -0
  150. data/bundler/lib/bundler/man/gemfile.5 +470 -0
  151. data/bundler/lib/bundler/man/gemfile.5.ronn +552 -0
  152. data/bundler/lib/bundler/man/index.txt +29 -0
  153. data/bundler/lib/bundler/match_metadata.rb +17 -0
  154. data/bundler/lib/bundler/match_platform.rb +23 -0
  155. data/bundler/lib/bundler/match_remote_metadata.rb +29 -0
  156. data/bundler/lib/bundler/mirror.rb +221 -0
  157. data/bundler/lib/bundler/plugin/api/source.rb +321 -0
  158. data/bundler/lib/bundler/plugin/api.rb +81 -0
  159. data/bundler/lib/bundler/plugin/dsl.rb +53 -0
  160. data/bundler/lib/bundler/plugin/events.rb +61 -0
  161. data/bundler/lib/bundler/plugin/index.rb +193 -0
  162. data/bundler/lib/bundler/plugin/installer/git.rb +34 -0
  163. data/bundler/lib/bundler/plugin/installer/rubygems.rb +19 -0
  164. data/bundler/lib/bundler/plugin/installer.rb +112 -0
  165. data/bundler/lib/bundler/plugin/source_list.rb +31 -0
  166. data/bundler/lib/bundler/plugin.rb +359 -0
  167. data/bundler/lib/bundler/process_lock.rb +24 -0
  168. data/bundler/lib/bundler/remote_specification.rb +117 -0
  169. data/bundler/lib/bundler/resolver/base.rb +107 -0
  170. data/bundler/lib/bundler/resolver/candidate.rb +94 -0
  171. data/bundler/lib/bundler/resolver/incompatibility.rb +15 -0
  172. data/bundler/lib/bundler/resolver/package.rb +77 -0
  173. data/bundler/lib/bundler/resolver/root.rb +25 -0
  174. data/bundler/lib/bundler/resolver/spec_group.rb +79 -0
  175. data/bundler/lib/bundler/resolver.rb +462 -0
  176. data/bundler/lib/bundler/retry.rb +66 -0
  177. data/bundler/lib/bundler/ruby_dsl.rb +53 -0
  178. data/bundler/lib/bundler/ruby_version.rb +131 -0
  179. data/bundler/lib/bundler/rubygems_ext.rb +328 -0
  180. data/bundler/lib/bundler/rubygems_gem_installer.rb +137 -0
  181. data/bundler/lib/bundler/rubygems_integration.rb +493 -0
  182. data/bundler/lib/bundler/runtime.rb +307 -0
  183. data/bundler/lib/bundler/safe_marshal.rb +31 -0
  184. data/bundler/lib/bundler/self_manager.rb +186 -0
  185. data/bundler/lib/bundler/settings/validator.rb +102 -0
  186. data/bundler/lib/bundler/settings.rb +588 -0
  187. data/bundler/lib/bundler/setup.rb +33 -0
  188. data/bundler/lib/bundler/shared_helpers.rb +380 -0
  189. data/bundler/lib/bundler/similarity_detector.rb +63 -0
  190. data/bundler/lib/bundler/source/gemspec.rb +18 -0
  191. data/bundler/lib/bundler/source/git/git_proxy.rb +455 -0
  192. data/bundler/lib/bundler/source/git.rb +380 -0
  193. data/bundler/lib/bundler/source/metadata.rb +62 -0
  194. data/bundler/lib/bundler/source/path/installer.rb +53 -0
  195. data/bundler/lib/bundler/source/path.rb +261 -0
  196. data/bundler/lib/bundler/source/rubygems/remote.rb +68 -0
  197. data/bundler/lib/bundler/source/rubygems.rb +516 -0
  198. data/bundler/lib/bundler/source/rubygems_aggregate.rb +68 -0
  199. data/bundler/lib/bundler/source.rb +116 -0
  200. data/bundler/lib/bundler/source_list.rb +227 -0
  201. data/bundler/lib/bundler/source_map.rb +71 -0
  202. data/bundler/lib/bundler/spec_set.rb +247 -0
  203. data/bundler/lib/bundler/stub_specification.rb +119 -0
  204. data/bundler/lib/bundler/templates/.document +1 -0
  205. data/bundler/lib/bundler/templates/Executable +27 -0
  206. data/bundler/lib/bundler/templates/Executable.bundler +109 -0
  207. data/bundler/lib/bundler/templates/Executable.standalone +14 -0
  208. data/bundler/lib/bundler/templates/Gemfile +5 -0
  209. data/bundler/lib/bundler/templates/newgem/CHANGELOG.md.tt +5 -0
  210. data/bundler/lib/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt +84 -0
  211. data/bundler/lib/bundler/templates/newgem/Cargo.toml.tt +7 -0
  212. data/bundler/lib/bundler/templates/newgem/Gemfile.tt +26 -0
  213. data/bundler/lib/bundler/templates/newgem/LICENSE.txt.tt +21 -0
  214. data/bundler/lib/bundler/templates/newgem/README.md.tt +45 -0
  215. data/bundler/lib/bundler/templates/newgem/Rakefile.tt +67 -0
  216. data/bundler/lib/bundler/templates/newgem/bin/console.tt +11 -0
  217. data/bundler/lib/bundler/templates/newgem/bin/setup.tt +8 -0
  218. data/bundler/lib/bundler/templates/newgem/circleci/config.yml.tt +25 -0
  219. data/bundler/lib/bundler/templates/newgem/exe/newgem.tt +3 -0
  220. data/bundler/lib/bundler/templates/newgem/ext/newgem/Cargo.toml.tt +15 -0
  221. data/bundler/lib/bundler/templates/newgem/ext/newgem/extconf-c.rb.tt +10 -0
  222. data/bundler/lib/bundler/templates/newgem/ext/newgem/extconf-rust.rb.tt +6 -0
  223. data/bundler/lib/bundler/templates/newgem/ext/newgem/newgem.c.tt +9 -0
  224. data/bundler/lib/bundler/templates/newgem/ext/newgem/newgem.h.tt +6 -0
  225. data/bundler/lib/bundler/templates/newgem/ext/newgem/src/lib.rs.tt +12 -0
  226. data/bundler/lib/bundler/templates/newgem/github/workflows/main.yml.tt +37 -0
  227. data/bundler/lib/bundler/templates/newgem/gitignore.tt +23 -0
  228. data/bundler/lib/bundler/templates/newgem/gitlab-ci.yml.tt +18 -0
  229. data/bundler/lib/bundler/templates/newgem/lib/newgem/version.rb.tt +9 -0
  230. data/bundler/lib/bundler/templates/newgem/lib/newgem.rb.tt +15 -0
  231. data/bundler/lib/bundler/templates/newgem/newgem.gemspec.tt +51 -0
  232. data/bundler/lib/bundler/templates/newgem/rspec.tt +3 -0
  233. data/bundler/lib/bundler/templates/newgem/rubocop.yml.tt +13 -0
  234. data/bundler/lib/bundler/templates/newgem/sig/newgem.rbs.tt +8 -0
  235. data/bundler/lib/bundler/templates/newgem/spec/newgem_spec.rb.tt +11 -0
  236. data/bundler/lib/bundler/templates/newgem/spec/spec_helper.rb.tt +15 -0
  237. data/bundler/lib/bundler/templates/newgem/standard.yml.tt +3 -0
  238. data/bundler/lib/bundler/templates/newgem/test/minitest/test_helper.rb.tt +6 -0
  239. data/bundler/lib/bundler/templates/newgem/test/minitest/test_newgem.rb.tt +13 -0
  240. data/bundler/lib/bundler/templates/newgem/test/test-unit/newgem_test.rb.tt +15 -0
  241. data/bundler/lib/bundler/templates/newgem/test/test-unit/test_helper.rb.tt +6 -0
  242. data/bundler/lib/bundler/ui/rg_proxy.rb +19 -0
  243. data/bundler/lib/bundler/ui/shell.rb +165 -0
  244. data/bundler/lib/bundler/ui/silent.rb +85 -0
  245. data/bundler/lib/bundler/ui.rb +9 -0
  246. data/bundler/lib/bundler/uri_credentials_filter.rb +43 -0
  247. data/bundler/lib/bundler/uri_normalizer.rb +23 -0
  248. data/bundler/lib/bundler/vendor/.document +1 -0
  249. data/bundler/lib/bundler/vendor/connection_pool/LICENSE +20 -0
  250. data/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb +174 -0
  251. data/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool/version.rb +3 -0
  252. data/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool/wrapper.rb +56 -0
  253. data/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool.rb +175 -0
  254. data/bundler/lib/bundler/vendor/fileutils/LICENSE.txt +22 -0
  255. data/bundler/lib/bundler/vendor/fileutils/lib/fileutils.rb +2694 -0
  256. data/bundler/lib/bundler/vendor/net-http-persistent/README.rdoc +82 -0
  257. data/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/connection.rb +41 -0
  258. data/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/pool.rb +65 -0
  259. data/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/timed_stack_multi.rb +79 -0
  260. data/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb +1073 -0
  261. data/bundler/lib/bundler/vendor/pub_grub/LICENSE.txt +21 -0
  262. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/assignment.rb +20 -0
  263. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/basic_package_source.rb +189 -0
  264. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/failure_writer.rb +182 -0
  265. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/incompatibility.rb +150 -0
  266. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/package.rb +43 -0
  267. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/partial_solution.rb +121 -0
  268. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/rubygems.rb +45 -0
  269. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/solve_failure.rb +19 -0
  270. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/static_package_source.rb +60 -0
  271. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/term.rb +105 -0
  272. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/version.rb +3 -0
  273. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/version_constraint.rb +129 -0
  274. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/version_range.rb +411 -0
  275. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/version_solver.rb +248 -0
  276. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/version_union.rb +178 -0
  277. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub.rb +31 -0
  278. data/bundler/lib/bundler/vendor/thor/LICENSE.md +20 -0
  279. data/bundler/lib/bundler/vendor/thor/lib/thor/actions/create_file.rb +105 -0
  280. data/bundler/lib/bundler/vendor/thor/lib/thor/actions/create_link.rb +61 -0
  281. data/bundler/lib/bundler/vendor/thor/lib/thor/actions/directory.rb +108 -0
  282. data/bundler/lib/bundler/vendor/thor/lib/thor/actions/empty_directory.rb +143 -0
  283. data/bundler/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb +373 -0
  284. data/bundler/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb +130 -0
  285. data/bundler/lib/bundler/vendor/thor/lib/thor/actions.rb +340 -0
  286. data/bundler/lib/bundler/vendor/thor/lib/thor/base.rb +825 -0
  287. data/bundler/lib/bundler/vendor/thor/lib/thor/command.rb +151 -0
  288. data/bundler/lib/bundler/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb +107 -0
  289. data/bundler/lib/bundler/vendor/thor/lib/thor/error.rb +106 -0
  290. data/bundler/lib/bundler/vendor/thor/lib/thor/group.rb +281 -0
  291. data/bundler/lib/bundler/vendor/thor/lib/thor/invocation.rb +178 -0
  292. data/bundler/lib/bundler/vendor/thor/lib/thor/line_editor/basic.rb +37 -0
  293. data/bundler/lib/bundler/vendor/thor/lib/thor/line_editor/readline.rb +88 -0
  294. data/bundler/lib/bundler/vendor/thor/lib/thor/line_editor.rb +17 -0
  295. data/bundler/lib/bundler/vendor/thor/lib/thor/nested_context.rb +29 -0
  296. data/bundler/lib/bundler/vendor/thor/lib/thor/parser/argument.rb +89 -0
  297. data/bundler/lib/bundler/vendor/thor/lib/thor/parser/arguments.rb +195 -0
  298. data/bundler/lib/bundler/vendor/thor/lib/thor/parser/option.rb +178 -0
  299. data/bundler/lib/bundler/vendor/thor/lib/thor/parser/options.rb +293 -0
  300. data/bundler/lib/bundler/vendor/thor/lib/thor/parser.rb +4 -0
  301. data/bundler/lib/bundler/vendor/thor/lib/thor/rake_compat.rb +72 -0
  302. data/bundler/lib/bundler/vendor/thor/lib/thor/runner.rb +335 -0
  303. data/bundler/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +388 -0
  304. data/bundler/lib/bundler/vendor/thor/lib/thor/shell/color.rb +115 -0
  305. data/bundler/lib/bundler/vendor/thor/lib/thor/shell/column_printer.rb +29 -0
  306. data/bundler/lib/bundler/vendor/thor/lib/thor/shell/html.rb +84 -0
  307. data/bundler/lib/bundler/vendor/thor/lib/thor/shell/lcs_diff.rb +49 -0
  308. data/bundler/lib/bundler/vendor/thor/lib/thor/shell/table_printer.rb +134 -0
  309. data/bundler/lib/bundler/vendor/thor/lib/thor/shell/terminal.rb +42 -0
  310. data/bundler/lib/bundler/vendor/thor/lib/thor/shell/wrapped_printer.rb +38 -0
  311. data/bundler/lib/bundler/vendor/thor/lib/thor/shell.rb +81 -0
  312. data/bundler/lib/bundler/vendor/thor/lib/thor/util.rb +285 -0
  313. data/bundler/lib/bundler/vendor/thor/lib/thor/version.rb +3 -0
  314. data/bundler/lib/bundler/vendor/thor/lib/thor.rb +663 -0
  315. data/bundler/lib/bundler/vendor/tsort/LICENSE.txt +22 -0
  316. data/bundler/lib/bundler/vendor/tsort/lib/tsort.rb +455 -0
  317. data/bundler/lib/bundler/vendor/uri/LICENSE.txt +22 -0
  318. data/bundler/lib/bundler/vendor/uri/lib/uri/common.rb +853 -0
  319. data/bundler/lib/bundler/vendor/uri/lib/uri/file.rb +100 -0
  320. data/bundler/lib/bundler/vendor/uri/lib/uri/ftp.rb +267 -0
  321. data/bundler/lib/bundler/vendor/uri/lib/uri/generic.rb +1588 -0
  322. data/bundler/lib/bundler/vendor/uri/lib/uri/http.rb +125 -0
  323. data/bundler/lib/bundler/vendor/uri/lib/uri/https.rb +23 -0
  324. data/bundler/lib/bundler/vendor/uri/lib/uri/ldap.rb +261 -0
  325. data/bundler/lib/bundler/vendor/uri/lib/uri/ldaps.rb +22 -0
  326. data/bundler/lib/bundler/vendor/uri/lib/uri/mailto.rb +293 -0
  327. data/bundler/lib/bundler/vendor/uri/lib/uri/rfc2396_parser.rb +539 -0
  328. data/bundler/lib/bundler/vendor/uri/lib/uri/rfc3986_parser.rb +183 -0
  329. data/bundler/lib/bundler/vendor/uri/lib/uri/version.rb +6 -0
  330. data/bundler/lib/bundler/vendor/uri/lib/uri/ws.rb +83 -0
  331. data/bundler/lib/bundler/vendor/uri/lib/uri/wss.rb +23 -0
  332. data/bundler/lib/bundler/vendor/uri/lib/uri.rb +104 -0
  333. data/bundler/lib/bundler/vendored_fileutils.rb +4 -0
  334. data/bundler/lib/bundler/vendored_net_http.rb +8 -0
  335. data/bundler/lib/bundler/vendored_persistent.rb +11 -0
  336. data/bundler/lib/bundler/vendored_pub_grub.rb +4 -0
  337. data/bundler/lib/bundler/vendored_thor.rb +8 -0
  338. data/bundler/lib/bundler/vendored_timeout.rb +8 -0
  339. data/bundler/lib/bundler/vendored_tsort.rb +4 -0
  340. data/bundler/lib/bundler/vendored_uri.rb +4 -0
  341. data/bundler/lib/bundler/version.rb +13 -0
  342. data/bundler/lib/bundler/vlad.rb +17 -0
  343. data/bundler/lib/bundler/worker.rb +117 -0
  344. data/bundler/lib/bundler/yaml_serializer.rb +93 -0
  345. data/bundler/lib/bundler.rb +665 -0
  346. data/{test/rubygems/bogussources.rb → exe/gem} +5 -2
  347. data/exe/update_rubygems +38 -0
  348. data/hide_lib_for_update/note.txt +0 -4
  349. data/lib/rubygems/available_set.rb +12 -12
  350. data/lib/rubygems/basic_specification.rb +75 -58
  351. data/lib/rubygems/bundler_version_finder.rb +77 -0
  352. data/lib/rubygems/ci_detector.rb +75 -0
  353. data/lib/rubygems/command.rb +144 -71
  354. data/lib/rubygems/command_manager.rb +64 -27
  355. data/lib/rubygems/commands/build_command.rb +88 -17
  356. data/lib/rubygems/commands/cert_command.rb +131 -83
  357. data/lib/rubygems/commands/check_command.rb +30 -27
  358. data/lib/rubygems/commands/cleanup_command.rb +57 -40
  359. data/lib/rubygems/commands/contents_command.rb +37 -39
  360. data/lib/rubygems/commands/dependency_command.rb +53 -65
  361. data/lib/rubygems/commands/environment_command.rb +32 -16
  362. data/lib/rubygems/commands/exec_command.rb +249 -0
  363. data/lib/rubygems/commands/fetch_command.rb +36 -19
  364. data/lib/rubygems/commands/generate_index_command.rb +40 -74
  365. data/lib/rubygems/commands/help_command.rb +22 -22
  366. data/lib/rubygems/commands/info_command.rb +38 -0
  367. data/lib/rubygems/commands/install_command.rb +67 -143
  368. data/lib/rubygems/commands/list_command.rb +10 -9
  369. data/lib/rubygems/commands/lock_command.rb +12 -14
  370. data/lib/rubygems/commands/mirror_command.rb +4 -4
  371. data/lib/rubygems/commands/open_command.rb +28 -26
  372. data/lib/rubygems/commands/outdated_command.rb +6 -6
  373. data/lib/rubygems/commands/owner_command.rb +51 -27
  374. data/lib/rubygems/commands/pristine_command.rb +99 -71
  375. data/lib/rubygems/commands/push_command.rb +53 -46
  376. data/lib/rubygems/commands/query_command.rb +21 -328
  377. data/lib/rubygems/commands/rdoc_command.rb +33 -33
  378. data/lib/rubygems/commands/search_command.rb +9 -9
  379. data/lib/rubygems/commands/server_command.rb +15 -76
  380. data/lib/rubygems/commands/setup_command.rb +370 -186
  381. data/lib/rubygems/commands/signin_command.rb +34 -0
  382. data/lib/rubygems/commands/signout_command.rb +32 -0
  383. data/lib/rubygems/commands/sources_command.rb +57 -41
  384. data/lib/rubygems/commands/specification_command.rb +38 -28
  385. data/lib/rubygems/commands/stale_command.rb +6 -5
  386. data/lib/rubygems/commands/uninstall_command.rb +96 -62
  387. data/lib/rubygems/commands/unpack_command.rb +44 -53
  388. data/lib/rubygems/commands/update_command.rb +155 -99
  389. data/lib/rubygems/commands/which_command.rb +14 -17
  390. data/lib/rubygems/commands/yank_command.rb +28 -32
  391. data/lib/rubygems/compatibility.rb +13 -32
  392. data/lib/rubygems/config_file.rb +214 -119
  393. data/lib/rubygems/core_ext/kernel_gem.rb +10 -16
  394. data/lib/rubygems/core_ext/kernel_require.rb +92 -90
  395. data/lib/rubygems/core_ext/kernel_warn.rb +49 -0
  396. data/lib/rubygems/core_ext/tcpsocket_init.rb +54 -0
  397. data/lib/rubygems/defaults.rb +184 -54
  398. data/lib/rubygems/dependency.rb +75 -62
  399. data/lib/rubygems/dependency_installer.rb +74 -230
  400. data/lib/rubygems/dependency_list.rb +32 -33
  401. data/lib/rubygems/deprecate.rb +113 -17
  402. data/lib/rubygems/doctor.rb +31 -31
  403. data/lib/rubygems/errors.rb +51 -13
  404. data/lib/rubygems/exceptions.rb +65 -35
  405. data/lib/rubygems/ext/build_error.rb +3 -1
  406. data/lib/rubygems/ext/builder.rb +103 -77
  407. data/lib/rubygems/ext/cargo_builder/link_flag_converter.rb +27 -0
  408. data/lib/rubygems/ext/cargo_builder.rb +360 -0
  409. data/lib/rubygems/ext/cmake_builder.rb +6 -7
  410. data/lib/rubygems/ext/configure_builder.rb +6 -9
  411. data/lib/rubygems/ext/ext_conf_builder.rb +40 -61
  412. data/lib/rubygems/ext/rake_builder.rb +18 -21
  413. data/lib/rubygems/ext.rb +8 -7
  414. data/lib/rubygems/gem_runner.rb +19 -21
  415. data/lib/rubygems/gemcutter_utilities/webauthn_listener/response.rb +163 -0
  416. data/lib/rubygems/gemcutter_utilities/webauthn_listener.rb +105 -0
  417. data/lib/rubygems/gemcutter_utilities/webauthn_poller.rb +78 -0
  418. data/lib/rubygems/gemcutter_utilities.rb +246 -43
  419. data/lib/rubygems/install_default_message.rb +3 -3
  420. data/lib/rubygems/install_message.rb +3 -3
  421. data/lib/rubygems/install_update_options.rb +104 -98
  422. data/lib/rubygems/installer.rb +407 -225
  423. data/lib/rubygems/installer_uninstaller_utils.rb +27 -0
  424. data/lib/rubygems/local_remote_options.rb +29 -32
  425. data/lib/rubygems/name_tuple.rb +18 -23
  426. data/lib/rubygems/net/http.rb +3 -0
  427. data/lib/rubygems/net-http/LICENSE.txt +22 -0
  428. data/lib/rubygems/net-http/lib/net/http/backward.rb +40 -0
  429. data/lib/rubygems/net-http/lib/net/http/exceptions.rb +34 -0
  430. data/lib/rubygems/net-http/lib/net/http/generic_request.rb +414 -0
  431. data/lib/rubygems/net-http/lib/net/http/header.rb +981 -0
  432. data/lib/rubygems/net-http/lib/net/http/proxy_delta.rb +17 -0
  433. data/lib/rubygems/net-http/lib/net/http/request.rb +88 -0
  434. data/lib/rubygems/net-http/lib/net/http/requests.rb +425 -0
  435. data/lib/rubygems/net-http/lib/net/http/response.rb +738 -0
  436. data/lib/rubygems/net-http/lib/net/http/responses.rb +1174 -0
  437. data/lib/rubygems/net-http/lib/net/http/status.rb +84 -0
  438. data/lib/rubygems/net-http/lib/net/http.rb +2496 -0
  439. data/lib/rubygems/net-http/lib/net/https.rb +23 -0
  440. data/lib/rubygems/net-protocol/LICENSE.txt +22 -0
  441. data/lib/rubygems/net-protocol/lib/net/protocol.rb +544 -0
  442. data/lib/rubygems/openssl.rb +7 -0
  443. data/lib/rubygems/optparse/.document +1 -0
  444. data/lib/rubygems/optparse/COPYING +56 -0
  445. data/lib/rubygems/optparse/lib/optionparser.rb +2 -0
  446. data/lib/rubygems/optparse/lib/optparse/ac.rb +54 -0
  447. data/lib/rubygems/optparse/lib/optparse/date.rb +18 -0
  448. data/lib/rubygems/optparse/lib/optparse/kwargs.rb +22 -0
  449. data/lib/rubygems/optparse/lib/optparse/shellwords.rb +7 -0
  450. data/lib/rubygems/optparse/lib/optparse/time.rb +11 -0
  451. data/lib/rubygems/optparse/lib/optparse/uri.rb +7 -0
  452. data/lib/rubygems/optparse/lib/optparse/version.rb +71 -0
  453. data/lib/rubygems/optparse/lib/optparse.rb +2330 -0
  454. data/lib/rubygems/optparse.rb +3 -0
  455. data/lib/rubygems/package/digest_io.rb +5 -7
  456. data/lib/rubygems/package/file_source.rb +6 -8
  457. data/lib/rubygems/package/io_source.rb +6 -4
  458. data/lib/rubygems/package/old.rb +19 -28
  459. data/lib/rubygems/package/source.rb +1 -1
  460. data/lib/rubygems/package/tar_header.rb +114 -93
  461. data/lib/rubygems/package/tar_reader/entry.rb +116 -22
  462. data/lib/rubygems/package/tar_reader.rb +18 -40
  463. data/lib/rubygems/package/tar_writer.rb +42 -56
  464. data/lib/rubygems/package.rb +245 -145
  465. data/lib/rubygems/package_task.rb +8 -14
  466. data/lib/rubygems/path_support.rb +21 -16
  467. data/lib/rubygems/platform.rb +135 -74
  468. data/lib/rubygems/psych_tree.rb +3 -2
  469. data/lib/rubygems/query_utils.rb +349 -0
  470. data/lib/rubygems/rdoc.rb +4 -326
  471. data/lib/rubygems/remote_fetcher.rb +99 -181
  472. data/lib/rubygems/request/connection_pools.rb +31 -24
  473. data/lib/rubygems/request/http_pool.rb +6 -7
  474. data/lib/rubygems/request/https_pool.rb +2 -3
  475. data/lib/rubygems/request.rb +103 -53
  476. data/lib/rubygems/request_set/gem_dependency_api.rb +182 -190
  477. data/lib/rubygems/request_set/lockfile/parser.rb +42 -52
  478. data/lib/rubygems/request_set/lockfile/tokenizer.rb +34 -24
  479. data/lib/rubygems/request_set/lockfile.rb +32 -35
  480. data/lib/rubygems/request_set.rb +115 -71
  481. data/lib/rubygems/requirement.rb +77 -68
  482. data/lib/rubygems/resolv/LICENSE.txt +22 -0
  483. data/lib/rubygems/resolv/lib/resolv.rb +3387 -0
  484. data/lib/rubygems/resolver/activation_request.rb +34 -61
  485. data/lib/rubygems/resolver/api_set/gem_parser.rb +24 -0
  486. data/lib/rubygems/resolver/api_set.rb +40 -32
  487. data/lib/rubygems/resolver/api_specification.rb +37 -18
  488. data/lib/rubygems/resolver/best_set.rb +15 -17
  489. data/lib/rubygems/resolver/composed_set.rb +9 -11
  490. data/lib/rubygems/resolver/conflict.rb +19 -33
  491. data/lib/rubygems/resolver/current_set.rb +2 -4
  492. data/lib/rubygems/resolver/dependency_request.rb +8 -9
  493. data/lib/rubygems/resolver/git_set.rb +8 -10
  494. data/lib/rubygems/resolver/git_specification.rb +11 -13
  495. data/lib/rubygems/resolver/index_set.rb +13 -15
  496. data/lib/rubygems/resolver/index_specification.rb +42 -11
  497. data/lib/rubygems/resolver/installed_specification.rb +9 -11
  498. data/lib/rubygems/resolver/installer_set.rb +87 -45
  499. data/lib/rubygems/resolver/local_specification.rb +5 -7
  500. data/lib/rubygems/resolver/lock_set.rb +13 -15
  501. data/lib/rubygems/resolver/lock_specification.rb +13 -15
  502. data/lib/rubygems/resolver/molinillo/LICENSE +9 -0
  503. data/lib/rubygems/resolver/molinillo/lib/molinillo/delegates/resolution_state.rb +57 -0
  504. data/lib/rubygems/resolver/molinillo/lib/molinillo/delegates/specification_provider.rb +88 -0
  505. data/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/action.rb +36 -0
  506. data/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb +66 -0
  507. data/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/add_vertex.rb +62 -0
  508. data/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/delete_edge.rb +63 -0
  509. data/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb +61 -0
  510. data/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/log.rb +126 -0
  511. data/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/set_payload.rb +46 -0
  512. data/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/tag.rb +36 -0
  513. data/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/vertex.rb +164 -0
  514. data/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph.rb +110 -146
  515. data/lib/rubygems/resolver/molinillo/lib/molinillo/errors.rb +83 -9
  516. data/lib/rubygems/resolver/molinillo/lib/molinillo/gem_metadata.rb +2 -1
  517. data/lib/rubygems/resolver/molinillo/lib/molinillo/modules/specification_provider.rb +13 -1
  518. data/lib/rubygems/resolver/molinillo/lib/molinillo/modules/ui.rb +3 -1
  519. data/lib/rubygems/resolver/molinillo/lib/molinillo/resolution.rb +552 -172
  520. data/lib/rubygems/resolver/molinillo/lib/molinillo/resolver.rb +3 -2
  521. data/lib/rubygems/resolver/molinillo/lib/molinillo/state.rb +12 -6
  522. data/lib/rubygems/resolver/molinillo/lib/molinillo.rb +6 -5
  523. data/lib/rubygems/resolver/molinillo.rb +2 -1
  524. data/lib/rubygems/resolver/requirement_list.rb +2 -2
  525. data/lib/rubygems/resolver/set.rb +3 -5
  526. data/lib/rubygems/resolver/source_set.rb +6 -7
  527. data/lib/rubygems/resolver/spec_specification.rb +16 -4
  528. data/lib/rubygems/resolver/specification.rb +25 -10
  529. data/lib/rubygems/resolver/stats.rb +1 -0
  530. data/lib/rubygems/resolver/vendor_set.rb +6 -8
  531. data/lib/rubygems/resolver/vendor_specification.rb +6 -8
  532. data/lib/rubygems/resolver.rb +121 -72
  533. data/lib/rubygems/s3_uri_signer.rb +177 -0
  534. data/lib/rubygems/safe_marshal/elements.rb +138 -0
  535. data/lib/rubygems/safe_marshal/reader.rb +306 -0
  536. data/lib/rubygems/safe_marshal/visitors/stream_printer.rb +31 -0
  537. data/lib/rubygems/safe_marshal/visitors/to_ruby.rb +385 -0
  538. data/lib/rubygems/safe_marshal/visitors/visitor.rb +74 -0
  539. data/lib/rubygems/safe_marshal.rb +74 -0
  540. data/lib/rubygems/safe_yaml.rb +36 -0
  541. data/lib/rubygems/security/policies.rb +49 -51
  542. data/lib/rubygems/security/policy.rb +46 -53
  543. data/lib/rubygems/security/signer.rb +86 -29
  544. data/lib/rubygems/security/trust_dir.rb +22 -24
  545. data/lib/rubygems/security.rb +101 -82
  546. data/lib/rubygems/security_option.rb +43 -0
  547. data/lib/rubygems/shellwords.rb +3 -0
  548. data/lib/rubygems/source/git.rb +40 -42
  549. data/lib/rubygems/source/installed.rb +5 -9
  550. data/lib/rubygems/source/local.rb +30 -33
  551. data/lib/rubygems/source/lock.rb +10 -10
  552. data/lib/rubygems/source/specific_file.rb +7 -9
  553. data/lib/rubygems/source/vendor.rb +3 -7
  554. data/lib/rubygems/source.rb +78 -68
  555. data/lib/rubygems/source_list.rb +11 -15
  556. data/lib/rubygems/spec_fetcher.rb +71 -83
  557. data/lib/rubygems/specification.rb +833 -1115
  558. data/lib/rubygems/specification_policy.rb +538 -0
  559. data/lib/rubygems/ssl_certs/rubygems.org/GlobalSignRootCA.pem +21 -0
  560. data/lib/rubygems/ssl_certs/rubygems.org/GlobalSignRootCA_R3.pem +21 -0
  561. data/lib/rubygems/stub_specification.rb +55 -57
  562. data/lib/rubygems/text.rb +39 -27
  563. data/lib/rubygems/timeout/LICENSE.txt +22 -0
  564. data/lib/rubygems/timeout/lib/timeout.rb +199 -0
  565. data/lib/rubygems/timeout.rb +3 -0
  566. data/lib/rubygems/tsort/.document +1 -0
  567. data/lib/rubygems/tsort/LICENSE.txt +22 -0
  568. data/lib/rubygems/tsort/lib/tsort.rb +455 -0
  569. data/lib/rubygems/tsort.rb +3 -0
  570. data/lib/rubygems/uninstaller.rb +150 -87
  571. data/lib/rubygems/unknown_command_spell_checker.rb +21 -0
  572. data/lib/rubygems/update_suggestion.rb +56 -0
  573. data/lib/rubygems/uri.rb +126 -0
  574. data/lib/rubygems/uri_formatter.rb +4 -7
  575. data/lib/rubygems/user_interaction.rb +92 -146
  576. data/lib/rubygems/util/licenses.rb +712 -317
  577. data/lib/rubygems/util/list.rb +5 -2
  578. data/lib/rubygems/util.rb +58 -75
  579. data/lib/rubygems/validator.rb +26 -48
  580. data/lib/rubygems/version.rb +106 -56
  581. data/lib/rubygems/version_option.rb +22 -14
  582. data/lib/rubygems/yaml_serializer.rb +93 -0
  583. data/lib/rubygems.rb +427 -361
  584. data/rubygems-update.gemspec +38 -0
  585. data/setup.rb +13 -27
  586. metadata +500 -363
  587. data/.autotest +0 -71
  588. data/.document +0 -5
  589. data/.travis.yml +0 -46
  590. data/CONTRIBUTING.rdoc +0 -129
  591. data/CVE-2013-4287.txt +0 -35
  592. data/CVE-2013-4363.txt +0 -45
  593. data/CVE-2015-3900.txt +0 -40
  594. data/History.txt +0 -3105
  595. data/MAINTAINERS.md +0 -5
  596. data/POLICIES.rdoc +0 -61
  597. data/README.rdoc +0 -54
  598. data/Rakefile +0 -449
  599. data/UPGRADING.rdoc +0 -92
  600. data/appveyor.yml +0 -36
  601. data/bin/gem +0 -25
  602. data/bin/update_rubygems +0 -37
  603. data/lib/gauntlet_rubygems.rb +0 -51
  604. data/lib/rubygems/indexer.rb +0 -434
  605. data/lib/rubygems/installer_test_case.rb +0 -194
  606. data/lib/rubygems/mock_gem_ui.rb +0 -89
  607. data/lib/rubygems/package/tar_test_case.rb +0 -147
  608. data/lib/rubygems/psych_additions.rb +0 -10
  609. data/lib/rubygems/server.rb +0 -869
  610. data/lib/rubygems/source_local.rb +0 -6
  611. data/lib/rubygems/source_specific_file.rb +0 -5
  612. data/lib/rubygems/ssl_certs/AddTrustExternalCARoot-2048.pem +0 -25
  613. data/lib/rubygems/ssl_certs/AddTrustExternalCARoot.pem +0 -32
  614. data/lib/rubygems/ssl_certs/Class3PublicPrimaryCertificationAuthority.pem +0 -14
  615. data/lib/rubygems/ssl_certs/DigiCertHighAssuranceEVRootCA.pem +0 -23
  616. data/lib/rubygems/ssl_certs/EntrustnetSecureServerCertificationAuthority.pem +0 -28
  617. data/lib/rubygems/ssl_certs/GeoTrustGlobalCA.pem +0 -20
  618. data/lib/rubygems/syck_hack.rb +0 -77
  619. data/lib/rubygems/test_case.rb +0 -1496
  620. data/lib/rubygems/test_utilities.rb +0 -384
  621. data/lib/ubygems.rb +0 -11
  622. data/test/rubygems/alternate_cert.pem +0 -18
  623. data/test/rubygems/alternate_cert_32.pem +0 -18
  624. data/test/rubygems/alternate_key.pem +0 -27
  625. data/test/rubygems/bad_rake.rb +0 -2
  626. data/test/rubygems/ca_cert.pem +0 -68
  627. data/test/rubygems/child_cert.pem +0 -18
  628. data/test/rubygems/child_cert_32.pem +0 -18
  629. data/test/rubygems/child_key.pem +0 -27
  630. data/test/rubygems/client.pem +0 -49
  631. data/test/rubygems/data/gem-private_key.pem +0 -27
  632. data/test/rubygems/data/gem-public_cert.pem +0 -20
  633. data/test/rubygems/data/null-type.gemspec.rz +0 -0
  634. data/test/rubygems/encrypted_private_key.pem +0 -30
  635. data/test/rubygems/expired_cert.pem +0 -18
  636. data/test/rubygems/fake_certlib/openssl.rb +0 -8
  637. data/test/rubygems/fix_openssl_warnings.rb +0 -13
  638. data/test/rubygems/foo/discover.rb +0 -1
  639. data/test/rubygems/future_cert.pem +0 -18
  640. data/test/rubygems/future_cert_32.pem +0 -18
  641. data/test/rubygems/good_rake.rb +0 -2
  642. data/test/rubygems/grandchild_cert.pem +0 -18
  643. data/test/rubygems/grandchild_cert_32.pem +0 -18
  644. data/test/rubygems/grandchild_key.pem +0 -27
  645. data/test/rubygems/invalid_client.pem +0 -49
  646. data/test/rubygems/invalid_issuer_cert.pem +0 -18
  647. data/test/rubygems/invalid_issuer_cert_32.pem +0 -18
  648. data/test/rubygems/invalid_key.pem +0 -27
  649. data/test/rubygems/invalid_signer_cert.pem +0 -18
  650. data/test/rubygems/invalid_signer_cert_32.pem +0 -18
  651. data/test/rubygems/invalidchild_cert.pem +0 -18
  652. data/test/rubygems/invalidchild_cert_32.pem +0 -18
  653. data/test/rubygems/invalidchild_key.pem +0 -27
  654. data/test/rubygems/plugin/exception/rubygems_plugin.rb +0 -3
  655. data/test/rubygems/plugin/load/rubygems_plugin.rb +0 -4
  656. data/test/rubygems/plugin/standarderror/rubygems_plugin.rb +0 -3
  657. data/test/rubygems/private_key.pem +0 -27
  658. data/test/rubygems/public_cert.pem +0 -18
  659. data/test/rubygems/public_cert_32.pem +0 -18
  660. data/test/rubygems/public_key.pem +0 -9
  661. data/test/rubygems/rubygems/commands/crash_command.rb +0 -6
  662. data/test/rubygems/rubygems_plugin.rb +0 -22
  663. data/test/rubygems/sff/discover.rb +0 -1
  664. data/test/rubygems/simple_gem.rb +0 -67
  665. data/test/rubygems/specifications/bar-0.0.2.gemspec +0 -9
  666. data/test/rubygems/specifications/foo-0.0.1-x86-mswin32.gemspec +0 -0
  667. data/test/rubygems/ssl_cert.pem +0 -19
  668. data/test/rubygems/ssl_key.pem +0 -15
  669. data/test/rubygems/test_bundled_ca.rb +0 -59
  670. data/test/rubygems/test_config.rb +0 -24
  671. data/test/rubygems/test_deprecate.rb +0 -77
  672. data/test/rubygems/test_gem.rb +0 -1718
  673. data/test/rubygems/test_gem_available_set.rb +0 -130
  674. data/test/rubygems/test_gem_command.rb +0 -248
  675. data/test/rubygems/test_gem_command_manager.rb +0 -264
  676. data/test/rubygems/test_gem_commands_build_command.rb +0 -121
  677. data/test/rubygems/test_gem_commands_cert_command.rb +0 -671
  678. data/test/rubygems/test_gem_commands_check_command.rb +0 -69
  679. data/test/rubygems/test_gem_commands_cleanup_command.rb +0 -197
  680. data/test/rubygems/test_gem_commands_contents_command.rb +0 -240
  681. data/test/rubygems/test_gem_commands_dependency_command.rb +0 -230
  682. data/test/rubygems/test_gem_commands_environment_command.rb +0 -154
  683. data/test/rubygems/test_gem_commands_fetch_command.rb +0 -127
  684. data/test/rubygems/test_gem_commands_generate_index_command.rb +0 -51
  685. data/test/rubygems/test_gem_commands_help_command.rb +0 -75
  686. data/test/rubygems/test_gem_commands_install_command.rb +0 -1007
  687. data/test/rubygems/test_gem_commands_list_command.rb +0 -34
  688. data/test/rubygems/test_gem_commands_lock_command.rb +0 -69
  689. data/test/rubygems/test_gem_commands_mirror.rb +0 -20
  690. data/test/rubygems/test_gem_commands_open_command.rb +0 -70
  691. data/test/rubygems/test_gem_commands_outdated_command.rb +0 -33
  692. data/test/rubygems/test_gem_commands_owner_command.rb +0 -205
  693. data/test/rubygems/test_gem_commands_pristine_command.rb +0 -491
  694. data/test/rubygems/test_gem_commands_push_command.rb +0 -330
  695. data/test/rubygems/test_gem_commands_query_command.rb +0 -657
  696. data/test/rubygems/test_gem_commands_search_command.rb +0 -18
  697. data/test/rubygems/test_gem_commands_server_command.rb +0 -60
  698. data/test/rubygems/test_gem_commands_setup_command.rb +0 -136
  699. data/test/rubygems/test_gem_commands_sources_command.rb +0 -249
  700. data/test/rubygems/test_gem_commands_specification_command.rb +0 -251
  701. data/test/rubygems/test_gem_commands_stale_command.rb +0 -43
  702. data/test/rubygems/test_gem_commands_uninstall_command.rb +0 -283
  703. data/test/rubygems/test_gem_commands_unpack_command.rb +0 -209
  704. data/test/rubygems/test_gem_commands_update_command.rb +0 -514
  705. data/test/rubygems/test_gem_commands_which_command.rb +0 -87
  706. data/test/rubygems/test_gem_commands_yank_command.rb +0 -100
  707. data/test/rubygems/test_gem_config_file.rb +0 -491
  708. data/test/rubygems/test_gem_dependency.rb +0 -362
  709. data/test/rubygems/test_gem_dependency_installer.rb +0 -1235
  710. data/test/rubygems/test_gem_dependency_list.rb +0 -260
  711. data/test/rubygems/test_gem_dependency_resolution_error.rb +0 -29
  712. data/test/rubygems/test_gem_doctor.rb +0 -169
  713. data/test/rubygems/test_gem_ext_builder.rb +0 -341
  714. data/test/rubygems/test_gem_ext_cmake_builder.rb +0 -87
  715. data/test/rubygems/test_gem_ext_configure_builder.rb +0 -87
  716. data/test/rubygems/test_gem_ext_ext_conf_builder.rb +0 -211
  717. data/test/rubygems/test_gem_ext_rake_builder.rb +0 -65
  718. data/test/rubygems/test_gem_gem_runner.rb +0 -69
  719. data/test/rubygems/test_gem_gemcutter_utilities.rb +0 -235
  720. data/test/rubygems/test_gem_impossible_dependencies_error.rb +0 -62
  721. data/test/rubygems/test_gem_indexer.rb +0 -367
  722. data/test/rubygems/test_gem_install_update_options.rb +0 -197
  723. data/test/rubygems/test_gem_installer.rb +0 -1552
  724. data/test/rubygems/test_gem_local_remote_options.rb +0 -134
  725. data/test/rubygems/test_gem_name_tuple.rb +0 -45
  726. data/test/rubygems/test_gem_package.rb +0 -876
  727. data/test/rubygems/test_gem_package_old.rb +0 -90
  728. data/test/rubygems/test_gem_package_tar_header.rb +0 -147
  729. data/test/rubygems/test_gem_package_tar_reader.rb +0 -90
  730. data/test/rubygems/test_gem_package_tar_reader_entry.rb +0 -142
  731. data/test/rubygems/test_gem_package_tar_writer.rb +0 -264
  732. data/test/rubygems/test_gem_package_task.rb +0 -84
  733. data/test/rubygems/test_gem_path_support.rb +0 -121
  734. data/test/rubygems/test_gem_platform.rb +0 -308
  735. data/test/rubygems/test_gem_rdoc.rb +0 -270
  736. data/test/rubygems/test_gem_remote_fetcher.rb +0 -1051
  737. data/test/rubygems/test_gem_request.rb +0 -363
  738. data/test/rubygems/test_gem_request_connection_pools.rb +0 -130
  739. data/test/rubygems/test_gem_request_set.rb +0 -595
  740. data/test/rubygems/test_gem_request_set_gem_dependency_api.rb +0 -831
  741. data/test/rubygems/test_gem_request_set_lockfile.rb +0 -470
  742. data/test/rubygems/test_gem_request_set_lockfile_parser.rb +0 -549
  743. data/test/rubygems/test_gem_request_set_lockfile_tokenizer.rb +0 -306
  744. data/test/rubygems/test_gem_requirement.rb +0 -387
  745. data/test/rubygems/test_gem_resolver.rb +0 -715
  746. data/test/rubygems/test_gem_resolver_activation_request.rb +0 -74
  747. data/test/rubygems/test_gem_resolver_api_set.rb +0 -209
  748. data/test/rubygems/test_gem_resolver_api_specification.rb +0 -145
  749. data/test/rubygems/test_gem_resolver_best_set.rb +0 -138
  750. data/test/rubygems/test_gem_resolver_composed_set.rb +0 -46
  751. data/test/rubygems/test_gem_resolver_conflict.rb +0 -88
  752. data/test/rubygems/test_gem_resolver_dependency_request.rb +0 -85
  753. data/test/rubygems/test_gem_resolver_git_set.rb +0 -190
  754. data/test/rubygems/test_gem_resolver_git_specification.rb +0 -114
  755. data/test/rubygems/test_gem_resolver_index_set.rb +0 -90
  756. data/test/rubygems/test_gem_resolver_index_specification.rb +0 -90
  757. data/test/rubygems/test_gem_resolver_installed_specification.rb +0 -50
  758. data/test/rubygems/test_gem_resolver_installer_set.rb +0 -258
  759. data/test/rubygems/test_gem_resolver_local_specification.rb +0 -46
  760. data/test/rubygems/test_gem_resolver_lock_set.rb +0 -64
  761. data/test/rubygems/test_gem_resolver_lock_specification.rb +0 -100
  762. data/test/rubygems/test_gem_resolver_requirement_list.rb +0 -21
  763. data/test/rubygems/test_gem_resolver_specification.rb +0 -65
  764. data/test/rubygems/test_gem_resolver_vendor_set.rb +0 -84
  765. data/test/rubygems/test_gem_resolver_vendor_specification.rb +0 -84
  766. data/test/rubygems/test_gem_security.rb +0 -307
  767. data/test/rubygems/test_gem_security_policy.rb +0 -541
  768. data/test/rubygems/test_gem_security_signer.rb +0 -209
  769. data/test/rubygems/test_gem_security_trust_dir.rb +0 -101
  770. data/test/rubygems/test_gem_server.rb +0 -409
  771. data/test/rubygems/test_gem_silent_ui.rb +0 -117
  772. data/test/rubygems/test_gem_source.rb +0 -242
  773. data/test/rubygems/test_gem_source_fetch_problem.rb +0 -20
  774. data/test/rubygems/test_gem_source_git.rb +0 -309
  775. data/test/rubygems/test_gem_source_installed.rb +0 -37
  776. data/test/rubygems/test_gem_source_list.rb +0 -118
  777. data/test/rubygems/test_gem_source_local.rb +0 -107
  778. data/test/rubygems/test_gem_source_lock.rb +0 -115
  779. data/test/rubygems/test_gem_source_specific_file.rb +0 -76
  780. data/test/rubygems/test_gem_source_vendor.rb +0 -32
  781. data/test/rubygems/test_gem_spec_fetcher.rb +0 -311
  782. data/test/rubygems/test_gem_specification.rb +0 -3519
  783. data/test/rubygems/test_gem_stream_ui.rb +0 -239
  784. data/test/rubygems/test_gem_stub_specification.rb +0 -217
  785. data/test/rubygems/test_gem_text.rb +0 -77
  786. data/test/rubygems/test_gem_uninstaller.rb +0 -485
  787. data/test/rubygems/test_gem_unsatisfiable_dependency_error.rb +0 -33
  788. data/test/rubygems/test_gem_uri_formatter.rb +0 -29
  789. data/test/rubygems/test_gem_util.rb +0 -40
  790. data/test/rubygems/test_gem_validator.rb +0 -46
  791. data/test/rubygems/test_gem_version.rb +0 -222
  792. data/test/rubygems/test_gem_version_option.rb +0 -152
  793. data/test/rubygems/test_kernel.rb +0 -86
  794. data/test/rubygems/test_require.rb +0 -322
  795. data/test/rubygems/wrong_key_cert.pem +0 -18
  796. data/test/rubygems/wrong_key_cert_32.pem +0 -18
  797. data/util/CL2notes +0 -56
  798. data/util/create_certs.rb +0 -157
  799. data/util/create_encrypted_key.rb +0 -17
  800. data/util/generate_spdx_license_list.rb +0 -51
  801. data/util/update_bundled_ca_certificates.rb +0 -118
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Gem::Resolver::Molinillo
3
4
  class Resolver
4
5
  # A specific resolution from a given {Resolver}
@@ -8,22 +9,125 @@ module Gem::Resolver::Molinillo
8
9
  # @attr [{String,Nil=>[Object]}] requirements the requirements that caused the conflict
9
10
  # @attr [Object, nil] existing the existing spec that was in conflict with
10
11
  # the {#possibility}
11
- # @attr [Object] possibility the spec that was unable to be activated due
12
- # to a conflict
12
+ # @attr [Object] possibility_set the set of specs that was unable to be
13
+ # activated due to a conflict.
13
14
  # @attr [Object] locked_requirement the relevant locking requirement.
14
15
  # @attr [Array<Array<Object>>] requirement_trees the different requirement
15
16
  # trees that led to every requirement for the conflicting name.
16
17
  # @attr [{String=>Object}] activated_by_name the already-activated specs.
18
+ # @attr [Object] underlying_error an error that has occurred during resolution, and
19
+ # will be raised at the end of it if no resolution is found.
17
20
  Conflict = Struct.new(
18
21
  :requirement,
19
22
  :requirements,
20
23
  :existing,
21
- :possibility,
24
+ :possibility_set,
22
25
  :locked_requirement,
23
26
  :requirement_trees,
24
- :activated_by_name
27
+ :activated_by_name,
28
+ :underlying_error
25
29
  )
26
30
 
31
+ class Conflict
32
+ # @return [Object] a spec that was unable to be activated due to a conflict
33
+ def possibility
34
+ possibility_set && possibility_set.latest_version
35
+ end
36
+ end
37
+
38
+ # A collection of possibility states that share the same dependencies
39
+ # @attr [Array] dependencies the dependencies for this set of possibilities
40
+ # @attr [Array] possibilities the possibilities
41
+ PossibilitySet = Struct.new(:dependencies, :possibilities)
42
+
43
+ class PossibilitySet
44
+ # String representation of the possibility set, for debugging
45
+ def to_s
46
+ "[#{possibilities.join(', ')}]"
47
+ end
48
+
49
+ # @return [Object] most up-to-date dependency in the possibility set
50
+ def latest_version
51
+ possibilities.last
52
+ end
53
+ end
54
+
55
+ # Details of the state to unwind to when a conflict occurs, and the cause of the unwind
56
+ # @attr [Integer] state_index the index of the state to unwind to
57
+ # @attr [Object] state_requirement the requirement of the state we're unwinding to
58
+ # @attr [Array] requirement_tree for the requirement we're relaxing
59
+ # @attr [Array] conflicting_requirements the requirements that combined to cause the conflict
60
+ # @attr [Array] requirement_trees for the conflict
61
+ # @attr [Array] requirements_unwound_to_instead array of unwind requirements that were chosen over this unwind
62
+ UnwindDetails = Struct.new(
63
+ :state_index,
64
+ :state_requirement,
65
+ :requirement_tree,
66
+ :conflicting_requirements,
67
+ :requirement_trees,
68
+ :requirements_unwound_to_instead
69
+ )
70
+
71
+ class UnwindDetails
72
+ include Comparable
73
+
74
+ # We compare UnwindDetails when choosing which state to unwind to. If
75
+ # two options have the same state_index we prefer the one most
76
+ # removed from a requirement that caused the conflict. Both options
77
+ # would unwind to the same state, but a `grandparent` option will
78
+ # filter out fewer of its possibilities after doing so - where a state
79
+ # is both a `parent` and a `grandparent` to requirements that have
80
+ # caused a conflict this is the correct behaviour.
81
+ # @param [UnwindDetail] other UnwindDetail to be compared
82
+ # @return [Integer] integer specifying ordering
83
+ def <=>(other)
84
+ if state_index > other.state_index
85
+ 1
86
+ elsif state_index == other.state_index
87
+ reversed_requirement_tree_index <=> other.reversed_requirement_tree_index
88
+ else
89
+ -1
90
+ end
91
+ end
92
+
93
+ # @return [Integer] index of state requirement in reversed requirement tree
94
+ # (the conflicting requirement itself will be at position 0)
95
+ def reversed_requirement_tree_index
96
+ @reversed_requirement_tree_index ||=
97
+ if state_requirement
98
+ requirement_tree.reverse.index(state_requirement)
99
+ else
100
+ 999_999
101
+ end
102
+ end
103
+
104
+ # @return [Boolean] where the requirement of the state we're unwinding
105
+ # to directly caused the conflict. Note: in this case, it is
106
+ # impossible for the state we're unwinding to to be a parent of
107
+ # any of the other conflicting requirements (or we would have
108
+ # circularity)
109
+ def unwinding_to_primary_requirement?
110
+ requirement_tree.last == state_requirement
111
+ end
112
+
113
+ # @return [Array] array of sub-dependencies to avoid when choosing a
114
+ # new possibility for the state we've unwound to. Only relevant for
115
+ # non-primary unwinds
116
+ def sub_dependencies_to_avoid
117
+ @requirements_to_avoid ||=
118
+ requirement_trees.map do |tree|
119
+ index = tree.index(state_requirement)
120
+ tree[index + 1] if index
121
+ end.compact
122
+ end
123
+
124
+ # @return [Array] array of all the requirements that led to the need for
125
+ # this unwind
126
+ def all_requirements
127
+ @all_requirements ||= requirement_trees.flatten(1)
128
+ end
129
+ end
130
+
27
131
  # @return [SpecificationProvider] the provider that knows about
28
132
  # dependencies, requirements, specifications, versions, etc.
29
133
  attr_reader :specification_provider
@@ -52,6 +156,7 @@ module Gem::Resolver::Molinillo
52
156
  @base = base
53
157
  @states = []
54
158
  @iteration_counter = 0
159
+ @parents_of = Hash.new { |h, k| h[k] = [] }
55
160
  end
56
161
 
57
162
  # Resolves the {#original_requested} dependencies into a full dependency
@@ -63,16 +168,21 @@ module Gem::Resolver::Molinillo
63
168
  start_resolution
64
169
 
65
170
  while state
66
- break unless state.requirements.any? || state.requirement
171
+ break if !state.requirement && state.requirements.empty?
67
172
  indicate_progress
68
173
  if state.respond_to?(:pop_possibility_state) # DependencyState
69
174
  debug(depth) { "Creating possibility state for #{requirement} (#{possibilities.count} remaining)" }
70
- state.pop_possibility_state.tap { |s| states.push(s) if s }
175
+ state.pop_possibility_state.tap do |s|
176
+ if s
177
+ states.push(s)
178
+ activated.tag(s)
179
+ end
180
+ end
71
181
  end
72
182
  process_topmost_state
73
183
  end
74
184
 
75
- activated.freeze
185
+ resolve_activated_specs
76
186
  ensure
77
187
  end_resolution
78
188
  end
@@ -97,12 +207,25 @@ module Gem::Resolver::Molinillo
97
207
  def start_resolution
98
208
  @started_at = Time.now
99
209
 
100
- handle_missing_or_push_dependency_state(initial_state)
210
+ push_initial_state
101
211
 
102
- debug { "Starting resolution (#{@started_at})" }
212
+ debug { "Starting resolution (#{@started_at})\nUser-requested dependencies: #{original_requested}" }
103
213
  resolver_ui.before_resolution
104
214
  end
105
215
 
216
+ def resolve_activated_specs
217
+ activated.vertices.each do |_, vertex|
218
+ next unless vertex.payload
219
+
220
+ latest_version = vertex.payload.possibilities.reverse_each.find do |possibility|
221
+ vertex.requirements.all? { |req| requirement_satisfied_by?(req, activated, possibility) }
222
+ end
223
+
224
+ activated.set_payload(vertex.name, latest_version)
225
+ end
226
+ activated.freeze
227
+ end
228
+
106
229
  # Ends the resolution process
107
230
  # @return [void]
108
231
  def end_resolution
@@ -115,30 +238,14 @@ module Gem::Resolver::Molinillo
115
238
  debug { 'Activated: ' + Hash[activated.vertices.select { |_n, v| v.payload }].keys.join(', ') } if state
116
239
  end
117
240
 
118
- require 'rubygems/resolver/molinillo/lib/molinillo/state'
119
- require 'rubygems/resolver/molinillo/lib/molinillo/modules/specification_provider'
241
+ require_relative 'state'
242
+ require_relative 'modules/specification_provider'
120
243
 
121
- ResolutionState.new.members.each do |member|
122
- define_method member do |*args, &block|
123
- current_state = state || ResolutionState.empty
124
- current_state.send(member, *args, &block)
125
- end
126
- end
244
+ require_relative 'delegates/resolution_state'
245
+ require_relative 'delegates/specification_provider'
127
246
 
128
- SpecificationProvider.instance_methods(false).each do |instance_method|
129
- define_method instance_method do |*args, &block|
130
- begin
131
- specification_provider.send(instance_method, *args, &block)
132
- rescue NoSuchDependencyError => error
133
- if state
134
- vertex = activated.vertex_named(name_for error.dependency)
135
- error.required_by += vertex.incoming_edges.map { |e| e.origin.name }
136
- error.required_by << name_for_explicit_dependency_source unless vertex.explicit_requirements.empty?
137
- end
138
- raise
139
- end
140
- end
141
- end
247
+ include Gem::Resolver::Molinillo::Delegates::ResolutionState
248
+ include Gem::Resolver::Molinillo::Delegates::SpecificationProvider
142
249
 
143
250
  # Processes the topmost available {RequirementState} on the stack
144
251
  # @return [void]
@@ -146,9 +253,12 @@ module Gem::Resolver::Molinillo
146
253
  if possibility
147
254
  attempt_to_activate
148
255
  else
149
- create_conflict if state.is_a? PossibilityState
150
- unwind_for_conflict until possibility && state.is_a?(DependencyState)
256
+ create_conflict
257
+ unwind_for_conflict
151
258
  end
259
+ rescue CircularDependencyError => underlying_error
260
+ create_conflict(underlying_error)
261
+ unwind_for_conflict
152
262
  end
153
263
 
154
264
  # @return [Object] the current possibility that the resolution is trying
@@ -163,106 +273,349 @@ module Gem::Resolver::Molinillo
163
273
  states.last
164
274
  end
165
275
 
166
- # Creates the initial state for the resolution, based upon the
276
+ # Creates and pushes the initial state for the resolution, based upon the
167
277
  # {#requested} dependencies
168
- # @return [DependencyState] the initial state for the resolution
169
- def initial_state
278
+ # @return [void]
279
+ def push_initial_state
170
280
  graph = DependencyGraph.new.tap do |dg|
171
- original_requested.each { |r| dg.add_vertex(name_for(r), nil, true).tap { |v| v.explicit_requirements << r } }
281
+ original_requested.each do |requested|
282
+ vertex = dg.add_vertex(name_for(requested), nil, true)
283
+ vertex.explicit_requirements << requested
284
+ end
285
+ dg.tag(:initial_state)
172
286
  end
173
287
 
174
- requirements = sort_dependencies(original_requested, graph, {})
175
- initial_requirement = requirements.shift
176
- DependencyState.new(
177
- initial_requirement && name_for(initial_requirement),
178
- requirements,
179
- graph,
180
- initial_requirement,
181
- initial_requirement && search_for(initial_requirement),
182
- 0,
183
- {}
184
- )
288
+ push_state_for_requirements(original_requested, true, graph)
185
289
  end
186
290
 
187
291
  # Unwinds the states stack because a conflict has been encountered
188
292
  # @return [void]
189
293
  def unwind_for_conflict
190
- debug(depth) { "Unwinding for conflict: #{requirement}" }
294
+ details_for_unwind = build_details_for_unwind
295
+ unwind_options = unused_unwind_options
296
+ debug(depth) { "Unwinding for conflict: #{requirement} to #{details_for_unwind.state_index / 2}" }
191
297
  conflicts.tap do |c|
192
- states.slice!((state_index_for_unwind + 1)..-1)
193
- raise VersionConflict.new(c) unless state
298
+ sliced_states = states.slice!((details_for_unwind.state_index + 1)..-1)
299
+ raise_error_unless_state(c)
300
+ activated.rewind_to(sliced_states.first || :initial_state) if sliced_states
194
301
  state.conflicts = c
302
+ state.unused_unwind_options = unwind_options
303
+ filter_possibilities_after_unwind(details_for_unwind)
304
+ index = states.size - 1
305
+ @parents_of.each { |_, a| a.reject! { |i| i >= index } }
306
+ state.unused_unwind_options.reject! { |uw| uw.state_index >= index }
307
+ end
308
+ end
309
+
310
+ # Raises a VersionConflict error, or any underlying error, if there is no
311
+ # current state
312
+ # @return [void]
313
+ def raise_error_unless_state(conflicts)
314
+ return if state
315
+
316
+ error = conflicts.values.map(&:underlying_error).compact.first
317
+ raise error || VersionConflict.new(conflicts, specification_provider)
318
+ end
319
+
320
+ # @return [UnwindDetails] Details of the nearest index to which we could unwind
321
+ def build_details_for_unwind
322
+ # Get the possible unwinds for the current conflict
323
+ current_conflict = conflicts[name]
324
+ binding_requirements = binding_requirements_for_conflict(current_conflict)
325
+ unwind_details = unwind_options_for_requirements(binding_requirements)
326
+
327
+ last_detail_for_current_unwind = unwind_details.sort.last
328
+ current_detail = last_detail_for_current_unwind
329
+
330
+ # Look for past conflicts that could be unwound to affect the
331
+ # requirement tree for the current conflict
332
+ all_reqs = last_detail_for_current_unwind.all_requirements
333
+ all_reqs_size = all_reqs.size
334
+ relevant_unused_unwinds = unused_unwind_options.select do |alternative|
335
+ diff_reqs = all_reqs - alternative.requirements_unwound_to_instead
336
+ next if diff_reqs.size == all_reqs_size
337
+ # Find the highest index unwind whilst looping through
338
+ current_detail = alternative if alternative > current_detail
339
+ alternative
340
+ end
341
+
342
+ # Add the current unwind options to the `unused_unwind_options` array.
343
+ # The "used" option will be filtered out during `unwind_for_conflict`.
344
+ state.unused_unwind_options += unwind_details.reject { |detail| detail.state_index == -1 }
345
+
346
+ # Update the requirements_unwound_to_instead on any relevant unused unwinds
347
+ relevant_unused_unwinds.each do |d|
348
+ (d.requirements_unwound_to_instead << current_detail.state_requirement).uniq!
349
+ end
350
+ unwind_details.each do |d|
351
+ (d.requirements_unwound_to_instead << current_detail.state_requirement).uniq!
352
+ end
353
+
354
+ current_detail
355
+ end
356
+
357
+ # @param [Array<Object>] binding_requirements array of requirements that combine to create a conflict
358
+ # @return [Array<UnwindDetails>] array of UnwindDetails that have a chance
359
+ # of resolving the passed requirements
360
+ def unwind_options_for_requirements(binding_requirements)
361
+ unwind_details = []
362
+
363
+ trees = []
364
+ binding_requirements.reverse_each do |r|
365
+ partial_tree = [r]
366
+ trees << partial_tree
367
+ unwind_details << UnwindDetails.new(-1, nil, partial_tree, binding_requirements, trees, [])
368
+
369
+ # If this requirement has alternative possibilities, check if any would
370
+ # satisfy the other requirements that created this conflict
371
+ requirement_state = find_state_for(r)
372
+ if conflict_fixing_possibilities?(requirement_state, binding_requirements)
373
+ unwind_details << UnwindDetails.new(
374
+ states.index(requirement_state),
375
+ r,
376
+ partial_tree,
377
+ binding_requirements,
378
+ trees,
379
+ []
380
+ )
381
+ end
382
+
383
+ # Next, look at the parent of this requirement, and check if the requirement
384
+ # could have been avoided if an alternative PossibilitySet had been chosen
385
+ parent_r = parent_of(r)
386
+ next if parent_r.nil?
387
+ partial_tree.unshift(parent_r)
388
+ requirement_state = find_state_for(parent_r)
389
+ if requirement_state.possibilities.any? { |set| !set.dependencies.include?(r) }
390
+ unwind_details << UnwindDetails.new(
391
+ states.index(requirement_state),
392
+ parent_r,
393
+ partial_tree,
394
+ binding_requirements,
395
+ trees,
396
+ []
397
+ )
398
+ end
399
+
400
+ # Finally, look at the grandparent and up of this requirement, looking
401
+ # for any possibilities that wouldn't create their parent requirement
402
+ grandparent_r = parent_of(parent_r)
403
+ until grandparent_r.nil?
404
+ partial_tree.unshift(grandparent_r)
405
+ requirement_state = find_state_for(grandparent_r)
406
+ if requirement_state.possibilities.any? { |set| !set.dependencies.include?(parent_r) }
407
+ unwind_details << UnwindDetails.new(
408
+ states.index(requirement_state),
409
+ grandparent_r,
410
+ partial_tree,
411
+ binding_requirements,
412
+ trees,
413
+ []
414
+ )
415
+ end
416
+ parent_r = grandparent_r
417
+ grandparent_r = parent_of(parent_r)
418
+ end
419
+ end
420
+
421
+ unwind_details
422
+ end
423
+
424
+ # @param [DependencyState] state
425
+ # @param [Array] binding_requirements array of requirements
426
+ # @return [Boolean] whether or not the given state has any possibilities
427
+ # that could satisfy the given requirements
428
+ def conflict_fixing_possibilities?(state, binding_requirements)
429
+ return false unless state
430
+
431
+ state.possibilities.any? do |possibility_set|
432
+ possibility_set.possibilities.any? do |poss|
433
+ possibility_satisfies_requirements?(poss, binding_requirements)
434
+ end
435
+ end
436
+ end
437
+
438
+ # Filter's a state's possibilities to remove any that would not fix the
439
+ # conflict we've just rewound from
440
+ # @param [UnwindDetails] unwind_details details of the conflict just
441
+ # unwound from
442
+ # @return [void]
443
+ def filter_possibilities_after_unwind(unwind_details)
444
+ return unless state && !state.possibilities.empty?
445
+
446
+ if unwind_details.unwinding_to_primary_requirement?
447
+ filter_possibilities_for_primary_unwind(unwind_details)
448
+ else
449
+ filter_possibilities_for_parent_unwind(unwind_details)
450
+ end
451
+ end
452
+
453
+ # Filter's a state's possibilities to remove any that would not satisfy
454
+ # the requirements in the conflict we've just rewound from
455
+ # @param [UnwindDetails] unwind_details details of the conflict just unwound from
456
+ # @return [void]
457
+ def filter_possibilities_for_primary_unwind(unwind_details)
458
+ unwinds_to_state = unused_unwind_options.select { |uw| uw.state_index == unwind_details.state_index }
459
+ unwinds_to_state << unwind_details
460
+ unwind_requirement_sets = unwinds_to_state.map(&:conflicting_requirements)
461
+
462
+ state.possibilities.reject! do |possibility_set|
463
+ possibility_set.possibilities.none? do |poss|
464
+ unwind_requirement_sets.any? do |requirements|
465
+ possibility_satisfies_requirements?(poss, requirements)
466
+ end
467
+ end
468
+ end
469
+ end
470
+
471
+ # @param [Object] possibility a single possibility
472
+ # @param [Array] requirements an array of requirements
473
+ # @return [Boolean] whether the possibility satisfies all of the
474
+ # given requirements
475
+ def possibility_satisfies_requirements?(possibility, requirements)
476
+ name = name_for(possibility)
477
+
478
+ activated.tag(:swap)
479
+ activated.set_payload(name, possibility) if activated.vertex_named(name)
480
+ satisfied = requirements.all? { |r| requirement_satisfied_by?(r, activated, possibility) }
481
+ activated.rewind_to(:swap)
482
+
483
+ satisfied
484
+ end
485
+
486
+ # Filter's a state's possibilities to remove any that would (eventually)
487
+ # create a requirement in the conflict we've just rewound from
488
+ # @param [UnwindDetails] unwind_details details of the conflict just unwound from
489
+ # @return [void]
490
+ def filter_possibilities_for_parent_unwind(unwind_details)
491
+ unwinds_to_state = unused_unwind_options.select { |uw| uw.state_index == unwind_details.state_index }
492
+ unwinds_to_state << unwind_details
493
+
494
+ primary_unwinds = unwinds_to_state.select(&:unwinding_to_primary_requirement?).uniq
495
+ parent_unwinds = unwinds_to_state.uniq - primary_unwinds
496
+
497
+ allowed_possibility_sets = primary_unwinds.flat_map do |unwind|
498
+ states[unwind.state_index].possibilities.select do |possibility_set|
499
+ possibility_set.possibilities.any? do |poss|
500
+ possibility_satisfies_requirements?(poss, unwind.conflicting_requirements)
501
+ end
502
+ end
503
+ end
504
+
505
+ requirements_to_avoid = parent_unwinds.flat_map(&:sub_dependencies_to_avoid)
506
+
507
+ state.possibilities.reject! do |possibility_set|
508
+ !allowed_possibility_sets.include?(possibility_set) &&
509
+ (requirements_to_avoid - possibility_set.dependencies).empty?
195
510
  end
196
511
  end
197
512
 
198
- # @return [Integer] The index to which the resolution should unwind in the
199
- # case of conflict.
200
- def state_index_for_unwind
201
- current_requirement = requirement
202
- existing_requirement = requirement_for_existing_name(name)
203
- until current_requirement.nil?
204
- current_state = find_state_for(current_requirement)
205
- return states.index(current_state) if state_any?(current_state)
206
- current_requirement = parent_of(current_requirement)
513
+ # @param [Conflict] conflict
514
+ # @return [Array] minimal array of requirements that would cause the passed
515
+ # conflict to occur.
516
+ def binding_requirements_for_conflict(conflict)
517
+ return [conflict.requirement] if conflict.possibility.nil?
518
+
519
+ possible_binding_requirements = conflict.requirements.values.flatten(1).uniq
520
+
521
+ # When there's a `CircularDependency` error the conflicting requirement
522
+ # (the one causing the circular) won't be `conflict.requirement`
523
+ # (which won't be for the right state, because we won't have created it,
524
+ # because it's circular).
525
+ # We need to make sure we have that requirement in the conflict's list,
526
+ # otherwise we won't be able to unwind properly, so we just return all
527
+ # the requirements for the conflict.
528
+ return possible_binding_requirements if conflict.underlying_error
529
+
530
+ possibilities = search_for(conflict.requirement)
531
+
532
+ # If all the requirements together don't filter out all possibilities,
533
+ # then the only two requirements we need to consider are the initial one
534
+ # (where the dependency's version was first chosen) and the last
535
+ if binding_requirement_in_set?(nil, possible_binding_requirements, possibilities)
536
+ return [conflict.requirement, requirement_for_existing_name(name_for(conflict.requirement))].compact
207
537
  end
208
538
 
209
- until existing_requirement.nil?
210
- existing_state = find_state_for(existing_requirement)
211
- return states.index(existing_state) if state_any?(existing_state)
212
- existing_requirement = parent_of(existing_requirement)
539
+ # Loop through the possible binding requirements, removing each one
540
+ # that doesn't bind. Use a `reverse_each` as we want the earliest set of
541
+ # binding requirements, and don't use `reject!` as we wish to refine the
542
+ # array *on each iteration*.
543
+ binding_requirements = possible_binding_requirements.dup
544
+ possible_binding_requirements.reverse_each do |req|
545
+ next if req == conflict.requirement
546
+ unless binding_requirement_in_set?(req, binding_requirements, possibilities)
547
+ binding_requirements -= [req]
548
+ end
213
549
  end
214
- -1
550
+
551
+ binding_requirements
215
552
  end
216
553
 
554
+ # @param [Object] requirement we wish to check
555
+ # @param [Array] possible_binding_requirements array of requirements
556
+ # @param [Array] possibilities array of possibilities the requirements will be used to filter
557
+ # @return [Boolean] whether or not the given requirement is required to filter
558
+ # out all elements of the array of possibilities.
559
+ def binding_requirement_in_set?(requirement, possible_binding_requirements, possibilities)
560
+ possibilities.any? do |poss|
561
+ possibility_satisfies_requirements?(poss, possible_binding_requirements - [requirement])
562
+ end
563
+ end
564
+
565
+ # @param [Object] requirement
217
566
  # @return [Object] the requirement that led to `requirement` being added
218
567
  # to the list of requirements.
219
568
  def parent_of(requirement)
220
- return nil unless requirement
221
- seen = false
222
- state = states.reverse_each.find do |s|
223
- seen ||= s.requirement == requirement || s.requirements.include?(requirement)
224
- seen && s.requirement != requirement && !s.requirements.include?(requirement)
225
- end
226
- state && state.requirement
569
+ return unless requirement
570
+ return unless index = @parents_of[requirement].last
571
+ return unless parent_state = @states[index]
572
+ parent_state.requirement
227
573
  end
228
574
 
575
+ # @param [String] name
229
576
  # @return [Object] the requirement that led to a version of a possibility
230
577
  # with the given name being activated.
231
578
  def requirement_for_existing_name(name)
232
- return nil unless activated.vertex_named(name).payload
233
- states.reverse_each.find { |s| !s.activated.vertex_named(name).payload }.requirement
579
+ return nil unless vertex = activated.vertex_named(name)
580
+ return nil unless vertex.payload
581
+ states.find { |s| s.name == name }.requirement
234
582
  end
235
583
 
584
+ # @param [Object] requirement
236
585
  # @return [ResolutionState] the state whose `requirement` is the given
237
586
  # `requirement`.
238
587
  def find_state_for(requirement)
239
588
  return nil unless requirement
240
- states.reverse_each.find { |i| requirement == i.requirement && i.is_a?(DependencyState) }
241
- end
242
-
243
- # @return [Boolean] whether or not the given state has any possibilities
244
- # left.
245
- def state_any?(state)
246
- state && state.possibilities.any?
589
+ states.find { |i| requirement == i.requirement }
247
590
  end
248
591
 
592
+ # @param [Object] underlying_error
249
593
  # @return [Conflict] a {Conflict} that reflects the failure to activate
250
594
  # the {#possibility} in conjunction with the current {#state}
251
- def create_conflict
595
+ def create_conflict(underlying_error = nil)
252
596
  vertex = activated.vertex_named(name)
253
- requirements = {
254
- name_for_explicit_dependency_source => vertex.explicit_requirements,
255
- name_for_locking_dependency_source => Array(locked_requirement_named(name)),
256
- }
257
- vertex.incoming_edges.each { |edge| (requirements[edge.origin.payload] ||= []).unshift(edge.requirement) }
597
+ locked_requirement = locked_requirement_named(name)
598
+
599
+ requirements = {}
600
+ unless vertex.explicit_requirements.empty?
601
+ requirements[name_for_explicit_dependency_source] = vertex.explicit_requirements
602
+ end
603
+ requirements[name_for_locking_dependency_source] = [locked_requirement] if locked_requirement
604
+ vertex.incoming_edges.each do |edge|
605
+ (requirements[edge.origin.payload.latest_version] ||= []).unshift(edge.requirement)
606
+ end
607
+
608
+ activated_by_name = {}
609
+ activated.each { |v| activated_by_name[v.name] = v.payload.latest_version if v.payload }
258
610
  conflicts[name] = Conflict.new(
259
611
  requirement,
260
- Hash[requirements.select { |_, r| !r.empty? }],
261
- vertex.payload,
612
+ requirements,
613
+ vertex.payload && vertex.payload.latest_version,
262
614
  possibility,
263
- locked_requirement_named(name),
615
+ locked_requirement,
264
616
  requirement_trees,
265
- Hash[activated.map { |v| [v.name, v.payload] }.select(&:last)]
617
+ activated_by_name,
618
+ underlying_error
266
619
  )
267
620
  end
268
621
 
@@ -273,6 +626,7 @@ module Gem::Resolver::Molinillo
273
626
  vertex.requirements.map { |r| requirement_tree_for(r) }
274
627
  end
275
628
 
629
+ # @param [Object] requirement
276
630
  # @return [Array<Object>] the list of requirements that led to
277
631
  # `requirement` being required.
278
632
  def requirement_tree_for(requirement)
@@ -312,84 +666,47 @@ module Gem::Resolver::Molinillo
312
666
  # @return [void]
313
667
  def attempt_to_activate
314
668
  debug(depth) { 'Attempting to activate ' + possibility.to_s }
315
- existing_node = activated.vertex_named(name)
316
- if existing_node.payload
317
- debug(depth) { "Found existing spec (#{existing_node.payload})" }
318
- attempt_to_activate_existing_spec(existing_node)
669
+ existing_vertex = activated.vertex_named(name)
670
+ if existing_vertex.payload
671
+ debug(depth) { "Found existing spec (#{existing_vertex.payload})" }
672
+ attempt_to_filter_existing_spec(existing_vertex)
319
673
  else
320
- attempt_to_activate_new_spec
674
+ latest = possibility.latest_version
675
+ possibility.possibilities.select! do |possibility|
676
+ requirement_satisfied_by?(requirement, activated, possibility)
677
+ end
678
+ if possibility.latest_version.nil?
679
+ # ensure there's a possibility for better error messages
680
+ possibility.possibilities << latest if latest
681
+ create_conflict
682
+ unwind_for_conflict
683
+ else
684
+ activate_new_spec
685
+ end
321
686
  end
322
687
  end
323
688
 
324
- # Attempts to activate the current {#possibility} (given that it has
325
- # already been activated)
689
+ # Attempts to update the existing vertex's `PossibilitySet` with a filtered version
326
690
  # @return [void]
327
- def attempt_to_activate_existing_spec(existing_node)
328
- existing_spec = existing_node.payload
329
- if requirement_satisfied_by?(requirement, activated, existing_spec)
691
+ def attempt_to_filter_existing_spec(vertex)
692
+ filtered_set = filtered_possibility_set(vertex)
693
+ if !filtered_set.possibilities.empty?
694
+ activated.set_payload(name, filtered_set)
330
695
  new_requirements = requirements.dup
331
696
  push_state_for_requirements(new_requirements, false)
332
- else
333
- return if attempt_to_swap_possibility
334
- create_conflict
335
- debug(depth) { "Unsatisfied by existing spec (#{existing_node.payload})" }
336
- unwind_for_conflict
337
- end
338
- end
339
-
340
- # Attempts to swp the current {#possibility} with the already-activated
341
- # spec with the given name
342
- # @return [Boolean] Whether the possibility was swapped into {#activated}
343
- def attempt_to_swap_possibility
344
- swapped = activated.dup
345
- vertex = swapped.vertex_named(name)
346
- vertex.payload = possibility
347
- return unless vertex.requirements.
348
- all? { |r| requirement_satisfied_by?(r, swapped, possibility) }
349
- return unless new_spec_satisfied?
350
- actual_vertex = activated.vertex_named(name)
351
- actual_vertex.payload = possibility
352
- fixup_swapped_children(actual_vertex)
353
- activate_spec
354
- end
355
-
356
- # Ensures there are no orphaned successors to the given {vertex}.
357
- # @param [DependencyGraph::Vertex] vertex the vertex to fix up.
358
- # @return [void]
359
- def fixup_swapped_children(vertex)
360
- payload = vertex.payload
361
- dep_names = dependencies_for(payload).map(&method(:name_for))
362
- vertex.successors.each do |succ|
363
- if !dep_names.include?(succ.name) && !succ.root? && succ.predecessors.to_a == [vertex]
364
- debug(depth) { "Removing orphaned spec #{succ.name} after swapping #{name}" }
365
- activated.detach_vertex_named(succ.name)
366
- requirements.delete_if { |r| name_for(r) == succ.name }
367
- end
368
- end
369
- end
370
-
371
- # Attempts to activate the current {#possibility} (given that it hasn't
372
- # already been activated)
373
- # @return [void]
374
- def attempt_to_activate_new_spec
375
- if new_spec_satisfied?
376
- activate_spec
377
697
  else
378
698
  create_conflict
699
+ debug(depth) { "Unsatisfied by existing spec (#{vertex.payload})" }
379
700
  unwind_for_conflict
380
701
  end
381
702
  end
382
703
 
383
- # @return [Boolean] whether the current spec is satisfied as a new
384
- # possibility.
385
- def new_spec_satisfied?
386
- locked_requirement = locked_requirement_named(name)
387
- requested_spec_satisfied = requirement_satisfied_by?(requirement, activated, possibility)
388
- locked_spec_satisfied = !locked_requirement ||
389
- requirement_satisfied_by?(locked_requirement, activated, possibility)
390
- debug(depth) { 'Unsatisfied by requested spec' } unless requested_spec_satisfied
391
- debug(depth) { 'Unsatisfied by locked spec' } unless locked_spec_satisfied
392
- requested_spec_satisfied && locked_spec_satisfied
704
+ # Generates a filtered version of the existing vertex's `PossibilitySet` using the
705
+ # current state's `requirement`
706
+ # @param [Object] vertex existing vertex
707
+ # @return [PossibilitySet] filtered possibility set
708
+ def filtered_possibility_set(vertex)
709
+ PossibilitySet.new(vertex.payload.dependencies, vertex.payload.possibilities & possibility.possibilities)
393
710
  end
394
711
 
395
712
  # @param [String] requirement_name the spec name to search for
@@ -403,46 +720,109 @@ module Gem::Resolver::Molinillo
403
720
  # Add the current {#possibility} to the dependency graph of the current
404
721
  # {#state}
405
722
  # @return [void]
406
- def activate_spec
723
+ def activate_new_spec
407
724
  conflicts.delete(name)
408
- debug(depth) { 'Activated ' + name + ' at ' + possibility.to_s }
409
- vertex = activated.vertex_named(name)
410
- vertex.payload = possibility
725
+ debug(depth) { "Activated #{name} at #{possibility}" }
726
+ activated.set_payload(name, possibility)
411
727
  require_nested_dependencies_for(possibility)
412
728
  end
413
729
 
414
730
  # Requires the dependencies that the recently activated spec has
415
- # @param [Object] activated_spec the specification that has just been
731
+ # @param [Object] possibility_set the PossibilitySet that has just been
416
732
  # activated
417
733
  # @return [void]
418
- def require_nested_dependencies_for(activated_spec)
419
- nested_dependencies = dependencies_for(activated_spec)
734
+ def require_nested_dependencies_for(possibility_set)
735
+ nested_dependencies = dependencies_for(possibility_set.latest_version)
420
736
  debug(depth) { "Requiring nested dependencies (#{nested_dependencies.join(', ')})" }
421
- nested_dependencies.each { |d| activated.add_child_vertex(name_for(d), nil, [name_for(activated_spec)], d) }
737
+ nested_dependencies.each do |d|
738
+ activated.add_child_vertex(name_for(d), nil, [name_for(possibility_set.latest_version)], d)
739
+ parent_index = states.size - 1
740
+ parents = @parents_of[d]
741
+ parents << parent_index if parents.empty?
742
+ end
422
743
 
423
- push_state_for_requirements(requirements + nested_dependencies, nested_dependencies.size > 0)
744
+ push_state_for_requirements(requirements + nested_dependencies, !nested_dependencies.empty?)
424
745
  end
425
746
 
426
747
  # Pushes a new {DependencyState} that encapsulates both existing and new
427
748
  # requirements
428
749
  # @param [Array] new_requirements
750
+ # @param [Boolean] requires_sort
751
+ # @param [Object] new_activated
429
752
  # @return [void]
430
- def push_state_for_requirements(new_requirements, requires_sort = true, new_activated = activated.dup)
753
+ def push_state_for_requirements(new_requirements, requires_sort = true, new_activated = activated)
431
754
  new_requirements = sort_dependencies(new_requirements.uniq, new_activated, conflicts) if requires_sort
432
- new_requirement = new_requirements.shift
433
- new_name = new_requirement ? name_for(new_requirement) : ''
434
- possibilities = new_requirement ? search_for(new_requirement) : []
755
+ new_requirement = nil
756
+ loop do
757
+ new_requirement = new_requirements.shift
758
+ break if new_requirement.nil? || states.none? { |s| s.requirement == new_requirement }
759
+ end
760
+ new_name = new_requirement ? name_for(new_requirement) : ''.freeze
761
+ possibilities = possibilities_for_requirement(new_requirement)
435
762
  handle_missing_or_push_dependency_state DependencyState.new(
436
763
  new_name, new_requirements, new_activated,
437
- new_requirement, possibilities, depth, conflicts.dup
764
+ new_requirement, possibilities, depth, conflicts.dup, unused_unwind_options.dup
438
765
  )
439
766
  end
440
767
 
768
+ # Checks a proposed requirement with any existing locked requirement
769
+ # before generating an array of possibilities for it.
770
+ # @param [Object] requirement the proposed requirement
771
+ # @param [Object] activated
772
+ # @return [Array] possibilities
773
+ def possibilities_for_requirement(requirement, activated = self.activated)
774
+ return [] unless requirement
775
+ if locked_requirement_named(name_for(requirement))
776
+ return locked_requirement_possibility_set(requirement, activated)
777
+ end
778
+
779
+ group_possibilities(search_for(requirement))
780
+ end
781
+
782
+ # @param [Object] requirement the proposed requirement
783
+ # @param [Object] activated
784
+ # @return [Array] possibility set containing only the locked requirement, if any
785
+ def locked_requirement_possibility_set(requirement, activated = self.activated)
786
+ all_possibilities = search_for(requirement)
787
+ locked_requirement = locked_requirement_named(name_for(requirement))
788
+
789
+ # Longwinded way to build a possibilities array with either the locked
790
+ # requirement or nothing in it. Required, since the API for
791
+ # locked_requirement isn't guaranteed.
792
+ locked_possibilities = all_possibilities.select do |possibility|
793
+ requirement_satisfied_by?(locked_requirement, activated, possibility)
794
+ end
795
+
796
+ group_possibilities(locked_possibilities)
797
+ end
798
+
799
+ # Build an array of PossibilitySets, with each element representing a group of
800
+ # dependency versions that all have the same sub-dependency version constraints
801
+ # and are contiguous.
802
+ # @param [Array] possibilities an array of possibilities
803
+ # @return [Array<PossibilitySet>] an array of possibility sets
804
+ def group_possibilities(possibilities)
805
+ possibility_sets = []
806
+ current_possibility_set = nil
807
+
808
+ possibilities.reverse_each do |possibility|
809
+ dependencies = dependencies_for(possibility)
810
+ if current_possibility_set && dependencies_equal?(current_possibility_set.dependencies, dependencies)
811
+ current_possibility_set.possibilities.unshift(possibility)
812
+ else
813
+ possibility_sets.unshift(PossibilitySet.new(dependencies, [possibility]))
814
+ current_possibility_set = possibility_sets.first
815
+ end
816
+ end
817
+
818
+ possibility_sets
819
+ end
820
+
441
821
  # Pushes a new {DependencyState}.
442
822
  # If the {#specification_provider} says to
443
823
  # {SpecificationProvider#allow_missing?} that particular requirement, and
444
824
  # there are no possibilities for that requirement, then `state` is not
445
- # pushed, and the node in {#activated} is removed, and we continue
825
+ # pushed, and the vertex in {#activated} is removed, and we continue
446
826
  # resolving the remaining requirements.
447
827
  # @param [DependencyState] state
448
828
  # @return [void]
@@ -451,7 +831,7 @@ module Gem::Resolver::Molinillo
451
831
  state.activated.detach_vertex_named(state.name)
452
832
  push_state_for_requirements(state.requirements.dup, false, state.activated)
453
833
  else
454
- states.push state
834
+ states.push(state).tap { activated.tag(state) }
455
835
  end
456
836
  end
457
837
  end