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
@@ -0,0 +1,74 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/compatibility_guard"
4
+
5
+ # Allows for declaring a Gemfile inline in a ruby script, optionally installing
6
+ # any gems that aren't already installed on the user's system.
7
+ #
8
+ # @note Every gem that is specified in this 'Gemfile' will be `require`d, as if
9
+ # the user had manually called `Bundler.require`. To avoid a requested gem
10
+ # being automatically required, add the `:require => false` option to the
11
+ # `gem` dependency declaration.
12
+ #
13
+ # @param install [Boolean] whether gems that aren't already installed on the
14
+ # user's system should be installed.
15
+ # Defaults to `false`.
16
+ #
17
+ # @param gemfile [Proc] a block that is evaluated as a `Gemfile`.
18
+ #
19
+ # @example Using an inline Gemfile
20
+ #
21
+ # #!/usr/bin/env ruby
22
+ #
23
+ # require 'bundler/inline'
24
+ #
25
+ # gemfile do
26
+ # source 'https://rubygems.org'
27
+ # gem 'json', require: false
28
+ # gem 'nap', require: 'rest'
29
+ # gem 'cocoapods', '~> 0.34.1'
30
+ # end
31
+ #
32
+ # puts Pod::VERSION # => "0.34.4"
33
+ #
34
+ def gemfile(install = false, options = {}, &gemfile)
35
+ require "bundler"
36
+
37
+ opts = options.dup
38
+ ui = opts.delete(:ui) { Bundler::UI::Shell.new }
39
+ raise ArgumentError, "Unknown options: #{opts.keys.join(", ")}" unless opts.empty?
40
+
41
+ old_root = Bundler.method(:root)
42
+ def Bundler.root
43
+ Bundler::SharedHelpers.pwd.expand_path
44
+ end
45
+ Bundler::SharedHelpers.set_env "BUNDLE_GEMFILE", "Gemfile"
46
+
47
+ Bundler::Plugin.gemfile_install(&gemfile) if Bundler.feature_flag.plugins?
48
+ builder = Bundler::Dsl.new
49
+ builder.instance_eval(&gemfile)
50
+
51
+ definition = builder.to_definition(nil, true)
52
+ def definition.lock(*); end
53
+ definition.validate_runtime!
54
+
55
+ missing_specs = proc do
56
+ definition.missing_specs?
57
+ end
58
+
59
+ Bundler.ui = ui if install
60
+ if install || missing_specs.call
61
+ Bundler.settings.temporary(:inline => true) do
62
+ installer = Bundler::Installer.install(Bundler.root, definition, :system => true)
63
+ installer.post_install_messages.each do |name, message|
64
+ Bundler.ui.info "Post-install message from #{name}:\n#{message}"
65
+ end
66
+ end
67
+ end
68
+
69
+ runtime = Bundler::Runtime.new(nil, definition)
70
+ runtime.setup.require
71
+ ensure
72
+ bundler_module = class << Bundler; self; end
73
+ bundler_module.send(:define_method, :root, old_root) if old_root
74
+ end
@@ -1,45 +1,60 @@
1
- require 'erb'
2
- require 'rubygems/dependency_installer'
3
- require 'bundler/worker'
1
+ # frozen_string_literal: true
2
+
3
+ require "erb"
4
+ require "rubygems/dependency_installer"
5
+ require "bundler/worker"
6
+ require "bundler/installer/parallel_installer"
7
+ require "bundler/installer/standalone"
8
+ require "bundler/installer/gem_installer"
4
9
 
5
10
  module Bundler
6
- class Installer < Environment
11
+ class Installer
7
12
  class << self
8
- attr_accessor :post_install_messages, :ambiguous_gems
13
+ attr_accessor :ambiguous_gems
9
14
 
10
- Installer.post_install_messages = {}
11
15
  Installer.ambiguous_gems = []
12
16
  end
13
17
 
18
+ attr_reader :post_install_messages
19
+
14
20
  # Begins the installation process for Bundler.
15
21
  # For more information see the #run method on this class.
16
22
  def self.install(root, definition, options = {})
17
23
  installer = new(root, definition)
24
+ Plugin.hook(Plugin::Events::GEM_BEFORE_INSTALL_ALL, definition.dependencies)
18
25
  installer.run(options)
26
+ Plugin.hook(Plugin::Events::GEM_AFTER_INSTALL_ALL, definition.dependencies)
19
27
  installer
20
28
  end
21
29
 
30
+ def initialize(root, definition)
31
+ @root = root
32
+ @definition = definition
33
+ @post_install_messages = {}
34
+ end
35
+
22
36
  # Runs the install procedures for a specific Gemfile.
23
37
  #
24
- # Firstly, this method will check to see if Bundler.bundle_path exists
25
- # and if not then will create it. This is usually the location of gems
26
- # on the system, be it RVM or at a system path.
38
+ # Firstly, this method will check to see if `Bundler.bundle_path` exists
39
+ # and if not then Bundler will create the directory. This is usually the same
40
+ # location as RubyGems which typically is the `~/.gem` directory
41
+ # unless other specified.
27
42
  #
28
- # Secondly, it checks if Bundler has been configured to be "frozen"
43
+ # Secondly, it checks if Bundler has been configured to be "frozen".
29
44
  # Frozen ensures that the Gemfile and the Gemfile.lock file are matching.
30
45
  # This stops a situation where a developer may update the Gemfile but may not run
31
46
  # `bundle install`, which leads to the Gemfile.lock file not being correctly updated.
32
47
  # If this file is not correctly updated then any other developer running
33
48
  # `bundle install` will potentially not install the correct gems.
34
49
  #
35
- # Thirdly, Bundler checks if there are any dependencies specified in the Gemfile using
36
- # Bundler::Environment#dependencies. If there are no dependencies specified then
37
- # Bundler returns a warning message stating so and this method returns.
50
+ # Thirdly, Bundler checks if there are any dependencies specified in the Gemfile.
51
+ # If there are no dependencies specified then Bundler returns a warning message stating
52
+ # so and this method returns.
38
53
  #
39
- # Fourthly, Bundler checks if the default lockfile (Gemfile.lock) exists, and if so
40
- # then proceeds to set up a defintion based on the default gemfile (Gemfile) and the
41
- # default lock file (Gemfile.lock). However, this is not the case if the platform is different
42
- # to that which is specified in Gemfile.lock, or if there are any missing specs for the gems.
54
+ # Fourthly, Bundler checks if the Gemfile.lock exists, and if so
55
+ # then proceeds to set up a definition based on the Gemfile and the Gemfile.lock.
56
+ # During this step Bundler will also download information about any new gems
57
+ # that are not in the Gemfile.lock and resolve any dependencies if needed.
43
58
  #
44
59
  # Fifthly, Bundler resolves the dependencies either through a cache of gems or by remote.
45
60
  # This then leads into the gems being installed, along with stubs for their executables,
@@ -49,94 +64,36 @@ module Bundler
49
64
  # Sixthly, a new Gemfile.lock is created from the installed gems to ensure that the next time
50
65
  # that a user runs `bundle install` they will receive any updates from this process.
51
66
  #
52
- # Finally: TODO add documentation for how the standalone process works.
67
+ # Finally, if the user has specified the standalone flag, Bundler will generate the needed
68
+ # require paths and save them in a `setup.rb` file. See `bundle standalone --help` for more
69
+ # information.
53
70
  def run(options)
54
71
  create_bundle_path
55
72
 
56
- if Bundler.settings[:frozen]
57
- @definition.ensure_equivalent_gemfile_and_lockfile(options[:deployment])
58
- end
59
-
60
- if dependencies.empty?
61
- Bundler.ui.warn "The Gemfile specifies no dependencies"
62
- lock
63
- return
64
- end
65
-
66
- if Bundler.default_lockfile.exist? && !options["update"]
67
- local = Bundler.ui.silence do
68
- begin
69
- tmpdef = Definition.build(Bundler.default_gemfile, Bundler.default_lockfile, nil)
70
- true unless tmpdef.new_platform? || tmpdef.missing_specs.any?
71
- rescue BundlerError
72
- end
73
+ ProcessLock.lock do
74
+ if Bundler.frozen_bundle?
75
+ @definition.ensure_equivalent_gemfile_and_lockfile(options[:deployment])
73
76
  end
74
- end
75
-
76
- # Since we are installing, we can resolve the definition
77
- # using remote specs
78
- unless local
79
- options["local"] ? @definition.resolve_with_cache! : @definition.resolve_remotely!
80
- end
81
77
 
82
- # the order that the resolver provides is significant, since
83
- # dependencies might actually affect the installation of a gem.
84
- # that said, it's a rare situation (other than rake), and parallel
85
- # installation is just SO MUCH FASTER. so we let people opt in.
86
- jobs = [Bundler.settings[:jobs].to_i-1, 1].max
87
- if jobs > 1 && can_install_in_parallel?
88
- install_in_parallel jobs, options[:standalone]
89
- else
90
- install_sequentially options[:standalone]
91
- end
92
-
93
- lock unless Bundler.settings[:frozen]
94
- generate_standalone(options[:standalone]) if options[:standalone]
95
- end
78
+ if @definition.dependencies.empty?
79
+ Bundler.ui.warn "The Gemfile specifies no dependencies"
80
+ lock
81
+ return
82
+ end
96
83
 
97
- def install_gem_from_spec(spec, standalone = false, worker = 0)
98
- # Fetch the build settings, if there are any
99
- settings = Bundler.settings["build.#{spec.name}"]
100
- install_message = nil
101
- post_install_message = nil
102
- debug_message = nil
103
- Bundler.rubygems.with_build_args [settings] do
104
- install_message, post_install_message, debug_message = spec.source.install(spec)
105
- if install_message.include? 'Installing'
106
- Bundler.ui.confirm install_message
84
+ if resolve_if_needed(options)
85
+ ensure_specs_are_compatible!
86
+ warn_on_incompatible_bundler_deps
87
+ load_plugins
88
+ options.delete(:jobs)
107
89
  else
108
- Bundler.ui.info install_message
90
+ options[:jobs] = 1 # to avoid the overhead of Bundler::Worker
109
91
  end
110
- Bundler.ui.debug debug_message if debug_message
111
- Bundler.ui.debug "#{worker}: #{spec.name} (#{spec.version}) from #{spec.loaded_from}"
112
- end
113
-
114
- if Bundler.settings[:bin] && standalone
115
- generate_standalone_bundler_executable_stubs(spec)
116
- elsif Bundler.settings[:bin]
117
- generate_bundler_executable_stubs(spec, :force => true)
118
- end
92
+ install(options)
119
93
 
120
- post_install_message
121
- rescue Errno::ENOSPC
122
- raise Bundler::InstallError, "Your disk is out of space. Free some " \
123
- "space to be able to install your bundle."
124
- rescue Exception => e
125
- # if install hook failed or gem signature is bad, just die
126
- raise e if e.is_a?(Bundler::InstallHookError) || e.is_a?(Bundler::SecurityError)
127
-
128
- # other failure, likely a native extension build failure
129
- Bundler.ui.info ""
130
- Bundler.ui.warn "#{e.class}: #{e.message}"
131
- msg = "An error occurred while installing #{spec.name} (#{spec.version}),"
132
- msg << " and Bundler cannot continue."
133
-
134
- unless spec.source.options["git"]
135
- msg << "\nMake sure that `gem install"
136
- msg << " #{spec.name} -v '#{spec.version}'` succeeds before bundling."
94
+ lock unless Bundler.frozen_bundle?
95
+ Standalone.new(options[:standalone], @definition).generate if options[:standalone]
137
96
  end
138
- Bundler.ui.debug e.backtrace.join("\n")
139
- raise Bundler::InstallError, msg
140
97
  end
141
98
 
142
99
  def generate_bundler_executable_stubs(spec, options = {})
@@ -147,9 +104,9 @@ module Bundler
147
104
  options[dep.name] = bins unless bins.empty?
148
105
  end
149
106
  if options.any?
150
- Bundler.ui.warn "#{spec.name} has no executables, but you may want " +
107
+ Bundler.ui.warn "#{spec.name} has no executables, but you may want " \
151
108
  "one from a gem it depends on."
152
- options.each{|name,bins| Bundler.ui.warn " #{name} has: #{bins.join(', ')}" }
109
+ options.each {|name, bins| Bundler.ui.warn " #{name} has: #{bins.join(", ")}" }
153
110
  else
154
111
  Bundler.ui.warn "There are no executables for the gem #{spec.name}."
155
112
  end
@@ -157,23 +114,33 @@ module Bundler
157
114
  end
158
115
 
159
116
  # double-assignment to avoid warnings about variables that will be used by ERB
160
- bin_path = bin_path = Bundler.bin_path
161
- template = template = File.read(File.expand_path('../templates/Executable', __FILE__))
162
- relative_gemfile_path = relative_gemfile_path = Bundler.default_gemfile.relative_path_from(bin_path)
163
- ruby_command = ruby_command = Thor::Util.ruby_command
117
+ bin_path = Bundler.bin_path
118
+ bin_path = bin_path
119
+ relative_gemfile_path = Bundler.default_gemfile.relative_path_from(bin_path)
120
+ relative_gemfile_path = relative_gemfile_path
121
+ ruby_command = Thor::Util.ruby_command
122
+ ruby_command = ruby_command
123
+ template_path = File.expand_path("../templates/Executable", __FILE__)
124
+ if spec.name == "bundler"
125
+ template_path += ".bundler"
126
+ spec.executables = %(bundle)
127
+ end
128
+ template = File.read(template_path)
164
129
 
165
130
  exists = []
166
131
  spec.executables.each do |executable|
167
- next if executable == "bundle"
168
-
169
132
  binstub_path = "#{bin_path}/#{executable}"
170
133
  if File.exist?(binstub_path) && !options[:force]
171
134
  exists << executable
172
135
  next
173
136
  end
174
137
 
175
- File.open(binstub_path, 'w', 0777 & ~File.umask) do |f|
176
- f.puts ERB.new(template, nil, '-').result(binding)
138
+ File.open(binstub_path, "w", 0o777 & ~File.umask) do |f|
139
+ if RUBY_VERSION >= "2.6"
140
+ f.puts ERB.new(template, :trim_mode => "-").result(binding)
141
+ else
142
+ f.puts ERB.new(template, nil, "-").result(binding)
143
+ end
177
144
  end
178
145
  end
179
146
 
@@ -182,152 +149,170 @@ module Bundler
182
149
  when 1
183
150
  Bundler.ui.warn "Skipped #{exists[0]} since it already exists."
184
151
  when 2
185
- Bundler.ui.warn "Skipped #{exists.join(' and ')} since they already exist."
152
+ Bundler.ui.warn "Skipped #{exists.join(" and ")} since they already exist."
186
153
  else
187
- items = exists[0...-1].empty? ? nil : exists[0...-1].join(', ')
188
- skipped = [items, exists[-1]].compact.join(' and ')
154
+ items = exists[0...-1].empty? ? nil : exists[0...-1].join(", ")
155
+ skipped = [items, exists[-1]].compact.join(" and ")
189
156
  Bundler.ui.warn "Skipped #{skipped} since they already exist."
190
157
  end
191
158
  Bundler.ui.warn "If you want to overwrite skipped stubs, use --force."
192
159
  end
193
160
  end
194
161
 
195
- private
196
-
197
- def can_install_in_parallel?
198
- if Bundler.rubygems.provides?(">= 2.1.0")
199
- true
200
- else
201
- Bundler.ui.warn "Rubygems #{Gem::VERSION} is not threadsafe, so your "\
202
- "gems must be installed one at a time. Upgrade to Rubygems 2.1.0 " \
203
- "or higher to enable parallel gem installation."
204
- false
205
- end
206
- end
207
-
208
162
  def generate_standalone_bundler_executable_stubs(spec)
209
163
  # double-assignment to avoid warnings about variables that will be used by ERB
210
164
  bin_path = Bundler.bin_path
211
- template = File.read(File.expand_path('../templates/Executable.standalone', __FILE__))
212
- ruby_command = ruby_command = Thor::Util.ruby_command
165
+ unless path = Bundler.settings[:path]
166
+ raise "Can't standalone without an explicit path set"
167
+ end
168
+ standalone_path = Bundler.root.join(path).relative_path_from(bin_path)
169
+ standalone_path = standalone_path
170
+ template = File.read(File.expand_path("../templates/Executable.standalone", __FILE__))
171
+ ruby_command = Thor::Util.ruby_command
172
+ ruby_command = ruby_command
213
173
 
214
174
  spec.executables.each do |executable|
215
175
  next if executable == "bundle"
216
- standalone_path = standalone_path = Pathname(Bundler.settings[:path]).expand_path.relative_path_from(bin_path)
217
- executable_path = executable_path = Pathname(spec.full_gem_path).join(spec.bindir, executable).relative_path_from(bin_path)
218
- File.open "#{bin_path}/#{executable}", 'w', 0755 do |f|
219
- f.puts ERB.new(template, nil, '-').result(binding)
176
+ executable_path = Pathname(spec.full_gem_path).join(spec.bindir, executable).relative_path_from(bin_path)
177
+ executable_path = executable_path
178
+ File.open "#{bin_path}/#{executable}", "w", 0o755 do |f|
179
+ if RUBY_VERSION >= "2.6"
180
+ f.puts ERB.new(template, :trim_mode => "-").result(binding)
181
+ else
182
+ f.puts ERB.new(template, nil, "-").result(binding)
183
+ end
220
184
  end
221
185
  end
222
186
  end
223
187
 
224
- def generate_standalone(groups)
225
- standalone_path = Bundler.settings[:path]
226
- bundler_path = File.join(standalone_path, "bundler")
227
- FileUtils.mkdir_p(bundler_path)
188
+ private
228
189
 
229
- paths = []
190
+ # the order that the resolver provides is significant, since
191
+ # dependencies might affect the installation of a gem.
192
+ # that said, it's a rare situation (other than rake), and parallel
193
+ # installation is SO MUCH FASTER. so we let people opt in.
194
+ def install(options)
195
+ force = options["force"]
196
+ jobs = installation_parallelization(options)
197
+ install_in_parallel jobs, options[:standalone], force
198
+ end
230
199
 
231
- if groups.empty?
232
- specs = @definition.requested_specs
233
- else
234
- specs = @definition.specs_for groups.map { |g| g.to_sym }
200
+ def installation_parallelization(options)
201
+ if jobs = options.delete(:jobs)
202
+ return jobs
235
203
  end
236
204
 
237
- specs.each do |spec|
238
- next if spec.name == "bundler"
239
- next if spec.require_paths.nil? # builtin gems
205
+ return 1 unless can_install_in_parallel?
240
206
 
241
- spec.require_paths.each do |path|
242
- full_path = File.join(spec.full_gem_path, path)
243
- gem_path = Pathname.new(full_path).relative_path_from(Bundler.root.join(bundler_path))
244
- paths << gem_path.to_s.sub("#{Bundler.ruby_version.engine}/#{RbConfig::CONFIG['ruby_version']}", '#{ruby_engine}/#{ruby_version}')
207
+ auto_config_jobs = Bundler.feature_flag.auto_config_jobs?
208
+ if jobs = Bundler.settings[:jobs]
209
+ if auto_config_jobs
210
+ jobs
211
+ else
212
+ [jobs.pred, 1].max
245
213
  end
214
+ elsif auto_config_jobs
215
+ processor_count
216
+ else
217
+ 1
246
218
  end
219
+ end
220
+
221
+ def processor_count
222
+ require "etc"
223
+ Etc.nprocessors
224
+ rescue
225
+ 1
226
+ end
247
227
 
228
+ def load_plugins
229
+ Bundler.rubygems.load_plugins
248
230
 
249
- File.open File.join(bundler_path, "setup.rb"), "w" do |file|
250
- file.puts "require 'rbconfig'"
251
- file.puts "# ruby 1.8.7 doesn't define RUBY_ENGINE"
252
- file.puts "ruby_engine = defined?(RUBY_ENGINE) ? RUBY_ENGINE : 'ruby'"
253
- file.puts "ruby_version = RbConfig::CONFIG[\"ruby_version\"]"
254
- file.puts "path = File.expand_path('..', __FILE__)"
255
- paths.each do |path|
256
- file.puts %{$:.unshift "\#{path}/#{path}"}
231
+ requested_path_gems = @definition.requested_specs.select {|s| s.source.is_a?(Source::Path) }
232
+ path_plugin_files = requested_path_gems.map do |spec|
233
+ begin
234
+ Bundler.rubygems.spec_matches_for_glob(spec, "rubygems_plugin#{Bundler.rubygems.suffix_pattern}")
235
+ rescue TypeError
236
+ error_message = "#{spec.name} #{spec.version} has an invalid gemspec"
237
+ raise Gem::InvalidSpecificationException, error_message
257
238
  end
258
- end
239
+ end.flatten
240
+ Bundler.rubygems.load_plugin_files(path_plugin_files)
259
241
  end
260
242
 
261
- def install_sequentially(standalone)
262
- specs.each do |spec|
263
- message = install_gem_from_spec spec, standalone, 0
264
- if message
265
- Installer.post_install_messages[spec.name] = message
243
+ def ensure_specs_are_compatible!
244
+ system_ruby = Bundler::RubyVersion.system
245
+ rubygems_version = Gem::Version.create(Gem::VERSION)
246
+ @definition.specs.each do |spec|
247
+ if required_ruby_version = spec.required_ruby_version
248
+ unless required_ruby_version.satisfied_by?(system_ruby.gem_version)
249
+ raise InstallError, "#{spec.full_name} requires ruby version #{required_ruby_version}, " \
250
+ "which is incompatible with the current version, #{system_ruby}"
251
+ end
252
+ end
253
+ next unless required_rubygems_version = spec.required_rubygems_version
254
+ unless required_rubygems_version.satisfied_by?(rubygems_version)
255
+ raise InstallError, "#{spec.full_name} requires rubygems version #{required_rubygems_version}, " \
256
+ "which is incompatible with the current version, #{rubygems_version}"
266
257
  end
267
258
  end
268
259
  end
269
260
 
270
- def install_in_parallel(size, standalone)
271
- name2spec = {}
272
- remains = {}
273
- enqueued = {}
274
- specs.each do |spec|
275
- name2spec[spec.name] = spec
276
- remains[spec.name] = true
277
- end
278
-
279
- worker_pool = Worker.new size, lambda { |name, worker_num|
280
- spec = name2spec[name]
281
- message = install_gem_from_spec spec, standalone, worker_num
282
- { :name => spec.name, :post_install => message }
283
- }
284
-
285
- # Keys in the remains hash represent uninstalled gems specs.
286
- # We enqueue all gem specs that do not have any dependencies.
287
- # Later we call this lambda again to install specs that depended on
288
- # previously installed specifications. We continue until all specs
289
- # are installed.
290
- enqueue_remaining_specs = lambda do
291
- remains.keys.each do |name|
292
- next if enqueued[name]
293
- spec = name2spec[name]
294
- if ready_to_install?(spec, remains)
295
- worker_pool.enq name
296
- enqueued[name] = true
297
- end
261
+ def warn_on_incompatible_bundler_deps
262
+ bundler_version = Gem::Version.create(Bundler::VERSION)
263
+ @definition.specs.each do |spec|
264
+ spec.dependencies.each do |dep|
265
+ next if dep.type == :development
266
+ next unless dep.name == "bundler".freeze
267
+ next if dep.requirement.satisfied_by?(bundler_version)
268
+
269
+ Bundler.ui.warn "#{spec.name} (#{spec.version}) has dependency" \
270
+ " #{SharedHelpers.pretty_dependency(dep)}" \
271
+ ", which is unsatisfied by the current bundler version #{VERSION}" \
272
+ ", so the dependency is being ignored"
298
273
  end
299
274
  end
300
- enqueue_remaining_specs.call
275
+ end
301
276
 
302
- until remains.empty?
303
- message = worker_pool.deq
304
- remains.delete message[:name]
305
- if message[:post_install]
306
- Installer.post_install_messages[message[:name]] = message[:post_install]
307
- end
308
- enqueue_remaining_specs.call
277
+ def can_install_in_parallel?
278
+ if Bundler.rubygems.provides?(">= 2.1.0")
279
+ true
280
+ else
281
+ Bundler.ui.warn "RubyGems #{Gem::VERSION} is not threadsafe, so your "\
282
+ "gems will be installed one at a time. Upgrade to RubyGems 2.1.0 " \
283
+ "or higher to enable parallel gem installation."
284
+ false
309
285
  end
310
- message
311
- ensure
312
- worker_pool && worker_pool.stop
313
286
  end
314
287
 
315
- # We only want to install a gem spec if all its dependencies are met.
316
- # If the dependency is no longer in the `remains` hash then it has been met.
317
- # If a dependency is only development or is self referential it can be ignored.
318
- def ready_to_install?(spec, remains)
319
- spec.dependencies.none? do |dep|
320
- next if dep.type == :development || dep.name == spec.name
321
- remains[dep.name]
288
+ def install_in_parallel(size, standalone, force = false)
289
+ spec_installations = ParallelInstaller.call(self, @definition.specs, size, standalone, force)
290
+ spec_installations.each do |installation|
291
+ post_install_messages[installation.name] = installation.post_install_message if installation.has_post_install_message?
322
292
  end
323
293
  end
324
294
 
325
295
  def create_bundle_path
326
- Bundler.mkdir_p(Bundler.bundle_path.to_s) unless Bundler.bundle_path.exist?
296
+ SharedHelpers.filesystem_access(Bundler.bundle_path.to_s) do |p|
297
+ Bundler.mkdir_p(p)
298
+ end unless Bundler.bundle_path.exist?
327
299
  rescue Errno::EEXIST
328
- raise PathError, "Could not install to path `#{Bundler.settings[:path]}` " +
329
- "because of an invalid symlink. Remove the symlink so the directory can be created."
300
+ raise PathError, "Could not install to path `#{Bundler.bundle_path}` " \
301
+ "because a file already exists at that path. Either remove or rename the file so the directory can be created."
302
+ end
303
+
304
+ # returns whether or not a re-resolve was needed
305
+ def resolve_if_needed(options)
306
+ if !@definition.unlocking? && !options["force"] && !Bundler.settings[:inline] && Bundler.default_lockfile.file?
307
+ return false if @definition.nothing_changed? && !@definition.missing_specs?
308
+ end
309
+
310
+ options["local"] ? @definition.resolve_with_cache! : @definition.resolve_remotely!
311
+ true
330
312
  end
331
313
 
314
+ def lock(opts = {})
315
+ @definition.lock(Bundler.default_lockfile, opts[:preserve_unknown_sections])
316
+ end
332
317
  end
333
318
  end