rubygems-update 3.3.26 → 3.4.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 (272) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +35 -0
  3. data/CONTRIBUTING.md +24 -1
  4. data/Manifest.txt +30 -27
  5. data/POLICIES.md +10 -8
  6. data/README.md +2 -2
  7. data/bin/gem +1 -4
  8. data/bin/update_rubygems +1 -1
  9. data/bundler/CHANGELOG.md +59 -0
  10. data/bundler/README.md +2 -2
  11. data/bundler/bundler.gemspec +2 -2
  12. data/bundler/exe/bundle +1 -4
  13. data/bundler/lib/bundler/build_metadata.rb +2 -2
  14. data/bundler/lib/bundler/cli/add.rb +1 -1
  15. data/bundler/lib/bundler/cli/check.rb +1 -1
  16. data/bundler/lib/bundler/cli/common.rb +1 -0
  17. data/bundler/lib/bundler/cli/console.rb +2 -2
  18. data/bundler/lib/bundler/cli/doctor.rb +4 -6
  19. data/bundler/lib/bundler/cli/gem.rb +62 -40
  20. data/bundler/lib/bundler/cli/install.rb +2 -3
  21. data/bundler/lib/bundler/cli/lock.rb +8 -5
  22. data/bundler/lib/bundler/cli/outdated.rb +1 -3
  23. data/bundler/lib/bundler/cli/viz.rb +1 -1
  24. data/bundler/lib/bundler/cli.rb +43 -2
  25. data/bundler/lib/bundler/compact_index_client/cache.rb +1 -1
  26. data/bundler/lib/bundler/compact_index_client/updater.rb +40 -39
  27. data/bundler/lib/bundler/constants.rb +1 -1
  28. data/bundler/lib/bundler/definition.rb +61 -31
  29. data/bundler/lib/bundler/dependency.rb +12 -11
  30. data/bundler/lib/bundler/digest.rb +1 -1
  31. data/bundler/lib/bundler/dsl.rb +1 -1
  32. data/bundler/lib/bundler/env.rb +1 -1
  33. data/bundler/lib/bundler/environment_preserver.rb +1 -0
  34. data/bundler/lib/bundler/errors.rb +1 -11
  35. data/bundler/lib/bundler/fetcher/compact_index.rb +9 -11
  36. data/bundler/lib/bundler/fetcher/dependency.rb +1 -1
  37. data/bundler/lib/bundler/fetcher/downloader.rb +2 -5
  38. data/bundler/lib/bundler/fetcher.rb +2 -6
  39. data/bundler/lib/bundler/force_platform.rb +18 -0
  40. data/bundler/lib/bundler/friendly_errors.rb +0 -3
  41. data/bundler/lib/bundler/gem_version_promoter.rb +52 -86
  42. data/bundler/lib/bundler/graph.rb +3 -3
  43. data/bundler/lib/bundler/index.rb +5 -13
  44. data/bundler/lib/bundler/injector.rb +1 -1
  45. data/bundler/lib/bundler/inline.rb +2 -2
  46. data/bundler/lib/bundler/installer/parallel_installer.rb +0 -31
  47. data/bundler/lib/bundler/installer.rb +6 -16
  48. data/bundler/lib/bundler/lazy_specification.rb +5 -1
  49. data/bundler/lib/bundler/lockfile_parser.rb +5 -5
  50. data/bundler/lib/bundler/man/bundle-add.1 +1 -1
  51. data/bundler/lib/bundler/man/bundle-binstubs.1 +1 -1
  52. data/bundler/lib/bundler/man/bundle-cache.1 +1 -1
  53. data/bundler/lib/bundler/man/bundle-check.1 +1 -1
  54. data/bundler/lib/bundler/man/bundle-clean.1 +1 -1
  55. data/bundler/lib/bundler/man/bundle-config.1 +1 -1
  56. data/bundler/lib/bundler/man/bundle-console.1 +1 -1
  57. data/bundler/lib/bundler/man/bundle-doctor.1 +1 -1
  58. data/bundler/lib/bundler/man/bundle-exec.1 +1 -1
  59. data/bundler/lib/bundler/man/bundle-gem.1 +27 -37
  60. data/bundler/lib/bundler/man/bundle-gem.1.ronn +5 -5
  61. data/bundler/lib/bundler/man/bundle-help.1 +1 -1
  62. data/bundler/lib/bundler/man/bundle-info.1 +1 -1
  63. data/bundler/lib/bundler/man/bundle-init.1 +1 -1
  64. data/bundler/lib/bundler/man/bundle-inject.1 +1 -1
  65. data/bundler/lib/bundler/man/bundle-install.1 +1 -30
  66. data/bundler/lib/bundler/man/bundle-install.1.ronn +0 -29
  67. data/bundler/lib/bundler/man/bundle-list.1 +1 -1
  68. data/bundler/lib/bundler/man/bundle-lock.1 +1 -1
  69. data/bundler/lib/bundler/man/bundle-open.1 +1 -1
  70. data/bundler/lib/bundler/man/bundle-outdated.1 +1 -1
  71. data/bundler/lib/bundler/man/bundle-platform.1 +2 -2
  72. data/bundler/lib/bundler/man/bundle-platform.1.ronn +1 -1
  73. data/bundler/lib/bundler/man/bundle-plugin.1 +1 -1
  74. data/bundler/lib/bundler/man/bundle-pristine.1 +1 -1
  75. data/bundler/lib/bundler/man/bundle-remove.1 +1 -1
  76. data/bundler/lib/bundler/man/bundle-show.1 +1 -1
  77. data/bundler/lib/bundler/man/bundle-update.1 +1 -1
  78. data/bundler/lib/bundler/man/bundle-version.1 +1 -1
  79. data/bundler/lib/bundler/man/bundle-viz.1 +1 -1
  80. data/bundler/lib/bundler/man/bundle.1 +1 -1
  81. data/bundler/lib/bundler/man/gemfile.5 +1 -1
  82. data/bundler/lib/bundler/mirror.rb +5 -7
  83. data/bundler/lib/bundler/plugin/index.rb +4 -4
  84. data/bundler/lib/bundler/plugin/installer/rubygems.rb +0 -4
  85. data/bundler/lib/bundler/resolver/base.rb +7 -11
  86. data/bundler/lib/bundler/resolver/candidate.rb +92 -0
  87. data/bundler/lib/bundler/resolver/incompatibility.rb +15 -0
  88. data/bundler/lib/bundler/resolver/package.rb +63 -0
  89. data/bundler/lib/bundler/resolver/root.rb +25 -0
  90. data/bundler/lib/bundler/resolver/spec_group.rb +26 -36
  91. data/bundler/lib/bundler/resolver.rb +294 -277
  92. data/bundler/lib/bundler/rubygems_ext.rb +11 -6
  93. data/bundler/lib/bundler/rubygems_gem_installer.rb +4 -2
  94. data/bundler/lib/bundler/rubygems_integration.rb +1 -9
  95. data/bundler/lib/bundler/runtime.rb +1 -5
  96. data/bundler/lib/bundler/settings.rb +0 -6
  97. data/bundler/lib/bundler/shared_helpers.rb +1 -0
  98. data/bundler/lib/bundler/source/git/git_proxy.rb +193 -67
  99. data/bundler/lib/bundler/source/git.rb +15 -17
  100. data/bundler/lib/bundler/source/metadata.rb +0 -1
  101. data/bundler/lib/bundler/source/path/installer.rb +1 -22
  102. data/bundler/lib/bundler/source/path.rb +5 -5
  103. data/bundler/lib/bundler/source/rubygems.rb +13 -67
  104. data/bundler/lib/bundler/source_list.rb +8 -2
  105. data/bundler/lib/bundler/spec_set.rb +7 -9
  106. data/bundler/lib/bundler/templates/Executable +1 -1
  107. data/bundler/lib/bundler/templates/Executable.bundler +4 -9
  108. data/bundler/lib/bundler/templates/Executable.standalone +2 -0
  109. data/bundler/lib/bundler/templates/newgem/Cargo.toml.tt +7 -0
  110. data/bundler/lib/bundler/templates/newgem/Gemfile.tt +3 -0
  111. data/bundler/lib/bundler/templates/newgem/README.md.tt +6 -4
  112. data/bundler/lib/bundler/templates/newgem/Rakefile.tt +2 -1
  113. data/bundler/lib/bundler/templates/newgem/circleci/config.yml.tt +12 -0
  114. data/bundler/lib/bundler/templates/newgem/ext/newgem/Cargo.toml.tt +15 -0
  115. data/bundler/lib/bundler/templates/newgem/ext/newgem/{extconf.rb.tt → extconf-c.rb.tt} +0 -0
  116. data/bundler/lib/bundler/templates/newgem/ext/newgem/extconf-rust.rb.tt +6 -0
  117. data/bundler/lib/bundler/templates/newgem/ext/newgem/src/lib.rs.tt +12 -0
  118. data/bundler/lib/bundler/templates/newgem/github/workflows/main.yml.tt +10 -0
  119. data/bundler/lib/bundler/templates/newgem/gitignore.tt +3 -0
  120. data/bundler/lib/bundler/templates/newgem/gitlab-ci.yml.tt +8 -0
  121. data/bundler/lib/bundler/templates/newgem/newgem.gemspec.tt +8 -2
  122. data/bundler/lib/bundler/ui/shell.rb +35 -12
  123. data/bundler/lib/bundler/ui/silent.rb +21 -5
  124. data/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb +3 -3
  125. data/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool/wrapper.rb +0 -1
  126. data/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool.rb +3 -1
  127. data/bundler/lib/bundler/vendor/fileutils/lib/fileutils.rb +1350 -408
  128. data/bundler/lib/bundler/vendor/net-http-persistent/README.rdoc +1 -1
  129. data/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb +1 -1
  130. data/bundler/lib/bundler/vendor/pub_grub/LICENSE.txt +21 -0
  131. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/assignment.rb +20 -0
  132. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/basic_package_source.rb +189 -0
  133. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/failure_writer.rb +182 -0
  134. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/incompatibility.rb +151 -0
  135. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/package.rb +43 -0
  136. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/partial_solution.rb +121 -0
  137. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/rubygems.rb +45 -0
  138. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/solve_failure.rb +19 -0
  139. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/static_package_source.rb +53 -0
  140. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/term.rb +105 -0
  141. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/version.rb +3 -0
  142. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/version_constraint.rb +124 -0
  143. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/version_range.rb +409 -0
  144. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/version_solver.rb +240 -0
  145. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/version_union.rb +178 -0
  146. data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub.rb +31 -0
  147. data/bundler/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +1 -1
  148. data/bundler/lib/bundler/vendor/uri/lib/uri/common.rb +64 -16
  149. data/bundler/lib/bundler/vendor/uri/lib/uri/file.rb +7 -1
  150. data/bundler/lib/bundler/vendor/uri/lib/uri/ftp.rb +2 -1
  151. data/bundler/lib/bundler/vendor/uri/lib/uri/generic.rb +27 -7
  152. data/bundler/lib/bundler/vendor/uri/lib/uri/http.rb +40 -2
  153. data/bundler/lib/bundler/vendor/uri/lib/uri/https.rb +2 -1
  154. data/bundler/lib/bundler/vendor/uri/lib/uri/ldap.rb +1 -1
  155. data/bundler/lib/bundler/vendor/uri/lib/uri/ldaps.rb +2 -1
  156. data/bundler/lib/bundler/vendor/uri/lib/uri/mailto.rb +2 -2
  157. data/bundler/lib/bundler/vendor/uri/lib/uri/rfc2396_parser.rb +13 -7
  158. data/bundler/lib/bundler/vendor/uri/lib/uri/rfc3986_parser.rb +10 -5
  159. data/bundler/lib/bundler/vendor/uri/lib/uri/version.rb +1 -1
  160. data/bundler/lib/bundler/vendor/uri/lib/uri/ws.rb +1 -2
  161. data/bundler/lib/bundler/vendor/uri/lib/uri/wss.rb +2 -1
  162. data/bundler/lib/bundler/vendor/uri/lib/uri.rb +3 -2
  163. data/bundler/lib/bundler/vendored_persistent.rb +1 -33
  164. data/bundler/lib/bundler/{vendored_tmpdir.rb → vendored_pub_grub.rb} +1 -1
  165. data/bundler/lib/bundler/version.rb +5 -1
  166. data/bundler/lib/bundler/worker.rb +5 -7
  167. data/bundler/lib/bundler.rb +20 -64
  168. data/lib/rubygems/command_manager.rb +2 -2
  169. data/lib/rubygems/commands/fetch_command.rb +1 -1
  170. data/lib/rubygems/commands/install_command.rb +7 -3
  171. data/lib/rubygems/commands/rdoc_command.rb +3 -2
  172. data/lib/rubygems/commands/setup_command.rb +2 -2
  173. data/lib/rubygems/commands/unpack_command.rb +1 -1
  174. data/lib/rubygems/commands/update_command.rb +1 -7
  175. data/lib/rubygems/config_file.rb +33 -0
  176. data/lib/rubygems/core_ext/kernel_warn.rb +1 -2
  177. data/lib/rubygems/defaults.rb +15 -1
  178. data/lib/rubygems/dependency.rb +4 -1
  179. data/lib/rubygems/dependency_installer.rb +24 -24
  180. data/lib/rubygems/exceptions.rb +1 -3
  181. data/lib/rubygems/ext/builder.rb +3 -3
  182. data/lib/rubygems/ext/cargo_builder/link_flag_converter.rb +9 -5
  183. data/lib/rubygems/ext/cargo_builder.rb +15 -20
  184. data/lib/rubygems/ext/ext_conf_builder.rb +2 -0
  185. data/lib/rubygems/indexer.rb +1 -1
  186. data/lib/rubygems/installer.rb +5 -5
  187. data/lib/rubygems/optparse/lib/optparse.rb +20 -15
  188. data/lib/rubygems/package/tar_header.rb +11 -11
  189. data/lib/rubygems/platform.rb +0 -2
  190. data/lib/rubygems/request_set/gem_dependency_api.rb +104 -104
  191. data/lib/rubygems/requirement.rb +7 -7
  192. data/lib/rubygems/resolver/installer_set.rb +1 -1
  193. data/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph.rb +1 -1
  194. data/lib/rubygems/resolver/molinillo/lib/molinillo/errors.rb +32 -26
  195. data/lib/rubygems/resolver/molinillo/lib/molinillo/gem_metadata.rb +1 -1
  196. data/lib/rubygems/security/policies.rb +40 -40
  197. data/lib/rubygems/security/trust_dir.rb +1 -1
  198. data/lib/rubygems/security.rb +3 -16
  199. data/lib/rubygems/source.rb +2 -2
  200. data/lib/rubygems/specification.rb +37 -49
  201. data/lib/rubygems/specification_policy.rb +14 -0
  202. data/lib/rubygems/stub_specification.rb +2 -2
  203. data/lib/rubygems/text.rb +1 -1
  204. data/lib/rubygems/tsort/lib/tsort.rb +308 -310
  205. data/lib/rubygems/update_suggestion.rb +69 -0
  206. data/lib/rubygems/util.rb +1 -5
  207. data/lib/rubygems/validator.rb +1 -1
  208. data/lib/rubygems.rb +8 -3
  209. data/rubygems-update.gemspec +2 -2
  210. data/test/rubygems/helper.rb +7 -3
  211. data/test/rubygems/test_bundled_ca.rb +1 -1
  212. data/test/rubygems/test_exit.rb +6 -0
  213. data/test/rubygems/test_gem.rb +4 -9
  214. data/test/rubygems/test_gem_bundler_version_finder.rb +2 -1
  215. data/test/rubygems/test_gem_command_manager.rb +1 -1
  216. data/test/rubygems/test_gem_commands_install_command.rb +19 -0
  217. data/test/rubygems/test_gem_commands_setup_command.rb +1 -8
  218. data/test/rubygems/test_gem_commands_update_command.rb +6 -6
  219. data/test/rubygems/test_gem_config_file.rb +1 -1
  220. data/test/rubygems/test_gem_dependency.rb +2 -0
  221. data/test/rubygems/test_gem_ext_builder.rb +3 -3
  222. data/test/rubygems/test_gem_ext_cargo_builder/custom_name/Cargo.lock +22 -32
  223. data/test/rubygems/test_gem_ext_cargo_builder/custom_name/Cargo.toml +1 -1
  224. data/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.lock +22 -32
  225. data/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.toml +1 -1
  226. data/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/src/lib.rs +12 -0
  227. data/test/rubygems/test_gem_ext_cargo_builder.rb +22 -27
  228. data/test/rubygems/test_gem_ext_cargo_builder_link_flag_converter.rb +16 -16
  229. data/test/rubygems/test_gem_ext_cargo_builder_unit.rb +0 -10
  230. data/test/rubygems/test_gem_indexer.rb +39 -20
  231. data/test/rubygems/test_gem_installer.rb +68 -2
  232. data/test/rubygems/test_gem_package_tar_header.rb +13 -13
  233. data/test/rubygems/test_gem_platform.rb +59 -60
  234. data/test/rubygems/test_gem_remote_fetcher.rb +4 -4
  235. data/test/rubygems/test_gem_request_set.rb +2 -2
  236. data/test/rubygems/test_gem_requirement.rb +1 -1
  237. data/test/rubygems/test_gem_resolver_api_set.rb +12 -12
  238. data/test/rubygems/test_gem_resolver_api_specification.rb +19 -19
  239. data/test/rubygems/test_gem_resolver_git_specification.rb +1 -1
  240. data/test/rubygems/test_gem_security_policy.rb +10 -10
  241. data/test/rubygems/test_gem_security_trust_dir.rb +2 -2
  242. data/test/rubygems/test_gem_specification.rb +50 -37
  243. data/test/rubygems/test_gem_uninstaller.rb +1 -1
  244. data/test/rubygems/test_gem_update_suggestion.rb +208 -0
  245. data/test/rubygems/test_kernel.rb +10 -8
  246. data/test/rubygems/test_require.rb +70 -55
  247. metadata +34 -31
  248. data/bundler/lib/bundler/templates/newgem/travis.yml.tt +0 -6
  249. data/bundler/lib/bundler/vendor/molinillo/LICENSE +0 -9
  250. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/delegates/resolution_state.rb +0 -57
  251. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/delegates/specification_provider.rb +0 -88
  252. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/action.rb +0 -36
  253. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb +0 -66
  254. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_vertex.rb +0 -62
  255. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/delete_edge.rb +0 -63
  256. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb +0 -61
  257. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/log.rb +0 -126
  258. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/set_payload.rb +0 -46
  259. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/tag.rb +0 -36
  260. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb +0 -164
  261. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb +0 -255
  262. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/errors.rb +0 -149
  263. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb +0 -6
  264. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/modules/specification_provider.rb +0 -112
  265. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/modules/ui.rb +0 -67
  266. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb +0 -839
  267. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/resolver.rb +0 -46
  268. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/state.rb +0 -58
  269. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo.rb +0 -11
  270. data/bundler/lib/bundler/vendor/tmpdir/lib/tmpdir.rb +0 -154
  271. data/bundler/lib/bundler/vendored_molinillo.rb +0 -4
  272. data/bundler/lib/bundler/version_ranges.rb +0 -122
@@ -1,7 +1,7 @@
1
1
  = net-http-persistent
2
2
 
3
3
  home :: https://github.com/drbrain/net-http-persistent
4
- rdoc :: http://docs.seattlerb.org/net-http-persistent
4
+ rdoc :: https://rdoc.info/gems/net-http-persistent
5
5
 
6
6
  == DESCRIPTION:
7
7
 
@@ -174,7 +174,7 @@ class Bundler::Persistent::Net::HTTP::Persistent
174
174
  ##
175
175
  # The version of Bundler::Persistent::Net::HTTP::Persistent you are using
176
176
 
177
- VERSION = '4.0.0'
177
+ VERSION = '4.0.1'
178
178
 
179
179
  ##
180
180
  # Error class for errors raised by Bundler::Persistent::Net::HTTP::Persistent. Various
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2018 John Hawthorn
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,20 @@
1
+ module Bundler::PubGrub
2
+ class Assignment
3
+ attr_reader :term, :cause, :decision_level, :index
4
+ def initialize(term, cause, decision_level, index)
5
+ @term = term
6
+ @cause = cause
7
+ @decision_level = decision_level
8
+ @index = index
9
+ end
10
+
11
+ def self.decision(package, version, decision_level, index)
12
+ term = Term.new(VersionConstraint.exact(package, version), true)
13
+ new(term, :decision, decision_level, index)
14
+ end
15
+
16
+ def decision?
17
+ cause == :decision
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,189 @@
1
+ require_relative 'version_constraint'
2
+ require_relative 'incompatibility'
3
+
4
+ module Bundler::PubGrub
5
+ # Types:
6
+ #
7
+ # Where possible, Bundler::PubGrub will accept user-defined types, so long as they quack.
8
+ #
9
+ # ## "Package":
10
+ #
11
+ # This class will be used to represent the various packages being solved for.
12
+ # .to_s will be called when displaying errors and debugging info, it should
13
+ # probably return the package's name.
14
+ # It must also have a reasonable definition of #== and #hash
15
+ #
16
+ # Example classes: String ("rails")
17
+ #
18
+ #
19
+ # ## "Version":
20
+ #
21
+ # This class will be used to represent a single version number.
22
+ #
23
+ # Versions don't need to store their associated package, however they will
24
+ # only be compared against other versions of the same package.
25
+ #
26
+ # It must be Comparible (and implement <=> reasonably)
27
+ #
28
+ # Example classes: Gem::Version, Integer
29
+ #
30
+ #
31
+ # ## "Dependency"
32
+ #
33
+ # This class represents the requirement one package has on another. It is
34
+ # returned by dependencies_for(package, version) and will be passed to
35
+ # parse_dependency to convert it to a format Bundler::PubGrub understands.
36
+ #
37
+ # It must also have a reasonable definition of #==
38
+ #
39
+ # Example classes: String ("~> 1.0"), Gem::Requirement
40
+ #
41
+ class BasicPackageSource
42
+ # Override me!
43
+ #
44
+ # This is called per package to find all possible versions of a package.
45
+ #
46
+ # It is called at most once per-package
47
+ #
48
+ # Returns: Array of versions for a package, in preferred order of selection
49
+ def all_versions_for(package)
50
+ raise NotImplementedError
51
+ end
52
+
53
+ # Override me!
54
+ #
55
+ # Returns: Hash in the form of { package => requirement, ... }
56
+ def dependencies_for(package, version)
57
+ raise NotImplementedError
58
+ end
59
+
60
+ # Override me!
61
+ #
62
+ # Convert a (user-defined) dependency into a format Bundler::PubGrub understands.
63
+ #
64
+ # Package is passed to this method but for many implementations is not
65
+ # needed.
66
+ #
67
+ # Returns: either a Bundler::PubGrub::VersionRange, Bundler::PubGrub::VersionUnion, or a
68
+ # Bundler::PubGrub::VersionConstraint
69
+ def parse_dependency(package, dependency)
70
+ raise NotImplementedError
71
+ end
72
+
73
+ # Override me!
74
+ #
75
+ # If not overridden, this will call dependencies_for with the root package.
76
+ #
77
+ # Returns: Hash in the form of { package => requirement, ... } (see dependencies_for)
78
+ def root_dependencies
79
+ dependencies_for(@root_package, @root_version)
80
+ end
81
+
82
+ # Override me (maybe)
83
+ #
84
+ # If not overridden, the order returned by all_versions_for will be used
85
+ #
86
+ # Returns: Array of versions in preferred order
87
+ def sort_versions_by_preferred(package, sorted_versions)
88
+ indexes = @version_indexes[package]
89
+ sorted_versions.sort_by { |version| indexes[version] }
90
+ end
91
+
92
+ def initialize
93
+ @root_package = Package.root
94
+ @root_version = Package.root_version
95
+
96
+ @cached_versions = Hash.new do |h,k|
97
+ if k == @root_package
98
+ h[k] = [@root_version]
99
+ else
100
+ h[k] = all_versions_for(k)
101
+ end
102
+ end
103
+ @sorted_versions = Hash.new { |h,k| h[k] = @cached_versions[k].sort }
104
+ @version_indexes = Hash.new { |h,k| h[k] = @cached_versions[k].each.with_index.to_h }
105
+
106
+ @cached_dependencies = Hash.new do |packages, package|
107
+ if package == @root_package
108
+ packages[package] = {
109
+ @root_version => root_dependencies
110
+ }
111
+ else
112
+ packages[package] = Hash.new do |versions, version|
113
+ versions[version] = dependencies_for(package, version)
114
+ end
115
+ end
116
+ end
117
+ end
118
+
119
+ def versions_for(package, range=VersionRange.any)
120
+ versions = range.select_versions(@sorted_versions[package])
121
+
122
+ # Conditional avoids (among other things) calling
123
+ # sort_versions_by_preferred with the root package
124
+ if versions.size > 1
125
+ sort_versions_by_preferred(package, versions)
126
+ else
127
+ versions
128
+ end
129
+ end
130
+
131
+ def no_versions_incompatibility_for(_package, unsatisfied_term)
132
+ cause = Incompatibility::NoVersions.new(unsatisfied_term)
133
+
134
+ Incompatibility.new([unsatisfied_term], cause: cause)
135
+ end
136
+
137
+ def incompatibilities_for(package, version)
138
+ package_deps = @cached_dependencies[package]
139
+ sorted_versions = @sorted_versions[package]
140
+ package_deps[version].map do |dep_package, dep_constraint_name|
141
+ low = high = sorted_versions.index(version)
142
+
143
+ # find version low such that all >= low share the same dep
144
+ while low > 0 &&
145
+ package_deps[sorted_versions[low - 1]][dep_package] == dep_constraint_name
146
+ low -= 1
147
+ end
148
+ low =
149
+ if low == 0
150
+ nil
151
+ else
152
+ sorted_versions[low]
153
+ end
154
+
155
+ # find version high such that all < high share the same dep
156
+ while high < sorted_versions.length &&
157
+ package_deps[sorted_versions[high]][dep_package] == dep_constraint_name
158
+ high += 1
159
+ end
160
+ high =
161
+ if high == sorted_versions.length
162
+ nil
163
+ else
164
+ sorted_versions[high]
165
+ end
166
+
167
+ range = VersionRange.new(min: low, max: high, include_min: true)
168
+
169
+ self_constraint = VersionConstraint.new(package, range: range)
170
+
171
+ if !@packages.include?(dep_package)
172
+ # no such package -> this version is invalid
173
+ end
174
+
175
+ dep_constraint = parse_dependency(dep_package, dep_constraint_name)
176
+ if !dep_constraint
177
+ # falsey indicates this dependency was invalid
178
+ cause = Bundler::PubGrub::Incompatibility::InvalidDependency.new(dep_package, dep_constraint_name)
179
+ return [Incompatibility.new([Term.new(self_constraint, true)], cause: cause)]
180
+ elsif !dep_constraint.is_a?(VersionConstraint)
181
+ # Upgrade range/union to VersionConstraint
182
+ dep_constraint = VersionConstraint.new(dep_package, range: dep_constraint)
183
+ end
184
+
185
+ Incompatibility.new([Term.new(self_constraint, true), Term.new(dep_constraint, false)], cause: :dependency)
186
+ end
187
+ end
188
+ end
189
+ end
@@ -0,0 +1,182 @@
1
+ module Bundler::PubGrub
2
+ class FailureWriter
3
+ def initialize(root)
4
+ @root = root
5
+
6
+ # { Incompatibility => Integer }
7
+ @derivations = {}
8
+
9
+ # [ [ String, Integer or nil ] ]
10
+ @lines = []
11
+
12
+ # { Incompatibility => Integer }
13
+ @line_numbers = {}
14
+
15
+ count_derivations(root)
16
+ end
17
+
18
+ def write
19
+ return @root.to_s unless @root.conflict?
20
+
21
+ visit(@root)
22
+
23
+ padding = @line_numbers.empty? ? 0 : "(#{@line_numbers.values.last}) ".length
24
+
25
+ @lines.map do |message, number|
26
+ next "" if message.empty?
27
+
28
+ lead = number ? "(#{number}) " : ""
29
+ lead = lead.ljust(padding)
30
+ message = message.gsub("\n", "\n" + " " * (padding + 2))
31
+ "#{lead}#{message}"
32
+ end.join("\n")
33
+ end
34
+
35
+ private
36
+
37
+ def write_line(incompatibility, message, numbered:)
38
+ if numbered
39
+ number = @line_numbers.length + 1
40
+ @line_numbers[incompatibility] = number
41
+ end
42
+
43
+ @lines << [message, number]
44
+ end
45
+
46
+ def visit(incompatibility, conclusion: false)
47
+ raise unless incompatibility.conflict?
48
+
49
+ numbered = conclusion || @derivations[incompatibility] > 1;
50
+ conjunction = conclusion || incompatibility == @root ? "So," : "And"
51
+
52
+ cause = incompatibility.cause
53
+
54
+ if cause.conflict.conflict? && cause.other.conflict?
55
+ conflict_line = @line_numbers[cause.conflict]
56
+ other_line = @line_numbers[cause.other]
57
+
58
+ if conflict_line && other_line
59
+ write_line(
60
+ incompatibility,
61
+ "Because #{cause.conflict} (#{conflict_line})\nand #{cause.other} (#{other_line}),\n#{incompatibility}.",
62
+ numbered: numbered
63
+ )
64
+ elsif conflict_line || other_line
65
+ with_line = conflict_line ? cause.conflict : cause.other
66
+ without_line = conflict_line ? cause.other : cause.conflict
67
+ line = @line_numbers[with_line]
68
+
69
+ visit(without_line);
70
+ write_line(
71
+ incompatibility,
72
+ "#{conjunction} because #{with_line} (#{line}),\n#{incompatibility}.",
73
+ numbered: numbered
74
+ )
75
+ else
76
+ single_line_conflict = single_line?(cause.conflict.cause)
77
+ single_line_other = single_line?(cause.other.cause)
78
+
79
+ if single_line_conflict || single_line_other
80
+ first = single_line_other ? cause.conflict : cause.other
81
+ second = single_line_other ? cause.other : cause.conflict
82
+ visit(first)
83
+ visit(second)
84
+ write_line(
85
+ incompatibility,
86
+ "Thus, #{incompatibility}.",
87
+ numbered: numbered
88
+ )
89
+ else
90
+ visit(cause.conflict, conclusion: true)
91
+ @lines << ["", nil]
92
+ visit(cause.other)
93
+
94
+ write_line(
95
+ incompatibility,
96
+ "#{conjunction} because #{cause.conflict} (#{@line_numbers[cause.conflict]}),\n#{incompatibility}.",
97
+ numbered: numbered
98
+ )
99
+ end
100
+ end
101
+ elsif cause.conflict.conflict? || cause.other.conflict?
102
+ derived = cause.conflict.conflict? ? cause.conflict : cause.other
103
+ ext = cause.conflict.conflict? ? cause.other : cause.conflict
104
+
105
+ derived_line = @line_numbers[derived]
106
+ if derived_line
107
+ write_line(
108
+ incompatibility,
109
+ "Because #{ext}\nand #{derived} (#{derived_line}),\n#{incompatibility}.",
110
+ numbered: numbered
111
+ )
112
+ elsif collapsible?(derived)
113
+ derived_cause = derived.cause
114
+ if derived_cause.conflict.conflict?
115
+ collapsed_derived = derived_cause.conflict
116
+ collapsed_ext = derived_cause.other
117
+ else
118
+ collapsed_derived = derived_cause.other
119
+ collapsed_ext = derived_cause.conflict
120
+ end
121
+
122
+ visit(collapsed_derived)
123
+
124
+ write_line(
125
+ incompatibility,
126
+ "#{conjunction} because #{collapsed_ext}\nand #{ext},\n#{incompatibility}.",
127
+ numbered: numbered
128
+ )
129
+ else
130
+ visit(derived)
131
+ write_line(
132
+ incompatibility,
133
+ "#{conjunction} because #{ext},\n#{incompatibility}.",
134
+ numbered: numbered
135
+ )
136
+ end
137
+ else
138
+ write_line(
139
+ incompatibility,
140
+ "Because #{cause.conflict}\nand #{cause.other},\n#{incompatibility}.",
141
+ numbered: numbered
142
+ )
143
+ end
144
+ end
145
+
146
+ def single_line?(cause)
147
+ !cause.conflict.conflict? && !cause.other.conflict?
148
+ end
149
+
150
+ def collapsible?(incompatibility)
151
+ return false if @derivations[incompatibility] > 1
152
+
153
+ cause = incompatibility.cause
154
+ # If incompatibility is derived from two derived incompatibilities,
155
+ # there are too many transitive causes to display concisely.
156
+ return false if cause.conflict.conflict? && cause.other.conflict?
157
+
158
+ # If incompatibility is derived from two external incompatibilities, it
159
+ # tends to be confusing to collapse it.
160
+ return false unless cause.conflict.conflict? || cause.other.conflict?
161
+
162
+ # If incompatibility's internal cause is numbered, collapsing it would
163
+ # get too noisy.
164
+ complex = cause.conflict.conflict? ? cause.conflict : cause.other
165
+
166
+ !@line_numbers.has_key?(complex)
167
+ end
168
+
169
+ def count_derivations(incompatibility)
170
+ if @derivations.has_key?(incompatibility)
171
+ @derivations[incompatibility] += 1
172
+ else
173
+ @derivations[incompatibility] = 1
174
+ if incompatibility.conflict?
175
+ cause = incompatibility.cause
176
+ count_derivations(cause.conflict)
177
+ count_derivations(cause.other)
178
+ end
179
+ end
180
+ end
181
+ end
182
+ end
@@ -0,0 +1,151 @@
1
+ module Bundler::PubGrub
2
+ class Incompatibility
3
+ ConflictCause = Struct.new(:incompatibility, :satisfier) do
4
+ alias_method :conflict, :incompatibility
5
+ alias_method :other, :satisfier
6
+ end
7
+
8
+ InvalidDependency = Struct.new(:package, :constraint) do
9
+ end
10
+
11
+ CircularDependency = Struct.new(:package, :constraint) do
12
+ end
13
+
14
+ NoVersions = Struct.new(:constraint) do
15
+ end
16
+
17
+ attr_reader :terms, :cause
18
+
19
+ def initialize(terms, cause:, custom_explanation: nil)
20
+ @cause = cause
21
+ @terms = cleanup_terms(terms)
22
+ @custom_explanation = custom_explanation
23
+
24
+ if cause == :dependency && @terms.length != 2
25
+ raise ArgumentError, "a dependency Incompatibility must have exactly two terms. Got #{@terms.inspect}"
26
+ end
27
+ end
28
+
29
+ def hash
30
+ cause.hash ^ terms.hash
31
+ end
32
+
33
+ def eql?(other)
34
+ cause.eql?(other.cause) &&
35
+ terms.eql?(other.terms)
36
+ end
37
+
38
+ def failure?
39
+ terms.empty? || (terms.length == 1 && Package.root?(terms[0].package) && terms[0].positive?)
40
+ end
41
+
42
+ def conflict?
43
+ ConflictCause === cause
44
+ end
45
+
46
+ # Returns all external incompatibilities in this incompatibility's
47
+ # derivation graph
48
+ def external_incompatibilities
49
+ if conflict?
50
+ [
51
+ cause.conflict,
52
+ cause.other
53
+ ].flat_map(&:external_incompatibilities)
54
+ else
55
+ [this]
56
+ end
57
+ end
58
+
59
+ def to_s
60
+ return @custom_explanation if @custom_explanation
61
+
62
+ case cause
63
+ when :root
64
+ "(root dependency)"
65
+ when :dependency
66
+ "#{terms[0].to_s(allow_every: true)} depends on #{terms[1].invert}"
67
+ when Bundler::PubGrub::Incompatibility::InvalidDependency
68
+ "#{terms[0].to_s(allow_every: true)} depends on unknown package #{cause.package}"
69
+ when Bundler::PubGrub::Incompatibility::CircularDependency
70
+ "#{terms[0].to_s(allow_every: true)} depends on itself"
71
+ when Bundler::PubGrub::Incompatibility::NoVersions
72
+ "no versions satisfy #{cause.constraint}"
73
+ when Bundler::PubGrub::Incompatibility::ConflictCause
74
+ if failure?
75
+ "version solving has failed"
76
+ elsif terms.length == 1
77
+ term = terms[0]
78
+ if term.positive?
79
+ "#{terms[0].to_s(allow_every: true)} is forbidden"
80
+ else
81
+ "#{terms[0].invert} is required"
82
+ end
83
+ else
84
+ if terms.all?(&:positive?)
85
+ if terms.length == 2
86
+ "#{terms[0].to_s(allow_every: true)} is incompatible with #{terms[1]}"
87
+ else
88
+ "one of #{terms.map(&:to_s).join(" or ")} must be false"
89
+ end
90
+ elsif terms.all?(&:negative?)
91
+ if terms.length == 2
92
+ "either #{terms[0].invert} or #{terms[1].invert}"
93
+ else
94
+ "one of #{terms.map(&:invert).join(" or ")} must be true";
95
+ end
96
+ else
97
+ positive = terms.select(&:positive?)
98
+ negative = terms.select(&:negative?).map(&:invert)
99
+
100
+ if positive.length == 1
101
+ "#{positive[0].to_s(allow_every: true)} requires #{negative.join(" or ")}"
102
+ else
103
+ "if #{positive.join(" and ")} then #{negative.join(" or ")}"
104
+ end
105
+ end
106
+ end
107
+ else
108
+ raise "unhandled cause: #{cause.inspect}"
109
+ end
110
+ end
111
+
112
+ def inspect
113
+ "#<#{self.class} #{to_s}>"
114
+ end
115
+
116
+ def pretty_print(q)
117
+ q.group 2, "#<#{self.class}", ">" do
118
+ q.breakable
119
+ q.text to_s
120
+
121
+ q.breakable
122
+ q.text " caused by "
123
+ q.pp @cause
124
+ end
125
+ end
126
+
127
+ private
128
+
129
+ def cleanup_terms(terms)
130
+ terms.each do |term|
131
+ raise "#{term.inspect} must be a term" unless term.is_a?(Term)
132
+ end
133
+
134
+ if terms.length != 1 && ConflictCause === cause
135
+ terms = terms.reject do |term|
136
+ term.positive? && Package.root?(term.package)
137
+ end
138
+ end
139
+
140
+ # Optimized simple cases
141
+ return terms if terms.length <= 1
142
+ return terms if terms.length == 2 && terms[0].package != terms[1].package
143
+
144
+ terms.group_by(&:package).map do |package, common_terms|
145
+ common_terms.inject do |acc, term|
146
+ acc.intersect(term)
147
+ end
148
+ end
149
+ end
150
+ end
151
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bundler::PubGrub
4
+ class Package
5
+
6
+ attr_reader :name
7
+
8
+ def initialize(name)
9
+ @name = name
10
+ end
11
+
12
+ def inspect
13
+ "#<#{self.class} #{name.inspect}>"
14
+ end
15
+
16
+ def <=>(other)
17
+ name <=> other.name
18
+ end
19
+
20
+ ROOT = Package.new(:root)
21
+ ROOT_VERSION = 0
22
+
23
+ def self.root
24
+ ROOT
25
+ end
26
+
27
+ def self.root_version
28
+ ROOT_VERSION
29
+ end
30
+
31
+ def self.root?(package)
32
+ if package.respond_to?(:root?)
33
+ package.root?
34
+ else
35
+ package == root
36
+ end
37
+ end
38
+
39
+ def to_s
40
+ name.to_s
41
+ end
42
+ end
43
+ end