bundler-plus 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,642 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "dependency"
4
+ require_relative "ruby_dsl"
5
+
6
+ module Bundler
7
+ class Dsl
8
+ include RubyDsl
9
+
10
+ def self.evaluate(gemfile, lockfile, unlock)
11
+ builder = new
12
+ builder.lockfile(lockfile)
13
+ builder.eval_gemfile(gemfile)
14
+ builder.to_definition(builder.lockfile_path, unlock)
15
+ end
16
+
17
+ VALID_PLATFORMS = Bundler::CurrentRuby::PLATFORM_MAP.keys.freeze
18
+
19
+ VALID_KEYS = %w[group groups git path glob name branch ref tag require submodules
20
+ platform platforms source install_if force_ruby_platform].freeze
21
+
22
+ GITHUB_PULL_REQUEST_URL = %r{\Ahttps://github\.com/([A-Za-z0-9_\-\.]+/[A-Za-z0-9_\-\.]+)/pull/(\d+)\z}
23
+ GITLAB_MERGE_REQUEST_URL = %r{\Ahttps://gitlab\.com/([A-Za-z0-9_\-\./]+)/-/merge_requests/(\d+)\z}
24
+
25
+ attr_reader :gemspecs, :gemfile
26
+ attr_accessor :dependencies
27
+
28
+ def initialize
29
+ @source = nil
30
+ @sources = SourceList.new
31
+ @git_sources = {}
32
+ @dependencies = []
33
+ @groups = []
34
+ @install_conditionals = []
35
+ @optional_groups = []
36
+ @platforms = []
37
+ @env = nil
38
+ @ruby_version = nil
39
+ @gemspecs = []
40
+ @gemfile = nil
41
+ @gemfiles = []
42
+ @lockfile = nil
43
+ add_git_sources
44
+ end
45
+
46
+ def eval_gemfile(gemfile, contents = nil)
47
+ with_gemfile(gemfile) do |current_gemfile|
48
+ contents ||= Bundler.read_file(current_gemfile)
49
+ instance_eval(contents, current_gemfile, 1)
50
+ rescue GemfileEvalError => e
51
+ message = "There was an error evaluating `#{File.basename current_gemfile}`: #{e.message}"
52
+ raise DSLError.new(message, current_gemfile, e.backtrace, contents)
53
+ rescue GemfileError, InvalidArgumentError, InvalidOption, DeprecatedError, ScriptError => e
54
+ message = "There was an error parsing `#{File.basename current_gemfile}`: #{e.message}"
55
+ raise DSLError.new(message, current_gemfile, e.backtrace, contents)
56
+ rescue StandardError => e
57
+ raise unless e.backtrace_locations.first.path == current_gemfile
58
+ message = "There was an error parsing `#{File.basename current_gemfile}`: #{e.message}"
59
+ raise DSLError.new(message, current_gemfile, e.backtrace, contents)
60
+ end
61
+ end
62
+
63
+ def gemspec(opts = nil)
64
+ opts ||= {}
65
+ path = opts[:path] || "."
66
+ glob = opts[:glob]
67
+ name = opts[:name]
68
+ development_group = opts[:development_group] || :development
69
+ expanded_path = gemfile_root.join(path)
70
+
71
+ gemspecs = Gem::Util.glob_files_in_dir("{,*}.gemspec", expanded_path).filter_map {|g| Bundler.load_gemspec(g) }
72
+ gemspecs.reject! {|s| s.name != name } if name
73
+ specs_by_name_and_version = gemspecs.group_by {|s| [s.name, s.version] }
74
+
75
+ case specs_by_name_and_version.size
76
+ when 1
77
+ specs = specs_by_name_and_version.values.first
78
+ spec = specs.find {|s| s.installable_on_platform?(Bundler.local_platform) } || specs.first
79
+
80
+ @gemspecs << spec
81
+
82
+ path path, "glob" => glob, "name" => spec.name, "gemspec" => spec do
83
+ add_dependency spec.name
84
+ end
85
+
86
+ spec.development_dependencies.each do |dep|
87
+ add_dependency dep.name, dep.requirement.as_list, "gemspec_dev_dep" => true, "group" => development_group
88
+ end
89
+ when 0
90
+ raise InvalidOption, "There are no gemspecs at #{expanded_path}"
91
+ else
92
+ raise InvalidOption, "There are multiple gemspecs at #{expanded_path}. " \
93
+ "Please use the :name option to specify which one should be used"
94
+ end
95
+ end
96
+
97
+ def gem(name, *args)
98
+ options = args.last.is_a?(Hash) ? args.pop.dup : {}
99
+ version = args || [">= 0"]
100
+
101
+ normalize_options(name, version, options)
102
+
103
+ add_dependency(name, version, options)
104
+ end
105
+
106
+ # For usage in Dsl.evaluate, since lockfile is used as part of the Gemfile.
107
+ def lockfile_path
108
+ @lockfile
109
+ end
110
+
111
+ def lockfile(file)
112
+ @lockfile = file
113
+ end
114
+
115
+ def source(source, *args, &blk)
116
+ options = args.last.is_a?(Hash) ? args.pop.dup : {}
117
+ options = normalize_hash(options)
118
+ source = normalize_source(source)
119
+ cooldown = options["cooldown"]
120
+ if cooldown && !(cooldown.is_a?(Integer) && cooldown >= 0)
121
+ raise InvalidOption, "Expected `cooldown` to be a non-negative integer, got #{cooldown.inspect}"
122
+ end
123
+
124
+ if options.key?("type")
125
+ options["type"] = options["type"].to_s
126
+ unless Plugin.source?(options["type"])
127
+ raise InvalidOption, "No plugin sources available for #{options["type"]}"
128
+ end
129
+
130
+ unless block_given?
131
+ raise InvalidOption, "You need to pass a block to #source with :type option"
132
+ end
133
+
134
+ source_opts = options.merge("uri" => source)
135
+ with_source(@sources.add_plugin_source(options["type"], source_opts), &blk)
136
+ elsif block_given?
137
+ with_source(@sources.add_rubygems_source("remotes" => source, "cooldown" => cooldown), &blk)
138
+ else
139
+ @sources.add_global_rubygems_remote(source, cooldown: cooldown)
140
+ end
141
+ end
142
+
143
+ def git_source(name, &block)
144
+ unless block_given?
145
+ raise InvalidOption, "You need to pass a block to #git_source"
146
+ end
147
+
148
+ if valid_keys.include?(name.to_s)
149
+ raise InvalidOption, "You cannot use #{name} as a git source. It " \
150
+ "is a reserved key. Reserved keys are: #{valid_keys.join(", ")}"
151
+ end
152
+
153
+ @git_sources[name.to_s] = block
154
+ end
155
+
156
+ def path(path, options = {}, &blk)
157
+ source_options = normalize_hash(options).merge(
158
+ "path" => Pathname.new(path),
159
+ "root_path" => gemfile_root
160
+ )
161
+
162
+ source_options["global"] = true unless block_given?
163
+
164
+ source = @sources.add_path_source(source_options)
165
+ with_source(source, &blk)
166
+ end
167
+
168
+ def git(uri, options = {}, &blk)
169
+ unless block_given?
170
+ msg = "You can no longer specify a git source by itself. Instead, \n" \
171
+ "either use the :git option on a gem, or specify the gems that \n" \
172
+ "bundler should find in the git source by passing a block to \n" \
173
+ "the git method, like: \n\n" \
174
+ " git 'git://github.com/rails/rails.git' do\n" \
175
+ " gem 'rails'\n" \
176
+ " end"
177
+ raise DeprecatedError, msg
178
+ end
179
+
180
+ with_source(@sources.add_git_source(normalize_hash(options).merge("uri" => uri)), &blk)
181
+ end
182
+
183
+ def github(repo, options = {})
184
+ raise InvalidArgumentError, "GitHub sources require a block" unless block_given?
185
+ github_uri = @git_sources["github"].call(repo)
186
+ git_options = normalize_hash(options).merge("uri" => github_uri)
187
+ git_source = @sources.add_git_source(git_options)
188
+ with_source(git_source) { yield }
189
+ end
190
+
191
+ def to_definition(lockfile, unlock)
192
+ check_primary_source_safety
193
+ lockfile = @lockfile unless @lockfile.nil?
194
+ Definition.new(lockfile, @dependencies, @sources, unlock, @ruby_version, @optional_groups, @gemfiles)
195
+ end
196
+
197
+ def group(*args, &blk)
198
+ options = args.last.is_a?(Hash) ? args.pop.dup : {}
199
+ normalize_group_options(options, args)
200
+
201
+ @groups.concat args
202
+
203
+ if options["optional"]
204
+ optional_groups = args - @optional_groups
205
+ @optional_groups.concat optional_groups
206
+ end
207
+
208
+ yield
209
+ ensure
210
+ args.each { @groups.pop }
211
+ end
212
+
213
+ def install_if(*args)
214
+ @install_conditionals.concat args
215
+ yield
216
+ ensure
217
+ args.each { @install_conditionals.pop }
218
+ end
219
+
220
+ def platforms(*platforms)
221
+ @platforms.concat platforms
222
+ yield
223
+ ensure
224
+ platforms.each { @platforms.pop }
225
+ end
226
+ alias_method :platform, :platforms
227
+
228
+ def env(name)
229
+ old = @env
230
+ @env = name
231
+ yield
232
+ ensure
233
+ @env = old
234
+ end
235
+
236
+ def plugin(*args)
237
+ # Pass on
238
+ end
239
+
240
+ def method_missing(name, *args)
241
+ raise GemfileError, "Undefined local variable or method `#{name}' for Gemfile"
242
+ end
243
+
244
+ def check_primary_source_safety
245
+ check_path_source_safety
246
+ check_rubygems_source_safety
247
+ end
248
+
249
+ private
250
+
251
+ def add_dependency(name, version = nil, options = {})
252
+ options["gemfile"] = @gemfile
253
+ options["source"] ||= @source
254
+ options["env"] ||= @env
255
+
256
+ dep = Dependency.new(name, version, options)
257
+
258
+ # if there's already a dependency with this name we try to prefer one
259
+ if current = @dependencies.find {|d| d.name == name }
260
+ if current.requirement != dep.requirement
261
+ current_requirement_open = current.requirements_list.include?(">= 0")
262
+
263
+ gemspec_dep = [dep, current].find(&:gemspec_dev_dep?)
264
+ if gemspec_dep
265
+ require_relative "vendor/pub_grub/lib/pub_grub/version_range"
266
+ require_relative "vendor/pub_grub/lib/pub_grub/version_constraint"
267
+ require_relative "vendor/pub_grub/lib/pub_grub/version_union"
268
+ require_relative "vendor/pub_grub/lib/pub_grub/rubygems"
269
+
270
+ current_gemspec_range = PubGrub::RubyGems.requirement_to_range(current.requirement)
271
+ next_gemspec_range = PubGrub::RubyGems.requirement_to_range(dep.requirement)
272
+
273
+ if current_gemspec_range.intersects?(next_gemspec_range)
274
+ dep = Dependency.new(name, current.requirement.as_list + dep.requirement.as_list, options)
275
+ else
276
+ gemfile_dep = [dep, current].find(&:gemfile_dep?)
277
+
278
+ if gemfile_dep
279
+ raise GemfileError, "The #{name} dependency has conflicting requirements in Gemfile (#{gemfile_dep.requirement}) and gemspec (#{gemspec_dep.requirement})"
280
+ else
281
+ raise GemfileError, "Two gemspec development dependencies have conflicting requirements on the same gem: #{dep} and #{current}"
282
+ end
283
+ end
284
+ else
285
+ update_prompt = ""
286
+
287
+ if File.basename(@gemfile) == Injector::INJECTED_GEMS
288
+ if dep.requirements_list.include?(">= 0") && !current_requirement_open
289
+ update_prompt = ". Gem already added"
290
+ else
291
+ update_prompt = ". If you want to update the gem version, run `bundle update #{name}`"
292
+
293
+ update_prompt += ". You may also need to change the version requirement specified in the Gemfile if it's too restrictive." unless current_requirement_open
294
+ end
295
+ end
296
+
297
+ raise GemfileError, "You cannot specify the same gem twice with different version requirements.\n" \
298
+ "You specified: #{name} (#{current.requirement}) and #{name} (#{dep.requirement})" \
299
+ "#{update_prompt}"
300
+ end
301
+ end
302
+
303
+ unless current.gemspec_dev_dep? && dep.gemspec_dev_dep?
304
+ # Always prefer the dependency from the Gemfile
305
+ if current.gemspec_dev_dep?
306
+ @dependencies.delete(current)
307
+ elsif dep.gemspec_dev_dep?
308
+ return
309
+ elsif current.source.to_s != dep.source.to_s
310
+ raise GemfileError, "You cannot specify the same gem twice coming from different sources.\n" \
311
+ "You specified that #{name} (#{dep.requirement}) should come from " \
312
+ "#{current.source || "an unspecified source"} and #{dep.source}\n"
313
+ else
314
+ Bundler.ui.warn "Your Gemfile lists the gem #{name} (#{current.requirement}) more than once.\n" \
315
+ "You should probably keep only one of them.\n" \
316
+ "Remove any duplicate entries and specify the gem only once.\n" \
317
+ "While it's not a problem now, it could cause errors if you change the version of one of them later."
318
+ end
319
+ end
320
+ end
321
+
322
+ @dependencies << dep
323
+ end
324
+
325
+ def with_gemfile(gemfile)
326
+ expanded_gemfile_path = Pathname.new(gemfile).expand_path(@gemfile&.parent)
327
+ original_gemfile = @gemfile
328
+ @gemfile = expanded_gemfile_path
329
+ @gemfiles << expanded_gemfile_path
330
+ yield @gemfile.to_s
331
+ ensure
332
+ @gemfile = original_gemfile
333
+ end
334
+
335
+ def add_git_sources
336
+ git_source(:github) do |repo_name|
337
+ if repo_name =~ GITHUB_PULL_REQUEST_URL
338
+ {
339
+ "git" => "https://github.com/#{$1}.git",
340
+ "branch" => nil,
341
+ "ref" => "refs/pull/#{$2}/head",
342
+ "tag" => nil,
343
+ }
344
+ else
345
+ repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?("/")
346
+ "https://github.com/#{repo_name}.git"
347
+ end
348
+ end
349
+
350
+ git_source(:gist) do |repo_name|
351
+ "https://gist.github.com/#{repo_name}.git"
352
+ end
353
+
354
+ git_source(:bitbucket) do |repo_name|
355
+ user_name, repo_name = repo_name.split("/")
356
+ repo_name ||= user_name
357
+ "https://#{user_name}@bitbucket.org/#{user_name}/#{repo_name}.git"
358
+ end
359
+
360
+ git_source(:gitlab) do |repo_name|
361
+ if repo_name =~ GITLAB_MERGE_REQUEST_URL
362
+ {
363
+ "git" => "https://gitlab.com/#{$1}.git",
364
+ "branch" => nil,
365
+ "ref" => "refs/merge-requests/#{$2}/head",
366
+ "tag" => nil,
367
+ }
368
+ else
369
+ repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?("/")
370
+ "https://gitlab.com/#{repo_name}.git"
371
+ end
372
+ end
373
+ end
374
+
375
+ def with_source(source)
376
+ old_source = @source
377
+ if block_given?
378
+ @source = source
379
+ yield
380
+ end
381
+ source
382
+ ensure
383
+ @source = old_source
384
+ end
385
+
386
+ def normalize_hash(opts)
387
+ opts.keys.each do |k|
388
+ opts[k.to_s] = opts.delete(k) unless k.is_a?(String)
389
+ end
390
+ opts
391
+ end
392
+
393
+ def valid_keys
394
+ @valid_keys ||= VALID_KEYS
395
+ end
396
+
397
+ def normalize_options(name, version, opts)
398
+ if name.is_a?(Symbol)
399
+ raise GemfileError, %(You need to specify gem names as Strings. Use 'gem "#{name}"' instead)
400
+ end
401
+ if /\s/.match?(name)
402
+ raise GemfileError, %('#{name}' is not a valid gem name because it contains whitespace)
403
+ end
404
+ raise GemfileError, %(an empty gem name is not valid) if name.empty?
405
+
406
+ normalize_hash(opts)
407
+
408
+ git_names = @git_sources.keys.map(&:to_s)
409
+ validate_keys("gem '#{name}'", opts, valid_keys + git_names)
410
+
411
+ groups = @groups.dup
412
+ opts["group"] = opts.delete("groups") || opts["group"]
413
+ groups.concat Array(opts.delete("group"))
414
+ groups = [:default] if groups.empty?
415
+
416
+ install_if = @install_conditionals.dup
417
+ install_if.concat Array(opts.delete("install_if"))
418
+ install_if = install_if.reduce(true) do |memo, val|
419
+ memo && (val.respond_to?(:call) ? val.call : val)
420
+ end
421
+
422
+ platforms = @platforms.dup
423
+ opts["platforms"] = opts["platform"] || opts["platforms"]
424
+ platforms.concat Array(opts.delete("platforms"))
425
+ platforms.map!(&:to_sym)
426
+ platforms.each do |p|
427
+ next if VALID_PLATFORMS.include?(p)
428
+ raise GemfileError, "`#{p}` is not a valid platform. The available options are: #{VALID_PLATFORMS.inspect}"
429
+ end
430
+
431
+ windows_platforms = platforms.select {|pl| pl.to_s.match?(/mingw|mswin/) }
432
+ if windows_platforms.any?
433
+ windows_platforms = windows_platforms.map! {|pl| ":#{pl}" }.join(", ")
434
+ deprecated_message = "Platform #{windows_platforms} will be removed in the future. Please use platform :windows instead."
435
+ Bundler::SharedHelpers.feature_deprecated! deprecated_message
436
+ end
437
+
438
+ # Save sources passed in a key
439
+ if opts.key?("source")
440
+ source = normalize_source(opts["source"])
441
+ opts["source"] = @sources.add_rubygems_source("remotes" => source)
442
+ end
443
+
444
+ git_name = (git_names & opts.keys).last
445
+ if @git_sources[git_name]
446
+ git_opts = @git_sources[git_name].call(opts[git_name])
447
+ git_opts = { "git" => git_opts } if git_opts.is_a?(String)
448
+ opts.merge!(git_opts) do |key, _gemfile_value, _git_source_value|
449
+ raise GemfileError, %(The :#{key} option can't be used with `#{git_name}: #{opts[git_name].inspect}`)
450
+ end
451
+ end
452
+
453
+ %w[git path].each do |type|
454
+ next unless param = opts[type]
455
+ if version.first && version.first =~ /^\s*=?\s*(\d[^\s]*)\s*$/
456
+ options = opts.merge("name" => name, "version" => $1)
457
+ else
458
+ options = opts.dup
459
+ end
460
+ source = send(type, param, options) {}
461
+ opts["source"] = source
462
+ end
463
+
464
+ opts["platforms"] = platforms.dup
465
+ opts["group"] = groups
466
+ opts["should_include"] = install_if
467
+ end
468
+
469
+ def normalize_group_options(opts, groups)
470
+ normalize_hash(opts)
471
+
472
+ groups = groups.map {|group| ":#{group}" }.join(", ")
473
+ validate_keys("group #{groups}", opts, %w[optional])
474
+
475
+ opts["optional"] ||= false
476
+ end
477
+
478
+ def validate_keys(command, opts, valid_keys)
479
+ if opts["branch"] && !(opts["git"] || opts["github"] || (opts.keys & @git_sources.keys.map(&:to_s)).any?)
480
+ raise GemfileError, %(The `branch` option for `#{command}` is not allowed. Only gems with a git source can specify a branch)
481
+ end
482
+
483
+ invalid_keys = opts.keys - valid_keys
484
+ return true unless invalid_keys.any?
485
+
486
+ message = String.new
487
+ message << "You passed #{invalid_keys.map {|k| ":" + k }.join(", ")} "
488
+ message << if invalid_keys.size > 1
489
+ "as options for #{command}, but they are invalid."
490
+ else
491
+ "as an option for #{command}, but it is invalid."
492
+ end
493
+
494
+ message << " Valid options are: #{valid_keys.join(", ")}."
495
+ message << " You may be able to resolve this by upgrading Bundler to the newest version."
496
+ raise InvalidOption, message
497
+ end
498
+
499
+ def normalize_source(source)
500
+ case source
501
+ when :gemcutter, :rubygems, :rubyforge
502
+ removed_message =
503
+ "The source :#{source} is disallowed because HTTP requests are insecure.\n" \
504
+ "Please change your source to 'https://rubygems.org' if possible, or 'http://rubygems.org' if not."
505
+ Bundler::SharedHelpers.feature_removed! removed_message
506
+ when String
507
+ source
508
+ else
509
+ raise GemfileError, "Unknown source '#{source}'"
510
+ end
511
+ end
512
+
513
+ def check_path_source_safety
514
+ return if @sources.global_path_source.nil?
515
+
516
+ msg = "You can no longer specify a path source by itself. Instead, \n" \
517
+ "either use the :path option on a gem, or specify the gems that \n" \
518
+ "bundler should find in the path source by passing a block to \n" \
519
+ "the path method, like: \n\n" \
520
+ " path 'dir/containing/rails' do\n" \
521
+ " gem 'rails'\n" \
522
+ " end\n\n"
523
+
524
+ SharedHelpers.feature_removed! msg.strip
525
+ end
526
+
527
+ def check_rubygems_source_safety
528
+ multiple_global_source_warning if @sources.aggregate_global_source?
529
+ end
530
+
531
+ def multiple_global_source_warning
532
+ msg = "This Gemfile contains multiple global sources. " \
533
+ "Each source after the first must include a block to indicate which gems " \
534
+ "should come from that source"
535
+ raise GemfileEvalError, msg
536
+ end
537
+
538
+ class DSLError < GemfileError
539
+ # @return [String] the description that should be presented to the user.
540
+ #
541
+ attr_reader :description
542
+
543
+ # @return [String] the path of the dsl file that raised the exception.
544
+ #
545
+ attr_reader :dsl_path
546
+
547
+ # @return [Exception] the backtrace of the exception raised by the
548
+ # evaluation of the dsl file.
549
+ #
550
+ attr_reader :backtrace
551
+
552
+ # @param [Exception] backtrace @see backtrace
553
+ # @param [String] dsl_path @see dsl_path
554
+ #
555
+ def initialize(description, dsl_path, backtrace, contents = nil)
556
+ @status_code = $!.respond_to?(:status_code) && $!.status_code
557
+
558
+ @description = description
559
+ @dsl_path = dsl_path
560
+ @backtrace = backtrace
561
+ @contents = contents
562
+ end
563
+
564
+ def status_code
565
+ @status_code || super
566
+ end
567
+
568
+ # @return [String] the contents of the DSL that cause the exception to
569
+ # be raised.
570
+ #
571
+ def contents
572
+ @contents ||= dsl_path && File.exist?(dsl_path) && File.read(dsl_path)
573
+ end
574
+
575
+ # The message of the exception reports the content of podspec for the
576
+ # line that generated the original exception.
577
+ #
578
+ # @example Output
579
+ #
580
+ # Invalid podspec at `RestKit.podspec` - undefined method
581
+ # `exclude_header_search_paths=' for #<Pod::Specification for
582
+ # `RestKit/Network (0.9.3)`>
583
+ #
584
+ # from spec-repos/master/RestKit/0.9.3/RestKit.podspec:36
585
+ # -------------------------------------------
586
+ # # because it would break: #import <CoreData/CoreData.h>
587
+ # > ns.exclude_header_search_paths = 'Code/RestKit.h'
588
+ # end
589
+ # -------------------------------------------
590
+ #
591
+ # @return [String] the message of the exception.
592
+ #
593
+ def to_s
594
+ @to_s ||= begin
595
+ trace_line, description = parse_line_number_from_description
596
+
597
+ m = String.new("\n[!] ")
598
+ m << description
599
+ m << ". Bundler cannot continue.\n"
600
+
601
+ return m unless backtrace && dsl_path && contents
602
+
603
+ trace_line = backtrace.find {|l| l.include?(dsl_path) } || trace_line
604
+ return m unless trace_line
605
+ line_number = trace_line.split(":")[1].to_i - 1
606
+ return m unless line_number
607
+
608
+ lines = contents.lines.to_a
609
+ indent = " # "
610
+ indicator = indent.tr("#", ">")
611
+ first_line = line_number.zero?
612
+ last_line = (line_number == (lines.count - 1))
613
+
614
+ m << "\n"
615
+ m << "#{indent}from #{trace_line.gsub(/:in.*$/, "")}\n"
616
+ m << "#{indent}-------------------------------------------\n"
617
+ m << "#{indent}#{lines[line_number - 1]}" unless first_line
618
+ m << "#{indicator}#{lines[line_number]}"
619
+ m << "#{indent}#{lines[line_number + 1]}" unless last_line
620
+ m << "\n" unless m.end_with?("\n")
621
+ m << "#{indent}-------------------------------------------\n"
622
+ end
623
+ end
624
+
625
+ private
626
+
627
+ def parse_line_number_from_description
628
+ description = self.description
629
+ if dsl_path && description =~ /((#{Regexp.quote File.expand_path(dsl_path)}|#{Regexp.quote dsl_path}):\d+)/
630
+ trace_line = Regexp.last_match[1]
631
+ description = description.sub(/\n.*\n(\.\.\.)? *\^~+$/, "").sub(/#{Regexp.quote trace_line}:\s*/, "").sub("\n", " - ")
632
+ end
633
+ [trace_line, description]
634
+ end
635
+ end
636
+
637
+ def gemfile_root
638
+ @gemfile ||= Bundler.default_gemfile
639
+ @gemfile.dirname
640
+ end
641
+ end
642
+ end