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,95 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bundler
4
+ class LockfileGenerator
5
+ attr_reader :definition
6
+ attr_reader :out
7
+
8
+ # @private
9
+ def initialize(definition)
10
+ @definition = definition
11
+ @out = String.new
12
+ end
13
+
14
+ def self.generate(definition)
15
+ new(definition).generate!
16
+ end
17
+
18
+ def generate!
19
+ add_sources
20
+ add_platforms
21
+ add_dependencies
22
+ add_locked_ruby_version
23
+ add_bundled_with
24
+
25
+ out
26
+ end
27
+
28
+ private
29
+
30
+ def add_sources
31
+ definition.send(:sources).lock_sources.each_with_index do |source, idx|
32
+ out << "\n" unless idx.zero?
33
+
34
+ # Add the source header
35
+ out << source.to_lock
36
+
37
+ # Find all specs for this source
38
+ specs = definition.resolve.select {|s| source.can_lock?(s) }
39
+ add_specs(specs)
40
+ end
41
+ end
42
+
43
+ def add_specs(specs)
44
+ # This needs to be sorted by full name so that
45
+ # gems with the same name, but different platform
46
+ # are ordered consistently
47
+ specs.sort_by(&:full_name).each do |spec|
48
+ next if spec.name == "bundler".freeze
49
+ out << spec.to_lock
50
+ end
51
+ end
52
+
53
+ def add_platforms
54
+ add_section("PLATFORMS", definition.platforms)
55
+ end
56
+
57
+ def add_dependencies
58
+ out << "\nDEPENDENCIES\n"
59
+
60
+ handled = []
61
+ definition.dependencies.sort_by(&:to_s).each do |dep|
62
+ next if handled.include?(dep.name)
63
+ out << dep.to_lock
64
+ handled << dep.name
65
+ end
66
+ end
67
+
68
+ def add_locked_ruby_version
69
+ return unless locked_ruby_version = definition.locked_ruby_version
70
+ add_section("RUBY VERSION", locked_ruby_version.to_s)
71
+ end
72
+
73
+ def add_bundled_with
74
+ add_section("BUNDLED WITH", definition.locked_bundler_version.to_s)
75
+ end
76
+
77
+ def add_section(name, value)
78
+ out << "\n#{name}\n"
79
+ case value
80
+ when Array
81
+ value.map(&:to_s).sort.each do |val|
82
+ out << " #{val}\n"
83
+ end
84
+ when Hash
85
+ value.to_a.sort_by {|k, _| k.to_s }.each do |key, val|
86
+ out << " #{key}: #{val}\n"
87
+ end
88
+ when String
89
+ out << " #{value}\n"
90
+ else
91
+ raise ArgumentError, "#{value.inspect} can't be serialized in a lockfile"
92
+ end
93
+ end
94
+ end
95
+ end
@@ -1,4 +1,4 @@
1
- require "strscan"
1
+ # frozen_string_literal: true
2
2
 
3
3
  # Some versions of the Bundler 1.1 RC series introduced corrupted
4
4
  # lockfiles. There were two major problems:
@@ -12,60 +12,121 @@ require "strscan"
12
12
 
13
13
  module Bundler
14
14
  class LockfileParser
15
- attr_reader :sources, :dependencies, :specs, :platforms
16
-
17
- DEPENDENCIES = "DEPENDENCIES"
18
- PLATFORMS = "PLATFORMS"
19
- GIT = "GIT"
20
- GEM = "GEM"
21
- PATH = "PATH"
22
- SPECS = " specs:"
15
+ attr_reader :sources, :dependencies, :specs, :platforms, :bundler_version, :ruby_version
16
+
17
+ BUNDLED = "BUNDLED WITH".freeze
18
+ DEPENDENCIES = "DEPENDENCIES".freeze
19
+ PLATFORMS = "PLATFORMS".freeze
20
+ RUBY = "RUBY VERSION".freeze
21
+ GIT = "GIT".freeze
22
+ GEM = "GEM".freeze
23
+ PATH = "PATH".freeze
24
+ PLUGIN = "PLUGIN SOURCE".freeze
25
+ SPECS = " specs:".freeze
23
26
  OPTIONS = /^ ([a-z]+): (.*)$/i
27
+ SOURCE = [GIT, GEM, PATH, PLUGIN].freeze
28
+
29
+ SECTIONS_BY_VERSION_INTRODUCED = {
30
+ # The strings have to be dup'ed for old RG on Ruby 2.3+
31
+ # TODO: remove dup in Bundler 2.0
32
+ Gem::Version.create("1.0".dup) => [DEPENDENCIES, PLATFORMS, GIT, GEM, PATH].freeze,
33
+ Gem::Version.create("1.10".dup) => [BUNDLED].freeze,
34
+ Gem::Version.create("1.12".dup) => [RUBY].freeze,
35
+ Gem::Version.create("1.13".dup) => [PLUGIN].freeze,
36
+ }.freeze
37
+
38
+ KNOWN_SECTIONS = SECTIONS_BY_VERSION_INTRODUCED.values.flatten.freeze
39
+
40
+ ENVIRONMENT_VERSION_SECTIONS = [BUNDLED, RUBY].freeze
41
+
42
+ def self.sections_in_lockfile(lockfile_contents)
43
+ lockfile_contents.scan(/^\w[\w ]*$/).uniq
44
+ end
45
+
46
+ def self.unknown_sections_in_lockfile(lockfile_contents)
47
+ sections_in_lockfile(lockfile_contents) - KNOWN_SECTIONS
48
+ end
49
+
50
+ def self.sections_to_ignore(base_version = nil)
51
+ base_version &&= base_version.release
52
+ base_version ||= Gem::Version.create("1.0".dup)
53
+ attributes = []
54
+ SECTIONS_BY_VERSION_INTRODUCED.each do |version, introduced|
55
+ next if version <= base_version
56
+ attributes += introduced
57
+ end
58
+ attributes
59
+ end
24
60
 
25
61
  def initialize(lockfile)
26
62
  @platforms = []
27
63
  @sources = []
28
- @dependencies = []
29
- @state = :source
64
+ @dependencies = {}
65
+ @state = nil
30
66
  @specs = {}
31
67
 
32
68
  @rubygems_aggregate = Source::Rubygems.new
33
69
 
34
70
  if lockfile.match(/<<<<<<<|=======|>>>>>>>|\|\|\|\|\|\|\|/)
35
- raise LockfileError, "Your Gemfile.lock contains merge conflicts.\n" \
36
- "Run `git checkout HEAD -- Gemfile.lock` first to get a clean lock."
71
+ raise LockfileError, "Your #{Bundler.default_lockfile.relative_path_from(SharedHelpers.pwd)} contains merge conflicts.\n" \
72
+ "Run `git checkout HEAD -- #{Bundler.default_lockfile.relative_path_from(SharedHelpers.pwd)}` first to get a clean lock."
37
73
  end
38
74
 
39
75
  lockfile.split(/(?:\r?\n)+/).each do |line|
40
- if line == DEPENDENCIES
76
+ if SOURCE.include?(line)
77
+ @state = :source
78
+ parse_source(line)
79
+ elsif line == DEPENDENCIES
41
80
  @state = :dependency
42
81
  elsif line == PLATFORMS
43
82
  @state = :platform
44
- else
83
+ elsif line == RUBY
84
+ @state = :ruby
85
+ elsif line == BUNDLED
86
+ @state = :bundled_with
87
+ elsif line =~ /^[^\s]/
88
+ @state = nil
89
+ elsif @state
45
90
  send("parse_#{@state}", line)
46
91
  end
47
92
  end
48
- @sources << @rubygems_aggregate
49
- @specs = @specs.values
93
+ @sources << @rubygems_aggregate unless Bundler.feature_flag.lockfile_uses_separate_rubygems_sources?
94
+ @specs = @specs.values.sort_by(&:identifier)
95
+ warn_for_outdated_bundler_version
50
96
  rescue ArgumentError => e
51
97
  Bundler.ui.debug(e)
52
- raise LockfileError, "Your lockfile is unreadable. Run `rm Gemfile.lock` " \
98
+ raise LockfileError, "Your lockfile is unreadable. Run `rm #{Bundler.default_lockfile.relative_path_from(SharedHelpers.pwd)}` " \
53
99
  "and then `bundle install` to generate a new lockfile."
54
100
  end
55
101
 
102
+ def warn_for_outdated_bundler_version
103
+ return unless bundler_version
104
+ prerelease_text = bundler_version.prerelease? ? " --pre" : ""
105
+ current_version = Gem::Version.create(Bundler::VERSION)
106
+ case current_version.segments.first <=> bundler_version.segments.first
107
+ when -1
108
+ raise LockfileError, "You must use Bundler #{bundler_version.segments.first} or greater with this lockfile."
109
+ when 0
110
+ if current_version < bundler_version
111
+ Bundler.ui.warn "Warning: the running version of Bundler (#{current_version}) is older " \
112
+ "than the version that created the lockfile (#{bundler_version}). We suggest you " \
113
+ "upgrade to the latest version of Bundler by running `gem " \
114
+ "install bundler#{prerelease_text}`.\n"
115
+ end
116
+ end
117
+ end
118
+
56
119
  private
57
120
 
58
121
  TYPES = {
59
- GIT => Bundler::Source::Git,
60
- GEM => Bundler::Source::Rubygems,
61
- PATH => Bundler::Source::Path,
62
- }
122
+ GIT => Bundler::Source::Git,
123
+ GEM => Bundler::Source::Rubygems,
124
+ PATH => Bundler::Source::Path,
125
+ PLUGIN => Bundler::Plugin,
126
+ }.freeze
63
127
 
64
128
  def parse_source(line)
65
129
  case line
66
- when GIT, GEM, PATH
67
- @current_source = nil
68
- @opts, @type = {}, line
69
130
  when SPECS
70
131
  case @type
71
132
  when PATH
@@ -75,15 +136,24 @@ module Bundler
75
136
  @current_source = TYPES[@type].from_lock(@opts)
76
137
  # Strip out duplicate GIT sections
77
138
  if @sources.include?(@current_source)
78
- @current_source = @sources.find { |s| s == @current_source }
139
+ @current_source = @sources.find {|s| s == @current_source }
79
140
  else
80
141
  @sources << @current_source
81
142
  end
82
143
  when GEM
83
- Array(@opts["remote"]).each do |url|
84
- @rubygems_aggregate.add_remote(url)
144
+ if Bundler.feature_flag.lockfile_uses_separate_rubygems_sources?
145
+ @opts["remotes"] = @opts.delete("remote")
146
+ @current_source = TYPES[@type].from_lock(@opts)
147
+ @sources << @current_source
148
+ else
149
+ Array(@opts["remote"]).each do |url|
150
+ @rubygems_aggregate.add_remote(url)
151
+ end
152
+ @current_source = @rubygems_aggregate
85
153
  end
86
- @current_source = @rubygems_aggregate
154
+ when PLUGIN
155
+ @current_source = Plugin.source_from_lock(@opts)
156
+ @sources << @current_source
87
157
  end
88
158
  when OPTIONS
89
159
  value = $2
@@ -98,64 +168,89 @@ module Bundler
98
168
  else
99
169
  @opts[key] = value
100
170
  end
171
+ when *SOURCE
172
+ @current_source = nil
173
+ @opts = {}
174
+ @type = line
101
175
  else
102
176
  parse_spec(line)
103
177
  end
104
178
  end
105
179
 
106
- NAME_VERSION = '(?! )(.*?)(?: \(([^-]*)(?:-(.*))?\))?'
107
- NAME_VERSION_2 = %r{^ {2}#{NAME_VERSION}(!)?$}
108
- NAME_VERSION_4 = %r{^ {4}#{NAME_VERSION}$}
109
- NAME_VERSION_6 = %r{^ {6}#{NAME_VERSION}$}
180
+ space = / /
181
+ NAME_VERSION = /
182
+ ^(#{space}{2}|#{space}{4}|#{space}{6})(?!#{space}) # Exactly 2, 4, or 6 spaces at the start of the line
183
+ (.*?) # Name
184
+ (?:#{space}\(([^-]*) # Space, followed by version
185
+ (?:-(.*))?\))? # Optional platform
186
+ (!)? # Optional pinned marker
187
+ $ # Line end
188
+ /xo
110
189
 
111
190
  def parse_dependency(line)
112
- if line =~ NAME_VERSION_2
113
- name, version, pinned = $1, $2, $4
114
- version = version.split(",").map { |d| d.strip } if version
115
-
116
- dep = Bundler::Dependency.new(name, version)
117
-
118
- if pinned && dep.name != 'bundler'
119
- spec = @specs.find {|k, v| v.name == dep.name }
120
- dep.source = spec.last.source if spec
121
-
122
- # Path sources need to know what the default name / version
123
- # to use in the case that there are no gemspecs present. A fake
124
- # gemspec is created based on the version set on the dependency
125
- # TODO: Use the version from the spec instead of from the dependency
126
- if version && version.size == 1 && version.first =~ /^\s*= (.+)\s*$/ && dep.source.is_a?(Bundler::Source::Path)
127
- dep.source.name = name
128
- dep.source.version = $1
129
- end
130
- end
191
+ return unless line =~ NAME_VERSION
192
+ spaces = $1
193
+ return unless spaces.size == 2
194
+ name = $2
195
+ version = $3
196
+ pinned = $5
197
+
198
+ version = version.split(",").map(&:strip) if version
199
+
200
+ dep = Bundler::Dependency.new(name, version)
131
201
 
132
- @dependencies << dep
202
+ if pinned && dep.name != "bundler"
203
+ spec = @specs.find {|_, v| v.name == dep.name }
204
+ dep.source = spec.last.source if spec
205
+
206
+ # Path sources need to know what the default name / version
207
+ # to use in the case that there are no gemspecs present. A fake
208
+ # gemspec is created based on the version set on the dependency
209
+ # TODO: Use the version from the spec instead of from the dependency
210
+ if version && version.size == 1 && version.first =~ /^\s*= (.+)\s*$/ && dep.source.is_a?(Bundler::Source::Path)
211
+ dep.source.name = name
212
+ dep.source.version = $1
213
+ end
133
214
  end
215
+
216
+ @dependencies[dep.name] = dep
134
217
  end
135
218
 
136
219
  def parse_spec(line)
137
- if line =~ NAME_VERSION_4
138
- name, version = $1, Gem::Version.new($2)
139
- platform = $3 ? Gem::Platform.new($3) : Gem::Platform::RUBY
220
+ return unless line =~ NAME_VERSION
221
+ spaces = $1
222
+ name = $2
223
+ version = $3
224
+ platform = $4
225
+
226
+ if spaces.size == 4
227
+ version = Gem::Version.new(version)
228
+ platform = platform ? Gem::Platform.new(platform) : Gem::Platform::RUBY
140
229
  @current_spec = LazySpecification.new(name, version, platform)
141
230
  @current_spec.source = @current_source
142
231
 
143
232
  # Avoid introducing multiple copies of the same spec (caused by
144
233
  # duplicate GIT sections)
145
234
  @specs[@current_spec.identifier] ||= @current_spec
146
- elsif line =~ NAME_VERSION_6
147
- name, version = $1, $2
148
- version = version.split(',').map { |d| d.strip } if version
235
+ elsif spaces.size == 6
236
+ version = version.split(",").map(&:strip) if version
149
237
  dep = Gem::Dependency.new(name, version)
150
238
  @current_spec.dependencies << dep
151
239
  end
152
240
  end
153
241
 
154
242
  def parse_platform(line)
155
- if line =~ /^ (.*)$/
156
- @platforms << Gem::Platform.new($1)
157
- end
243
+ @platforms << Gem::Platform.new($1) if line =~ /^ (.*)$/
244
+ end
245
+
246
+ def parse_bundled_with(line)
247
+ line = line.strip
248
+ return unless Gem::Version.correct?(line)
249
+ @bundler_version = Gem::Version.create(line)
158
250
  end
159
251
 
252
+ def parse_ruby(line)
253
+ @ruby_version = line.strip
254
+ end
160
255
  end
161
256
  end
@@ -1,13 +1,24 @@
1
- require 'bundler/gem_helpers'
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_helpers"
2
4
 
3
5
  module Bundler
4
6
  module MatchPlatform
5
7
  include GemHelpers
6
8
 
7
9
  def match_platform(p)
8
- Gem::Platform::RUBY == platform or
9
- platform.nil? or p == platform or
10
- generic(Gem::Platform.new(platform)) == p
10
+ MatchPlatform.platforms_match?(platform, p)
11
+ end
12
+
13
+ def self.platforms_match?(gemspec_platform, local_platform)
14
+ return true if gemspec_platform.nil?
15
+ return true if Gem::Platform::RUBY == gemspec_platform
16
+ return true if local_platform == gemspec_platform
17
+ gemspec_platform = Gem::Platform.new(gemspec_platform)
18
+ return true if GemHelpers.generic(gemspec_platform) === local_platform
19
+ return true if gemspec_platform === local_platform
20
+
21
+ false
11
22
  end
12
23
  end
13
24
  end
@@ -0,0 +1,223 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "socket"
4
+
5
+ module Bundler
6
+ class Settings
7
+ # Class used to build the mirror set and then find a mirror for a given URI
8
+ #
9
+ # @param prober [Prober object, nil] by default a TCPSocketProbe, this object
10
+ # will be used to probe the mirror address to validate that the mirror replies.
11
+ class Mirrors
12
+ def initialize(prober = nil)
13
+ @all = Mirror.new
14
+ @prober = prober || TCPSocketProbe.new
15
+ @mirrors = {}
16
+ end
17
+
18
+ # Returns a mirror for the given uri.
19
+ #
20
+ # Depending on the uri having a valid mirror or not, it may be a
21
+ # mirror that points to the provided uri
22
+ def for(uri)
23
+ if @all.validate!(@prober).valid?
24
+ @all
25
+ else
26
+ fetch_valid_mirror_for(Settings.normalize_uri(uri))
27
+ end
28
+ end
29
+
30
+ def each
31
+ @mirrors.each do |k, v|
32
+ yield k, v.uri.to_s
33
+ end
34
+ end
35
+
36
+ def parse(key, value)
37
+ config = MirrorConfig.new(key, value)
38
+ mirror = if config.all?
39
+ @all
40
+ else
41
+ @mirrors[config.uri] ||= Mirror.new
42
+ end
43
+ config.update_mirror(mirror)
44
+ end
45
+
46
+ private
47
+
48
+ def fetch_valid_mirror_for(uri)
49
+ downcased = uri.to_s.downcase
50
+ mirror = @mirrors[downcased] || @mirrors[URI(downcased).host] || Mirror.new(uri)
51
+ mirror.validate!(@prober)
52
+ mirror = Mirror.new(uri) unless mirror.valid?
53
+ mirror
54
+ end
55
+ end
56
+
57
+ # A mirror
58
+ #
59
+ # Contains both the uri that should be used as a mirror and the
60
+ # fallback timeout which will be used for probing if the mirror
61
+ # replies on time or not.
62
+ class Mirror
63
+ DEFAULT_FALLBACK_TIMEOUT = 0.1
64
+
65
+ attr_reader :uri, :fallback_timeout
66
+
67
+ def initialize(uri = nil, fallback_timeout = 0)
68
+ self.uri = uri
69
+ self.fallback_timeout = fallback_timeout
70
+ @valid = nil
71
+ end
72
+
73
+ def uri=(uri)
74
+ @uri = if uri.nil?
75
+ nil
76
+ else
77
+ URI(uri.to_s)
78
+ end
79
+ @valid = nil
80
+ end
81
+
82
+ def fallback_timeout=(timeout)
83
+ case timeout
84
+ when true, "true"
85
+ @fallback_timeout = DEFAULT_FALLBACK_TIMEOUT
86
+ when false, "false"
87
+ @fallback_timeout = 0
88
+ else
89
+ @fallback_timeout = timeout.to_i
90
+ end
91
+ @valid = nil
92
+ end
93
+
94
+ def ==(other)
95
+ !other.nil? && uri == other.uri && fallback_timeout == other.fallback_timeout
96
+ end
97
+
98
+ def valid?
99
+ return false if @uri.nil?
100
+ return @valid unless @valid.nil?
101
+ false
102
+ end
103
+
104
+ def validate!(probe = nil)
105
+ @valid = false if uri.nil?
106
+ if @valid.nil?
107
+ @valid = fallback_timeout == 0 || (probe || TCPSocketProbe.new).replies?(self)
108
+ end
109
+ self
110
+ end
111
+ end
112
+
113
+ # Class used to parse one configuration line
114
+ #
115
+ # Gets the configuration line and the value.
116
+ # This object provides a `update_mirror` method
117
+ # used to setup the given mirror value.
118
+ class MirrorConfig
119
+ attr_accessor :uri, :value
120
+
121
+ def initialize(config_line, value)
122
+ uri, fallback =
123
+ config_line.match(%r{\Amirror\.(all|.+?)(\.fallback_timeout)?\/?\z}).captures
124
+ @fallback = !fallback.nil?
125
+ @all = false
126
+ if uri == "all"
127
+ @all = true
128
+ else
129
+ @uri = URI(uri).absolute? ? Settings.normalize_uri(uri) : uri
130
+ end
131
+ @value = value
132
+ end
133
+
134
+ def all?
135
+ @all
136
+ end
137
+
138
+ def update_mirror(mirror)
139
+ if @fallback
140
+ mirror.fallback_timeout = @value
141
+ else
142
+ mirror.uri = Settings.normalize_uri(@value)
143
+ end
144
+ end
145
+ end
146
+
147
+ # Class used for probing TCP availability for a given mirror.
148
+ class TCPSocketProbe
149
+ def replies?(mirror)
150
+ MirrorSockets.new(mirror).any? do |socket, address, timeout|
151
+ begin
152
+ socket.connect_nonblock(address)
153
+ rescue Errno::EINPROGRESS
154
+ wait_for_writtable_socket(socket, address, timeout)
155
+ rescue RuntimeError # Connection failed somehow, again
156
+ false
157
+ end
158
+ end
159
+ end
160
+
161
+ private
162
+
163
+ def wait_for_writtable_socket(socket, address, timeout)
164
+ if IO.select(nil, [socket], nil, timeout)
165
+ probe_writtable_socket(socket, address)
166
+ else # TCP Handshake timed out, or there is something dropping packets
167
+ false
168
+ end
169
+ end
170
+
171
+ def probe_writtable_socket(socket, address)
172
+ socket.connect_nonblock(address)
173
+ rescue Errno::EISCONN
174
+ true
175
+ rescue StandardError # Connection failed
176
+ false
177
+ end
178
+ end
179
+ end
180
+
181
+ # Class used to build the list of sockets that correspond to
182
+ # a given mirror.
183
+ #
184
+ # One mirror may correspond to many different addresses, both
185
+ # because of it having many dns entries or because
186
+ # the network interface is both ipv4 and ipv5
187
+ class MirrorSockets
188
+ def initialize(mirror)
189
+ @timeout = mirror.fallback_timeout
190
+ @addresses = Socket.getaddrinfo(mirror.uri.host, mirror.uri.port).map do |address|
191
+ SocketAddress.new(address[0], address[3], address[1])
192
+ end
193
+ end
194
+
195
+ def any?
196
+ @addresses.any? do |address|
197
+ socket = Socket.new(Socket.const_get(address.type), Socket::SOCK_STREAM, 0)
198
+ socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
199
+ value = yield socket, address.to_socket_address, @timeout
200
+ socket.close unless socket.closed?
201
+ value
202
+ end
203
+ end
204
+ end
205
+
206
+ # Socket address builder.
207
+ #
208
+ # Given a socket type, a host and a port,
209
+ # provides a method to build sockaddr string
210
+ class SocketAddress
211
+ attr_reader :type, :host, :port
212
+
213
+ def initialize(type, host, port)
214
+ @type = type
215
+ @host = host
216
+ @port = port
217
+ end
218
+
219
+ def to_socket_address
220
+ Socket.pack_sockaddr_in(@port, @host)
221
+ end
222
+ end
223
+ end