bundler_pack 4.0.15

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 (350) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +5670 -0
  3. data/LICENSE.md +22 -0
  4. data/README.md +58 -0
  5. data/bundler.gemspec +46 -0
  6. data/exe/bundle +29 -0
  7. data/exe/bundler +4 -0
  8. data/lib/bundler/.document +1 -0
  9. data/lib/bundler/build_metadata.rb +44 -0
  10. data/lib/bundler/capistrano.rb +4 -0
  11. data/lib/bundler/checksum.rb +270 -0
  12. data/lib/bundler/ci_detector.rb +75 -0
  13. data/lib/bundler/cli/add.rb +62 -0
  14. data/lib/bundler/cli/binstubs.rb +57 -0
  15. data/lib/bundler/cli/cache.rb +32 -0
  16. data/lib/bundler/cli/check.rb +40 -0
  17. data/lib/bundler/cli/clean.rb +25 -0
  18. data/lib/bundler/cli/common.rb +161 -0
  19. data/lib/bundler/cli/config.rb +208 -0
  20. data/lib/bundler/cli/console.rb +47 -0
  21. data/lib/bundler/cli/doctor/diagnose.rb +167 -0
  22. data/lib/bundler/cli/doctor/ssl.rb +249 -0
  23. data/lib/bundler/cli/doctor.rb +33 -0
  24. data/lib/bundler/cli/exec.rb +114 -0
  25. data/lib/bundler/cli/fund.rb +36 -0
  26. data/lib/bundler/cli/gem.rb +493 -0
  27. data/lib/bundler/cli/info.rb +83 -0
  28. data/lib/bundler/cli/init.rb +51 -0
  29. data/lib/bundler/cli/install.rb +127 -0
  30. data/lib/bundler/cli/issue.rb +41 -0
  31. data/lib/bundler/cli/list.rb +97 -0
  32. data/lib/bundler/cli/lock.rb +94 -0
  33. data/lib/bundler/cli/open.rb +29 -0
  34. data/lib/bundler/cli/outdated.rb +337 -0
  35. data/lib/bundler/cli/platform.rb +48 -0
  36. data/lib/bundler/cli/plugin.rb +39 -0
  37. data/lib/bundler/cli/pristine.rb +64 -0
  38. data/lib/bundler/cli/remove.rb +17 -0
  39. data/lib/bundler/cli/show.rb +71 -0
  40. data/lib/bundler/cli/update.rb +125 -0
  41. data/lib/bundler/cli.rb +829 -0
  42. data/lib/bundler/compact_index_client/cache.rb +96 -0
  43. data/lib/bundler/compact_index_client/cache_file.rb +148 -0
  44. data/lib/bundler/compact_index_client/parser.rb +87 -0
  45. data/lib/bundler/compact_index_client/updater.rb +105 -0
  46. data/lib/bundler/compact_index_client.rb +92 -0
  47. data/lib/bundler/constants.rb +14 -0
  48. data/lib/bundler/current_ruby.rb +94 -0
  49. data/lib/bundler/definition.rb +1304 -0
  50. data/lib/bundler/dependency.rb +151 -0
  51. data/lib/bundler/deployment.rb +6 -0
  52. data/lib/bundler/deprecate.rb +44 -0
  53. data/lib/bundler/digest.rb +71 -0
  54. data/lib/bundler/dsl.rb +642 -0
  55. data/lib/bundler/endpoint_specification.rb +184 -0
  56. data/lib/bundler/env.rb +148 -0
  57. data/lib/bundler/environment_preserver.rb +69 -0
  58. data/lib/bundler/errors.rb +277 -0
  59. data/lib/bundler/feature_flag.rb +20 -0
  60. data/lib/bundler/fetcher/base.rb +55 -0
  61. data/lib/bundler/fetcher/compact_index.rb +133 -0
  62. data/lib/bundler/fetcher/dependency.rb +85 -0
  63. data/lib/bundler/fetcher/downloader.rb +116 -0
  64. data/lib/bundler/fetcher/gem_remote_fetcher.rb +24 -0
  65. data/lib/bundler/fetcher/index.rb +25 -0
  66. data/lib/bundler/fetcher.rb +365 -0
  67. data/lib/bundler/force_platform.rb +16 -0
  68. data/lib/bundler/friendly_errors.rb +127 -0
  69. data/lib/bundler/gem_helper.rb +237 -0
  70. data/lib/bundler/gem_tasks.rb +7 -0
  71. data/lib/bundler/gem_version_promoter.rb +147 -0
  72. data/lib/bundler/index.rb +203 -0
  73. data/lib/bundler/injector.rb +284 -0
  74. data/lib/bundler/inline.rb +106 -0
  75. data/lib/bundler/installer/gem_installer.rb +88 -0
  76. data/lib/bundler/installer/parallel_installer.rb +280 -0
  77. data/lib/bundler/installer/standalone.rb +113 -0
  78. data/lib/bundler/installer.rb +241 -0
  79. data/lib/bundler/lazy_specification.rb +270 -0
  80. data/lib/bundler/lockfile_generator.rb +119 -0
  81. data/lib/bundler/lockfile_parser.rb +328 -0
  82. data/lib/bundler/man/.document +1 -0
  83. data/lib/bundler/man/bundle-add.1 +79 -0
  84. data/lib/bundler/man/bundle-add.1.ronn +92 -0
  85. data/lib/bundler/man/bundle-binstubs.1 +30 -0
  86. data/lib/bundler/man/bundle-binstubs.1.ronn +42 -0
  87. data/lib/bundler/man/bundle-cache.1 +56 -0
  88. data/lib/bundler/man/bundle-cache.1.ronn +95 -0
  89. data/lib/bundler/man/bundle-check.1 +21 -0
  90. data/lib/bundler/man/bundle-check.1.ronn +26 -0
  91. data/lib/bundler/man/bundle-clean.1 +17 -0
  92. data/lib/bundler/man/bundle-clean.1.ronn +18 -0
  93. data/lib/bundler/man/bundle-config.1 +339 -0
  94. data/lib/bundler/man/bundle-config.1.ronn +455 -0
  95. data/lib/bundler/man/bundle-console.1 +33 -0
  96. data/lib/bundler/man/bundle-console.1.ronn +39 -0
  97. data/lib/bundler/man/bundle-doctor.1 +69 -0
  98. data/lib/bundler/man/bundle-doctor.1.ronn +77 -0
  99. data/lib/bundler/man/bundle-env.1 +9 -0
  100. data/lib/bundler/man/bundle-env.1.ronn +10 -0
  101. data/lib/bundler/man/bundle-exec.1 +104 -0
  102. data/lib/bundler/man/bundle-exec.1.ronn +150 -0
  103. data/lib/bundler/man/bundle-fund.1 +22 -0
  104. data/lib/bundler/man/bundle-fund.1.ronn +25 -0
  105. data/lib/bundler/man/bundle-gem.1 +107 -0
  106. data/lib/bundler/man/bundle-gem.1.ronn +150 -0
  107. data/lib/bundler/man/bundle-help.1 +9 -0
  108. data/lib/bundler/man/bundle-help.1.ronn +12 -0
  109. data/lib/bundler/man/bundle-info.1 +17 -0
  110. data/lib/bundler/man/bundle-info.1.ronn +21 -0
  111. data/lib/bundler/man/bundle-init.1 +20 -0
  112. data/lib/bundler/man/bundle-init.1.ronn +32 -0
  113. data/lib/bundler/man/bundle-install.1 +178 -0
  114. data/lib/bundler/man/bundle-install.1.ronn +314 -0
  115. data/lib/bundler/man/bundle-issue.1 +45 -0
  116. data/lib/bundler/man/bundle-issue.1.ronn +37 -0
  117. data/lib/bundler/man/bundle-licenses.1 +9 -0
  118. data/lib/bundler/man/bundle-licenses.1.ronn +10 -0
  119. data/lib/bundler/man/bundle-list.1 +40 -0
  120. data/lib/bundler/man/bundle-list.1.ronn +41 -0
  121. data/lib/bundler/man/bundle-lock.1 +75 -0
  122. data/lib/bundler/man/bundle-lock.1.ronn +115 -0
  123. data/lib/bundler/man/bundle-open.1 +32 -0
  124. data/lib/bundler/man/bundle-open.1.ronn +28 -0
  125. data/lib/bundler/man/bundle-outdated.1 +106 -0
  126. data/lib/bundler/man/bundle-outdated.1.ronn +117 -0
  127. data/lib/bundler/man/bundle-platform.1 +49 -0
  128. data/lib/bundler/man/bundle-platform.1.ronn +49 -0
  129. data/lib/bundler/man/bundle-plugin.1 +76 -0
  130. data/lib/bundler/man/bundle-plugin.1.ronn +84 -0
  131. data/lib/bundler/man/bundle-pristine.1 +23 -0
  132. data/lib/bundler/man/bundle-pristine.1.ronn +34 -0
  133. data/lib/bundler/man/bundle-remove.1 +15 -0
  134. data/lib/bundler/man/bundle-remove.1.ronn +16 -0
  135. data/lib/bundler/man/bundle-show.1 +16 -0
  136. data/lib/bundler/man/bundle-show.1.ronn +21 -0
  137. data/lib/bundler/man/bundle-update.1 +284 -0
  138. data/lib/bundler/man/bundle-update.1.ronn +367 -0
  139. data/lib/bundler/man/bundle-version.1 +22 -0
  140. data/lib/bundler/man/bundle-version.1.ronn +24 -0
  141. data/lib/bundler/man/bundle.1 +93 -0
  142. data/lib/bundler/man/bundle.1.ronn +107 -0
  143. data/lib/bundler/man/gemfile.5 +503 -0
  144. data/lib/bundler/man/gemfile.5.ronn +586 -0
  145. data/lib/bundler/man/index.txt +31 -0
  146. data/lib/bundler/match_metadata.rb +30 -0
  147. data/lib/bundler/match_platform.rb +42 -0
  148. data/lib/bundler/match_remote_metadata.rb +29 -0
  149. data/lib/bundler/materialization.rb +59 -0
  150. data/lib/bundler/mirror.rb +221 -0
  151. data/lib/bundler/plugin/api/source.rb +330 -0
  152. data/lib/bundler/plugin/api.rb +81 -0
  153. data/lib/bundler/plugin/dsl.rb +53 -0
  154. data/lib/bundler/plugin/events.rb +85 -0
  155. data/lib/bundler/plugin/index.rb +203 -0
  156. data/lib/bundler/plugin/installer/git.rb +34 -0
  157. data/lib/bundler/plugin/installer/path.rb +26 -0
  158. data/lib/bundler/plugin/installer/rubygems.rb +19 -0
  159. data/lib/bundler/plugin/installer.rb +123 -0
  160. data/lib/bundler/plugin/source_list.rb +31 -0
  161. data/lib/bundler/plugin/unloaded_source.rb +25 -0
  162. data/lib/bundler/plugin.rb +387 -0
  163. data/lib/bundler/process_lock.rb +20 -0
  164. data/lib/bundler/remote_specification.rb +126 -0
  165. data/lib/bundler/resolver/base.rb +127 -0
  166. data/lib/bundler/resolver/candidate.rb +85 -0
  167. data/lib/bundler/resolver/incompatibility.rb +15 -0
  168. data/lib/bundler/resolver/package.rb +95 -0
  169. data/lib/bundler/resolver/root.rb +25 -0
  170. data/lib/bundler/resolver/spec_group.rb +74 -0
  171. data/lib/bundler/resolver/strategy.rb +43 -0
  172. data/lib/bundler/resolver.rb +603 -0
  173. data/lib/bundler/retry.rb +92 -0
  174. data/lib/bundler/ruby_dsl.rb +67 -0
  175. data/lib/bundler/ruby_version.rb +135 -0
  176. data/lib/bundler/rubygems_ext.rb +503 -0
  177. data/lib/bundler/rubygems_gem_installer.rb +206 -0
  178. data/lib/bundler/rubygems_integration.rb +456 -0
  179. data/lib/bundler/runtime.rb +331 -0
  180. data/lib/bundler/safe_marshal.rb +31 -0
  181. data/lib/bundler/self_manager.rb +197 -0
  182. data/lib/bundler/settings/validator.rb +86 -0
  183. data/lib/bundler/settings.rb +585 -0
  184. data/lib/bundler/setup.rb +39 -0
  185. data/lib/bundler/shared_helpers.rb +392 -0
  186. data/lib/bundler/source/gemspec.rb +19 -0
  187. data/lib/bundler/source/git/git_proxy.rb +509 -0
  188. data/lib/bundler/source/git.rb +451 -0
  189. data/lib/bundler/source/metadata.rb +67 -0
  190. data/lib/bundler/source/path/installer.rb +53 -0
  191. data/lib/bundler/source/path.rb +256 -0
  192. data/lib/bundler/source/rubygems/remote.rb +86 -0
  193. data/lib/bundler/source/rubygems.rb +606 -0
  194. data/lib/bundler/source/rubygems_aggregate.rb +71 -0
  195. data/lib/bundler/source.rb +120 -0
  196. data/lib/bundler/source_list.rb +240 -0
  197. data/lib/bundler/source_map.rb +72 -0
  198. data/lib/bundler/spec_set.rb +390 -0
  199. data/lib/bundler/stub_specification.rb +147 -0
  200. data/lib/bundler/templates/.document +1 -0
  201. data/lib/bundler/templates/Executable +16 -0
  202. data/lib/bundler/templates/Executable.standalone +14 -0
  203. data/lib/bundler/templates/Gemfile +5 -0
  204. data/lib/bundler/templates/newgem/CHANGELOG.md.tt +5 -0
  205. data/lib/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt +10 -0
  206. data/lib/bundler/templates/newgem/Cargo.toml.tt +13 -0
  207. data/lib/bundler/templates/newgem/Gemfile.tt +24 -0
  208. data/lib/bundler/templates/newgem/LICENSE.txt.tt +21 -0
  209. data/lib/bundler/templates/newgem/README.md.tt +49 -0
  210. data/lib/bundler/templates/newgem/Rakefile.tt +72 -0
  211. data/lib/bundler/templates/newgem/bin/console.tt +11 -0
  212. data/lib/bundler/templates/newgem/bin/setup.tt +8 -0
  213. data/lib/bundler/templates/newgem/circleci/config.yml.tt +37 -0
  214. data/lib/bundler/templates/newgem/exe/newgem.tt +3 -0
  215. data/lib/bundler/templates/newgem/ext/newgem/Cargo.toml.tt +22 -0
  216. data/lib/bundler/templates/newgem/ext/newgem/build.rs.tt +5 -0
  217. data/lib/bundler/templates/newgem/ext/newgem/extconf-c.rb.tt +10 -0
  218. data/lib/bundler/templates/newgem/ext/newgem/extconf-go.rb.tt +11 -0
  219. data/lib/bundler/templates/newgem/ext/newgem/extconf-rust.rb.tt +6 -0
  220. data/lib/bundler/templates/newgem/ext/newgem/go.mod.tt +5 -0
  221. data/lib/bundler/templates/newgem/ext/newgem/newgem-go.c.tt +2 -0
  222. data/lib/bundler/templates/newgem/ext/newgem/newgem.c.tt +9 -0
  223. data/lib/bundler/templates/newgem/ext/newgem/newgem.go.tt +31 -0
  224. data/lib/bundler/templates/newgem/ext/newgem/newgem.h.tt +6 -0
  225. data/lib/bundler/templates/newgem/ext/newgem/src/lib.rs.tt +23 -0
  226. data/lib/bundler/templates/newgem/github/workflows/build-gems.yml.tt +69 -0
  227. data/lib/bundler/templates/newgem/github/workflows/main.yml.tt +48 -0
  228. data/lib/bundler/templates/newgem/gitignore.tt +23 -0
  229. data/lib/bundler/templates/newgem/gitlab-ci.yml.tt +27 -0
  230. data/lib/bundler/templates/newgem/lib/newgem/version.rb.tt +9 -0
  231. data/lib/bundler/templates/newgem/lib/newgem.rb.tt +15 -0
  232. data/lib/bundler/templates/newgem/newgem.gemspec.tt +58 -0
  233. data/lib/bundler/templates/newgem/rspec.tt +3 -0
  234. data/lib/bundler/templates/newgem/rubocop.yml.tt +8 -0
  235. data/lib/bundler/templates/newgem/sig/newgem.rbs.tt +8 -0
  236. data/lib/bundler/templates/newgem/spec/newgem_spec.rb.tt +19 -0
  237. data/lib/bundler/templates/newgem/spec/spec_helper.rb.tt +15 -0
  238. data/lib/bundler/templates/newgem/standard.yml.tt +3 -0
  239. data/lib/bundler/templates/newgem/test/minitest/test_helper.rb.tt +6 -0
  240. data/lib/bundler/templates/newgem/test/minitest/test_newgem.rb.tt +19 -0
  241. data/lib/bundler/templates/newgem/test/test-unit/newgem_test.rb.tt +15 -0
  242. data/lib/bundler/templates/newgem/test/test-unit/test_helper.rb.tt +6 -0
  243. data/lib/bundler/ui/rg_proxy.rb +19 -0
  244. data/lib/bundler/ui/shell.rb +191 -0
  245. data/lib/bundler/ui/silent.rb +96 -0
  246. data/lib/bundler/ui.rb +9 -0
  247. data/lib/bundler/uri_credentials_filter.rb +43 -0
  248. data/lib/bundler/uri_normalizer.rb +23 -0
  249. data/lib/bundler/vendor/.document +1 -0
  250. data/lib/bundler/vendor/connection_pool/LICENSE +20 -0
  251. data/lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb +227 -0
  252. data/lib/bundler/vendor/connection_pool/lib/connection_pool/version.rb +3 -0
  253. data/lib/bundler/vendor/connection_pool/lib/connection_pool/wrapper.rb +56 -0
  254. data/lib/bundler/vendor/connection_pool/lib/connection_pool.rb +230 -0
  255. data/lib/bundler/vendor/fileutils/COPYING +56 -0
  256. data/lib/bundler/vendor/fileutils/lib/fileutils.rb +2701 -0
  257. data/lib/bundler/vendor/net-http-persistent/README.rdoc +82 -0
  258. data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/connection.rb +41 -0
  259. data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/pool.rb +65 -0
  260. data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/timed_stack_multi.rb +80 -0
  261. data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb +1153 -0
  262. data/lib/bundler/vendor/pub_grub/LICENSE.txt +21 -0
  263. data/lib/bundler/vendor/pub_grub/lib/pub_grub/assignment.rb +20 -0
  264. data/lib/bundler/vendor/pub_grub/lib/pub_grub/basic_package_source.rb +169 -0
  265. data/lib/bundler/vendor/pub_grub/lib/pub_grub/failure_writer.rb +182 -0
  266. data/lib/bundler/vendor/pub_grub/lib/pub_grub/incompatibility.rb +150 -0
  267. data/lib/bundler/vendor/pub_grub/lib/pub_grub/package.rb +43 -0
  268. data/lib/bundler/vendor/pub_grub/lib/pub_grub/partial_solution.rb +121 -0
  269. data/lib/bundler/vendor/pub_grub/lib/pub_grub/rubygems.rb +45 -0
  270. data/lib/bundler/vendor/pub_grub/lib/pub_grub/solve_failure.rb +19 -0
  271. data/lib/bundler/vendor/pub_grub/lib/pub_grub/static_package_source.rb +61 -0
  272. data/lib/bundler/vendor/pub_grub/lib/pub_grub/strategy.rb +42 -0
  273. data/lib/bundler/vendor/pub_grub/lib/pub_grub/term.rb +105 -0
  274. data/lib/bundler/vendor/pub_grub/lib/pub_grub/version.rb +3 -0
  275. data/lib/bundler/vendor/pub_grub/lib/pub_grub/version_constraint.rb +129 -0
  276. data/lib/bundler/vendor/pub_grub/lib/pub_grub/version_range.rb +423 -0
  277. data/lib/bundler/vendor/pub_grub/lib/pub_grub/version_solver.rb +236 -0
  278. data/lib/bundler/vendor/pub_grub/lib/pub_grub/version_union.rb +178 -0
  279. data/lib/bundler/vendor/pub_grub/lib/pub_grub.rb +31 -0
  280. data/lib/bundler/vendor/securerandom/COPYING +56 -0
  281. data/lib/bundler/vendor/securerandom/lib/securerandom.rb +102 -0
  282. data/lib/bundler/vendor/thor/LICENSE.md +20 -0
  283. data/lib/bundler/vendor/thor/lib/thor/actions/create_file.rb +105 -0
  284. data/lib/bundler/vendor/thor/lib/thor/actions/create_link.rb +61 -0
  285. data/lib/bundler/vendor/thor/lib/thor/actions/directory.rb +108 -0
  286. data/lib/bundler/vendor/thor/lib/thor/actions/empty_directory.rb +143 -0
  287. data/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb +407 -0
  288. data/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb +130 -0
  289. data/lib/bundler/vendor/thor/lib/thor/actions.rb +340 -0
  290. data/lib/bundler/vendor/thor/lib/thor/base.rb +825 -0
  291. data/lib/bundler/vendor/thor/lib/thor/command.rb +151 -0
  292. data/lib/bundler/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb +107 -0
  293. data/lib/bundler/vendor/thor/lib/thor/error.rb +106 -0
  294. data/lib/bundler/vendor/thor/lib/thor/group.rb +292 -0
  295. data/lib/bundler/vendor/thor/lib/thor/invocation.rb +178 -0
  296. data/lib/bundler/vendor/thor/lib/thor/line_editor/basic.rb +37 -0
  297. data/lib/bundler/vendor/thor/lib/thor/line_editor/readline.rb +88 -0
  298. data/lib/bundler/vendor/thor/lib/thor/line_editor.rb +17 -0
  299. data/lib/bundler/vendor/thor/lib/thor/nested_context.rb +29 -0
  300. data/lib/bundler/vendor/thor/lib/thor/parser/argument.rb +86 -0
  301. data/lib/bundler/vendor/thor/lib/thor/parser/arguments.rb +195 -0
  302. data/lib/bundler/vendor/thor/lib/thor/parser/option.rb +178 -0
  303. data/lib/bundler/vendor/thor/lib/thor/parser/options.rb +294 -0
  304. data/lib/bundler/vendor/thor/lib/thor/parser.rb +4 -0
  305. data/lib/bundler/vendor/thor/lib/thor/rake_compat.rb +72 -0
  306. data/lib/bundler/vendor/thor/lib/thor/runner.rb +335 -0
  307. data/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +384 -0
  308. data/lib/bundler/vendor/thor/lib/thor/shell/color.rb +112 -0
  309. data/lib/bundler/vendor/thor/lib/thor/shell/column_printer.rb +29 -0
  310. data/lib/bundler/vendor/thor/lib/thor/shell/html.rb +81 -0
  311. data/lib/bundler/vendor/thor/lib/thor/shell/table_printer.rb +118 -0
  312. data/lib/bundler/vendor/thor/lib/thor/shell/terminal.rb +42 -0
  313. data/lib/bundler/vendor/thor/lib/thor/shell/wrapped_printer.rb +38 -0
  314. data/lib/bundler/vendor/thor/lib/thor/shell.rb +81 -0
  315. data/lib/bundler/vendor/thor/lib/thor/util.rb +285 -0
  316. data/lib/bundler/vendor/thor/lib/thor/version.rb +3 -0
  317. data/lib/bundler/vendor/thor/lib/thor.rb +674 -0
  318. data/lib/bundler/vendor/tsort/LICENSE.txt +22 -0
  319. data/lib/bundler/vendor/tsort/lib/tsort.rb +455 -0
  320. data/lib/bundler/vendor/uri/COPYING +56 -0
  321. data/lib/bundler/vendor/uri/lib/uri/common.rb +922 -0
  322. data/lib/bundler/vendor/uri/lib/uri/file.rb +100 -0
  323. data/lib/bundler/vendor/uri/lib/uri/ftp.rb +267 -0
  324. data/lib/bundler/vendor/uri/lib/uri/generic.rb +1592 -0
  325. data/lib/bundler/vendor/uri/lib/uri/http.rb +137 -0
  326. data/lib/bundler/vendor/uri/lib/uri/https.rb +23 -0
  327. data/lib/bundler/vendor/uri/lib/uri/ldap.rb +261 -0
  328. data/lib/bundler/vendor/uri/lib/uri/ldaps.rb +22 -0
  329. data/lib/bundler/vendor/uri/lib/uri/mailto.rb +293 -0
  330. data/lib/bundler/vendor/uri/lib/uri/rfc2396_parser.rb +547 -0
  331. data/lib/bundler/vendor/uri/lib/uri/rfc3986_parser.rb +206 -0
  332. data/lib/bundler/vendor/uri/lib/uri/version.rb +6 -0
  333. data/lib/bundler/vendor/uri/lib/uri/ws.rb +83 -0
  334. data/lib/bundler/vendor/uri/lib/uri/wss.rb +23 -0
  335. data/lib/bundler/vendor/uri/lib/uri.rb +104 -0
  336. data/lib/bundler/vendored_fileutils.rb +4 -0
  337. data/lib/bundler/vendored_net_http.rb +23 -0
  338. data/lib/bundler/vendored_persistent.rb +11 -0
  339. data/lib/bundler/vendored_pub_grub.rb +4 -0
  340. data/lib/bundler/vendored_securerandom.rb +12 -0
  341. data/lib/bundler/vendored_thor.rb +8 -0
  342. data/lib/bundler/vendored_timeout.rb +12 -0
  343. data/lib/bundler/vendored_tsort.rb +4 -0
  344. data/lib/bundler/vendored_uri.rb +21 -0
  345. data/lib/bundler/version.rb +21 -0
  346. data/lib/bundler/vlad.rb +4 -0
  347. data/lib/bundler/worker.rb +125 -0
  348. data/lib/bundler/yaml_serializer.rb +98 -0
  349. data/lib/bundler.rb +691 -0
  350. metadata +409 -0
@@ -0,0 +1,331 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bundler
4
+ class Runtime
5
+ include SharedHelpers
6
+
7
+ def initialize(root, definition)
8
+ @root = root
9
+ @definition = definition
10
+ end
11
+
12
+ def setup(*groups)
13
+ @definition.ensure_equivalent_gemfile_and_lockfile
14
+
15
+ # Has to happen first
16
+ clean_load_path
17
+
18
+ specs = @definition.specs_for(groups)
19
+
20
+ SharedHelpers.set_bundle_environment
21
+ Bundler.rubygems.replace_entrypoints(specs)
22
+
23
+ # Activate the specs
24
+ load_paths = specs.map do |spec|
25
+ check_for_activated_spec!(spec)
26
+
27
+ Bundler.rubygems.mark_loaded(spec)
28
+ spec.load_paths.reject {|path| $LOAD_PATH.include?(path) }
29
+ end.reverse.flatten
30
+
31
+ Gem.add_to_load_path(*load_paths)
32
+
33
+ setup_manpath
34
+
35
+ lock(preserve_unknown_sections: true)
36
+
37
+ self
38
+ end
39
+
40
+ def require(*groups)
41
+ groups.map!(&:to_sym)
42
+ groups = [:default] if groups.empty?
43
+
44
+ dependencies = @definition.dependencies.select do |dep|
45
+ # Select the dependency if it is in any of the requested groups, and
46
+ # for the current platform, and matches the gem constraints.
47
+ (dep.groups & groups).any? && dep.should_include?
48
+ end
49
+
50
+ Plugin.hook(Plugin::Events::GEM_BEFORE_REQUIRE_ALL, dependencies)
51
+
52
+ dependencies.each do |dep|
53
+ Plugin.hook(Plugin::Events::GEM_BEFORE_REQUIRE, dep)
54
+
55
+ # Loop through all the specified autorequires for the
56
+ # dependency. If there are none, use the dependency's name
57
+ # as the autorequire.
58
+ Array(dep.autorequire || dep.name).each do |file|
59
+ # Allow `require: true` as an alias for `require: <name>`
60
+ file = dep.name if file == true
61
+ required_file = file
62
+ begin
63
+ Kernel.require required_file
64
+ rescue LoadError => e
65
+ if dep.autorequire.nil? && e.path == required_file
66
+ if required_file.include?("-")
67
+ required_file = required_file.tr("-", "/")
68
+ retry
69
+ end
70
+ else
71
+ raise Bundler::GemRequireError.new e,
72
+ "There was an error while trying to load the gem '#{file}'."
73
+ end
74
+ rescue StandardError => e
75
+ raise Bundler::GemRequireError.new e,
76
+ "There was an error while trying to load the gem '#{file}'."
77
+ end
78
+ end
79
+
80
+ Plugin.hook(Plugin::Events::GEM_AFTER_REQUIRE, dep)
81
+ end
82
+
83
+ Plugin.hook(Plugin::Events::GEM_AFTER_REQUIRE_ALL, dependencies)
84
+
85
+ dependencies
86
+ end
87
+
88
+ def self.definition_method(meth)
89
+ define_method(meth) do
90
+ raise ArgumentError, "no definition when calling Runtime##{meth}" unless @definition
91
+ @definition.send(meth)
92
+ end
93
+ end
94
+ private_class_method :definition_method
95
+
96
+ definition_method :requested_specs
97
+ definition_method :specs
98
+ definition_method :dependencies
99
+ definition_method :current_dependencies
100
+ definition_method :requires
101
+
102
+ def lock(opts = {})
103
+ return if @definition.no_resolve_needed?
104
+ @definition.lock(opts[:preserve_unknown_sections])
105
+ end
106
+
107
+ alias_method :gems, :specs
108
+
109
+ def cache(custom_path = nil, local = false)
110
+ cache_path = Bundler.app_cache(custom_path)
111
+ SharedHelpers.filesystem_access(cache_path) do |p|
112
+ FileUtils.mkdir_p(p)
113
+ end unless File.exist?(cache_path)
114
+
115
+ Bundler.ui.info "Updating files in #{Bundler.settings.app_cache_path}"
116
+
117
+ specs_to_cache = if Bundler.settings[:cache_all_platforms]
118
+ @definition.resolve.materialized_for_all_platforms
119
+ else
120
+ begin
121
+ specs
122
+ rescue GemNotFound
123
+ if local
124
+ Bundler.ui.warn "Some gems seem to be missing from your #{Bundler.settings.app_cache_path} directory."
125
+ end
126
+
127
+ raise
128
+ end
129
+ end
130
+
131
+ specs_to_cache.each do |spec|
132
+ next if spec.name == "bundler"
133
+
134
+ source = spec.source
135
+ next if source.is_a?(Source::Gemspec)
136
+
137
+ if source.respond_to?(:migrate_cache)
138
+ source.migrate_cache(custom_path, local: local)
139
+ elsif source.respond_to?(:cache)
140
+ source.cache(spec, custom_path)
141
+ end
142
+ end
143
+
144
+ Dir[cache_path.join("*/.git")].each do |git_dir|
145
+ FileUtils.rm_rf(git_dir)
146
+ FileUtils.touch(File.expand_path("../.bundlecache", git_dir))
147
+ end
148
+
149
+ prune_cache(cache_path) unless Bundler.settings[:no_prune]
150
+ end
151
+
152
+ def prune_cache(cache_path)
153
+ SharedHelpers.filesystem_access(cache_path) do |p|
154
+ FileUtils.mkdir_p(p)
155
+ end unless File.exist?(cache_path)
156
+ resolve = @definition.resolve
157
+ prune_gem_cache(resolve, cache_path)
158
+ prune_git_and_path_cache(resolve, cache_path)
159
+ end
160
+
161
+ def clean(dry_run = false)
162
+ gem_bins = Dir["#{Gem.dir}/bin/*"]
163
+ git_dirs = Dir["#{Gem.dir}/bundler/gems/*"]
164
+ git_cache_dirs = Dir["#{Gem.dir}/cache/bundler/git/*"]
165
+ gem_dirs = Dir["#{Gem.dir}/gems/*"]
166
+ gem_files = Dir["#{Gem.dir}/cache/*.gem"]
167
+ gemspec_files = Dir["#{Gem.dir}/specifications/*.gemspec"]
168
+ extension_dirs = Dir["#{Gem.dir}/extensions/*/*/*"] + Dir["#{Gem.dir}/bundler/gems/extensions/*/*/*"]
169
+ spec_gem_paths = []
170
+ # need to keep git sources around
171
+ spec_git_paths = @definition.spec_git_paths
172
+ spec_git_cache_dirs = []
173
+ spec_gem_executables = []
174
+ spec_cache_paths = []
175
+ spec_gemspec_paths = []
176
+ spec_extension_paths = []
177
+ specs_to_keep = Bundler.rubygems.add_default_gems_to(specs).values
178
+
179
+ current_bundler = Bundler.rubygems.find_bundler(Bundler.gem_version)
180
+ if current_bundler
181
+ specs_to_keep << current_bundler
182
+ end
183
+
184
+ specs_to_keep.each do |spec|
185
+ spec_gem_paths << spec.full_gem_path
186
+ # need to check here in case gems are nested like for the rails git repo
187
+ md = %r{(.+bundler/gems/.+-[a-f0-9]{7,12})}.match(spec.full_gem_path)
188
+ spec_git_paths << md[1] if md
189
+ spec_gem_executables << spec.executables.collect do |executable|
190
+ e = "#{Bundler.rubygems.gem_bindir}/#{executable}"
191
+ [e, "#{e}.bat"]
192
+ end
193
+ spec_cache_paths << spec.cache_file
194
+ spec_gemspec_paths << spec.spec_file
195
+ spec_extension_paths << spec.extension_dir if spec.respond_to?(:extension_dir)
196
+ spec_git_cache_dirs << spec.source.cache_path.to_s if spec.source.is_a?(Bundler::Source::Git)
197
+ end
198
+ spec_gem_paths.uniq!
199
+ spec_gem_executables.flatten!
200
+
201
+ stale_gem_bins = gem_bins - spec_gem_executables
202
+ stale_git_dirs = git_dirs - spec_git_paths - ["#{Gem.dir}/bundler/gems/extensions"]
203
+ stale_git_cache_dirs = git_cache_dirs - spec_git_cache_dirs
204
+ stale_gem_dirs = gem_dirs - spec_gem_paths
205
+ stale_gem_files = gem_files - spec_cache_paths
206
+ stale_gemspec_files = gemspec_files - spec_gemspec_paths
207
+ stale_extension_dirs = extension_dirs - spec_extension_paths
208
+
209
+ removed_stale_gem_dirs = stale_gem_dirs.collect {|dir| remove_dir(dir, dry_run) }
210
+ removed_stale_git_dirs = stale_git_dirs.collect {|dir| remove_dir(dir, dry_run) }
211
+ output = removed_stale_gem_dirs + removed_stale_git_dirs
212
+
213
+ unless dry_run
214
+ stale_files = stale_gem_bins + stale_gem_files + stale_gemspec_files
215
+ stale_files.each do |file|
216
+ SharedHelpers.filesystem_access(File.dirname(file)) do |_p|
217
+ FileUtils.rm(file) if File.exist?(file)
218
+ end
219
+ end
220
+
221
+ stale_dirs = stale_git_cache_dirs + stale_extension_dirs
222
+ stale_dirs.each do |stale_dir|
223
+ SharedHelpers.filesystem_access(stale_dir) do |dir|
224
+ FileUtils.rm_rf(dir) if File.exist?(dir)
225
+ end
226
+ end
227
+ end
228
+
229
+ output
230
+ end
231
+
232
+ private
233
+
234
+ def prune_gem_cache(resolve, cache_path)
235
+ cached = Dir["#{cache_path}/*.gem"]
236
+
237
+ cached = cached.delete_if do |path|
238
+ spec = Bundler.rubygems.spec_from_gem path
239
+
240
+ resolve.any? do |s|
241
+ s.name == spec.name && s.version == spec.version && !s.source.is_a?(Bundler::Source::Git)
242
+ end
243
+ end
244
+
245
+ if cached.any?
246
+ Bundler.ui.info "Removing outdated .gem files from #{Bundler.settings.app_cache_path}"
247
+
248
+ cached.each do |path|
249
+ Bundler.ui.info " * #{File.basename(path)}"
250
+
251
+ begin
252
+ File.delete(path)
253
+ rescue Errno::ENOENT
254
+ end
255
+ end
256
+ end
257
+ end
258
+
259
+ def prune_git_and_path_cache(resolve, cache_path)
260
+ cached = Dir["#{cache_path}/*/.bundlecache"]
261
+
262
+ cached = cached.delete_if do |path|
263
+ name = File.basename(File.dirname(path))
264
+
265
+ resolve.any? do |s|
266
+ source = s.source
267
+ source.respond_to?(:app_cache_dirname) && source.app_cache_dirname == name
268
+ end
269
+ end
270
+
271
+ if cached.any?
272
+ Bundler.ui.info "Removing outdated git and path gems from #{Bundler.settings.app_cache_path}"
273
+
274
+ cached.each do |path|
275
+ path = File.dirname(path)
276
+ Bundler.ui.info " * #{File.basename(path)}"
277
+ FileUtils.rm_rf(path)
278
+ end
279
+ end
280
+ end
281
+
282
+ def setup_manpath
283
+ # Add man/ subdirectories from activated bundles to MANPATH for man(1)
284
+ manuals = $LOAD_PATH.filter_map do |path|
285
+ man_subdir = path.sub(/lib$/, "man")
286
+ man_subdir unless Dir[man_subdir + "/man?/"].empty?
287
+ end
288
+
289
+ return if manuals.empty?
290
+ Bundler::SharedHelpers.set_env "MANPATH", manuals.concat(
291
+ ENV["MANPATH"] ? ENV["MANPATH"].to_s.split(File::PATH_SEPARATOR) : [""]
292
+ ).uniq.join(File::PATH_SEPARATOR)
293
+ end
294
+
295
+ def remove_dir(dir, dry_run)
296
+ full_name = Pathname.new(dir).basename.to_s
297
+
298
+ parts = full_name.split("-")
299
+ name = parts[0..-2].join("-")
300
+ version = parts.last
301
+ output = "#{name} (#{version})"
302
+
303
+ if dry_run
304
+ Bundler.ui.info "Would have removed #{output}"
305
+ else
306
+ Bundler.ui.info "Removing #{output}"
307
+ FileUtils.rm_rf(dir)
308
+ end
309
+
310
+ output
311
+ end
312
+
313
+ def check_for_activated_spec!(spec)
314
+ return unless activated_spec = Bundler.rubygems.loaded_specs(spec.name)
315
+ return if activated_spec.version == spec.version
316
+
317
+ suggestion = if activated_spec.default_gem?
318
+ "Since #{spec.name} is a default gem, you can either remove your dependency on it" \
319
+ " or try updating to a newer version of bundler that supports #{spec.name} as a default gem."
320
+ else
321
+ "Prepending `bundle exec` to your command may solve this."
322
+ end
323
+
324
+ e = Gem::LoadError.new "You have already activated #{activated_spec.name} #{activated_spec.version}, " \
325
+ "but your Gemfile requires #{spec.name} #{spec.version}. #{suggestion}"
326
+ e.name = spec.name
327
+ e.requirement = Gem::Requirement.new(spec.version.to_s)
328
+ raise e
329
+ end
330
+ end
331
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bundler
4
+ module SafeMarshal
5
+ ALLOWED_CLASSES = [
6
+ Array,
7
+ FalseClass,
8
+ Gem::Specification,
9
+ Gem::Version,
10
+ Hash,
11
+ String,
12
+ Symbol,
13
+ Time,
14
+ TrueClass,
15
+ ].freeze
16
+
17
+ ERROR = "Unexpected class %s present in marshaled data. Only %s are allowed."
18
+
19
+ PROC = proc do |object|
20
+ object.tap do
21
+ unless ALLOWED_CLASSES.include?(object.class)
22
+ raise TypeError, format(ERROR, object.class, ALLOWED_CLASSES.join(", "))
23
+ end
24
+ end
25
+ end
26
+
27
+ def self.proc
28
+ PROC
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,197 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bundler
4
+ #
5
+ # This class handles installing and switching to the version of bundler needed
6
+ # by an application.
7
+ #
8
+ class SelfManager
9
+ def restart_with_locked_bundler_if_needed
10
+ restart_version = find_restart_version
11
+ return unless restart_version && installed?(restart_version)
12
+
13
+ restart_with(restart_version)
14
+ end
15
+
16
+ def install_locked_bundler_and_restart_with_it_if_needed
17
+ restart_version = find_restart_version
18
+ return unless restart_version
19
+
20
+ if restart_version == lockfile_version
21
+ Bundler.ui.info \
22
+ "Bundler #{current_version} is running, but your lockfile was generated with #{lockfile_version}. " \
23
+ "Installing Bundler #{lockfile_version} and restarting using that version."
24
+ else
25
+ Bundler.ui.info \
26
+ "Bundler #{current_version} is running, but your configuration was #{restart_version}. " \
27
+ "Installing Bundler #{restart_version} and restarting using that version."
28
+ end
29
+
30
+ install_and_restart_with(restart_version)
31
+ end
32
+
33
+ def update_bundler_and_restart_with_it_if_needed(target)
34
+ spec = resolve_update_version_from(target)
35
+ return unless spec
36
+
37
+ version = spec.version
38
+
39
+ Bundler.ui.info "Updating bundler to #{version}."
40
+
41
+ install(spec) unless installed?(version)
42
+
43
+ restart_with(version)
44
+ end
45
+
46
+ private
47
+
48
+ def install_and_restart_with(version)
49
+ requirement = Gem::Requirement.new(version)
50
+ spec = find_latest_matching_spec(requirement)
51
+
52
+ if spec.nil?
53
+ Bundler.ui.warn "Your lockfile is locked to a version of bundler (#{lockfile_version}) that doesn't exist at https://rubygems.org/. Going on using #{current_version}"
54
+ return
55
+ end
56
+
57
+ install(spec)
58
+ rescue StandardError => e
59
+ Bundler.ui.trace e
60
+ Bundler.ui.warn "There was an error installing the locked bundler version (#{lockfile_version}), rerun with the `--verbose` flag for more details. Going on using bundler #{current_version}."
61
+ else
62
+ restart_with(version)
63
+ end
64
+
65
+ def install(spec)
66
+ spec.source.download(spec)
67
+ spec.source.install(spec)
68
+ end
69
+
70
+ def restart_with(version)
71
+ configured_gem_home = ENV["GEM_HOME"]
72
+ configured_orig_gem_home = ENV["BUNDLER_ORIG_GEM_HOME"]
73
+ configured_gem_path = ENV["GEM_PATH"]
74
+ configured_orig_gem_path = ENV["BUNDLER_ORIG_GEM_PATH"]
75
+
76
+ argv0 = File.exist?($PROGRAM_NAME) ? $PROGRAM_NAME : Process.argv0
77
+ cmd = [argv0, *ARGV]
78
+ cmd.unshift(Gem.ruby) unless File.executable?(argv0)
79
+
80
+ Bundler.with_original_env do
81
+ Kernel.exec(
82
+ {
83
+ "GEM_HOME" => configured_gem_home,
84
+ "BUNDLER_ORIG_GEM_HOME" => configured_orig_gem_home,
85
+ "GEM_PATH" => configured_gem_path,
86
+ "BUNDLER_ORIG_GEM_PATH" => configured_orig_gem_path,
87
+ "BUNDLER_VERSION" => version.to_s,
88
+ },
89
+ *cmd
90
+ )
91
+ end
92
+ end
93
+
94
+ def needs_switching?(restart_version)
95
+ autoswitching_applies? &&
96
+ released?(restart_version) &&
97
+ !running?(restart_version)
98
+ end
99
+
100
+ def autoswitching_applies?
101
+ (ENV["BUNDLER_VERSION"].nil? || ENV["BUNDLER_VERSION"].empty?) &&
102
+ ruby_can_restart_with_same_arguments? &&
103
+ lockfile_version
104
+ end
105
+
106
+ def resolve_update_version_from(target)
107
+ requirement = Gem::Requirement.new(target)
108
+ update_candidate = find_latest_matching_spec(requirement)
109
+
110
+ if update_candidate.nil?
111
+ raise InvalidOption, "The `bundle update --bundler` target version (#{target}) does not exist"
112
+ end
113
+
114
+ resolved_version = update_candidate.version
115
+ needs_update = requirement.specific? ? !running?(resolved_version) : running_older_than?(resolved_version)
116
+
117
+ return unless needs_update
118
+
119
+ update_candidate
120
+ end
121
+
122
+ def local_specs
123
+ @local_specs ||= Bundler::Source::Rubygems.new("allow_local" => true).specs.select {|spec| spec.name == "bundler" }
124
+ end
125
+
126
+ def remote_specs
127
+ @remote_specs ||= begin
128
+ source = Bundler::Source::Rubygems.new("remotes" => "https://rubygems.org")
129
+ source.remote!
130
+ source.add_dependency_names("bundler")
131
+ source.specs.select(&:matches_current_metadata?)
132
+ end
133
+ end
134
+
135
+ def find_latest_matching_spec(requirement)
136
+ Bundler.configure
137
+ local_result = find_latest_matching_spec_from_collection(local_specs, requirement)
138
+ return local_result if local_result && requirement.specific?
139
+
140
+ remote_result = find_latest_matching_spec_from_collection(remote_specs, requirement)
141
+ return remote_result if local_result.nil?
142
+
143
+ [local_result, remote_result].max
144
+ end
145
+
146
+ def find_latest_matching_spec_from_collection(specs, requirement)
147
+ specs.sort.reverse_each.find {|spec| requirement.satisfied_by?(spec.version) }
148
+ end
149
+
150
+ def running?(version)
151
+ version == current_version
152
+ end
153
+
154
+ def running_older_than?(version)
155
+ current_version < version
156
+ end
157
+
158
+ def released?(version)
159
+ !version.to_s.end_with?(".dev")
160
+ end
161
+
162
+ def ruby_can_restart_with_same_arguments?
163
+ $PROGRAM_NAME != "-e"
164
+ end
165
+
166
+ def installed?(restart_version)
167
+ Bundler.configure
168
+
169
+ Bundler.rubygems.find_bundler(restart_version.to_s)
170
+ end
171
+
172
+ def current_version
173
+ @current_version ||= Bundler.gem_version
174
+ end
175
+
176
+ def lockfile_version
177
+ return @lockfile_version if defined?(@lockfile_version)
178
+
179
+ parsed_version = Bundler::LockfileParser.bundled_with
180
+ @lockfile_version = parsed_version ? Gem::Version.new(parsed_version) : nil
181
+ rescue ArgumentError
182
+ @lockfile_version = nil
183
+ end
184
+
185
+ def find_restart_version
186
+ return unless SharedHelpers.in_bundle?
187
+
188
+ configured_version = Bundler.settings[:version]
189
+ return if configured_version == "system"
190
+
191
+ restart_version = configured_version == "lockfile" ? lockfile_version : Gem::Version.new(configured_version)
192
+ return unless needs_switching?(restart_version)
193
+
194
+ restart_version
195
+ end
196
+ end
197
+ end
@@ -0,0 +1,86 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bundler
4
+ class Settings
5
+ class Validator
6
+ class Rule
7
+ attr_reader :description
8
+
9
+ def initialize(keys, description, &validate)
10
+ @keys = keys
11
+ @description = description
12
+ @validate = validate
13
+ end
14
+
15
+ def validate!(key, value, settings)
16
+ instance_exec(key, value, settings, &@validate)
17
+ end
18
+
19
+ def fail!(key, value, *reasons)
20
+ reasons.unshift @description
21
+ raise InvalidOption, "Setting `#{key}` to #{value.inspect} failed:\n#{reasons.map {|r| " - #{r}" }.join("\n")}"
22
+ end
23
+
24
+ def set(settings, key, value, *reasons)
25
+ hash_key = k(key)
26
+ return if settings[hash_key] == value
27
+ reasons.unshift @description
28
+ Bundler.ui.info "Setting `#{key}` to #{value.inspect}, since #{reasons.join(", ")}"
29
+ if value.nil?
30
+ settings.delete(hash_key)
31
+ else
32
+ settings[hash_key] = value
33
+ end
34
+ end
35
+
36
+ def k(key)
37
+ Bundler.settings.key_for(key)
38
+ end
39
+ end
40
+
41
+ def self.rules
42
+ @rules ||= Hash.new {|h, k| h[k] = [] }
43
+ end
44
+ private_class_method :rules
45
+
46
+ def self.rule(keys, description, &blk)
47
+ rule = Rule.new(keys, description, &blk)
48
+ keys.each {|k| rules[k] << rule }
49
+ end
50
+ private_class_method :rule
51
+
52
+ def self.validate!(key, value, settings)
53
+ rules_to_validate = rules[key]
54
+ rules_to_validate.each {|rule| rule.validate!(key, value, settings) }
55
+ end
56
+
57
+ rule %w[path path.system], "path and path.system are mutually exclusive" do |key, value, settings|
58
+ if key == "path" && value
59
+ set(settings, "path.system", nil)
60
+ elsif key == "path.system" && value
61
+ set(settings, :path, nil)
62
+ end
63
+ end
64
+
65
+ rule %w[with without], "a group cannot be in both `with` & `without` simultaneously" do |key, value, settings|
66
+ with = settings.fetch(k(:with), "").split(":").map(&:to_sym)
67
+ without = settings.fetch(k(:without), "").split(":").map(&:to_sym)
68
+
69
+ other_key = key == "with" ? :without : :with
70
+ other_setting = key == "with" ? without : with
71
+
72
+ conflicting = with & without
73
+ if conflicting.any?
74
+ fail!(key, value, "`#{other_key}` is current set to #{other_setting.inspect}", "the `#{conflicting.join("`, `")}` groups conflict")
75
+ end
76
+ end
77
+
78
+ rule %w[default_cli_command], "default_cli_command must be either 'install' or 'cli_help'" do |key, value, _settings|
79
+ valid_values = %w[install cli_help]
80
+ if !value.nil? && !valid_values.include?(value.to_s)
81
+ fail!(key, value, "must be one of: #{valid_values.join(", ")}")
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end