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,47 +1,51 @@
1
- require "digest/sha1"
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Bundler
4
- class Runtime < Environment
4
+ class Runtime
5
5
  include SharedHelpers
6
6
 
7
+ def initialize(root, definition)
8
+ @root = root
9
+ @definition = definition
10
+ end
11
+
7
12
  def setup(*groups)
8
- groups.map! { |g| g.to_sym }
13
+ @definition.ensure_equivalent_gemfile_and_lockfile if Bundler.frozen_bundle?
14
+
15
+ groups.map!(&:to_sym)
9
16
 
10
17
  # Has to happen first
11
18
  clean_load_path
12
19
 
13
20
  specs = groups.any? ? @definition.specs_for(groups) : requested_specs
14
21
 
15
- setup_environment
22
+ SharedHelpers.set_bundle_environment
16
23
  Bundler.rubygems.replace_entrypoints(specs)
17
24
 
18
25
  # Activate the specs
19
- specs.each do |spec|
26
+ load_paths = specs.map do |spec|
20
27
  unless spec.loaded_from
21
- raise GemNotFound, "#{spec.full_name} is missing. Run `bundle` to get it."
28
+ raise GemNotFound, "#{spec.full_name} is missing. Run `bundle install` to get it."
22
29
  end
23
30
 
24
- if activated_spec = Bundler.rubygems.loaded_specs(spec.name) and activated_spec.version != spec.version
25
- e = Gem::LoadError.new "You have already activated #{activated_spec.name} #{activated_spec.version}, " \
26
- "but your Gemfile requires #{spec.name} #{spec.version}. Prepending " \
27
- "`bundle exec` to your command may solve this."
28
- e.name = spec.name
29
- if e.respond_to?(:requirement=)
30
- e.requirement = Gem::Requirement.new(spec.version.to_s)
31
- else
32
- e.version_requirement = Gem::Requirement.new(spec.version.to_s)
33
- end
34
- raise e
35
- end
31
+ check_for_activated_spec!(spec)
36
32
 
37
33
  Bundler.rubygems.mark_loaded(spec)
38
- load_paths = spec.load_paths.reject {|path| $LOAD_PATH.include?(path)}
34
+ spec.load_paths.reject {|path| $LOAD_PATH.include?(path) }
35
+ end.reverse.flatten
36
+
37
+ # See Gem::Specification#add_self_to_load_path (since RubyGems 1.8)
38
+ if insert_index = Bundler.rubygems.load_path_insert_index
39
+ # Gem directories must come after -I and ENV['RUBYLIB']
40
+ $LOAD_PATH.insert(insert_index, *load_paths)
41
+ else
42
+ # We are probably testing in core, -I and RUBYLIB don't apply
39
43
  $LOAD_PATH.unshift(*load_paths)
40
44
  end
41
45
 
42
46
  setup_manpath
43
47
 
44
- lock
48
+ lock(:preserve_unknown_sections => true)
45
49
 
46
50
  self
47
51
  end
@@ -52,16 +56,16 @@ module Bundler
52
56
  /^Missing API definition file in (.+)$/i,
53
57
  /^cannot load such file -- (.+)$/i,
54
58
  /^dlopen\([^)]*\): Library not loaded: (.+)$/i,
55
- ]
59
+ ].freeze
56
60
 
57
61
  def require(*groups)
58
- groups.map! { |g| g.to_sym }
62
+ groups.map!(&:to_sym)
59
63
  groups = [:default] if groups.empty?
60
64
 
61
65
  @definition.dependencies.each do |dep|
62
- # Skip the dependency if it is not in any of the requested
63
- # groups
64
- next unless ((dep.groups & groups).any? && dep.current_platform?)
66
+ # Skip the dependency if it is not in any of the requested groups, or
67
+ # not for the current platform, or doesn't match the gem constraints.
68
+ next unless (dep.groups & groups).any? && dep.should_include?
65
69
 
66
70
  required_file = nil
67
71
 
@@ -73,45 +77,64 @@ module Bundler
73
77
  # Allow `require: true` as an alias for `require: <name>`
74
78
  file = dep.name if file == true
75
79
  required_file = file
76
- Kernel.require file
80
+ begin
81
+ Kernel.require file
82
+ rescue RuntimeError => e
83
+ raise e if e.is_a?(LoadError) # we handle this a little later
84
+ raise Bundler::GemRequireError.new e,
85
+ "There was an error while trying to load the gem '#{file}'."
86
+ end
77
87
  end
78
88
  rescue LoadError => e
79
- REQUIRE_ERRORS.find { |r| r =~ e.message }
89
+ REQUIRE_ERRORS.find {|r| r =~ e.message }
80
90
  raise if dep.autorequire || $1 != required_file
81
91
 
82
- if dep.autorequire.nil? && dep.name.include?('-')
92
+ if dep.autorequire.nil? && dep.name.include?("-")
83
93
  begin
84
- namespaced_file = dep.name.gsub('-', '/')
94
+ namespaced_file = dep.name.tr("-", "/")
85
95
  Kernel.require namespaced_file
86
96
  rescue LoadError => e
87
- REQUIRE_ERRORS.find { |r| r =~ e.message }
97
+ REQUIRE_ERRORS.find {|r| r =~ e.message }
88
98
  raise if $1 != namespaced_file
89
99
  end
90
100
  end
91
- rescue => e
92
- Bundler.ui.debug e
93
- Bundler.ui.warn "Unable to require #{required_file}. #{e.class}: #{e.message}."
94
101
  end
95
102
  end
96
103
  end
97
104
 
98
- def dependencies_for(*groups)
99
- if groups.empty?
100
- dependencies
101
- else
102
- dependencies.select { |d| (groups & d.groups).any? }
105
+ def self.definition_method(meth)
106
+ define_method(meth) do
107
+ raise ArgumentError, "no definition when calling Runtime##{meth}" unless @definition
108
+ @definition.send(meth)
103
109
  end
104
110
  end
111
+ private_class_method :definition_method
105
112
 
106
- alias gems specs
113
+ definition_method :requested_specs
114
+ definition_method :specs
115
+ definition_method :dependencies
116
+ definition_method :current_dependencies
117
+ definition_method :requires
118
+
119
+ def lock(opts = {})
120
+ return if @definition.nothing_changed? && !@definition.unlocking?
121
+ @definition.lock(Bundler.default_lockfile, opts[:preserve_unknown_sections])
122
+ end
123
+
124
+ alias_method :gems, :specs
107
125
 
108
126
  def cache(custom_path = nil)
109
127
  cache_path = Bundler.app_cache(custom_path)
110
- FileUtils.mkdir_p(cache_path) unless File.exist?(cache_path)
128
+ SharedHelpers.filesystem_access(cache_path) do |p|
129
+ FileUtils.mkdir_p(p)
130
+ end unless File.exist?(cache_path)
111
131
 
112
132
  Bundler.ui.info "Updating files in #{Bundler.settings.app_cache_path}"
113
- specs.each do |spec|
114
- next if spec.name == 'bundler'
133
+
134
+ specs_to_cache = Bundler.settings[:cache_all_platforms] ? @definition.resolve.materialized_for_all_platforms : specs
135
+ specs_to_cache.each do |spec|
136
+ next if spec.name == "bundler"
137
+ next if spec.source.is_a?(Source::Gemspec)
115
138
  spec.source.send(:fetch_gem, spec) if Bundler.settings[:cache_all_platforms] && spec.source.respond_to?(:fetch_gem, true)
116
139
  spec.source.cache(spec, custom_path) if spec.source.respond_to?(:cache)
117
140
  end
@@ -125,7 +148,9 @@ module Bundler
125
148
  end
126
149
 
127
150
  def prune_cache(cache_path)
128
- FileUtils.mkdir_p(cache_path) unless File.exist?(cache_path)
151
+ SharedHelpers.filesystem_access(cache_path) do |p|
152
+ FileUtils.mkdir_p(p)
153
+ end unless File.exist?(cache_path)
129
154
  resolve = @definition.resolve
130
155
  prune_gem_cache(resolve, cache_path)
131
156
  prune_git_and_path_cache(resolve, cache_path)
@@ -138,6 +163,7 @@ module Bundler
138
163
  gem_dirs = Dir["#{Gem.dir}/gems/*"]
139
164
  gem_files = Dir["#{Gem.dir}/cache/*.gem"]
140
165
  gemspec_files = Dir["#{Gem.dir}/specifications/*.gemspec"]
166
+ extension_dirs = Dir["#{Gem.dir}/extensions/*/*/*"]
141
167
  spec_gem_paths = []
142
168
  # need to keep git sources around
143
169
  spec_git_paths = @definition.spec_git_paths
@@ -145,6 +171,7 @@ module Bundler
145
171
  spec_gem_executables = []
146
172
  spec_cache_paths = []
147
173
  spec_gemspec_paths = []
174
+ spec_extension_paths = []
148
175
  specs.each do |spec|
149
176
  spec_gem_paths << spec.full_gem_path
150
177
  # need to check here in case gems are nested like for the rails git repo
@@ -156,79 +183,47 @@ module Bundler
156
183
  end
157
184
  spec_cache_paths << spec.cache_file
158
185
  spec_gemspec_paths << spec.spec_file
186
+ spec_extension_paths << spec.extension_dir if spec.respond_to?(:extension_dir)
159
187
  spec_git_cache_dirs << spec.source.cache_path.to_s if spec.source.is_a?(Bundler::Source::Git)
160
188
  end
161
189
  spec_gem_paths.uniq!
162
190
  spec_gem_executables.flatten!
163
191
 
164
192
  stale_gem_bins = gem_bins - spec_gem_executables
165
- stale_git_dirs = git_dirs - spec_git_paths
193
+ stale_git_dirs = git_dirs - spec_git_paths - ["#{Gem.dir}/bundler/gems/extensions"]
166
194
  stale_git_cache_dirs = git_cache_dirs - spec_git_cache_dirs
167
195
  stale_gem_dirs = gem_dirs - spec_gem_paths
168
196
  stale_gem_files = gem_files - spec_cache_paths
169
197
  stale_gemspec_files = gemspec_files - spec_gemspec_paths
198
+ stale_extension_dirs = extension_dirs - spec_extension_paths
170
199
 
171
- output = stale_gem_dirs.collect do |gem_dir|
172
- full_name = Pathname.new(gem_dir).basename.to_s
173
-
174
- parts = full_name.split('-')
175
- name = parts[0..-2].join('-')
176
- version = parts.last
177
- output = "#{name} (#{version})"
200
+ removed_stale_gem_dirs = stale_gem_dirs.collect {|dir| remove_dir(dir, dry_run) }
201
+ removed_stale_git_dirs = stale_git_dirs.collect {|dir| remove_dir(dir, dry_run) }
202
+ output = removed_stale_gem_dirs + removed_stale_git_dirs
178
203
 
179
- if dry_run
180
- Bundler.ui.info "Would have removed #{output}"
181
- else
182
- Bundler.ui.info "Removing #{output}"
183
- FileUtils.rm_rf(gem_dir)
204
+ unless dry_run
205
+ stale_files = stale_gem_bins + stale_gem_files + stale_gemspec_files
206
+ stale_files.each do |file|
207
+ SharedHelpers.filesystem_access(File.dirname(file)) do |_p|
208
+ FileUtils.rm(file) if File.exist?(file)
209
+ end
184
210
  end
185
211
 
186
- output
187
- end + stale_git_dirs.collect do |gem_dir|
188
- full_name = Pathname.new(gem_dir).basename.to_s
189
-
190
- parts = full_name.split('-')
191
- name = parts[0..-2].join('-')
192
- revision = parts[-1]
193
- output = "#{name} (#{revision})"
194
-
195
- if dry_run
196
- Bundler.ui.info "Would have removed #{output}"
197
- else
198
- Bundler.ui.info "Removing #{output}"
199
- FileUtils.rm_rf(gem_dir)
212
+ stale_dirs = stale_git_cache_dirs + stale_extension_dirs
213
+ stale_dirs.each do |stale_dir|
214
+ SharedHelpers.filesystem_access(stale_dir) do |dir|
215
+ FileUtils.rm_rf(dir) if File.exist?(dir)
216
+ end
200
217
  end
201
-
202
- output
203
- end
204
-
205
- unless dry_run
206
- stale_gem_bins.each { |bin| FileUtils.rm(bin) if File.exist?(bin) }
207
- stale_gem_files.each { |file| FileUtils.rm(file) if File.exist?(file) }
208
- stale_gemspec_files.each { |file| FileUtils.rm(file) if File.exist?(file) }
209
- stale_git_cache_dirs.each { |dir| FileUtils.rm_rf(dir) if File.exist?(dir) }
210
218
  end
211
219
 
212
220
  output
213
221
  end
214
222
 
215
- def setup_environment
216
- begin
217
- ENV["BUNDLE_BIN_PATH"] = Bundler.rubygems.bin_path("bundler", "bundle", VERSION)
218
- rescue Gem::GemNotFoundException
219
- ENV["BUNDLE_BIN_PATH"] = File.expand_path("../../../bin/bundle", __FILE__)
220
- end
221
-
222
- # Set BUNDLE_GEMFILE
223
- ENV["BUNDLE_GEMFILE"] = default_gemfile.to_s
224
-
225
- SharedHelpers.set_bundle_environment
226
- end
227
-
228
223
  private
229
224
 
230
225
  def prune_gem_cache(resolve, cache_path)
231
- cached = Dir["#{cache_path}/*.gem"]
226
+ cached = Dir["#{cache_path}/*.gem"]
232
227
 
233
228
  cached = cached.delete_if do |path|
234
229
  spec = Bundler.rubygems.spec_from_gem path
@@ -249,7 +244,7 @@ module Bundler
249
244
  end
250
245
 
251
246
  def prune_git_and_path_cache(resolve, cache_path)
252
- cached = Dir["#{cache_path}/*/.bundlecache"]
247
+ cached = Dir["#{cache_path}/*/.bundlecache"]
253
248
 
254
249
  cached = cached.delete_if do |path|
255
250
  name = File.basename(File.dirname(path))
@@ -272,21 +267,56 @@ module Bundler
272
267
  end
273
268
 
274
269
  def setup_manpath
275
- # Store original MANPATH for restoration later in with_clean_env()
276
- ENV['BUNDLE_ORIG_MANPATH'] = ENV['MANPATH']
277
-
278
270
  # Add man/ subdirectories from activated bundles to MANPATH for man(1)
279
271
  manuals = $LOAD_PATH.map do |path|
280
- man_subdir = path.sub(/lib$/, 'man')
281
- man_subdir unless Dir[man_subdir + '/man?/'].empty?
272
+ man_subdir = path.sub(/lib$/, "man")
273
+ man_subdir unless Dir[man_subdir + "/man?/"].empty?
282
274
  end.compact
283
275
 
284
- unless manuals.empty?
285
- ENV['MANPATH'] = manuals.concat(
286
- ENV['MANPATH'].to_s.split(File::PATH_SEPARATOR)
287
- ).uniq.join(File::PATH_SEPARATOR)
276
+ return if manuals.empty?
277
+ Bundler::SharedHelpers.set_env "MANPATH", manuals.concat(
278
+ ENV["MANPATH"].to_s.split(File::PATH_SEPARATOR)
279
+ ).uniq.join(File::PATH_SEPARATOR)
280
+ end
281
+
282
+ def remove_dir(dir, dry_run)
283
+ full_name = Pathname.new(dir).basename.to_s
284
+
285
+ parts = full_name.split("-")
286
+ name = parts[0..-2].join("-")
287
+ version = parts.last
288
+ output = "#{name} (#{version})"
289
+
290
+ if dry_run
291
+ Bundler.ui.info "Would have removed #{output}"
292
+ else
293
+ Bundler.ui.info "Removing #{output}"
294
+ FileUtils.rm_rf(dir)
288
295
  end
296
+
297
+ output
289
298
  end
290
299
 
300
+ def check_for_activated_spec!(spec)
301
+ return unless activated_spec = Bundler.rubygems.loaded_specs(spec.name)
302
+ return if activated_spec.version == spec.version
303
+
304
+ suggestion = if Bundler.rubygems.spec_default_gem?(activated_spec)
305
+ "Since #{spec.name} is a default gem, you can either remove your dependency on it" \
306
+ " or try updating to a newer version of bundler that supports #{spec.name} as a default gem."
307
+ else
308
+ "Prepending `bundle exec` to your command may solve this."
309
+ end
310
+
311
+ e = Gem::LoadError.new "You have already activated #{activated_spec.name} #{activated_spec.version}, " \
312
+ "but your Gemfile requires #{spec.name} #{spec.version}. #{suggestion}"
313
+ e.name = spec.name
314
+ if e.respond_to?(:requirement=)
315
+ e.requirement = Gem::Requirement.new(spec.version.to_s)
316
+ else
317
+ e.version_requirement = Gem::Requirement.new(spec.version.to_s)
318
+ end
319
+ raise e
320
+ end
291
321
  end
292
322
  end
@@ -1,35 +1,149 @@
1
- require 'uri'
1
+ # frozen_string_literal: true
2
+
3
+ require "uri"
2
4
 
3
5
  module Bundler
4
6
  class Settings
5
- BOOL_KEYS = %w(frozen cache_all no_prune disable_local_branch_check gem.mit gem.coc).freeze
7
+ autoload :Mirror, "bundler/mirror"
8
+ autoload :Mirrors, "bundler/mirror"
9
+ autoload :Validator, "bundler/settings/validator"
10
+
11
+ BOOL_KEYS = %w[
12
+ allow_bundler_dependency_conflicts
13
+ allow_deployment_source_credential_changes
14
+ allow_offline_install
15
+ auto_clean_without_path
16
+ auto_install
17
+ auto_config_jobs
18
+ cache_all
19
+ cache_all_platforms
20
+ cache_command_is_package
21
+ console_command
22
+ default_install_uses_path
23
+ deployment
24
+ deployment_means_frozen
25
+ disable_checksum_validation
26
+ disable_exec_load
27
+ disable_local_branch_check
28
+ disable_multisource
29
+ disable_platform_warnings
30
+ disable_shared_gems
31
+ disable_version_check
32
+ error_on_stderr
33
+ force_ruby_platform
34
+ forget_cli_options
35
+ frozen
36
+ gem.coc
37
+ gem.mit
38
+ global_path_appends_ruby_scope
39
+ global_gem_cache
40
+ ignore_messages
41
+ init_gems_rb
42
+ list_command
43
+ lockfile_uses_separate_rubygems_sources
44
+ major_deprecations
45
+ no_install
46
+ no_prune
47
+ only_update_to_newer_versions
48
+ path_relative_to_cwd
49
+ path.system
50
+ plugins
51
+ prefer_gems_rb
52
+ print_only_version_number
53
+ setup_makes_kernel_gem_public
54
+ silence_root_warning
55
+ skip_default_git_sources
56
+ specific_platform
57
+ suppress_install_using_messages
58
+ unlock_source_unlocks_spec
59
+ update_requires_all_flag
60
+ use_gem_version_promoter_for_major_updates
61
+ viz_command
62
+ ].freeze
63
+
64
+ NUMBER_KEYS = %w[
65
+ jobs
66
+ redirect
67
+ retry
68
+ ssl_verify_mode
69
+ timeout
70
+ ].freeze
71
+
72
+ ARRAY_KEYS = %w[
73
+ with
74
+ without
75
+ ].freeze
76
+
77
+ DEFAULT_CONFIG = {
78
+ :disable_version_check => true,
79
+ :redirect => 5,
80
+ :retry => 3,
81
+ :timeout => 10,
82
+ }.freeze
6
83
 
7
84
  def initialize(root = nil)
8
- @root = root
9
- @local_config = load_config(local_config_file)
10
- @global_config = load_config(global_config_file)
85
+ @root = root
86
+ @local_config = load_config(local_config_file)
87
+ @global_config = load_config(global_config_file)
88
+ @temporary = {}
11
89
  end
12
90
 
13
91
  def [](name)
14
92
  key = key_for(name)
15
- value = (@local_config[key] || ENV[key] || @global_config[key])
93
+ value = @temporary.fetch(key) do
94
+ @local_config.fetch(key) do
95
+ ENV.fetch(key) do
96
+ @global_config.fetch(key) do
97
+ DEFAULT_CONFIG.fetch(name) do
98
+ nil
99
+ end end end end end
100
+
101
+ converted_value(value, name)
102
+ end
16
103
 
17
- if !value.nil? && is_bool(name)
18
- to_bool(value)
19
- else
104
+ def set_command_option(key, value)
105
+ if Bundler.feature_flag.forget_cli_options?
106
+ temporary(key => value)
20
107
  value
108
+ else
109
+ command = if value.nil?
110
+ "bundle config --delete #{key}"
111
+ else
112
+ "bundle config #{key} #{Array(value).join(":")}"
113
+ end
114
+
115
+ Bundler::SharedHelpers.major_deprecation 2,\
116
+ "flags passed to commands " \
117
+ "will no longer be automatically remembered. Instead please set flags " \
118
+ "you want remembered between commands using `bundle config " \
119
+ "<setting name> <setting value>`, i.e. `#{command}`"
120
+
121
+ set_local(key, value)
21
122
  end
22
123
  end
23
124
 
24
- def []=(key, value)
25
- local_config_file or raise GemfileNotFound, "Could not locate Gemfile"
26
- set_key(key, value, @local_config, local_config_file)
125
+ def set_command_option_if_given(key, value)
126
+ return if value.nil?
127
+ set_command_option(key, value)
27
128
  end
28
129
 
29
- alias :set_local :[]=
130
+ def set_local(key, value)
131
+ local_config_file || raise(GemfileNotFound, "Could not locate Gemfile")
132
+
133
+ set_key(key, value, @local_config, local_config_file)
134
+ end
30
135
 
31
- def delete(key)
32
- @local_config.delete(key_for(key))
136
+ def temporary(update)
137
+ existing = Hash[update.map {|k, _| [k, @temporary[key_for(k)]] }]
138
+ update.each do |k, v|
139
+ set_key(k, v, @temporary, nil)
140
+ end
141
+ return unless block_given?
142
+ begin
143
+ yield
144
+ ensure
145
+ existing.each {|k, v| set_key(k, v, @temporary, nil) }
146
+ end
33
147
  end
34
148
 
35
149
  def set_global(key, value)
@@ -37,41 +151,47 @@ module Bundler
37
151
  end
38
152
 
39
153
  def all
40
- env_keys = ENV.keys.select { |k| k =~ /BUNDLE_.*/ }
154
+ env_keys = ENV.keys.grep(/\ABUNDLE_.+/)
41
155
 
42
- keys = @global_config.keys | @local_config.keys | env_keys
156
+ keys = @temporary.keys | @global_config.keys | @local_config.keys | env_keys
43
157
 
44
158
  keys.map do |key|
45
- key.sub(/^BUNDLE_/, '').gsub(/__/, ".").downcase
159
+ key.sub(/^BUNDLE_/, "").gsub(/__/, ".").downcase
46
160
  end
47
161
  end
48
162
 
49
163
  def local_overrides
50
164
  repos = {}
51
165
  all.each do |k|
52
- if k =~ /^local\./
53
- repos[$'] = self[k]
54
- end
166
+ repos[$'] = self[k] if k =~ /^local\./
55
167
  end
56
168
  repos
57
169
  end
58
170
 
171
+ def mirror_for(uri)
172
+ uri = URI(uri.to_s) unless uri.is_a?(URI)
173
+ gem_mirrors.for(uri.to_s).uri
174
+ end
175
+
176
+ def credentials_for(uri)
177
+ self[uri.to_s] || self[uri.host]
178
+ end
179
+
59
180
  def gem_mirrors
60
- all.inject({}) do |h, k|
61
- if k =~ /^mirror\./
62
- uri = normalize_uri($')
63
- h[uri] = normalize_uri(self[k])
64
- end
65
- h
181
+ all.inject(Mirrors.new) do |mirrors, k|
182
+ mirrors.parse(k, self[k]) if k.start_with?("mirror.")
183
+ mirrors
66
184
  end
67
185
  end
68
186
 
69
187
  def locations(key)
70
188
  key = key_for(key)
71
189
  locations = {}
190
+ locations[:temporary] = @temporary[key] if @temporary.key?(key)
72
191
  locations[:local] = @local_config[key] if @local_config.key?(key)
73
192
  locations[:env] = ENV[key] if ENV[key]
74
193
  locations[:global] = @global_config[key] if @global_config.key?(key)
194
+ locations[:default] = DEFAULT_CONFIG[key] if DEFAULT_CONFIG.key?(key)
75
195
  locations
76
196
  end
77
197
 
@@ -79,124 +199,265 @@ module Bundler
79
199
  key = key_for(exposed_key)
80
200
 
81
201
  locations = []
202
+
203
+ if @temporary.key?(key)
204
+ locations << "Set for the current command: #{converted_value(@temporary[key], exposed_key).inspect}"
205
+ end
206
+
82
207
  if @local_config.key?(key)
83
- locations << "Set for your local app (#{local_config_file}): #{@local_config[key].inspect}"
208
+ locations << "Set for your local app (#{local_config_file}): #{converted_value(@local_config[key], exposed_key).inspect}"
84
209
  end
85
210
 
86
211
  if value = ENV[key]
87
- locations << "Set via #{key}: #{value.inspect}"
212
+ locations << "Set via #{key}: #{converted_value(value, exposed_key).inspect}"
88
213
  end
89
214
 
90
215
  if @global_config.key?(key)
91
- locations << "Set for the current user (#{global_config_file}): #{@global_config[key].inspect}"
216
+ locations << "Set for the current user (#{global_config_file}): #{converted_value(@global_config[key], exposed_key).inspect}"
92
217
  end
93
218
 
94
219
  return ["You have not configured a value for `#{exposed_key}`"] if locations.empty?
95
220
  locations
96
221
  end
97
222
 
98
- def without=(array)
99
- self[:without] = (array.empty? ? nil : array.join(":")) if array
100
- end
101
-
102
- def without
103
- self[:without] ? self[:without].split(":").map { |w| w.to_sym } : []
104
- end
105
-
106
- # @local_config["BUNDLE_PATH"] should be prioritized over ENV["BUNDLE_PATH"]
223
+ # for legacy reasons, in Bundler 1, the ruby scope isnt appended when the setting comes from ENV or the global config,
224
+ # nor do we respect :disable_shared_gems
107
225
  def path
108
226
  key = key_for(:path)
109
227
  path = ENV[key] || @global_config[key]
110
- return path if path && !@local_config.key?(key)
228
+ if path && !@temporary.key?(key) && !@local_config.key?(key)
229
+ return Path.new(path, Bundler.feature_flag.global_path_appends_ruby_scope?, false, false)
230
+ end
111
231
 
112
- if path = self[:path]
113
- "#{path}/#{Bundler.ruby_scope}"
114
- else
115
- Bundler.rubygems.gem_dir
232
+ system_path = self["path.system"] || (self[:disable_shared_gems] == false)
233
+ Path.new(self[:path], true, system_path, Bundler.feature_flag.default_install_uses_path?)
234
+ end
235
+
236
+ Path = Struct.new(:explicit_path, :append_ruby_scope, :system_path, :default_install_uses_path) do
237
+ def path
238
+ path = base_path
239
+ path = File.join(path, Bundler.ruby_scope) if append_ruby_scope && !use_system_gems?
240
+ path
241
+ end
242
+
243
+ def use_system_gems?
244
+ return true if system_path
245
+ return false if explicit_path
246
+ !default_install_uses_path
247
+ end
248
+
249
+ def base_path
250
+ path = explicit_path
251
+ path ||= ".bundle" unless use_system_gems?
252
+ path ||= Bundler.rubygems.gem_dir
253
+ path
254
+ end
255
+
256
+ def base_path_relative_to_pwd
257
+ base_path = Pathname.new(self.base_path)
258
+ expanded_base_path = base_path.expand_path(Bundler.root)
259
+ relative_path = expanded_base_path.relative_path_from(Pathname.pwd)
260
+ if relative_path.to_s.start_with?("..")
261
+ relative_path = base_path if base_path.absolute?
262
+ else
263
+ relative_path = Pathname.new(File.join(".", relative_path))
264
+ end
265
+ relative_path
266
+ rescue ArgumentError
267
+ expanded_base_path
268
+ end
269
+
270
+ def validate!
271
+ return unless explicit_path && system_path
272
+ path = Bundler.settings.pretty_values_for(:path)
273
+ path.unshift(nil, "path:") unless path.empty?
274
+ system_path = Bundler.settings.pretty_values_for("path.system")
275
+ system_path.unshift(nil, "path.system:") unless system_path.empty?
276
+ disable_shared_gems = Bundler.settings.pretty_values_for(:disable_shared_gems)
277
+ disable_shared_gems.unshift(nil, "disable_shared_gems:") unless disable_shared_gems.empty?
278
+ raise InvalidOption,
279
+ "Using a custom path while using system gems is unsupported.\n#{path.join("\n")}\n#{system_path.join("\n")}\n#{disable_shared_gems.join("\n")}"
116
280
  end
117
281
  end
118
282
 
119
283
  def allow_sudo?
120
- !@local_config.key?(key_for(:path))
284
+ key = key_for(:path)
285
+ path_configured = @temporary.key?(key) || @local_config.key?(key)
286
+ !path_configured
121
287
  end
122
288
 
123
289
  def ignore_config?
124
- ENV['BUNDLE_IGNORE_CONFIG']
290
+ ENV["BUNDLE_IGNORE_CONFIG"]
125
291
  end
126
292
 
127
293
  def app_cache_path
128
- @app_cache_path ||= begin
129
- path = self[:cache_path] || "vendor/cache"
130
- raise InvalidOption, "Cache path must be relative to the bundle path" if path.start_with?("/")
131
- path
294
+ @app_cache_path ||= self[:cache_path] || "vendor/cache"
295
+ end
296
+
297
+ def validate!
298
+ all.each do |raw_key|
299
+ [@local_config, ENV, @global_config].each do |settings|
300
+ value = converted_value(settings[key_for(raw_key)], raw_key)
301
+ Validator.validate!(raw_key, value, settings.to_hash.dup)
302
+ end
132
303
  end
133
304
  end
134
305
 
135
- private
136
306
  def key_for(key)
137
- if key.is_a?(String) && /https?:/ =~ key
138
- key = normalize_uri(key).to_s
139
- end
307
+ key = Settings.normalize_uri(key).to_s if key.is_a?(String) && /https?:/ =~ key
140
308
  key = key.to_s.gsub(".", "__").upcase
141
309
  "BUNDLE_#{key}"
142
310
  end
143
311
 
144
- def is_bool(key)
145
- BOOL_KEYS.include?(key.to_s)
312
+ private
313
+
314
+ def parent_setting_for(name)
315
+ split_specific_setting_for(name)[0]
316
+ end
317
+
318
+ def specific_gem_for(name)
319
+ split_specific_setting_for(name)[1]
320
+ end
321
+
322
+ def split_specific_setting_for(name)
323
+ name.split(".")
324
+ end
325
+
326
+ def is_bool(name)
327
+ BOOL_KEYS.include?(name.to_s) || BOOL_KEYS.include?(parent_setting_for(name.to_s))
146
328
  end
147
329
 
148
330
  def to_bool(value)
149
- !(value.nil? || value == '' || value =~ /^(false|f|no|n|0)$/i || value == false)
331
+ case value
332
+ when nil, /\A(false|f|no|n|0|)\z/i, false
333
+ false
334
+ else
335
+ true
336
+ end
150
337
  end
151
338
 
152
- def set_key(key, value, hash, file)
153
- key = key_for(key)
339
+ def is_num(key)
340
+ NUMBER_KEYS.include?(key.to_s)
341
+ end
342
+
343
+ def is_array(key)
344
+ ARRAY_KEYS.include?(key.to_s)
345
+ end
346
+
347
+ def to_array(value)
348
+ return [] unless value
349
+ value.split(":").map(&:to_sym)
350
+ end
154
351
 
155
- unless hash[key] == value
156
- hash[key] = value
157
- hash.delete(key) if value.nil?
158
- FileUtils.mkdir_p(file.dirname)
159
- require 'bundler/psyched_yaml'
160
- File.open(file, "w") { |f| f.puts YAML.dump(hash) }
352
+ def array_to_s(array)
353
+ array = Array(array)
354
+ return nil if array.empty?
355
+ array.join(":").tr(" ", ":")
356
+ end
357
+
358
+ def set_key(raw_key, value, hash, file)
359
+ raw_key = raw_key.to_s
360
+ value = array_to_s(value) if is_array(raw_key)
361
+
362
+ key = key_for(raw_key)
363
+
364
+ return if hash[key] == value
365
+
366
+ hash[key] = value
367
+ hash.delete(key) if value.nil?
368
+
369
+ Validator.validate!(raw_key, converted_value(value, raw_key), hash)
370
+
371
+ return unless file
372
+ SharedHelpers.filesystem_access(file) do |p|
373
+ FileUtils.mkdir_p(p.dirname)
374
+ require "bundler/yaml_serializer"
375
+ p.open("w") {|f| f.write(YAMLSerializer.dump(hash)) }
161
376
  end
377
+ end
162
378
 
163
- value
379
+ def converted_value(value, key)
380
+ if is_array(key)
381
+ to_array(value)
382
+ elsif value.nil?
383
+ nil
384
+ elsif is_bool(key) || value == "false"
385
+ to_bool(value)
386
+ elsif is_num(key)
387
+ value.to_i
388
+ else
389
+ value.to_s
390
+ end
164
391
  end
165
392
 
166
393
  def global_config_file
167
- file = ENV["BUNDLE_CONFIG"] || File.join(Bundler.rubygems.user_home, ".bundle/config")
168
- Pathname.new(file)
394
+ if ENV["BUNDLE_CONFIG"] && !ENV["BUNDLE_CONFIG"].empty?
395
+ Pathname.new(ENV["BUNDLE_CONFIG"])
396
+ else
397
+ begin
398
+ Bundler.user_bundle_path("config")
399
+ rescue PermissionError, GenericSystemCallError
400
+ nil
401
+ end
402
+ end
169
403
  end
170
404
 
171
405
  def local_config_file
172
406
  Pathname.new(@root).join("config") if @root
173
407
  end
174
408
 
409
+ CONFIG_REGEX = %r{ # rubocop:disable Style/RegexpLiteral
410
+ ^
411
+ (BUNDLE_.+):\s # the key
412
+ (?: !\s)? # optional exclamation mark found with ruby 1.9.3
413
+ (['"]?) # optional opening quote
414
+ (.* # contents of the value
415
+ (?: # optionally, up until the next key
416
+ (\n(?!BUNDLE).+)*
417
+ )
418
+ )
419
+ \2 # matching closing quote
420
+ $
421
+ }xo
422
+
175
423
  def load_config(config_file)
176
- valid_file = config_file && config_file.exist? && !config_file.size.zero?
177
- if !ignore_config? && valid_file
178
- config_regex = /^(BUNDLE_.+): (['"]?)(.*(?:\n(?!BUNDLE).+)?)\2$/
179
- config_pairs = config_file.read.scan(config_regex).map do |m|
180
- key, _, value = m
181
- [key, value.gsub(/\s+/, " ").tr('"', "'")]
182
- end
183
- Hash[config_pairs]
184
- else
185
- {}
424
+ return {} if !config_file || ignore_config?
425
+ SharedHelpers.filesystem_access(config_file, :read) do |file|
426
+ valid_file = file.exist? && !file.size.zero?
427
+ return {} unless valid_file
428
+ require "bundler/yaml_serializer"
429
+ YAMLSerializer.load file.read
186
430
  end
187
431
  end
188
432
 
433
+ PER_URI_OPTIONS = %w[
434
+ fallback_timeout
435
+ ].freeze
436
+
437
+ NORMALIZE_URI_OPTIONS_PATTERN =
438
+ /
439
+ \A
440
+ (\w+\.)? # optional prefix key
441
+ (https?.*?) # URI
442
+ (\.#{Regexp.union(PER_URI_OPTIONS)})? # optional suffix key
443
+ \z
444
+ /ix
445
+
189
446
  # TODO: duplicates Rubygems#normalize_uri
190
447
  # TODO: is this the correct place to validate mirror URIs?
191
- def normalize_uri(uri)
448
+ def self.normalize_uri(uri)
192
449
  uri = uri.to_s
193
- uri = "#{uri}/" unless uri =~ %r[/\Z]
450
+ if uri =~ NORMALIZE_URI_OPTIONS_PATTERN
451
+ prefix = $1
452
+ uri = $2
453
+ suffix = $3
454
+ end
455
+ uri = "#{uri}/" unless uri.end_with?("/")
194
456
  uri = URI(uri)
195
457
  unless uri.absolute?
196
- raise ArgumentError, "Gem sources must be absolute. You provided '#{uri}'."
458
+ raise ArgumentError, format("Gem sources must be absolute. You provided '%s'.", uri)
197
459
  end
198
- uri
460
+ "#{prefix}#{uri}#{suffix}"
199
461
  end
200
-
201
462
  end
202
463
  end