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,106 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rubygems/installer"
4
+
5
+ module Bundler
6
+ class RubyGemsGemInstaller < Gem::Installer
7
+ unless respond_to?(:at)
8
+ def self.at(*args)
9
+ new(*args)
10
+ end
11
+ end
12
+
13
+ attr_reader :options
14
+
15
+ def initialize(gem, options = {})
16
+ @options = {}
17
+ super
18
+ end
19
+
20
+ def check_executable_overwrite(filename)
21
+ # Bundler needs to install gems regardless of binstub overwriting
22
+ end
23
+
24
+ def pre_install_checks
25
+ super && validate_bundler_checksum(options[:bundler_expected_checksum])
26
+ end
27
+
28
+ def build_extensions
29
+ extension_cache_path = options[:bundler_extension_cache_path]
30
+ return super unless extension_cache_path && extension_dir = Bundler.rubygems.spec_extension_dir(spec)
31
+
32
+ extension_dir = Pathname.new(extension_dir)
33
+ build_complete = SharedHelpers.filesystem_access(extension_cache_path.join("gem.build_complete"), :read, &:file?)
34
+ if build_complete && !options[:force]
35
+ SharedHelpers.filesystem_access(extension_dir.parent, &:mkpath)
36
+ SharedHelpers.filesystem_access(extension_cache_path) do
37
+ FileUtils.cp_r extension_cache_path, spec.extension_dir
38
+ end
39
+ else
40
+ super
41
+ if extension_dir.directory? # not made for gems without extensions
42
+ SharedHelpers.filesystem_access(extension_cache_path.parent, &:mkpath)
43
+ SharedHelpers.filesystem_access(extension_cache_path) do
44
+ FileUtils.cp_r extension_dir, extension_cache_path
45
+ end
46
+ end
47
+ end
48
+ end
49
+
50
+ private
51
+
52
+ def validate_bundler_checksum(checksum)
53
+ return true if Bundler.settings[:disable_checksum_validation]
54
+ return true unless checksum
55
+ return true unless source = @package.instance_variable_get(:@gem)
56
+ return true unless source.respond_to?(:with_read_io)
57
+ digest = source.with_read_io do |io|
58
+ digest = SharedHelpers.digest(:SHA256).new
59
+ digest << io.read(16_384) until io.eof?
60
+ io.rewind
61
+ send(checksum_type(checksum), digest)
62
+ end
63
+ unless digest == checksum
64
+ raise SecurityError, <<-MESSAGE
65
+ Bundler cannot continue installing #{spec.name} (#{spec.version}).
66
+ The checksum for the downloaded `#{spec.full_name}.gem` does not match \
67
+ the checksum given by the server. This means the contents of the downloaded \
68
+ gem is different from what was uploaded to the server, and could be a potential security issue.
69
+
70
+ To resolve this issue:
71
+ 1. delete the downloaded gem located at: `#{spec.gem_dir}/#{spec.full_name}.gem`
72
+ 2. run `bundle install`
73
+
74
+ If you wish to continue installing the downloaded gem, and are certain it does not pose a \
75
+ security issue despite the mismatching checksum, do the following:
76
+ 1. run `bundle config disable_checksum_validation true` to turn off checksum verification
77
+ 2. run `bundle install`
78
+
79
+ (More info: The expected SHA256 checksum was #{checksum.inspect}, but the \
80
+ checksum for the downloaded gem was #{digest.inspect}.)
81
+ MESSAGE
82
+ end
83
+ true
84
+ end
85
+
86
+ def checksum_type(checksum)
87
+ case checksum.length
88
+ when 64 then :hexdigest!
89
+ when 44 then :base64digest!
90
+ else raise InstallError, "The given checksum for #{spec.full_name} (#{checksum.inspect}) is not a valid SHA256 hexdigest nor base64digest"
91
+ end
92
+ end
93
+
94
+ def hexdigest!(digest)
95
+ digest.hexdigest!
96
+ end
97
+
98
+ def base64digest!(digest)
99
+ if digest.respond_to?(:base64digest!)
100
+ digest.base64digest!
101
+ else
102
+ [digest.digest!].pack("m0")
103
+ end
104
+ end
105
+ end
106
+ end
@@ -1,9 +1,16 @@
1
- require 'monitor'
2
- require 'rubygems'
3
- require 'rubygems/config_file'
1
+ # frozen_string_literal: true
2
+
3
+ require "monitor"
4
+ require "rubygems"
5
+ require "rubygems/config_file"
4
6
 
5
7
  module Bundler
6
8
  class RubygemsIntegration
9
+ if defined?(Gem::Ext::Builder::CHDIR_MONITOR)
10
+ EXT_LOCK = Gem::Ext::Builder::CHDIR_MONITOR
11
+ else
12
+ EXT_LOCK = Monitor.new
13
+ end
7
14
 
8
15
  def self.version
9
16
  @version ||= Gem::Version.new(Gem::VERSION)
@@ -13,6 +20,10 @@ module Bundler
13
20
  Gem::Requirement.new(req_str).satisfied_by?(version)
14
21
  end
15
22
 
23
+ def initialize
24
+ @replaced_methods = {}
25
+ end
26
+
16
27
  def version
17
28
  self.class.version
18
29
  end
@@ -29,28 +40,87 @@ module Bundler
29
40
  Gem::Command.build_args = args
30
41
  end
31
42
 
43
+ def load_path_insert_index
44
+ Gem.load_path_insert_index
45
+ end
46
+
32
47
  def loaded_specs(name)
33
48
  Gem.loaded_specs[name]
34
49
  end
35
50
 
36
51
  def mark_loaded(spec)
52
+ if spec.respond_to?(:activated=)
53
+ current = Gem.loaded_specs[spec.name]
54
+ current.activated = false if current
55
+ spec.activated = true
56
+ end
37
57
  Gem.loaded_specs[spec.name] = spec
38
58
  end
39
59
 
60
+ def validate(spec)
61
+ Bundler.ui.silence { spec.validate(false) }
62
+ rescue Gem::InvalidSpecificationException => e
63
+ error_message = "The gemspec at #{spec.loaded_from} is not valid. Please fix this gemspec.\n" \
64
+ "The validation error was '#{e.message}'\n"
65
+ raise Gem::InvalidSpecificationException.new(error_message)
66
+ rescue Errno::ENOENT
67
+ nil
68
+ end
69
+
70
+ def set_installed_by_version(spec, installed_by_version = Gem::VERSION)
71
+ return unless spec.respond_to?(:installed_by_version=)
72
+ spec.installed_by_version = Gem::Version.create(installed_by_version)
73
+ end
74
+
75
+ def spec_missing_extensions?(spec, default = true)
76
+ return spec.missing_extensions? if spec.respond_to?(:missing_extensions?)
77
+
78
+ return false if spec_default_gem?(spec)
79
+ return false if spec.extensions.empty?
80
+
81
+ default
82
+ end
83
+
84
+ def spec_default_gem?(spec)
85
+ spec.respond_to?(:default_gem?) && spec.default_gem?
86
+ end
87
+
88
+ def spec_matches_for_glob(spec, glob)
89
+ return spec.matches_for_glob(glob) if spec.respond_to?(:matches_for_glob)
90
+
91
+ spec.load_paths.map do |lp|
92
+ Dir["#{lp}/#{glob}#{suffix_pattern}"]
93
+ end.flatten(1)
94
+ end
95
+
96
+ def spec_extension_dir(spec)
97
+ return unless spec.respond_to?(:extension_dir)
98
+ spec.extension_dir
99
+ end
100
+
101
+ def stub_set_spec(stub, spec)
102
+ stub.instance_variable_set(:@spec, spec)
103
+ end
104
+
40
105
  def path(obj)
41
106
  obj.to_s
42
107
  end
43
108
 
44
109
  def platforms
110
+ return [Gem::Platform::RUBY] if Bundler.settings[:force_ruby_platform]
45
111
  Gem.platforms
46
112
  end
47
113
 
48
114
  def configuration
115
+ require "bundler/psyched_yaml"
49
116
  Gem.configuration
50
- rescue Gem::SystemExitException => e
117
+ rescue Gem::SystemExitException, LoadError => e
51
118
  Bundler.ui.error "#{e.class}: #{e.message}"
52
119
  Bundler.ui.trace e
53
- raise Gem::SystemExitException
120
+ raise
121
+ rescue YamlLibrarySyntaxError => e
122
+ raise YamlSyntaxError.new(e, "Your RubyGems configuration, which is " \
123
+ "usually located in ~/.gemrc, contains invalid YAML syntax.")
54
124
  end
55
125
 
56
126
  def ruby_engine
@@ -62,7 +132,11 @@ module Bundler
62
132
  end
63
133
 
64
134
  def inflate(obj)
65
- Gem.inflate(obj)
135
+ if defined?(Gem::Util)
136
+ Gem::Util.inflate(obj)
137
+ else
138
+ Gem.inflate(obj)
139
+ end
66
140
  end
67
141
 
68
142
  def sources=(val)
@@ -94,15 +168,27 @@ module Bundler
94
168
  Gem.path
95
169
  end
96
170
 
171
+ def reset
172
+ Gem::Specification.reset
173
+ end
174
+
175
+ def post_reset_hooks
176
+ Gem.post_reset_hooks
177
+ end
178
+
179
+ def suffix_pattern
180
+ Gem.suffix_pattern
181
+ end
182
+
97
183
  def gem_cache
98
- gem_path.map{|p| File.expand_path("cache", p) }
184
+ gem_path.map {|p| File.expand_path("cache", p) }
99
185
  end
100
186
 
101
187
  def spec_cache_dirs
102
188
  @spec_cache_dirs ||= begin
103
- dirs = gem_path.map {|dir| File.join(dir, 'specifications')}
104
- dirs << Gem.spec_cache_dir if Gem.respond_to?(:spec_cache_dir) # Not in Rubygems 2.0.3 or earlier
105
- dirs.uniq.select {|dir| File.directory? dir}
189
+ dirs = gem_path.map {|dir| File.join(dir, "specifications") }
190
+ dirs << Gem.spec_cache_dir if Gem.respond_to?(:spec_cache_dir) # Not in RubyGems 2.0.3 or earlier
191
+ dirs.uniq.select {|dir| File.directory? dir }
106
192
  end
107
193
  end
108
194
 
@@ -126,20 +212,46 @@ module Bundler
126
212
  Gem.bin_path(gem, bin, ver)
127
213
  end
128
214
 
215
+ def path_separator
216
+ File::PATH_SEPARATOR
217
+ end
218
+
129
219
  def preserve_paths
130
- # this is a no-op outside of Rubygems 1.8
220
+ # this is a no-op outside of RubyGems 1.8
131
221
  yield
132
222
  end
133
223
 
224
+ def loaded_gem_paths
225
+ # RubyGems 2.2+ can put binary extension into dedicated folders,
226
+ # therefore use RubyGems facilities to obtain their load paths.
227
+ if Gem::Specification.method_defined? :full_require_paths
228
+ loaded_gem_paths = Gem.loaded_specs.map {|_, s| s.full_require_paths }
229
+ loaded_gem_paths.flatten
230
+ else
231
+ $LOAD_PATH.select do |p|
232
+ Bundler.rubygems.gem_path.any? {|gp| p =~ /^#{Regexp.escape(gp)}/ }
233
+ end
234
+ end
235
+ end
236
+
237
+ def load_plugins
238
+ Gem.load_plugins if Gem.respond_to?(:load_plugins)
239
+ end
240
+
241
+ def load_plugin_files(files)
242
+ Gem.load_plugin_files(files) if Gem.respond_to?(:load_plugin_files)
243
+ end
244
+
134
245
  def ui=(obj)
135
246
  Gem::DefaultUserInteraction.ui = obj
136
247
  end
137
248
 
138
249
  def ext_lock
139
- @ext_lock ||= Monitor.new
250
+ EXT_LOCK
140
251
  end
141
252
 
142
253
  def fetch_specs(all, pre, &blk)
254
+ require "rubygems/spec_fetcher"
143
255
  specs = Gem::SpecFetcher.new.list(all, pre)
144
256
  specs.each { yield } if block_given?
145
257
  specs
@@ -148,35 +260,50 @@ module Bundler
148
260
  def fetch_prerelease_specs
149
261
  fetch_specs(false, true)
150
262
  rescue Gem::RemoteFetcher::FetchError
151
- [] # if we can't download them, there aren't any
263
+ {} # if we can't download them, there aren't any
152
264
  end
153
265
 
154
- def fetch_all_remote_specs
266
+ # TODO: This is for older versions of RubyGems... should we support the
267
+ # X-Gemfile-Source header on these old versions?
268
+ # Maybe the newer implementation will work on older RubyGems?
269
+ # It seems difficult to keep this implementation and still send the header.
270
+ def fetch_all_remote_specs(remote)
271
+ old_sources = Bundler.rubygems.sources
272
+ Bundler.rubygems.sources = [remote.uri.to_s]
155
273
  # Fetch all specs, minus prerelease specs
156
274
  spec_list = fetch_specs(true, false)
157
275
  # Then fetch the prerelease specs
158
- fetch_prerelease_specs.each {|k, v| spec_list[k] += v }
276
+ fetch_prerelease_specs.each {|k, v| spec_list[k].concat(v) }
159
277
 
160
- return spec_list
278
+ spec_list.values.first
279
+ ensure
280
+ Bundler.rubygems.sources = old_sources
161
281
  end
162
282
 
163
283
  def with_build_args(args)
164
- old_args = self.build_args
165
- begin
166
- self.build_args = args
167
- yield
168
- ensure
169
- self.build_args = old_args
284
+ ext_lock.synchronize do
285
+ old_args = build_args
286
+ begin
287
+ self.build_args = args
288
+ yield
289
+ ensure
290
+ self.build_args = old_args
291
+ end
170
292
  end
171
293
  end
172
294
 
295
+ def install_with_build_args(args)
296
+ with_build_args(args) { yield }
297
+ end
298
+
173
299
  def gem_from_path(path, policy = nil)
174
- require 'rubygems/format'
300
+ require "rubygems/format"
175
301
  Gem::Format.from_file_by_path(path, policy)
176
302
  end
177
303
 
178
304
  def spec_from_gem(path, policy = nil)
179
- require 'rubygems/security'
305
+ require "rubygems/security"
306
+ require "bundler/psyched_yaml"
180
307
  gem_from_path(path, security_policies[policy]).spec
181
308
  rescue Gem::Package::FormatError
182
309
  raise GemspecError, "Could not read gem at #{path}. It may be corrupted."
@@ -185,7 +312,7 @@ module Bundler
185
312
  e.message =~ /unknown trust policy|unsigned gem/i ||
186
313
  e.message =~ /couldn't verify (meta)?data signature/i
187
314
  raise SecurityError,
188
- "The gem #{File.basename(path, '.gem')} can't be installed because " \
315
+ "The gem #{File.basename(path, ".gem")} can't be installed because " \
189
316
  "the security policy didn't allow it, with the message: #{e.message}"
190
317
  else
191
318
  raise e
@@ -193,27 +320,29 @@ module Bundler
193
320
  end
194
321
 
195
322
  def build(spec, skip_validation = false)
196
- require 'rubygems/builder'
323
+ require "rubygems/builder"
197
324
  Gem::Builder.new(spec).build
198
325
  end
199
326
 
200
327
  def build_gem(gem_dir, spec)
201
- build(spec)
328
+ build(spec)
202
329
  end
203
330
 
204
331
  def download_gem(spec, uri, path)
205
- uri = Bundler::Source.mirror_for(uri)
332
+ uri = Bundler.settings.mirror_for(uri)
206
333
  fetcher = Gem::RemoteFetcher.new(configuration[:http_proxy])
207
- fetcher.download(spec, uri, path)
334
+ Bundler::Retry.new("download gem from #{uri}").attempts do
335
+ fetcher.download(spec, uri, path)
336
+ end
208
337
  end
209
338
 
210
339
  def security_policy_keys
211
- %w{High Medium Low AlmostNo No}.map { |level| "#{level}Security" }
340
+ %w[High Medium Low AlmostNo No].map {|level| "#{level}Security" }
212
341
  end
213
342
 
214
343
  def security_policies
215
344
  @security_policies ||= begin
216
- require 'rubygems/security'
345
+ require "rubygems/security"
217
346
  Gem::Security::Policies
218
347
  rescue LoadError, NameError
219
348
  {}
@@ -222,56 +351,65 @@ module Bundler
222
351
 
223
352
  def reverse_rubygems_kernel_mixin
224
353
  # Disable rubygems' gem activation system
225
- ::Kernel.class_eval do
226
- if private_method_defined?(:gem_original_require)
227
- alias rubygems_require require
228
- alias require gem_original_require
354
+ kernel = (class << ::Kernel; self; end)
355
+ [kernel, ::Kernel].each do |k|
356
+ if k.private_method_defined?(:gem_original_require)
357
+ redefine_method(k, :require, k.instance_method(:gem_original_require))
229
358
  end
230
-
231
- undef gem
232
359
  end
233
360
  end
234
361
 
235
- def replace_gem(specs)
362
+ def binstubs_call_gem?
363
+ true
364
+ end
365
+
366
+ def stubs_provide_full_functionality?
367
+ false
368
+ end
369
+
370
+ def replace_gem(specs, specs_by_name)
236
371
  reverse_rubygems_kernel_mixin
237
372
 
238
- executables = specs.map { |s| s.executables }.flatten
373
+ executables = nil
239
374
 
240
- ::Kernel.send(:define_method, :gem) do |dep, *reqs|
241
- if executables.include? File.basename(caller.first.split(':').first)
242
- return
243
- end
244
- reqs.pop if reqs.last.is_a?(Hash)
375
+ kernel = (class << ::Kernel; self; end)
376
+ [kernel, ::Kernel].each do |kernel_class|
377
+ redefine_method(kernel_class, :gem) do |dep, *reqs|
378
+ executables ||= specs.map(&:executables).flatten if ::Bundler.rubygems.binstubs_call_gem?
379
+ if executables && executables.include?(File.basename(caller.first.split(":").first))
380
+ break
381
+ end
245
382
 
246
- unless dep.respond_to?(:name) && dep.respond_to?(:requirement)
247
- dep = Gem::Dependency.new(dep, reqs)
248
- end
383
+ reqs.pop if reqs.last.is_a?(Hash)
249
384
 
250
- spec = specs.find { |s| s.name == dep.name }
385
+ unless dep.respond_to?(:name) && dep.respond_to?(:requirement)
386
+ dep = Gem::Dependency.new(dep, reqs)
387
+ end
251
388
 
252
- if spec.nil?
389
+ if spec = specs_by_name[dep.name]
390
+ return true if dep.matches_spec?(spec)
391
+ end
253
392
 
254
- e = Gem::LoadError.new "#{dep.name} is not part of the bundle. Add it to Gemfile."
255
- e.name = dep.name
256
- if e.respond_to?(:requirement=)
257
- e.requirement = dep.requirement
393
+ message = if spec.nil?
394
+ "#{dep.name} is not part of the bundle." \
395
+ " Add it to your #{Bundler.default_gemfile.basename}."
258
396
  else
259
- e.version_requirement = dep.requirement
397
+ "can't activate #{dep}, already activated #{spec.full_name}. " \
398
+ "Make sure all dependencies are added to Gemfile."
260
399
  end
261
- raise e
262
- elsif dep !~ spec
263
- e = Gem::LoadError.new "can't activate #{dep}, already activated #{spec.full_name}. " \
264
- "Make sure all dependencies are added to Gemfile."
400
+
401
+ e = Gem::LoadError.new(message)
265
402
  e.name = dep.name
266
403
  if e.respond_to?(:requirement=)
267
404
  e.requirement = dep.requirement
268
- else
405
+ elsif e.respond_to?(:version_requirement=)
269
406
  e.version_requirement = dep.requirement
270
407
  end
271
408
  raise e
272
409
  end
273
410
 
274
- true
411
+ # backwards compatibility shim, see https://github.com/bundler/bundler/issues/5102
412
+ kernel_class.send(:public, :gem) if Bundler.feature_flag.setup_makes_kernel_gem_public?
275
413
  end
276
414
  end
277
415
 
@@ -298,30 +436,63 @@ module Bundler
298
436
  # Used to make bin stubs that are not created by bundler work
299
437
  # under bundler. The new Gem.bin_path only considers gems in
300
438
  # +specs+
301
- def replace_bin_path(specs)
302
- gem_class = (class << Gem ; self ; end)
303
- redefine_method(gem_class, :bin_path) do |name, *args|
439
+ def replace_bin_path(specs, specs_by_name)
440
+ gem_class = (class << Gem; self; end)
441
+
442
+ redefine_method(gem_class, :find_spec_for_exe) do |gem_name, *args|
304
443
  exec_name = args.first
305
444
 
306
- if exec_name == 'bundle'
307
- return ENV['BUNDLE_BIN_PATH']
445
+ spec_with_name = specs_by_name[gem_name]
446
+ spec = if exec_name
447
+ if spec_with_name && spec_with_name.executables.include?(exec_name)
448
+ spec_with_name
449
+ else
450
+ specs.find {|s| s.executables.include?(exec_name) }
451
+ end
452
+ else
453
+ spec_with_name
308
454
  end
309
455
 
310
- spec = nil
311
-
312
- if exec_name
313
- spec = specs.find { |s| s.executables.include?(exec_name) }
314
- spec or raise Gem::Exception, "can't find executable #{exec_name}"
315
- unless spec.name == name
316
- warn "Bundler is using a binstub that was created for a different gem.\n" \
317
- "This is deprecated, in future versions you may need to `bundle binstub #{name}` " \
318
- "to work around a system/bundle conflict."
456
+ unless spec
457
+ message = "can't find executable #{exec_name} for gem #{gem_name}"
458
+ if !exec_name || spec_with_name.nil?
459
+ message += ". #{gem_name} is not currently included in the bundle, " \
460
+ "perhaps you meant to add it to your #{Bundler.default_gemfile.basename}?"
319
461
  end
320
- else
321
- spec = specs.find { |s| s.name == name }
322
- exec_name = spec.default_executable or raise Gem::Exception, "no default executable for #{spec.full_name}"
462
+ raise Gem::Exception, message
323
463
  end
324
464
 
465
+ raise Gem::Exception, "no default executable for #{spec.full_name}" unless exec_name ||= spec.default_executable
466
+
467
+ unless spec.name == gem_name
468
+ Bundler::SharedHelpers.major_deprecation 2,
469
+ "Bundler is using a binstub that was created for a different gem (#{spec.name}).\n" \
470
+ "You should run `bundle binstub #{gem_name}` " \
471
+ "to work around a system/bundle conflict."
472
+ end
473
+ spec
474
+ end
475
+
476
+ redefine_method(gem_class, :activate_bin_path) do |name, *args|
477
+ exec_name = args.first
478
+ return ENV["BUNDLE_BIN_PATH"] if exec_name == "bundle"
479
+
480
+ # Copy of Rubygems activate_bin_path impl
481
+ requirement = args.last
482
+ spec = find_spec_for_exe name, exec_name, [requirement]
483
+
484
+ gem_bin = File.join(spec.full_gem_path, spec.bindir, exec_name)
485
+ gem_from_path_bin = File.join(File.dirname(spec.loaded_from), spec.bindir, exec_name)
486
+ File.exist?(gem_bin) ? gem_bin : gem_from_path_bin
487
+ end
488
+
489
+ redefine_method(gem_class, :bin_path) do |name, *args|
490
+ exec_name = args.first
491
+ return ENV["BUNDLE_BIN_PATH"] if exec_name == "bundle"
492
+
493
+ spec = find_spec_for_exe(name, *args)
494
+ exec_name ||= spec.default_executable
495
+
325
496
  gem_bin = File.join(spec.full_gem_path, spec.bindir, exec_name)
326
497
  gem_from_path_bin = File.join(File.dirname(spec.loaded_from), spec.bindir, exec_name)
327
498
  File.exist?(gem_bin) ? gem_bin : gem_from_path_bin
@@ -331,25 +502,28 @@ module Bundler
331
502
  # Because Bundler has a static view of what specs are available,
332
503
  # we don't #refresh, so stub it out.
333
504
  def replace_refresh
334
- gem_class = (class << Gem ; self ; end)
335
- redefine_method(gem_class, :refresh) { }
505
+ gem_class = (class << Gem; self; end)
506
+ redefine_method(gem_class, :refresh) {}
336
507
  end
337
508
 
338
- # Replace or hook into Rubygems to provide a bundlerized view
509
+ # Replace or hook into RubyGems to provide a bundlerized view
339
510
  # of the world.
340
511
  def replace_entrypoints(specs)
341
- replace_gem(specs)
512
+ specs_by_name = specs.reduce({}) do |h, s|
513
+ h[s.name] = s
514
+ h
515
+ end
342
516
 
517
+ replace_gem(specs, specs_by_name)
343
518
  stub_rubygems(specs)
344
-
345
- replace_bin_path(specs)
519
+ replace_bin_path(specs, specs_by_name)
346
520
  replace_refresh
347
521
 
348
522
  Gem.clear_paths
349
523
  end
350
524
 
351
- # This backports the correct segment generation code from Rubygems 1.4+
352
- # by monkeypatching it into the method in Rubygems 1.3.6 and 1.3.7.
525
+ # This backports the correct segment generation code from RubyGems 1.4+
526
+ # by monkeypatching it into the method in RubyGems 1.3.6 and 1.3.7.
353
527
  def backport_segment_generation
354
528
  redefine_method(Gem::Version, :segments) do
355
529
  @segments ||= @version.scan(/[0-9]+|[a-z]+/i).map do |s|
@@ -360,15 +534,15 @@ module Bundler
360
534
 
361
535
  # This backport fixes the marshaling of @segments.
362
536
  def backport_yaml_initialize
363
- redefine_method(Gem::Version, :yaml_initialize) do |tag, map|
364
- @version = map['version']
537
+ redefine_method(Gem::Version, :yaml_initialize) do |_, map|
538
+ @version = map["version"]
365
539
  @segments = nil
366
540
  @hash = nil
367
541
  end
368
542
  end
369
543
 
370
544
  # This backports base_dir which replaces installation path
371
- # Rubygems 1.8+
545
+ # RubyGems 1.8+
372
546
  def backport_base_dir
373
547
  redefine_method(Gem::Specification, :base_dir) do
374
548
  return Gem.dir unless loaded_from
@@ -396,14 +570,50 @@ module Bundler
396
570
  end
397
571
  end
398
572
 
399
- def redefine_method(klass, method, &block)
400
- if klass.instance_methods(false).include?(method)
401
- klass.send(:remove_method, method)
573
+ def undo_replacements
574
+ @replaced_methods.each do |(sym, klass), method|
575
+ redefine_method(klass, sym, method)
576
+ end
577
+ if Binding.public_method_defined?(:source_location)
578
+ post_reset_hooks.reject! {|proc| proc.binding.source_location[0] == __FILE__ }
579
+ else
580
+ post_reset_hooks.reject! {|proc| proc.binding.eval("__FILE__") == __FILE__ }
581
+ end
582
+ @replaced_methods.clear
583
+ end
584
+
585
+ def redefine_method(klass, method, unbound_method = nil, &block)
586
+ visibility = method_visibility(klass, method)
587
+ begin
588
+ if (instance_method = klass.instance_method(method)) && method != :initialize
589
+ # doing this to ensure we also get private methods
590
+ klass.send(:remove_method, method)
591
+ end
592
+ rescue NameError
593
+ # method isn't defined
594
+ nil
595
+ end
596
+ @replaced_methods[[method, klass]] = instance_method
597
+ if unbound_method
598
+ klass.send(:define_method, method, unbound_method)
599
+ klass.send(visibility, method)
600
+ elsif block
601
+ klass.send(:define_method, method, &block)
602
+ klass.send(visibility, method)
603
+ end
604
+ end
605
+
606
+ def method_visibility(klass, method)
607
+ if klass.private_method_defined?(method)
608
+ :private
609
+ elsif klass.protected_method_defined?(method)
610
+ :protected
611
+ else
612
+ :public
402
613
  end
403
- klass.send(:define_method, method, &block)
404
614
  end
405
615
 
406
- # Rubygems 1.4 through 1.6
616
+ # RubyGems 1.4 through 1.6
407
617
  class Legacy < RubygemsIntegration
408
618
  def initialize
409
619
  super
@@ -414,13 +624,13 @@ module Bundler
414
624
  end
415
625
 
416
626
  def stub_rubygems(specs)
417
- # Rubygems versions lower than 1.7 use SourceIndex#from_gems_in
418
- source_index_class = (class << Gem::SourceIndex ; self ; end)
419
- source_index_class.send(:define_method, :from_gems_in) do |*args|
420
- source_index = Gem::SourceIndex.new
421
- source_index.spec_dirs = *args
422
- source_index.add_specs(*specs)
423
- source_index
627
+ # RubyGems versions lower than 1.7 use SourceIndex#from_gems_in
628
+ source_index_class = (class << Gem::SourceIndex; self; end)
629
+ redefine_method(source_index_class, :from_gems_in) do |*args|
630
+ Gem::SourceIndex.new.tap do |source_index|
631
+ source_index.spec_dirs = *args
632
+ source_index.add_specs(*specs)
633
+ end
424
634
  end
425
635
  end
426
636
 
@@ -431,9 +641,22 @@ module Bundler
431
641
  def find_name(name)
432
642
  Gem.source_index.find_name(name)
433
643
  end
644
+
645
+ def validate(spec)
646
+ # These versions of RubyGems always validate in "packaging" mode,
647
+ # which is too strict for the kinds of checks we care about. As a
648
+ # result, validation is disabled on versions of RubyGems below 1.7.
649
+ end
650
+
651
+ def post_reset_hooks
652
+ []
653
+ end
654
+
655
+ def reset
656
+ end
434
657
  end
435
658
 
436
- # Rubygems versions 1.3.6 and 1.3.7
659
+ # RubyGems versions 1.3.6 and 1.3.7
437
660
  class Ancient < Legacy
438
661
  def initialize
439
662
  super
@@ -441,21 +664,28 @@ module Bundler
441
664
  end
442
665
  end
443
666
 
444
- # Rubygems 1.7
667
+ # RubyGems 1.7
445
668
  class Transitional < Legacy
446
669
  def stub_rubygems(specs)
447
670
  stub_source_index(specs)
448
671
  end
672
+
673
+ def validate(spec)
674
+ # Missing summary is downgraded to a warning in later versions,
675
+ # so we set it to an empty string to prevent an exception here.
676
+ spec.summary ||= ""
677
+ RubygemsIntegration.instance_method(:validate).bind(self).call(spec)
678
+ end
449
679
  end
450
680
 
451
- # Rubygems 1.8.5-1.8.19
681
+ # RubyGems 1.8.5-1.8.19
452
682
  class Modern < RubygemsIntegration
453
683
  def stub_rubygems(specs)
454
684
  Gem::Specification.all = specs
455
685
 
456
- Gem.post_reset {
686
+ Gem.post_reset do
457
687
  Gem::Specification.all = specs
458
- }
688
+ end
459
689
 
460
690
  stub_source_index(specs)
461
691
  end
@@ -469,29 +699,30 @@ module Bundler
469
699
  end
470
700
  end
471
701
 
472
- # Rubygems 1.8.0 to 1.8.4
702
+ # RubyGems 1.8.0 to 1.8.4
473
703
  class AlmostModern < Modern
474
- # Rubygems [>= 1.8.0, < 1.8.5] has a bug that changes Gem.dir whenever
704
+ # RubyGems [>= 1.8.0, < 1.8.5] has a bug that changes Gem.dir whenever
475
705
  # you call Gem::Installer#install with an :install_dir set. We have to
476
706
  # change it back for our sudo mode to work.
477
707
  def preserve_paths
478
- old_dir, old_path = gem_dir, gem_path
708
+ old_dir = gem_dir
709
+ old_path = gem_path
479
710
  yield
480
711
  Gem.use_paths(old_dir, old_path)
481
712
  end
482
713
  end
483
714
 
484
- # Rubygems 1.8.20+
715
+ # RubyGems 1.8.20+
485
716
  class MoreModern < Modern
486
- # Rubygems 1.8.20 and adds the skip_validation parameter, so that's
717
+ # RubyGems 1.8.20 and adds the skip_validation parameter, so that's
487
718
  # when we start passing it through.
488
719
  def build(spec, skip_validation = false)
489
- require 'rubygems/builder'
720
+ require "rubygems/builder"
490
721
  Gem::Builder.new(spec).build(skip_validation)
491
722
  end
492
723
  end
493
724
 
494
- # Rubygems 2.0
725
+ # RubyGems 2.0
495
726
  class Future < RubygemsIntegration
496
727
  def stub_rubygems(specs)
497
728
  Gem::Specification.all = specs
@@ -499,6 +730,10 @@ module Bundler
499
730
  Gem.post_reset do
500
731
  Gem::Specification.all = specs
501
732
  end
733
+
734
+ redefine_method((class << Gem; self; end), :finish_resolve) do |*|
735
+ []
736
+ end
502
737
  end
503
738
 
504
739
  def all_specs
@@ -509,103 +744,155 @@ module Bundler
509
744
  Gem::Specification.find_all_by_name name
510
745
  end
511
746
 
512
- def fetch_specs(source, name)
747
+ def fetch_specs(source, remote, name)
513
748
  path = source + "#{name}.#{Gem.marshal_version}.gz"
514
- string = Gem::RemoteFetcher.fetcher.fetch_path(path)
749
+ fetcher = gem_remote_fetcher
750
+ fetcher.headers = { "X-Gemfile-Source" => remote.original_uri.to_s } if remote.original_uri
751
+ string = fetcher.fetch_path(path)
515
752
  Bundler.load_marshal(string)
516
753
  rescue Gem::RemoteFetcher::FetchError => e
517
754
  # it's okay for prerelease to fail
518
755
  raise e unless name == "prerelease_specs"
519
756
  end
520
757
 
521
- def fetch_all_remote_specs
522
- # Since SpecFetcher now returns NameTuples, we just fetch directly
523
- # and unmarshal the array ourselves.
524
- hash = {}
525
-
526
- Gem.sources.each do |source|
527
- source = URI.parse(source.to_s) unless source.is_a?(URI)
528
- hash[source] = fetch_specs(source, "specs")
758
+ def fetch_all_remote_specs(remote)
759
+ source = remote.uri.is_a?(URI) ? remote.uri : URI.parse(source.to_s)
529
760
 
530
- pres = fetch_specs(source, "prerelease_specs")
531
- hash[source].push(*pres) if pres && !pres.empty?
532
- end
761
+ specs = fetch_specs(source, remote, "specs")
762
+ pres = fetch_specs(source, remote, "prerelease_specs") || []
533
763
 
534
- hash
764
+ specs.concat(pres)
535
765
  end
536
766
 
537
767
  def download_gem(spec, uri, path)
538
- require 'resolv'
539
- uri = Bundler::Source.mirror_for(uri)
540
- proxy, dns = configuration[:http_proxy], Resolv::DNS.new
541
- fetcher = Gem::RemoteFetcher.new(proxy, dns)
542
- fetcher.download(spec, uri, path)
768
+ uri = Bundler.settings.mirror_for(uri)
769
+ fetcher = gem_remote_fetcher
770
+ fetcher.headers = { "X-Gemfile-Source" => spec.remote.original_uri.to_s } if spec.remote.original_uri
771
+ Bundler::Retry.new("download gem from #{uri}").attempts do
772
+ fetcher.download(spec, uri, path)
773
+ end
774
+ end
775
+
776
+ def gem_remote_fetcher
777
+ require "resolv"
778
+ proxy = configuration[:http_proxy]
779
+ dns = Resolv::DNS.new
780
+ Bundler::GemRemoteFetcher.new(proxy, dns)
543
781
  end
544
782
 
545
783
  def gem_from_path(path, policy = nil)
546
- require 'rubygems/package'
784
+ require "rubygems/package"
547
785
  p = Gem::Package.new(path)
548
786
  p.security_policy = policy if policy
549
- return p
787
+ p
550
788
  end
551
789
 
552
790
  def build(spec, skip_validation = false)
553
- require 'rubygems/package'
791
+ require "rubygems/package"
554
792
  Gem::Package.build(spec, skip_validation)
555
793
  end
556
794
 
557
795
  def repository_subdirectories
558
796
  Gem::REPOSITORY_SUBDIRECTORIES
559
797
  end
798
+
799
+ def install_with_build_args(args)
800
+ yield
801
+ end
802
+
803
+ def path_separator
804
+ Gem.path_separator
805
+ end
560
806
  end
561
807
 
808
+ # RubyGems 2.1.0
562
809
  class MoreFuture < Future
563
810
  def initialize
564
811
  super
565
812
  backport_ext_builder_monitor
566
813
  end
567
814
 
815
+ def all_specs
816
+ require "bundler/remote_specification"
817
+ Gem::Specification.stubs.map do |stub|
818
+ StubSpecification.from_stub(stub)
819
+ end
820
+ end
821
+
568
822
  def backport_ext_builder_monitor
569
- require 'rubygems/ext'
823
+ # So we can avoid requiring "rubygems/ext" in its entirety
824
+ Gem.module_eval <<-RB, __FILE__, __LINE__ + 1
825
+ module Ext
826
+ end
827
+ RB
828
+
829
+ require "rubygems/ext/builder"
570
830
 
571
831
  Gem::Ext::Builder.class_eval do
572
- if !const_defined?(:CHDIR_MONITOR)
573
- const_set(:CHDIR_MONITOR, Monitor.new)
832
+ unless const_defined?(:CHDIR_MONITOR)
833
+ const_set(:CHDIR_MONITOR, EXT_LOCK)
574
834
  end
575
835
 
576
- if const_defined?(:CHDIR_MUTEX)
577
- remove_const(:CHDIR_MUTEX)
578
- const_set(:CHDIR_MUTEX, const_get(:CHDIR_MONITOR))
579
- end
836
+ remove_const(:CHDIR_MUTEX) if const_defined?(:CHDIR_MUTEX)
837
+ const_set(:CHDIR_MUTEX, const_get(:CHDIR_MONITOR))
838
+ end
839
+ end
840
+
841
+ if Gem::Specification.respond_to?(:stubs_for)
842
+ def find_name(name)
843
+ Gem::Specification.stubs_for(name).map(&:to_spec)
844
+ end
845
+ else
846
+ def find_name(name)
847
+ Gem::Specification.stubs.find_all do |spec|
848
+ spec.name == name
849
+ end.map(&:to_spec)
580
850
  end
581
851
  end
582
852
 
583
- def ext_lock
584
- Gem::Ext::Builder::CHDIR_MONITOR
853
+ def use_gemdeps(gemfile)
854
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path(gemfile)
855
+ require "bundler/gemdeps"
856
+ runtime = Bundler.setup
857
+ Bundler.ui = nil
858
+ activated_spec_names = runtime.requested_specs.map(&:to_spec).sort_by(&:name)
859
+ [Gemdeps.new(runtime), activated_spec_names]
585
860
  end
586
- end
587
861
 
588
- end
862
+ if provides?(">= 2.5.2")
863
+ # RubyGems-generated binstubs call Kernel#gem
864
+ def binstubs_call_gem?
865
+ false
866
+ end
589
867
 
590
- if RubygemsIntegration.provides?(">= 2.1.0")
591
- @rubygems = RubygemsIntegration::MoreFuture.new
592
- elsif RubygemsIntegration.provides?(">= 1.99.99")
593
- @rubygems = RubygemsIntegration::Future.new
594
- elsif RubygemsIntegration.provides?('>= 1.8.20')
595
- @rubygems = RubygemsIntegration::MoreModern.new
596
- elsif RubygemsIntegration.provides?('>= 1.8.5')
597
- @rubygems = RubygemsIntegration::Modern.new
598
- elsif RubygemsIntegration.provides?('>= 1.8.0')
599
- @rubygems = RubygemsIntegration::AlmostModern.new
600
- elsif RubygemsIntegration.provides?('>= 1.7.0')
601
- @rubygems = RubygemsIntegration::Transitional.new
602
- elsif RubygemsIntegration.provides?('>= 1.4.0')
603
- @rubygems = RubygemsIntegration::Legacy.new
604
- else # Rubygems 1.3.6 and 1.3.7
605
- @rubygems = RubygemsIntegration::Ancient.new
868
+ # only 2.5.2+ has all of the stub methods we want to use, and since this
869
+ # is a performance optimization _only_,
870
+ # we'll restrict ourselves to the most
871
+ # recent RG versions instead of all versions that have stubs
872
+ def stubs_provide_full_functionality?
873
+ true
874
+ end
875
+ end
876
+ end
606
877
  end
607
878
 
608
- class << self
609
- attr_reader :rubygems
879
+ def self.rubygems
880
+ @rubygems ||= if RubygemsIntegration.provides?(">= 2.1.0")
881
+ RubygemsIntegration::MoreFuture.new
882
+ elsif RubygemsIntegration.provides?(">= 1.99.99")
883
+ RubygemsIntegration::Future.new
884
+ elsif RubygemsIntegration.provides?(">= 1.8.20")
885
+ RubygemsIntegration::MoreModern.new
886
+ elsif RubygemsIntegration.provides?(">= 1.8.5")
887
+ RubygemsIntegration::Modern.new
888
+ elsif RubygemsIntegration.provides?(">= 1.8.0")
889
+ RubygemsIntegration::AlmostModern.new
890
+ elsif RubygemsIntegration.provides?(">= 1.7.0")
891
+ RubygemsIntegration::Transitional.new
892
+ elsif RubygemsIntegration.provides?(">= 1.4.0")
893
+ RubygemsIntegration::Legacy.new
894
+ else # RubyGems 1.3.6 and 1.3.7
895
+ RubygemsIntegration::Ancient.new
896
+ end
610
897
  end
611
898
  end