bundler 1.9.0 → 1.17.3

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of bundler might be problematic. Click here for more details.

Files changed (328) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +1157 -6
  3. data/README.md +33 -6
  4. data/bundler.gemspec +51 -18
  5. data/exe/bundle +31 -0
  6. data/{bin → exe}/bundle_ruby +10 -6
  7. data/exe/bundler +4 -0
  8. data/lib/bundler.rb +326 -207
  9. data/lib/bundler/build_metadata.rb +53 -0
  10. data/lib/bundler/capistrano.rb +9 -3
  11. data/lib/bundler/cli.rb +522 -141
  12. data/lib/bundler/cli/add.rb +35 -0
  13. data/lib/bundler/cli/binstubs.rb +22 -11
  14. data/lib/bundler/cli/cache.rb +7 -6
  15. data/lib/bundler/cli/check.rb +11 -8
  16. data/lib/bundler/cli/clean.rb +7 -8
  17. data/lib/bundler/cli/common.rb +53 -7
  18. data/lib/bundler/cli/config.rb +84 -49
  19. data/lib/bundler/cli/console.rb +13 -8
  20. data/lib/bundler/cli/doctor.rb +140 -0
  21. data/lib/bundler/cli/exec.rb +77 -16
  22. data/lib/bundler/cli/gem.rb +120 -52
  23. data/lib/bundler/cli/info.rb +50 -0
  24. data/lib/bundler/cli/init.rb +21 -7
  25. data/lib/bundler/cli/inject.rb +37 -10
  26. data/lib/bundler/cli/install.rb +139 -78
  27. data/lib/bundler/cli/issue.rb +40 -0
  28. data/lib/bundler/cli/list.rb +58 -0
  29. data/lib/bundler/cli/lock.rb +63 -0
  30. data/lib/bundler/cli/open.rb +9 -6
  31. data/lib/bundler/cli/outdated.rb +221 -35
  32. data/lib/bundler/cli/package.rb +11 -7
  33. data/lib/bundler/cli/platform.rb +7 -4
  34. data/lib/bundler/cli/plugin.rb +24 -0
  35. data/lib/bundler/cli/pristine.rb +47 -0
  36. data/lib/bundler/cli/remove.rb +18 -0
  37. data/lib/bundler/cli/show.rb +11 -10
  38. data/lib/bundler/cli/update.rb +47 -29
  39. data/lib/bundler/cli/viz.rb +12 -8
  40. data/lib/bundler/compact_index_client.rb +109 -0
  41. data/lib/bundler/compact_index_client/cache.rb +118 -0
  42. data/lib/bundler/compact_index_client/updater.rb +116 -0
  43. data/lib/bundler/compatibility_guard.rb +14 -0
  44. data/lib/bundler/constants.rb +3 -1
  45. data/lib/bundler/current_ruby.rb +47 -137
  46. data/lib/bundler/definition.rb +599 -230
  47. data/lib/bundler/dep_proxy.rb +15 -10
  48. data/lib/bundler/dependency.rb +54 -25
  49. data/lib/bundler/deployment.rb +12 -2
  50. data/lib/bundler/deprecate.rb +33 -4
  51. data/lib/bundler/dsl.rb +383 -99
  52. data/lib/bundler/endpoint_specification.rb +72 -7
  53. data/lib/bundler/env.rb +121 -41
  54. data/lib/bundler/environment_preserver.rb +59 -0
  55. data/lib/bundler/errors.rb +158 -0
  56. data/lib/bundler/feature_flag.rb +74 -0
  57. data/lib/bundler/fetcher.rb +171 -280
  58. data/lib/bundler/fetcher/base.rb +52 -0
  59. data/lib/bundler/fetcher/compact_index.rb +126 -0
  60. data/lib/bundler/fetcher/dependency.rb +82 -0
  61. data/lib/bundler/fetcher/downloader.rb +84 -0
  62. data/lib/bundler/fetcher/index.rb +52 -0
  63. data/lib/bundler/friendly_errors.rb +113 -58
  64. data/lib/bundler/gem_helper.rb +73 -46
  65. data/lib/bundler/gem_helpers.rb +85 -9
  66. data/lib/bundler/gem_remote_fetcher.rb +43 -0
  67. data/lib/bundler/gem_tasks.rb +6 -1
  68. data/lib/bundler/gem_version_promoter.rb +190 -0
  69. data/lib/bundler/gemdeps.rb +29 -0
  70. data/lib/bundler/graph.rb +32 -49
  71. data/lib/bundler/index.rb +79 -67
  72. data/lib/bundler/injector.rb +219 -30
  73. data/lib/bundler/inline.rb +74 -0
  74. data/lib/bundler/installer.rb +191 -206
  75. data/lib/bundler/installer/gem_installer.rb +85 -0
  76. data/lib/bundler/installer/parallel_installer.rb +233 -0
  77. data/lib/bundler/installer/standalone.rb +53 -0
  78. data/lib/bundler/lazy_specification.rb +53 -13
  79. data/lib/bundler/lockfile_generator.rb +95 -0
  80. data/lib/bundler/lockfile_parser.rb +157 -62
  81. data/lib/bundler/match_platform.rb +15 -4
  82. data/lib/bundler/mirror.rb +223 -0
  83. data/lib/bundler/plugin.rb +292 -0
  84. data/lib/bundler/plugin/api.rb +81 -0
  85. data/lib/bundler/plugin/api/source.rb +306 -0
  86. data/lib/bundler/plugin/dsl.rb +53 -0
  87. data/lib/bundler/plugin/events.rb +61 -0
  88. data/lib/bundler/plugin/index.rb +162 -0
  89. data/lib/bundler/plugin/installer.rb +96 -0
  90. data/lib/bundler/plugin/installer/git.rb +38 -0
  91. data/lib/bundler/plugin/installer/rubygems.rb +27 -0
  92. data/lib/bundler/plugin/source_list.rb +27 -0
  93. data/lib/bundler/process_lock.rb +24 -0
  94. data/lib/bundler/psyched_yaml.rb +17 -6
  95. data/lib/bundler/remote_specification.rb +68 -11
  96. data/lib/bundler/resolver.rb +263 -229
  97. data/lib/bundler/resolver/spec_group.rb +106 -0
  98. data/lib/bundler/retry.rb +25 -19
  99. data/lib/bundler/ruby_dsl.rb +9 -2
  100. data/lib/bundler/ruby_version.rb +101 -66
  101. data/lib/bundler/rubygems_ext.rb +77 -37
  102. data/lib/bundler/rubygems_gem_installer.rb +106 -0
  103. data/lib/bundler/rubygems_integration.rb +450 -163
  104. data/lib/bundler/runtime.rb +133 -103
  105. data/lib/bundler/settings.rb +344 -83
  106. data/lib/bundler/settings/validator.rb +102 -0
  107. data/lib/bundler/setup.rb +7 -3
  108. data/lib/bundler/shared_helpers.rb +284 -54
  109. data/lib/bundler/similarity_detector.rb +21 -21
  110. data/lib/bundler/source.rb +68 -15
  111. data/lib/bundler/source/gemspec.rb +18 -0
  112. data/lib/bundler/source/git.rb +90 -55
  113. data/lib/bundler/source/git/git_proxy.rb +135 -35
  114. data/lib/bundler/source/metadata.rb +62 -0
  115. data/lib/bundler/source/path.rb +84 -61
  116. data/lib/bundler/source/path/installer.rb +53 -17
  117. data/lib/bundler/source/rubygems.rb +282 -122
  118. data/lib/bundler/source/rubygems/remote.rb +69 -0
  119. data/lib/bundler/source_list.rb +107 -22
  120. data/lib/bundler/spec_set.rb +83 -45
  121. data/lib/bundler/ssl_certs/certificate_manager.rb +8 -7
  122. data/lib/bundler/ssl_certs/index.rubygems.org/GlobalSignRootCA.pem +21 -0
  123. data/lib/bundler/ssl_certs/{DigiCertHighAssuranceEVRootCA.pem → rubygems.global.ssl.fastly.net/DigiCertHighAssuranceEVRootCA.pem} +0 -0
  124. data/lib/bundler/ssl_certs/{AddTrustExternalCARoot-2048.pem → rubygems.org/AddTrustExternalCARoot.pem} +0 -0
  125. data/lib/bundler/stub_specification.rb +108 -0
  126. data/lib/bundler/templates/.document +1 -0
  127. data/lib/bundler/templates/Executable +19 -6
  128. data/lib/bundler/templates/Executable.bundler +105 -0
  129. data/lib/bundler/templates/Executable.standalone +6 -4
  130. data/lib/bundler/templates/Gemfile +4 -1
  131. data/lib/bundler/templates/gems.rb +8 -0
  132. data/lib/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt +68 -7
  133. data/lib/bundler/templates/newgem/Gemfile.tt +4 -2
  134. data/lib/bundler/templates/newgem/LICENSE.txt.tt +1 -1
  135. data/lib/bundler/templates/newgem/README.md.tt +19 -11
  136. data/lib/bundler/templates/newgem/Rakefile.tt +10 -6
  137. data/lib/bundler/templates/newgem/bin/console.tt +1 -1
  138. data/lib/bundler/templates/newgem/bin/setup.tt +2 -1
  139. data/lib/bundler/templates/newgem/ext/newgem/newgem.c.tt +4 -4
  140. data/lib/bundler/templates/newgem/ext/newgem/newgem.h.tt +3 -3
  141. data/lib/bundler/templates/newgem/gitignore.tt +5 -1
  142. data/lib/bundler/templates/newgem/lib/newgem.rb.tt +7 -6
  143. data/lib/bundler/templates/newgem/lib/newgem/version.rb.tt +4 -4
  144. data/lib/bundler/templates/newgem/newgem.gemspec.tt +31 -15
  145. data/lib/bundler/templates/newgem/rspec.tt +1 -0
  146. data/lib/bundler/templates/newgem/spec/newgem_spec.rb.tt +3 -5
  147. data/lib/bundler/templates/newgem/spec/spec_helper.rb.tt +14 -2
  148. data/lib/bundler/templates/newgem/test/{test_newgem.rb.tt → newgem_test.rb.tt} +2 -2
  149. data/lib/bundler/templates/newgem/test/test_helper.rb.tt +4 -0
  150. data/lib/bundler/templates/newgem/travis.yml.tt +7 -0
  151. data/lib/bundler/ui.rb +5 -3
  152. data/lib/bundler/ui/rg_proxy.rb +5 -7
  153. data/lib/bundler/ui/shell.rb +69 -18
  154. data/lib/bundler/ui/silent.rb +26 -1
  155. data/lib/bundler/uri_credentials_filter.rb +37 -0
  156. data/lib/bundler/vendor/fileutils/lib/fileutils.rb +1638 -0
  157. data/lib/bundler/vendor/molinillo/lib/molinillo.rb +12 -0
  158. data/lib/bundler/vendor/molinillo/lib/molinillo/compatibility.rb +26 -0
  159. data/lib/bundler/vendor/molinillo/lib/molinillo/delegates/resolution_state.rb +57 -0
  160. data/lib/bundler/vendor/molinillo/lib/molinillo/delegates/specification_provider.rb +81 -0
  161. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb +223 -0
  162. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/action.rb +36 -0
  163. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb +66 -0
  164. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_vertex.rb +62 -0
  165. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/delete_edge.rb +63 -0
  166. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb +61 -0
  167. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/log.rb +126 -0
  168. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/set_payload.rb +46 -0
  169. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/tag.rb +36 -0
  170. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb +136 -0
  171. data/lib/bundler/vendor/molinillo/lib/molinillo/errors.rb +143 -0
  172. data/lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb +6 -0
  173. data/lib/bundler/vendor/{Molinillo-0.2.1 → molinillo}/lib/molinillo/modules/specification_provider.rb +11 -0
  174. data/lib/bundler/vendor/{Molinillo-0.2.1 → molinillo}/lib/molinillo/modules/ui.rb +6 -2
  175. data/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb +837 -0
  176. data/lib/bundler/vendor/{Molinillo-0.2.1 → molinillo}/lib/molinillo/resolver.rb +6 -3
  177. data/lib/bundler/vendor/molinillo/lib/molinillo/state.rb +58 -0
  178. data/lib/bundler/vendor/{net → net-http-persistent/lib/net}/http/faster.rb +1 -0
  179. data/lib/bundler/vendor/{net → net-http-persistent/lib/net}/http/persistent.rb +27 -24
  180. data/lib/bundler/vendor/{net → net-http-persistent/lib/net}/http/persistent/ssl_reuse.rb +2 -1
  181. data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor.rb +47 -22
  182. data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/actions.rb +31 -29
  183. data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/actions/create_file.rb +3 -2
  184. data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/actions/create_link.rb +3 -2
  185. data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/actions/directory.rb +3 -3
  186. data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/actions/empty_directory.rb +16 -8
  187. data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/actions/file_manipulation.rb +66 -18
  188. data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/actions/inject_into_file.rb +18 -16
  189. data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/base.rb +67 -44
  190. data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/command.rb +13 -11
  191. data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/core_ext/hash_with_indifferent_access.rb +21 -1
  192. data/lib/bundler/vendor/thor/lib/thor/core_ext/io_binary_read.rb +12 -0
  193. data/lib/bundler/vendor/thor/lib/thor/core_ext/ordered_hash.rb +129 -0
  194. data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/error.rb +3 -3
  195. data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/group.rb +14 -14
  196. data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/invocation.rb +4 -5
  197. data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/line_editor.rb +2 -2
  198. data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/line_editor/basic.rb +2 -0
  199. data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/line_editor/readline.rb +0 -0
  200. data/lib/bundler/vendor/thor/lib/thor/parser.rb +4 -0
  201. data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/parser/argument.rb +4 -7
  202. data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/parser/arguments.rb +16 -16
  203. data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/parser/option.rb +42 -21
  204. data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/parser/options.rb +13 -10
  205. data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/rake_compat.rb +1 -1
  206. data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/runner.rb +35 -33
  207. data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/shell.rb +4 -4
  208. data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/shell/basic.rb +49 -33
  209. data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/shell/color.rb +2 -2
  210. data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/shell/html.rb +5 -5
  211. data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/util.rb +8 -7
  212. data/lib/bundler/vendor/{thor-0.19.1 → thor}/lib/thor/version.rb +1 -1
  213. data/lib/bundler/vendored_fileutils.rb +9 -0
  214. data/lib/bundler/vendored_molinillo.rb +4 -5
  215. data/lib/bundler/vendored_persistent.rb +45 -4
  216. data/lib/bundler/vendored_thor.rb +8 -5
  217. data/lib/bundler/version.rb +23 -1
  218. data/lib/bundler/version_ranges.rb +76 -0
  219. data/lib/bundler/vlad.rb +8 -2
  220. data/lib/bundler/worker.rb +39 -6
  221. data/lib/bundler/yaml_serializer.rb +90 -0
  222. data/man/bundle-add.1 +58 -0
  223. data/man/bundle-add.1.txt +52 -0
  224. data/man/bundle-add.ronn +40 -0
  225. data/man/bundle-binstubs.1 +40 -0
  226. data/man/bundle-binstubs.1.txt +48 -0
  227. data/man/bundle-binstubs.ronn +43 -0
  228. data/man/bundle-check.1 +31 -0
  229. data/man/bundle-check.1.txt +33 -0
  230. data/man/bundle-check.ronn +26 -0
  231. data/man/bundle-clean.1 +24 -0
  232. data/man/bundle-clean.1.txt +26 -0
  233. data/man/bundle-clean.ronn +18 -0
  234. data/man/bundle-config.1 +497 -0
  235. data/man/bundle-config.1.txt +529 -0
  236. data/man/bundle-config.ronn +256 -31
  237. data/man/bundle-doctor.1 +44 -0
  238. data/man/bundle-doctor.1.txt +44 -0
  239. data/man/bundle-doctor.ronn +33 -0
  240. data/man/bundle-exec.1 +165 -0
  241. data/man/bundle-exec.1.txt +178 -0
  242. data/man/bundle-exec.ronn +19 -3
  243. data/man/bundle-gem.1 +80 -0
  244. data/man/bundle-gem.1.txt +91 -0
  245. data/man/bundle-gem.ronn +78 -0
  246. data/man/bundle-info.1 +20 -0
  247. data/man/bundle-info.1.txt +21 -0
  248. data/man/bundle-info.ronn +17 -0
  249. data/man/bundle-init.1 +25 -0
  250. data/man/bundle-init.1.txt +34 -0
  251. data/man/bundle-init.ronn +29 -0
  252. data/man/bundle-inject.1 +33 -0
  253. data/man/bundle-inject.1.txt +32 -0
  254. data/man/bundle-inject.ronn +22 -0
  255. data/man/bundle-install.1 +308 -0
  256. data/man/bundle-install.1.txt +396 -0
  257. data/man/bundle-install.ronn +64 -67
  258. data/man/bundle-list.1 +50 -0
  259. data/man/bundle-list.1.txt +43 -0
  260. data/man/bundle-list.ronn +33 -0
  261. data/man/bundle-lock.1 +84 -0
  262. data/man/bundle-lock.1.txt +93 -0
  263. data/man/bundle-lock.ronn +94 -0
  264. data/man/bundle-open.1 +32 -0
  265. data/man/bundle-open.1.txt +29 -0
  266. data/man/bundle-open.ronn +19 -0
  267. data/man/bundle-outdated.1 +155 -0
  268. data/man/bundle-outdated.1.txt +131 -0
  269. data/man/bundle-outdated.ronn +111 -0
  270. data/man/bundle-package.1 +55 -0
  271. data/man/bundle-package.1.txt +79 -0
  272. data/man/bundle-package.ronn +14 -8
  273. data/man/bundle-platform.1 +61 -0
  274. data/man/bundle-platform.1.txt +57 -0
  275. data/man/bundle-platform.ronn +1 -1
  276. data/man/bundle-pristine.1 +34 -0
  277. data/man/bundle-pristine.1.txt +44 -0
  278. data/man/bundle-pristine.ronn +34 -0
  279. data/man/bundle-remove.1 +31 -0
  280. data/man/bundle-remove.1.txt +34 -0
  281. data/man/bundle-remove.ronn +23 -0
  282. data/man/bundle-show.1 +23 -0
  283. data/man/bundle-show.1.txt +27 -0
  284. data/man/bundle-show.ronn +21 -0
  285. data/man/bundle-update.1 +394 -0
  286. data/man/bundle-update.1.txt +391 -0
  287. data/man/bundle-update.ronn +180 -18
  288. data/man/bundle-viz.1 +39 -0
  289. data/man/bundle-viz.1.txt +39 -0
  290. data/man/bundle-viz.ronn +30 -0
  291. data/man/bundle.1 +136 -0
  292. data/man/bundle.1.txt +116 -0
  293. data/man/bundle.ronn +46 -33
  294. data/man/gemfile.5 +689 -0
  295. data/man/gemfile.5.ronn +127 -79
  296. data/man/gemfile.5.txt +653 -0
  297. data/man/index.txt +25 -7
  298. metadata +242 -95
  299. data/.gitignore +0 -16
  300. data/.rspec +0 -3
  301. data/.travis.yml +0 -110
  302. data/CODE_OF_CONDUCT.md +0 -40
  303. data/CONTRIBUTING.md +0 -32
  304. data/DEVELOPMENT.md +0 -119
  305. data/ISSUES.md +0 -96
  306. data/Rakefile +0 -302
  307. data/UPGRADING.md +0 -103
  308. data/bin/bundle +0 -21
  309. data/bin/bundler +0 -21
  310. data/lib/bundler/anonymizable_uri.rb +0 -32
  311. data/lib/bundler/environment.rb +0 -42
  312. data/lib/bundler/gem_installer.rb +0 -9
  313. data/lib/bundler/gem_path_manipulation.rb +0 -8
  314. data/lib/bundler/ssl_certs/AddTrustExternalCARoot.pem +0 -32
  315. data/lib/bundler/ssl_certs/Class3PublicPrimaryCertificationAuthority.pem +0 -14
  316. data/lib/bundler/ssl_certs/EntrustnetSecureServerCertificationAuthority.pem +0 -28
  317. data/lib/bundler/ssl_certs/GeoTrustGlobalCA.pem +0 -20
  318. data/lib/bundler/templates/newgem/.travis.yml.tt +0 -3
  319. data/lib/bundler/templates/newgem/test/minitest_helper.rb.tt +0 -4
  320. data/lib/bundler/vendor/Molinillo-0.2.1/lib/molinillo.rb +0 -5
  321. data/lib/bundler/vendor/Molinillo-0.2.1/lib/molinillo/dependency_graph.rb +0 -266
  322. data/lib/bundler/vendor/Molinillo-0.2.1/lib/molinillo/errors.rb +0 -69
  323. data/lib/bundler/vendor/Molinillo-0.2.1/lib/molinillo/gem_metadata.rb +0 -3
  324. data/lib/bundler/vendor/Molinillo-0.2.1/lib/molinillo/resolution.rb +0 -412
  325. data/lib/bundler/vendor/Molinillo-0.2.1/lib/molinillo/state.rb +0 -43
  326. data/lib/bundler/vendor/thor-0.19.1/lib/thor/core_ext/io_binary_read.rb +0 -10
  327. data/lib/bundler/vendor/thor-0.19.1/lib/thor/core_ext/ordered_hash.rb +0 -98
  328. data/lib/bundler/vendor/thor-0.19.1/lib/thor/parser.rb +0 -4
@@ -1,21 +1,24 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Bundler
2
4
  class DepProxy
3
-
4
5
  attr_reader :__platform, :dep
5
6
 
6
7
  def initialize(dep, platform)
7
- @dep, @__platform = dep, platform
8
+ @dep = dep
9
+ @__platform = platform
8
10
  end
9
11
 
10
12
  def hash
11
- @hash ||= dep.hash
13
+ @hash ||= [dep, __platform].hash
12
14
  end
13
15
 
14
- def ==(o)
15
- dep == o.dep && __platform == o.__platform
16
+ def ==(other)
17
+ return false if other.class != self.class
18
+ dep == other.dep && __platform == other.__platform
16
19
  end
17
20
 
18
- alias eql? ==
21
+ alias_method :eql?, :==
19
22
 
20
23
  def type
21
24
  @dep.type
@@ -30,14 +33,16 @@ module Bundler
30
33
  end
31
34
 
32
35
  def to_s
33
- "#{name} (#{requirement}) #{__platform}"
36
+ s = name.dup
37
+ s << " (#{requirement})" unless requirement == Gem::Requirement.default
38
+ s << " #{__platform}" unless __platform == Gem::Platform::RUBY
39
+ s
34
40
  end
35
41
 
36
42
  private
37
43
 
38
- def method_missing(*args)
39
- @dep.send(*args)
44
+ def method_missing(*args, &blk)
45
+ @dep.send(*args, &blk)
40
46
  end
41
-
42
47
  end
43
48
  end
@@ -1,12 +1,13 @@
1
- require 'rubygems/dependency'
2
- require 'bundler/shared_helpers'
3
- require 'bundler/rubygems_ext'
1
+ # frozen_string_literal: true
2
+
3
+ require "rubygems/dependency"
4
+ require "bundler/shared_helpers"
5
+ require "bundler/rubygems_ext"
4
6
 
5
7
  module Bundler
6
8
  class Dependency < Gem::Dependency
7
9
  attr_reader :autorequire
8
- attr_reader :groups
9
- attr_reader :platforms
10
+ attr_reader :groups, :platforms, :gemfile
10
11
 
11
12
  PLATFORM_MAP = {
12
13
  :ruby => Gem::Platform::RUBY,
@@ -15,13 +16,20 @@ module Bundler
15
16
  :ruby_20 => Gem::Platform::RUBY,
16
17
  :ruby_21 => Gem::Platform::RUBY,
17
18
  :ruby_22 => Gem::Platform::RUBY,
19
+ :ruby_23 => Gem::Platform::RUBY,
20
+ :ruby_24 => Gem::Platform::RUBY,
21
+ :ruby_25 => Gem::Platform::RUBY,
18
22
  :mri => Gem::Platform::RUBY,
19
23
  :mri_18 => Gem::Platform::RUBY,
20
24
  :mri_19 => Gem::Platform::RUBY,
21
25
  :mri_20 => Gem::Platform::RUBY,
22
26
  :mri_21 => Gem::Platform::RUBY,
23
27
  :mri_22 => Gem::Platform::RUBY,
28
+ :mri_23 => Gem::Platform::RUBY,
29
+ :mri_24 => Gem::Platform::RUBY,
30
+ :mri_25 => Gem::Platform::RUBY,
24
31
  :rbx => Gem::Platform::RUBY,
32
+ :truffleruby => Gem::Platform::RUBY,
25
33
  :jruby => Gem::Platform::JAVA,
26
34
  :jruby_18 => Gem::Platform::JAVA,
27
35
  :jruby_19 => Gem::Platform::JAVA,
@@ -30,51 +38,72 @@ module Bundler
30
38
  :mswin_19 => Gem::Platform::MSWIN,
31
39
  :mswin_20 => Gem::Platform::MSWIN,
32
40
  :mswin_21 => Gem::Platform::MSWIN,
41
+ :mswin_22 => Gem::Platform::MSWIN,
42
+ :mswin_23 => Gem::Platform::MSWIN,
43
+ :mswin_24 => Gem::Platform::MSWIN,
44
+ :mswin_25 => Gem::Platform::MSWIN,
33
45
  :mswin64 => Gem::Platform::MSWIN64,
34
46
  :mswin64_19 => Gem::Platform::MSWIN64,
35
47
  :mswin64_20 => Gem::Platform::MSWIN64,
36
48
  :mswin64_21 => Gem::Platform::MSWIN64,
49
+ :mswin64_22 => Gem::Platform::MSWIN64,
50
+ :mswin64_23 => Gem::Platform::MSWIN64,
51
+ :mswin64_24 => Gem::Platform::MSWIN64,
52
+ :mswin64_25 => Gem::Platform::MSWIN64,
37
53
  :mingw => Gem::Platform::MINGW,
38
54
  :mingw_18 => Gem::Platform::MINGW,
39
55
  :mingw_19 => Gem::Platform::MINGW,
40
56
  :mingw_20 => Gem::Platform::MINGW,
41
57
  :mingw_21 => Gem::Platform::MINGW,
42
58
  :mingw_22 => Gem::Platform::MINGW,
59
+ :mingw_23 => Gem::Platform::MINGW,
60
+ :mingw_24 => Gem::Platform::MINGW,
61
+ :mingw_25 => Gem::Platform::MINGW,
43
62
  :x64_mingw => Gem::Platform::X64_MINGW,
44
63
  :x64_mingw_20 => Gem::Platform::X64_MINGW,
45
64
  :x64_mingw_21 => Gem::Platform::X64_MINGW,
46
- :x64_mingw_22 => Gem::Platform::X64_MINGW
65
+ :x64_mingw_22 => Gem::Platform::X64_MINGW,
66
+ :x64_mingw_23 => Gem::Platform::X64_MINGW,
67
+ :x64_mingw_24 => Gem::Platform::X64_MINGW,
68
+ :x64_mingw_25 => Gem::Platform::X64_MINGW,
47
69
  }.freeze
48
70
 
71
+ REVERSE_PLATFORM_MAP = {}.tap do |reverse_platform_map|
72
+ PLATFORM_MAP.each do |key, value|
73
+ reverse_platform_map[value] ||= []
74
+ reverse_platform_map[value] << key
75
+ end
76
+
77
+ reverse_platform_map.each {|_, platforms| platforms.freeze }
78
+ end.freeze
79
+
49
80
  def initialize(name, version, options = {}, &blk)
50
81
  type = options["type"] || :runtime
51
82
  super(name, version, type)
52
83
 
53
- @autorequire = nil
54
- @groups = Array(options["group"] || :default).map { |g| g.to_sym }
55
- @source = options["source"]
56
- @platforms = Array(options["platforms"])
57
- @env = options["env"]
84
+ @autorequire = nil
85
+ @groups = Array(options["group"] || :default).map(&:to_sym)
86
+ @source = options["source"]
87
+ @platforms = Array(options["platforms"])
88
+ @env = options["env"]
89
+ @should_include = options.fetch("should_include", true)
90
+ @gemfile = options["gemfile"]
58
91
 
59
- if options.key?('require')
60
- @autorequire = Array(options['require'] || [])
61
- end
92
+ @autorequire = Array(options["require"] || []) if options.key?("require")
62
93
  end
63
94
 
95
+ # Returns the platforms this dependency is valid for, in the same order as
96
+ # passed in the `valid_platforms` parameter
64
97
  def gem_platforms(valid_platforms)
65
98
  return valid_platforms if @platforms.empty?
66
99
 
67
- platforms = []
68
- @platforms.each do |p|
69
- platform = PLATFORM_MAP[p]
70
- next unless valid_platforms.include?(platform)
71
- platforms |= [platform]
72
- end
73
- platforms
100
+ @gem_platforms ||= @platforms.map {|pl| PLATFORM_MAP[pl] }.compact.uniq
101
+
102
+ valid_platforms & @gem_platforms
74
103
  end
75
104
 
76
105
  def should_include?
77
- current_env? && current_platform?
106
+ @should_include && current_env? && current_platform?
78
107
  end
79
108
 
80
109
  def current_env?
@@ -90,14 +119,14 @@ module Bundler
90
119
 
91
120
  def current_platform?
92
121
  return true if @platforms.empty?
93
- @platforms.any? { |p|
122
+ @platforms.any? do |p|
94
123
  Bundler.current_ruby.send("#{p}?")
95
- }
124
+ end
96
125
  end
97
126
 
98
127
  def to_lock
99
128
  out = super
100
- out << '!' if source
129
+ out << "!" if source
101
130
  out << "\n"
102
131
  end
103
132
 
@@ -1,3 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/shared_helpers"
4
+ Bundler::SharedHelpers.major_deprecation 2, "Bundler no longer integrates with " \
5
+ "Capistrano, but Capistrano provides its own integration with " \
6
+ "Bundler via the capistrano-bundler gem. Use it instead."
7
+
1
8
  module Bundler
2
9
  class Deployment
3
10
  def self.define_task(context, task_method = :task, opts = {})
@@ -33,15 +40,17 @@ module Bundler
33
40
  set :bundle_dir, File.join(fetch(:shared_path), 'bundle')
34
41
  set :bundle_flags, "--deployment --quiet"
35
42
  set :bundle_without, [:development, :test]
43
+ set :bundle_with, [:mysql]
36
44
  set :bundle_cmd, "bundle" # e.g. "/opt/ruby/bin/bundle"
37
45
  set :bundle_roles, #{role_default} # e.g. [:app, :batch]
38
46
  DESC
39
47
  send task_method, :install, opts do
40
48
  bundle_cmd = context.fetch(:bundle_cmd, "bundle")
41
49
  bundle_flags = context.fetch(:bundle_flags, "--deployment --quiet")
42
- bundle_dir = context.fetch(:bundle_dir, File.join(context.fetch(:shared_path), 'bundle'))
50
+ bundle_dir = context.fetch(:bundle_dir, File.join(context.fetch(:shared_path), "bundle"))
43
51
  bundle_gemfile = context.fetch(:bundle_gemfile, "Gemfile")
44
52
  bundle_without = [*context.fetch(:bundle_without, [:development, :test])].compact
53
+ bundle_with = [*context.fetch(:bundle_with, [])].compact
45
54
  app_path = context.fetch(:latest_release)
46
55
  if app_path.to_s.empty?
47
56
  raise error_type.new("Cannot detect current release path - make sure you have deployed at least once.")
@@ -50,8 +59,9 @@ module Bundler
50
59
  args << "--path #{bundle_dir}" unless bundle_dir.to_s.empty?
51
60
  args << bundle_flags.to_s
52
61
  args << "--without #{bundle_without.join(" ")}" unless bundle_without.empty?
62
+ args << "--with #{bundle_with.join(" ")}" unless bundle_with.empty?
53
63
 
54
- run "cd #{app_path} && #{bundle_cmd} install #{args.join(' ')}"
64
+ run "cd #{app_path} && #{bundle_cmd} install #{args.join(" ")}"
55
65
  end
56
66
  end
57
67
  end
@@ -1,15 +1,44 @@
1
- module Bundler
1
+ # frozen_string_literal: true
2
+
3
+ begin
4
+ require "rubygems/deprecate"
5
+ rescue LoadError
6
+ # it's fine if it doesn't exist on the current RubyGems...
7
+ nil
8
+ end
2
9
 
3
- if defined? ::Deprecate
10
+ module Bundler
11
+ # If Bundler::Deprecate is an autoload constant, we need to define it
12
+ if defined?(Bundler::Deprecate) && !autoload?(:Deprecate)
13
+ # nothing to do!
14
+ elsif defined? ::Deprecate
4
15
  Deprecate = ::Deprecate
5
16
  elsif defined? Gem::Deprecate
6
17
  Deprecate = Gem::Deprecate
7
18
  else
8
- class Deprecate; end
19
+ class Deprecate
20
+ end
9
21
  end
10
22
 
11
23
  unless Deprecate.respond_to?(:skip_during)
12
- def Deprecate.skip_during; yield; end
24
+ def Deprecate.skip_during
25
+ original = skip
26
+ self.skip = true
27
+ yield
28
+ ensure
29
+ self.skip = original
30
+ end
13
31
  end
14
32
 
33
+ unless Deprecate.respond_to?(:skip)
34
+ def Deprecate.skip
35
+ @skip ||= false
36
+ end
37
+ end
38
+
39
+ unless Deprecate.respond_to?(:skip=)
40
+ def Deprecate.skip=(skip)
41
+ @skip = skip
42
+ end
43
+ end
15
44
  end
@@ -1,5 +1,7 @@
1
- require 'bundler/dependency'
2
- require 'bundler/ruby_dsl'
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/dependency"
4
+ require "bundler/ruby_dsl"
3
5
 
4
6
  module Bundler
5
7
  class Dsl
@@ -13,60 +15,85 @@ module Bundler
13
15
 
14
16
  VALID_PLATFORMS = Bundler::Dependency::PLATFORM_MAP.keys.freeze
15
17
 
18
+ VALID_KEYS = %w[group groups git path glob name branch ref tag require submodules
19
+ platform platforms type source install_if gemfile].freeze
20
+
21
+ attr_reader :gemspecs
16
22
  attr_accessor :dependencies
17
23
 
18
24
  def initialize
19
- @source = nil
20
- @sources = SourceList.new
21
- @git_sources = {}
22
- @dependencies = []
23
- @groups = []
24
- @platforms = []
25
- @env = nil
26
- @ruby_version = nil
25
+ @source = nil
26
+ @sources = SourceList.new
27
+ @git_sources = {}
28
+ @dependencies = []
29
+ @groups = []
30
+ @install_conditionals = []
31
+ @optional_groups = []
32
+ @platforms = []
33
+ @env = nil
34
+ @ruby_version = nil
35
+ @gemspecs = []
36
+ @gemfile = nil
37
+ @gemfiles = []
27
38
  add_git_sources
28
39
  end
29
40
 
30
41
  def eval_gemfile(gemfile, contents = nil)
31
- contents ||= Bundler.read_file(gemfile.to_s)
32
- instance_eval(contents, gemfile.to_s, 1)
33
- rescue SyntaxError => e
34
- syntax_msg = e.message.gsub("#{gemfile}:", 'on line ')
35
- raise GemfileError, "Gemfile syntax error #{syntax_msg}"
36
- rescue ScriptError, RegexpError, NameError, ArgumentError, RuntimeError => e
37
- e.backtrace[0] = "#{e.backtrace[0]}: #{e.message} (#{e.class})"
38
- Bundler.ui.warn e.backtrace.join("\n ")
39
- raise GemfileError, "There was an error in your Gemfile," \
40
- " and Bundler cannot continue."
42
+ expanded_gemfile_path = Pathname.new(gemfile).expand_path(@gemfile && @gemfile.parent)
43
+ original_gemfile = @gemfile
44
+ @gemfile = expanded_gemfile_path
45
+ @gemfiles << expanded_gemfile_path
46
+ contents ||= Bundler.read_file(@gemfile.to_s)
47
+ instance_eval(contents.dup.untaint, gemfile.to_s, 1)
48
+ rescue Exception => e
49
+ message = "There was an error " \
50
+ "#{e.is_a?(GemfileEvalError) ? "evaluating" : "parsing"} " \
51
+ "`#{File.basename gemfile.to_s}`: #{e.message}"
52
+
53
+ raise DSLError.new(message, gemfile, e.backtrace, contents)
54
+ ensure
55
+ @gemfile = original_gemfile
41
56
  end
42
57
 
43
58
  def gemspec(opts = nil)
44
- path = opts && opts[:path] || '.'
45
- name = opts && opts[:name] || '{,*}'
46
- development_group = opts && opts[:development_group] || :development
47
- expanded_path = File.expand_path(path, Bundler.default_gemfile.dirname)
59
+ opts ||= {}
60
+ path = opts[:path] || "."
61
+ glob = opts[:glob]
62
+ name = opts[:name]
63
+ development_group = opts[:development_group] || :development
64
+ expanded_path = gemfile_root.join(path)
65
+
66
+ gemspecs = Dir[File.join(expanded_path, "{,*}.gemspec")].map {|g| Bundler.load_gemspec(g) }.compact
67
+ gemspecs.reject! {|s| s.name != name } if name
68
+ Index.sort_specs(gemspecs)
69
+ specs_by_name_and_version = gemspecs.group_by {|s| [s.name, s.version] }
70
+
71
+ case specs_by_name_and_version.size
72
+ when 1
73
+ specs = specs_by_name_and_version.values.first
74
+ spec = specs.find {|s| s.match_platform(Bundler.local_platform) } || specs.first
48
75
 
49
- gemspecs = Dir[File.join(expanded_path, "#{name}.gemspec")]
76
+ @gemspecs << spec
77
+
78
+ gem_platforms = Bundler::Dependency::REVERSE_PLATFORM_MAP[Bundler::GemHelpers.generic_local_platform]
79
+ gem spec.name, :name => spec.name, :path => path, :glob => glob, :platforms => gem_platforms
50
80
 
51
- case gemspecs.size
52
- when 1
53
- spec = Bundler.load_gemspec(gemspecs.first)
54
- raise InvalidOption, "There was an error loading the gemspec at #{gemspecs.first}." unless spec
55
- gem spec.name, :path => path
56
81
  group(development_group) do
57
82
  spec.development_dependencies.each do |dep|
58
83
  gem dep.name, *(dep.requirement.as_list + [:type => :development])
59
84
  end
60
85
  end
61
86
  when 0
62
- raise InvalidOption, "There are no gemspecs at #{expanded_path}."
87
+ raise InvalidOption, "There are no gemspecs at #{expanded_path}"
63
88
  else
64
- raise InvalidOption, "There are multiple gemspecs at #{expanded_path}. Please use the :name option to specify which one."
89
+ raise InvalidOption, "There are multiple gemspecs at #{expanded_path}. " \
90
+ "Please use the :name option to specify which one should be used"
65
91
  end
66
92
  end
67
93
 
68
94
  def gem(name, *args)
69
95
  options = args.last.is_a?(Hash) ? args.pop.dup : {}
96
+ options["gemfile"] = @gemfile
70
97
  version = args || [">= 0"]
71
98
 
72
99
  normalize_options(name, version, options)
@@ -74,32 +101,43 @@ module Bundler
74
101
  dep = Dependency.new(name, version, options)
75
102
 
76
103
  # if there's already a dependency with this name we try to prefer one
77
- if current = @dependencies.find { |d| d.name == dep.name }
104
+ if current = @dependencies.find {|d| d.name == dep.name }
105
+ deleted_dep = @dependencies.delete(current) if current.type == :development
106
+
78
107
  if current.requirement != dep.requirement
79
- if current.type == :development
80
- @dependencies.delete current
81
- elsif dep.type == :development
82
- return
83
- else
108
+ unless deleted_dep
109
+ return if dep.type == :development
110
+
111
+ update_prompt = ""
112
+
113
+ if File.basename(@gemfile) == Injector::INJECTED_GEMS
114
+ if dep.requirements_list.include?(">= 0") && !current.requirements_list.include?(">= 0")
115
+ update_prompt = ". Gem already added"
116
+ else
117
+ update_prompt = ". If you want to update the gem version, run `bundle update #{current.name}`"
118
+
119
+ update_prompt += ". You may also need to change the version requirement specified in the Gemfile if it's too restrictive." unless current.requirements_list.include?(">= 0")
120
+ end
121
+ end
122
+
84
123
  raise GemfileError, "You cannot specify the same gem twice with different version requirements.\n" \
85
- "You specified: #{current.name} (#{current.requirement}) and #{dep.name} (#{dep.requirement})"
124
+ "You specified: #{current.name} (#{current.requirement}) and #{dep.name} (#{dep.requirement})" \
125
+ "#{update_prompt}"
86
126
  end
87
127
 
88
128
  else
89
129
  Bundler.ui.warn "Your Gemfile lists the gem #{current.name} (#{current.requirement}) more than once.\n" \
90
130
  "You should probably keep only one of them.\n" \
91
- "While it's not a problem now, it could cause errors if you change the version of just one of them later."
131
+ "Remove any duplicate entries and specify the gem only once (per group).\n" \
132
+ "While it's not a problem now, it could cause errors if you change the version of one of them later."
92
133
  end
93
134
 
94
135
  if current.source != dep.source
95
- if current.type == :development
96
- @dependencies.delete current
97
- elsif dep.type == :development
98
- return
99
- else
136
+ unless deleted_dep
137
+ return if dep.type == :development
100
138
  raise GemfileError, "You cannot specify the same gem twice coming from different sources.\n" \
101
139
  "You specified that #{dep.name} (#{dep.requirement}) should come from " \
102
- "#{current.source || 'an unspecified source'} and #{dep.source}\n"
140
+ "#{current.source || "an unspecified source"} and #{dep.source}\n"
103
141
  end
104
142
  end
105
143
  end
@@ -107,13 +145,28 @@ module Bundler
107
145
  @dependencies << dep
108
146
  end
109
147
 
110
- def source(source, &blk)
148
+ def source(source, *args, &blk)
149
+ options = args.last.is_a?(Hash) ? args.pop.dup : {}
150
+ options = normalize_hash(options)
111
151
  source = normalize_source(source)
112
- if block_given?
152
+
153
+ if options.key?("type")
154
+ options["type"] = options["type"].to_s
155
+ unless Plugin.source?(options["type"])
156
+ raise InvalidOption, "No plugin sources available for #{options["type"]}"
157
+ end
158
+
159
+ unless block_given?
160
+ raise InvalidOption, "You need to pass a block to #source with :type option"
161
+ end
162
+
163
+ source_opts = options.merge("uri" => source)
164
+ with_source(@sources.add_plugin_source(options["type"], source_opts), &blk)
165
+ elsif block_given?
113
166
  with_source(@sources.add_rubygems_source("remotes" => source), &blk)
114
167
  else
115
168
  check_primary_source_safety(@sources)
116
- @sources.add_rubygems_remote(source)
169
+ @sources.global_rubygems_source = source
117
170
  end
118
171
  end
119
172
 
@@ -131,7 +184,26 @@ module Bundler
131
184
  end
132
185
 
133
186
  def path(path, options = {}, &blk)
134
- with_source(@sources.add_path_source(normalize_hash(options).merge("path" => Pathname.new(path))), &blk)
187
+ unless block_given?
188
+ msg = "You can no longer specify a path source by itself. Instead, \n" \
189
+ "either use the :path option on a gem, or specify the gems that \n" \
190
+ "bundler should find in the path source by passing a block to \n" \
191
+ "the path method, like: \n\n" \
192
+ " path 'dir/containing/rails' do\n" \
193
+ " gem 'rails'\n" \
194
+ " end\n\n"
195
+
196
+ raise DeprecatedError, msg if Bundler.feature_flag.disable_multisource?
197
+ SharedHelpers.major_deprecation(2, msg.strip)
198
+ end
199
+
200
+ source_options = normalize_hash(options).merge(
201
+ "path" => Pathname.new(path),
202
+ "root_path" => gemfile_root,
203
+ "gemspec" => gemspecs.find {|g| g.name == options["name"] }
204
+ )
205
+ source = @sources.add_path_source(source_options)
206
+ with_source(source, &blk)
135
207
  end
136
208
 
137
209
  def git(uri, options = {}, &blk)
@@ -150,7 +222,8 @@ module Bundler
150
222
  end
151
223
 
152
224
  def github(repo, options = {})
153
- raise ArgumentError, "Github sources require a block" unless block_given?
225
+ raise ArgumentError, "GitHub sources require a block" unless block_given?
226
+ raise DeprecatedError, "The #github method has been removed" if Bundler.feature_flag.skip_default_git_sources?
154
227
  github_uri = @git_sources["github"].call(repo)
155
228
  git_options = normalize_hash(options).merge("uri" => github_uri)
156
229
  git_source = @sources.add_git_source(git_options)
@@ -158,16 +231,32 @@ module Bundler
158
231
  end
159
232
 
160
233
  def to_definition(lockfile, unlock)
161
- Definition.new(lockfile, @dependencies, @sources, unlock, @ruby_version)
234
+ Definition.new(lockfile, @dependencies, @sources, unlock, @ruby_version, @optional_groups, @gemfiles)
162
235
  end
163
236
 
164
237
  def group(*args, &blk)
238
+ options = args.last.is_a?(Hash) ? args.pop.dup : {}
239
+ normalize_group_options(options, args)
240
+
165
241
  @groups.concat args
242
+
243
+ if options["optional"]
244
+ optional_groups = args - @optional_groups
245
+ @optional_groups.concat optional_groups
246
+ end
247
+
166
248
  yield
167
249
  ensure
168
250
  args.each { @groups.pop }
169
251
  end
170
252
 
253
+ def install_if(*args)
254
+ @install_conditionals.concat args
255
+ yield
256
+ ensure
257
+ args.each { @install_conditionals.pop }
258
+ end
259
+
171
260
  def platforms(*platforms)
172
261
  @platforms.concat platforms
173
262
  yield
@@ -177,43 +266,83 @@ module Bundler
177
266
  alias_method :platform, :platforms
178
267
 
179
268
  def env(name)
180
- @env, old = name, @env
269
+ old = @env
270
+ @env = name
181
271
  yield
182
272
  ensure
183
273
  @env = old
184
274
  end
185
275
 
276
+ def plugin(*args)
277
+ # Pass on
278
+ end
279
+
186
280
  def method_missing(name, *args)
187
- location = caller[0].split(':')[0..1].join(':')
188
- raise GemfileError, "Undefined local variable or method `#{name}' for Gemfile\n" \
189
- " from #{location}"
281
+ raise GemfileError, "Undefined local variable or method `#{name}' for Gemfile"
190
282
  end
191
283
 
192
284
  private
193
285
 
194
286
  def add_git_sources
287
+ return if Bundler.feature_flag.skip_default_git_sources?
288
+
195
289
  git_source(:github) do |repo_name|
290
+ warn_deprecated_git_source(:github, <<-'RUBY'.strip, 'Change any "reponame" :github sources to "username/reponame".')
291
+ "https://github.com/#{repo_name}.git"
292
+ RUBY
293
+ # It would be better to use https instead of the git protocol, but this
294
+ # can break deployment of existing locked bundles when switching between
295
+ # different versions of Bundler. The change will be made in 2.0, which
296
+ # does not guarantee compatibility with the 1.x series.
297
+ #
298
+ # See https://github.com/bundler/bundler/pull/2569 for discussion
299
+ #
300
+ # This can be overridden by adding this code to your Gemfiles:
301
+ #
302
+ # git_source(:github) do |repo_name|
303
+ # repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?("/")
304
+ # "https://github.com/#{repo_name}.git"
305
+ # end
196
306
  repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?("/")
197
- "git://github.com/#{repo_name}.git"
307
+ # TODO: 2.0 upgrade this setting to the default
308
+ if Bundler.feature_flag.github_https?
309
+ Bundler::SharedHelpers.major_deprecation 2, "The `github.https` setting will be removed"
310
+ "https://github.com/#{repo_name}.git"
311
+ else
312
+ "git://github.com/#{repo_name}.git"
313
+ end
198
314
  end
199
315
 
200
- git_source(:gist){ |repo_name| "https://gist.github.com/#{repo_name}.git" }
316
+ # TODO: 2.0 remove this deprecated git source
317
+ git_source(:gist) do |repo_name|
318
+ warn_deprecated_git_source(:gist, '"https://gist.github.com/#{repo_name}.git"')
319
+
320
+ "https://gist.github.com/#{repo_name}.git"
321
+ end
201
322
 
323
+ # TODO: 2.0 remove this deprecated git source
202
324
  git_source(:bitbucket) do |repo_name|
203
- user_name, repo_name = repo_name.split '/'
325
+ warn_deprecated_git_source(:bitbucket, <<-'RUBY'.strip)
326
+ user_name, repo_name = repo_name.split("/")
327
+ repo_name ||= user_name
328
+ "https://#{user_name}@bitbucket.org/#{user_name}/#{repo_name}.git"
329
+ RUBY
330
+
331
+ user_name, repo_name = repo_name.split("/")
204
332
  repo_name ||= user_name
205
333
  "https://#{user_name}@bitbucket.org/#{user_name}/#{repo_name}.git"
206
334
  end
207
335
  end
208
336
 
209
337
  def with_source(source)
338
+ old_source = @source
210
339
  if block_given?
211
340
  @source = source
212
341
  yield
213
342
  end
214
343
  source
215
344
  ensure
216
- @source = nil
345
+ @source = old_source
217
346
  end
218
347
 
219
348
  def normalize_hash(opts)
@@ -224,50 +353,47 @@ module Bundler
224
353
  end
225
354
 
226
355
  def valid_keys
227
- @valid_keys ||= %w(group groups git path name branch ref tag require submodules platform platforms type source)
356
+ @valid_keys ||= VALID_KEYS
228
357
  end
229
358
 
230
359
  def normalize_options(name, version, opts)
231
360
  if name.is_a?(Symbol)
232
- raise GemfileError, %{You need to specify gem names as Strings. Use 'gem "#{name}"' instead.}
361
+ raise GemfileError, %(You need to specify gem names as Strings. Use 'gem "#{name}"' instead)
233
362
  end
234
363
  if name =~ /\s/
235
- raise GemfileError, %{'#{name}' is not a valid gem name because it contains whitespace.}
364
+ raise GemfileError, %('#{name}' is not a valid gem name because it contains whitespace)
365
+ end
366
+ if name.empty?
367
+ raise GemfileError, %(an empty gem name is not valid)
236
368
  end
237
369
 
238
370
  normalize_hash(opts)
239
371
 
240
372
  git_names = @git_sources.keys.map(&:to_s)
241
-
242
- invalid_keys = opts.keys - (valid_keys + git_names)
243
- if invalid_keys.any?
244
- message = "You passed #{invalid_keys.map{|k| ':'+k }.join(", ")} "
245
- message << if invalid_keys.size > 1
246
- "as options for gem '#{name}', but they are invalid."
247
- else
248
- "as an option for gem '#{name}', but it is invalid."
249
- end
250
-
251
- message << " Valid options are: #{valid_keys.join(", ")}"
252
- raise InvalidOption, message
253
- end
373
+ validate_keys("gem '#{name}'", opts, valid_keys + git_names)
254
374
 
255
375
  groups = @groups.dup
256
376
  opts["group"] = opts.delete("groups") || opts["group"]
257
377
  groups.concat Array(opts.delete("group"))
258
378
  groups = [:default] if groups.empty?
259
379
 
380
+ install_if = @install_conditionals.dup
381
+ install_if.concat Array(opts.delete("install_if"))
382
+ install_if = install_if.reduce(true) do |memo, val|
383
+ memo && (val.respond_to?(:call) ? val.call : val)
384
+ end
385
+
260
386
  platforms = @platforms.dup
261
387
  opts["platforms"] = opts["platform"] || opts["platforms"]
262
388
  platforms.concat Array(opts.delete("platforms"))
263
- platforms.map! { |p| p.to_sym }
389
+ platforms.map!(&:to_sym)
264
390
  platforms.each do |p|
265
391
  next if VALID_PLATFORMS.include?(p)
266
392
  raise GemfileError, "`#{p}` is not a valid platform. The available options are: #{VALID_PLATFORMS.inspect}"
267
393
  end
268
394
 
269
395
  # Save sources passed in a key
270
- if opts.has_key?("source")
396
+ if opts.key?("source")
271
397
  source = normalize_source(opts["source"])
272
398
  opts["source"] = @sources.add_rubygems_source("remotes" => source)
273
399
  end
@@ -277,28 +403,60 @@ module Bundler
277
403
  opts["git"] = @git_sources[git_name].call(opts[git_name])
278
404
  end
279
405
 
280
- ["git", "path"].each do |type|
281
- if param = opts[type]
282
- if version.first && version.first =~ /^\s*=?\s*(\d[^\s]*)\s*$/
283
- options = opts.merge("name" => name, "version" => $1)
284
- else
285
- options = opts.dup
286
- end
287
- source = send(type, param, options) {}
288
- opts["source"] = source
406
+ %w[git path].each do |type|
407
+ next unless param = opts[type]
408
+ if version.first && version.first =~ /^\s*=?\s*(\d[^\s]*)\s*$/
409
+ options = opts.merge("name" => name, "version" => $1)
410
+ else
411
+ options = opts.dup
289
412
  end
413
+ source = send(type, param, options) {}
414
+ opts["source"] = source
415
+ end
416
+
417
+ opts["source"] ||= @source
418
+ opts["env"] ||= @env
419
+ opts["platforms"] = platforms.dup
420
+ opts["group"] = groups
421
+ opts["should_include"] = install_if
422
+ end
423
+
424
+ def normalize_group_options(opts, groups)
425
+ normalize_hash(opts)
426
+
427
+ groups = groups.map {|group| ":#{group}" }.join(", ")
428
+ validate_keys("group #{groups}", opts, %w[optional])
429
+
430
+ opts["optional"] ||= false
431
+ end
432
+
433
+ def validate_keys(command, opts, valid_keys)
434
+ invalid_keys = opts.keys - valid_keys
435
+
436
+ git_source = opts.keys & @git_sources.keys.map(&:to_s)
437
+ if opts["branch"] && !(opts["git"] || opts["github"] || git_source.any?)
438
+ raise GemfileError, %(The `branch` option for `#{command}` is not allowed. Only gems with a git source can specify a branch)
290
439
  end
291
440
 
292
- opts["source"] ||= @source
293
- opts["env"] ||= @env
294
- opts["platforms"] = platforms.dup
295
- opts["group"] = groups
441
+ return true unless invalid_keys.any?
442
+
443
+ message = String.new
444
+ message << "You passed #{invalid_keys.map {|k| ":" + k }.join(", ")} "
445
+ message << if invalid_keys.size > 1
446
+ "as options for #{command}, but they are invalid."
447
+ else
448
+ "as an option for #{command}, but it is invalid."
449
+ end
450
+
451
+ message << " Valid options are: #{valid_keys.join(", ")}."
452
+ message << " You may be able to resolve this by upgrading Bundler to the newest version."
453
+ raise InvalidOption, message
296
454
  end
297
455
 
298
456
  def normalize_source(source)
299
457
  case source
300
458
  when :gemcutter, :rubygems, :rubyforge
301
- Bundler.ui.warn "The source :#{source} is deprecated because HTTP " \
459
+ Bundler::SharedHelpers.major_deprecation 2, "The source :#{source} is deprecated because HTTP " \
302
460
  "requests are insecure.\nPlease change your source to 'https://" \
303
461
  "rubygems.org' if possible, or 'http://rubygems.org' if not."
304
462
  "http://rubygems.org"
@@ -309,16 +467,20 @@ module Bundler
309
467
  end
310
468
  end
311
469
 
312
- def check_primary_source_safety(source)
313
- return unless source.rubygems_primary_remotes.any?
470
+ def check_primary_source_safety(source_list)
471
+ return if source_list.rubygems_primary_remotes.empty? && source_list.global_rubygems_source.nil?
314
472
 
315
- if Bundler.settings[:disable_multisource]
316
- raise GemspecError, "Warning: this Gemfile contains multiple primary sources. " \
473
+ if Bundler.feature_flag.disable_multisource?
474
+ msg = "This Gemfile contains multiple primary sources. " \
317
475
  "Each source after the first must include a block to indicate which gems " \
318
- "should come from that source. To downgrade this error to a warning, run " \
319
- "`bundle config --delete disable_multisource`."
476
+ "should come from that source"
477
+ unless Bundler.feature_flag.bundler_2_mode?
478
+ msg += ". To downgrade this error to a warning, run " \
479
+ "`bundle config --delete disable_multisource`"
480
+ end
481
+ raise GemfileEvalError, msg
320
482
  else
321
- Bundler.ui.warn "Warning: this Gemfile contains multiple primary sources. " \
483
+ Bundler::SharedHelpers.major_deprecation 2, "Your Gemfile contains multiple primary sources. " \
322
484
  "Using `source` more than once without a block is a security risk, and " \
323
485
  "may result in installing unexpected gems. To resolve this warning, use " \
324
486
  "a block to indicate which gems should come from the secondary source. " \
@@ -327,5 +489,127 @@ module Bundler
327
489
  end
328
490
  end
329
491
 
492
+ def warn_deprecated_git_source(name, replacement, additional_message = nil)
493
+ # TODO: 2.0 remove deprecation
494
+ additional_message &&= " #{additional_message}"
495
+ replacement = if replacement.count("\n").zero?
496
+ "{|repo_name| #{replacement} }"
497
+ else
498
+ "do |repo_name|\n#{replacement.to_s.gsub(/^/, " ")}\n end"
499
+ end
500
+
501
+ Bundler::SharedHelpers.major_deprecation 2, <<-EOS
502
+ The :#{name} git source is deprecated, and will be removed in Bundler 2.0.#{additional_message} Add this code to the top of your Gemfile to ensure it continues to work:
503
+
504
+ git_source(:#{name}) #{replacement}
505
+
506
+ EOS
507
+ end
508
+
509
+ class DSLError < GemfileError
510
+ # @return [String] the description that should be presented to the user.
511
+ #
512
+ attr_reader :description
513
+
514
+ # @return [String] the path of the dsl file that raised the exception.
515
+ #
516
+ attr_reader :dsl_path
517
+
518
+ # @return [Exception] the backtrace of the exception raised by the
519
+ # evaluation of the dsl file.
520
+ #
521
+ attr_reader :backtrace
522
+
523
+ # @param [Exception] backtrace @see backtrace
524
+ # @param [String] dsl_path @see dsl_path
525
+ #
526
+ def initialize(description, dsl_path, backtrace, contents = nil)
527
+ @status_code = $!.respond_to?(:status_code) && $!.status_code
528
+
529
+ @description = description
530
+ @dsl_path = dsl_path
531
+ @backtrace = backtrace
532
+ @contents = contents
533
+ end
534
+
535
+ def status_code
536
+ @status_code || super
537
+ end
538
+
539
+ # @return [String] the contents of the DSL that cause the exception to
540
+ # be raised.
541
+ #
542
+ def contents
543
+ @contents ||= begin
544
+ dsl_path && File.exist?(dsl_path) && File.read(dsl_path)
545
+ end
546
+ end
547
+
548
+ # The message of the exception reports the content of podspec for the
549
+ # line that generated the original exception.
550
+ #
551
+ # @example Output
552
+ #
553
+ # Invalid podspec at `RestKit.podspec` - undefined method
554
+ # `exclude_header_search_paths=' for #<Pod::Specification for
555
+ # `RestKit/Network (0.9.3)`>
556
+ #
557
+ # from spec-repos/master/RestKit/0.9.3/RestKit.podspec:36
558
+ # -------------------------------------------
559
+ # # because it would break: #import <CoreData/CoreData.h>
560
+ # > ns.exclude_header_search_paths = 'Code/RestKit.h'
561
+ # end
562
+ # -------------------------------------------
563
+ #
564
+ # @return [String] the message of the exception.
565
+ #
566
+ def to_s
567
+ @to_s ||= begin
568
+ trace_line, description = parse_line_number_from_description
569
+
570
+ m = String.new("\n[!] ")
571
+ m << description
572
+ m << ". Bundler cannot continue.\n"
573
+
574
+ return m unless backtrace && dsl_path && contents
575
+
576
+ trace_line = backtrace.find {|l| l.include?(dsl_path.to_s) } || trace_line
577
+ return m unless trace_line
578
+ line_numer = trace_line.split(":")[1].to_i - 1
579
+ return m unless line_numer
580
+
581
+ lines = contents.lines.to_a
582
+ indent = " # "
583
+ indicator = indent.tr("#", ">")
584
+ first_line = line_numer.zero?
585
+ last_line = (line_numer == (lines.count - 1))
586
+
587
+ m << "\n"
588
+ m << "#{indent}from #{trace_line.gsub(/:in.*$/, "")}\n"
589
+ m << "#{indent}-------------------------------------------\n"
590
+ m << "#{indent}#{lines[line_numer - 1]}" unless first_line
591
+ m << "#{indicator}#{lines[line_numer]}"
592
+ m << "#{indent}#{lines[line_numer + 1]}" unless last_line
593
+ m << "\n" unless m.end_with?("\n")
594
+ m << "#{indent}-------------------------------------------\n"
595
+ end
596
+ end
597
+
598
+ private
599
+
600
+ def parse_line_number_from_description
601
+ description = self.description
602
+ if dsl_path && description =~ /((#{Regexp.quote File.expand_path(dsl_path)}|#{Regexp.quote dsl_path.to_s}):\d+)/
603
+ trace_line = Regexp.last_match[1]
604
+ description = description.sub(/#{Regexp.quote trace_line}:\s*/, "").sub("\n", " - ")
605
+ end
606
+ [trace_line, description]
607
+ end
608
+ end
609
+
610
+ def gemfile_root
611
+ @gemfile ||= Bundler.default_gemfile
612
+ @gemfile.dirname
613
+ end
330
614
  end
331
615
  end