bundler 2.0.2

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 (303) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +3111 -0
  3. data/LICENSE.md +23 -0
  4. data/README.md +63 -0
  5. data/bundler.gemspec +65 -0
  6. data/exe/bundle +31 -0
  7. data/exe/bundle_ruby +60 -0
  8. data/exe/bundler +4 -0
  9. data/lib/bundler.rb +567 -0
  10. data/lib/bundler/build_metadata.rb +53 -0
  11. data/lib/bundler/capistrano.rb +22 -0
  12. data/lib/bundler/cli.rb +792 -0
  13. data/lib/bundler/cli/add.rb +35 -0
  14. data/lib/bundler/cli/binstubs.rb +49 -0
  15. data/lib/bundler/cli/cache.rb +36 -0
  16. data/lib/bundler/cli/check.rb +38 -0
  17. data/lib/bundler/cli/clean.rb +25 -0
  18. data/lib/bundler/cli/common.rb +102 -0
  19. data/lib/bundler/cli/config.rb +119 -0
  20. data/lib/bundler/cli/console.rb +43 -0
  21. data/lib/bundler/cli/doctor.rb +140 -0
  22. data/lib/bundler/cli/exec.rb +105 -0
  23. data/lib/bundler/cli/gem.rb +252 -0
  24. data/lib/bundler/cli/info.rb +50 -0
  25. data/lib/bundler/cli/init.rb +47 -0
  26. data/lib/bundler/cli/inject.rb +60 -0
  27. data/lib/bundler/cli/install.rb +218 -0
  28. data/lib/bundler/cli/issue.rb +40 -0
  29. data/lib/bundler/cli/list.rb +58 -0
  30. data/lib/bundler/cli/lock.rb +63 -0
  31. data/lib/bundler/cli/open.rb +26 -0
  32. data/lib/bundler/cli/outdated.rb +266 -0
  33. data/lib/bundler/cli/package.rb +49 -0
  34. data/lib/bundler/cli/platform.rb +46 -0
  35. data/lib/bundler/cli/plugin.rb +24 -0
  36. data/lib/bundler/cli/pristine.rb +47 -0
  37. data/lib/bundler/cli/remove.rb +18 -0
  38. data/lib/bundler/cli/show.rb +75 -0
  39. data/lib/bundler/cli/update.rb +91 -0
  40. data/lib/bundler/cli/viz.rb +31 -0
  41. data/lib/bundler/compact_index_client.rb +109 -0
  42. data/lib/bundler/compact_index_client/cache.rb +118 -0
  43. data/lib/bundler/compact_index_client/updater.rb +116 -0
  44. data/lib/bundler/compatibility_guard.rb +13 -0
  45. data/lib/bundler/constants.rb +7 -0
  46. data/lib/bundler/current_ruby.rb +94 -0
  47. data/lib/bundler/definition.rb +995 -0
  48. data/lib/bundler/dep_proxy.rb +48 -0
  49. data/lib/bundler/dependency.rb +139 -0
  50. data/lib/bundler/deployment.rb +69 -0
  51. data/lib/bundler/deprecate.rb +44 -0
  52. data/lib/bundler/dsl.rb +615 -0
  53. data/lib/bundler/endpoint_specification.rb +141 -0
  54. data/lib/bundler/env.rb +149 -0
  55. data/lib/bundler/environment_preserver.rb +59 -0
  56. data/lib/bundler/errors.rb +158 -0
  57. data/lib/bundler/feature_flag.rb +75 -0
  58. data/lib/bundler/fetcher.rb +312 -0
  59. data/lib/bundler/fetcher/base.rb +52 -0
  60. data/lib/bundler/fetcher/compact_index.rb +126 -0
  61. data/lib/bundler/fetcher/dependency.rb +82 -0
  62. data/lib/bundler/fetcher/downloader.rb +84 -0
  63. data/lib/bundler/fetcher/index.rb +52 -0
  64. data/lib/bundler/friendly_errors.rb +131 -0
  65. data/lib/bundler/gem_helper.rb +217 -0
  66. data/lib/bundler/gem_helpers.rb +101 -0
  67. data/lib/bundler/gem_remote_fetcher.rb +43 -0
  68. data/lib/bundler/gem_tasks.rb +7 -0
  69. data/lib/bundler/gem_version_promoter.rb +190 -0
  70. data/lib/bundler/gemdeps.rb +29 -0
  71. data/lib/bundler/graph.rb +152 -0
  72. data/lib/bundler/index.rb +213 -0
  73. data/lib/bundler/injector.rb +253 -0
  74. data/lib/bundler/inline.rb +74 -0
  75. data/lib/bundler/installer.rb +318 -0
  76. data/lib/bundler/installer/gem_installer.rb +85 -0
  77. data/lib/bundler/installer/parallel_installer.rb +229 -0
  78. data/lib/bundler/installer/standalone.rb +53 -0
  79. data/lib/bundler/lazy_specification.rb +123 -0
  80. data/lib/bundler/lockfile_generator.rb +95 -0
  81. data/lib/bundler/lockfile_parser.rb +256 -0
  82. data/lib/bundler/match_platform.rb +24 -0
  83. data/lib/bundler/mirror.rb +223 -0
  84. data/lib/bundler/plugin.rb +294 -0
  85. data/lib/bundler/plugin/api.rb +81 -0
  86. data/lib/bundler/plugin/api/source.rb +306 -0
  87. data/lib/bundler/plugin/dsl.rb +53 -0
  88. data/lib/bundler/plugin/events.rb +61 -0
  89. data/lib/bundler/plugin/index.rb +165 -0
  90. data/lib/bundler/plugin/installer.rb +96 -0
  91. data/lib/bundler/plugin/installer/git.rb +38 -0
  92. data/lib/bundler/plugin/installer/rubygems.rb +27 -0
  93. data/lib/bundler/plugin/source_list.rb +27 -0
  94. data/lib/bundler/process_lock.rb +24 -0
  95. data/lib/bundler/psyched_yaml.rb +37 -0
  96. data/lib/bundler/remote_specification.rb +114 -0
  97. data/lib/bundler/resolver.rb +373 -0
  98. data/lib/bundler/resolver/spec_group.rb +106 -0
  99. data/lib/bundler/retry.rb +66 -0
  100. data/lib/bundler/ruby_dsl.rb +18 -0
  101. data/lib/bundler/ruby_version.rb +152 -0
  102. data/lib/bundler/rubygems_ext.rb +209 -0
  103. data/lib/bundler/rubygems_gem_installer.rb +99 -0
  104. data/lib/bundler/rubygems_integration.rb +915 -0
  105. data/lib/bundler/runtime.rb +322 -0
  106. data/lib/bundler/settings.rb +464 -0
  107. data/lib/bundler/settings/validator.rb +102 -0
  108. data/lib/bundler/setup.rb +28 -0
  109. data/lib/bundler/shared_helpers.rb +386 -0
  110. data/lib/bundler/similarity_detector.rb +63 -0
  111. data/lib/bundler/source.rb +94 -0
  112. data/lib/bundler/source/gemspec.rb +18 -0
  113. data/lib/bundler/source/git.rb +329 -0
  114. data/lib/bundler/source/git/git_proxy.rb +262 -0
  115. data/lib/bundler/source/metadata.rb +62 -0
  116. data/lib/bundler/source/path.rb +249 -0
  117. data/lib/bundler/source/path/installer.rb +74 -0
  118. data/lib/bundler/source/rubygems.rb +539 -0
  119. data/lib/bundler/source/rubygems/remote.rb +69 -0
  120. data/lib/bundler/source_list.rb +186 -0
  121. data/lib/bundler/spec_set.rb +208 -0
  122. data/lib/bundler/ssl_certs/.document +1 -0
  123. data/lib/bundler/ssl_certs/certificate_manager.rb +66 -0
  124. data/lib/bundler/ssl_certs/index.rubygems.org/GlobalSignRootCA.pem +21 -0
  125. data/lib/bundler/ssl_certs/rubygems.global.ssl.fastly.net/DigiCertHighAssuranceEVRootCA.pem +23 -0
  126. data/lib/bundler/ssl_certs/rubygems.org/AddTrustExternalCARoot.pem +25 -0
  127. data/lib/bundler/stub_specification.rb +108 -0
  128. data/lib/bundler/templates/.document +1 -0
  129. data/lib/bundler/templates/Executable +29 -0
  130. data/lib/bundler/templates/Executable.bundler +105 -0
  131. data/lib/bundler/templates/Executable.standalone +14 -0
  132. data/lib/bundler/templates/Gemfile +7 -0
  133. data/lib/bundler/templates/gems.rb +8 -0
  134. data/lib/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt +74 -0
  135. data/lib/bundler/templates/newgem/Gemfile.tt +4 -0
  136. data/lib/bundler/templates/newgem/LICENSE.txt.tt +21 -0
  137. data/lib/bundler/templates/newgem/README.md.tt +47 -0
  138. data/lib/bundler/templates/newgem/Rakefile.tt +29 -0
  139. data/lib/bundler/templates/newgem/bin/console.tt +14 -0
  140. data/lib/bundler/templates/newgem/bin/setup.tt +8 -0
  141. data/lib/bundler/templates/newgem/exe/newgem.tt +3 -0
  142. data/lib/bundler/templates/newgem/ext/newgem/extconf.rb.tt +3 -0
  143. data/lib/bundler/templates/newgem/ext/newgem/newgem.c.tt +9 -0
  144. data/lib/bundler/templates/newgem/ext/newgem/newgem.h.tt +6 -0
  145. data/lib/bundler/templates/newgem/gitignore.tt +20 -0
  146. data/lib/bundler/templates/newgem/lib/newgem.rb.tt +13 -0
  147. data/lib/bundler/templates/newgem/lib/newgem/version.rb.tt +7 -0
  148. data/lib/bundler/templates/newgem/newgem.gemspec.tt +50 -0
  149. data/lib/bundler/templates/newgem/rspec.tt +3 -0
  150. data/lib/bundler/templates/newgem/spec/newgem_spec.rb.tt +9 -0
  151. data/lib/bundler/templates/newgem/spec/spec_helper.rb.tt +14 -0
  152. data/lib/bundler/templates/newgem/test/newgem_test.rb.tt +11 -0
  153. data/lib/bundler/templates/newgem/test/test_helper.rb.tt +8 -0
  154. data/lib/bundler/templates/newgem/travis.yml.tt +7 -0
  155. data/lib/bundler/ui.rb +9 -0
  156. data/lib/bundler/ui/rg_proxy.rb +19 -0
  157. data/lib/bundler/ui/shell.rb +146 -0
  158. data/lib/bundler/ui/silent.rb +69 -0
  159. data/lib/bundler/uri_credentials_filter.rb +37 -0
  160. data/lib/bundler/vendor/fileutils/lib/fileutils.rb +1741 -0
  161. data/lib/bundler/vendor/fileutils/lib/fileutils/version.rb +5 -0
  162. data/lib/bundler/vendor/molinillo/lib/molinillo.rb +12 -0
  163. data/lib/bundler/vendor/molinillo/lib/molinillo/compatibility.rb +26 -0
  164. data/lib/bundler/vendor/molinillo/lib/molinillo/delegates/resolution_state.rb +57 -0
  165. data/lib/bundler/vendor/molinillo/lib/molinillo/delegates/specification_provider.rb +81 -0
  166. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb +223 -0
  167. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/action.rb +36 -0
  168. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb +66 -0
  169. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_vertex.rb +62 -0
  170. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/delete_edge.rb +63 -0
  171. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb +61 -0
  172. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/log.rb +126 -0
  173. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/set_payload.rb +46 -0
  174. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/tag.rb +36 -0
  175. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb +136 -0
  176. data/lib/bundler/vendor/molinillo/lib/molinillo/errors.rb +143 -0
  177. data/lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb +6 -0
  178. data/lib/bundler/vendor/molinillo/lib/molinillo/modules/specification_provider.rb +101 -0
  179. data/lib/bundler/vendor/molinillo/lib/molinillo/modules/ui.rb +67 -0
  180. data/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb +837 -0
  181. data/lib/bundler/vendor/molinillo/lib/molinillo/resolver.rb +46 -0
  182. data/lib/bundler/vendor/molinillo/lib/molinillo/state.rb +58 -0
  183. data/lib/bundler/vendor/net-http-persistent/lib/net/http/faster.rb +27 -0
  184. data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb +1233 -0
  185. data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/ssl_reuse.rb +129 -0
  186. data/lib/bundler/vendor/thor/lib/thor.rb +509 -0
  187. data/lib/bundler/vendor/thor/lib/thor/actions.rb +331 -0
  188. data/lib/bundler/vendor/thor/lib/thor/actions/create_file.rb +104 -0
  189. data/lib/bundler/vendor/thor/lib/thor/actions/create_link.rb +60 -0
  190. data/lib/bundler/vendor/thor/lib/thor/actions/directory.rb +118 -0
  191. data/lib/bundler/vendor/thor/lib/thor/actions/empty_directory.rb +143 -0
  192. data/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb +373 -0
  193. data/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb +109 -0
  194. data/lib/bundler/vendor/thor/lib/thor/base.rb +678 -0
  195. data/lib/bundler/vendor/thor/lib/thor/command.rb +135 -0
  196. data/lib/bundler/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb +97 -0
  197. data/lib/bundler/vendor/thor/lib/thor/core_ext/io_binary_read.rb +12 -0
  198. data/lib/bundler/vendor/thor/lib/thor/core_ext/ordered_hash.rb +129 -0
  199. data/lib/bundler/vendor/thor/lib/thor/error.rb +114 -0
  200. data/lib/bundler/vendor/thor/lib/thor/group.rb +281 -0
  201. data/lib/bundler/vendor/thor/lib/thor/invocation.rb +177 -0
  202. data/lib/bundler/vendor/thor/lib/thor/line_editor.rb +17 -0
  203. data/lib/bundler/vendor/thor/lib/thor/line_editor/basic.rb +37 -0
  204. data/lib/bundler/vendor/thor/lib/thor/line_editor/readline.rb +88 -0
  205. data/lib/bundler/vendor/thor/lib/thor/parser.rb +4 -0
  206. data/lib/bundler/vendor/thor/lib/thor/parser/argument.rb +70 -0
  207. data/lib/bundler/vendor/thor/lib/thor/parser/arguments.rb +175 -0
  208. data/lib/bundler/vendor/thor/lib/thor/parser/option.rb +146 -0
  209. data/lib/bundler/vendor/thor/lib/thor/parser/options.rb +226 -0
  210. data/lib/bundler/vendor/thor/lib/thor/rake_compat.rb +71 -0
  211. data/lib/bundler/vendor/thor/lib/thor/runner.rb +324 -0
  212. data/lib/bundler/vendor/thor/lib/thor/shell.rb +81 -0
  213. data/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +482 -0
  214. data/lib/bundler/vendor/thor/lib/thor/shell/color.rb +149 -0
  215. data/lib/bundler/vendor/thor/lib/thor/shell/html.rb +126 -0
  216. data/lib/bundler/vendor/thor/lib/thor/util.rb +268 -0
  217. data/lib/bundler/vendor/thor/lib/thor/version.rb +3 -0
  218. data/lib/bundler/vendored_fileutils.rb +9 -0
  219. data/lib/bundler/vendored_molinillo.rb +4 -0
  220. data/lib/bundler/vendored_persistent.rb +52 -0
  221. data/lib/bundler/vendored_thor.rb +8 -0
  222. data/lib/bundler/version.rb +28 -0
  223. data/lib/bundler/version_ranges.rb +76 -0
  224. data/lib/bundler/vlad.rb +17 -0
  225. data/lib/bundler/worker.rb +106 -0
  226. data/lib/bundler/yaml_serializer.rb +90 -0
  227. data/man/bundle-add.1 +58 -0
  228. data/man/bundle-add.1.txt +52 -0
  229. data/man/bundle-add.ronn +40 -0
  230. data/man/bundle-binstubs.1 +40 -0
  231. data/man/bundle-binstubs.1.txt +48 -0
  232. data/man/bundle-binstubs.ronn +43 -0
  233. data/man/bundle-check.1 +31 -0
  234. data/man/bundle-check.1.txt +33 -0
  235. data/man/bundle-check.ronn +26 -0
  236. data/man/bundle-clean.1 +24 -0
  237. data/man/bundle-clean.1.txt +26 -0
  238. data/man/bundle-clean.ronn +18 -0
  239. data/man/bundle-config.1 +497 -0
  240. data/man/bundle-config.1.txt +529 -0
  241. data/man/bundle-config.ronn +397 -0
  242. data/man/bundle-doctor.1 +44 -0
  243. data/man/bundle-doctor.1.txt +44 -0
  244. data/man/bundle-doctor.ronn +33 -0
  245. data/man/bundle-exec.1 +165 -0
  246. data/man/bundle-exec.1.txt +178 -0
  247. data/man/bundle-exec.ronn +152 -0
  248. data/man/bundle-gem.1 +80 -0
  249. data/man/bundle-gem.1.txt +91 -0
  250. data/man/bundle-gem.ronn +78 -0
  251. data/man/bundle-info.1 +20 -0
  252. data/man/bundle-info.1.txt +21 -0
  253. data/man/bundle-info.ronn +17 -0
  254. data/man/bundle-init.1 +25 -0
  255. data/man/bundle-init.1.txt +34 -0
  256. data/man/bundle-init.ronn +29 -0
  257. data/man/bundle-inject.1 +33 -0
  258. data/man/bundle-inject.1.txt +32 -0
  259. data/man/bundle-inject.ronn +22 -0
  260. data/man/bundle-install.1 +308 -0
  261. data/man/bundle-install.1.txt +396 -0
  262. data/man/bundle-install.ronn +378 -0
  263. data/man/bundle-list.1 +50 -0
  264. data/man/bundle-list.1.txt +43 -0
  265. data/man/bundle-list.ronn +33 -0
  266. data/man/bundle-lock.1 +84 -0
  267. data/man/bundle-lock.1.txt +93 -0
  268. data/man/bundle-lock.ronn +94 -0
  269. data/man/bundle-open.1 +32 -0
  270. data/man/bundle-open.1.txt +29 -0
  271. data/man/bundle-open.ronn +19 -0
  272. data/man/bundle-outdated.1 +155 -0
  273. data/man/bundle-outdated.1.txt +131 -0
  274. data/man/bundle-outdated.ronn +111 -0
  275. data/man/bundle-package.1 +55 -0
  276. data/man/bundle-package.1.txt +79 -0
  277. data/man/bundle-package.ronn +72 -0
  278. data/man/bundle-platform.1 +61 -0
  279. data/man/bundle-platform.1.txt +57 -0
  280. data/man/bundle-platform.ronn +42 -0
  281. data/man/bundle-pristine.1 +34 -0
  282. data/man/bundle-pristine.1.txt +44 -0
  283. data/man/bundle-pristine.ronn +34 -0
  284. data/man/bundle-remove.1 +31 -0
  285. data/man/bundle-remove.1.txt +34 -0
  286. data/man/bundle-remove.ronn +23 -0
  287. data/man/bundle-show.1 +23 -0
  288. data/man/bundle-show.1.txt +27 -0
  289. data/man/bundle-show.ronn +21 -0
  290. data/man/bundle-update.1 +394 -0
  291. data/man/bundle-update.1.txt +391 -0
  292. data/man/bundle-update.ronn +350 -0
  293. data/man/bundle-viz.1 +39 -0
  294. data/man/bundle-viz.1.txt +39 -0
  295. data/man/bundle-viz.ronn +30 -0
  296. data/man/bundle.1 +136 -0
  297. data/man/bundle.1.txt +116 -0
  298. data/man/bundle.ronn +111 -0
  299. data/man/gemfile.5 +689 -0
  300. data/man/gemfile.5.ronn +521 -0
  301. data/man/gemfile.5.txt +653 -0
  302. data/man/index.txt +25 -0
  303. metadata +463 -0
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bundler
4
+ class ProcessLock
5
+ def self.lock(bundle_path = Bundler.bundle_path)
6
+ lock_file_path = File.join(bundle_path, "bundler.lock")
7
+ has_lock = false
8
+
9
+ File.open(lock_file_path, "w") do |f|
10
+ f.flock(File::LOCK_EX)
11
+ has_lock = true
12
+ yield
13
+ f.flock(File::LOCK_UN)
14
+ end
15
+ rescue Errno::EACCES, Errno::ENOLCK, *[SharedHelpers.const_get_safely(:ENOTSUP, Errno)].compact
16
+ # In the case the user does not have access to
17
+ # create the lock file or is using NFS where
18
+ # locks are not available we skip locking.
19
+ yield
20
+ ensure
21
+ FileUtils.rm_f(lock_file_path) if has_lock
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Psych could be a gem, so try to ask for it
4
+ begin
5
+ gem "psych"
6
+ rescue LoadError
7
+ end if defined?(gem)
8
+
9
+ # Psych could be in the stdlib
10
+ # but it's too late if Syck is already loaded
11
+ begin
12
+ require "psych" unless defined?(Syck)
13
+ rescue LoadError
14
+ # Apparently Psych wasn't available. Oh well.
15
+ end
16
+
17
+ # At least load the YAML stdlib, whatever that may be
18
+ require "yaml" unless defined?(YAML.dump)
19
+
20
+ module Bundler
21
+ # On encountering invalid YAML,
22
+ # Psych raises Psych::SyntaxError
23
+ if defined?(::Psych::SyntaxError)
24
+ YamlLibrarySyntaxError = ::Psych::SyntaxError
25
+ else # Syck raises ArgumentError
26
+ YamlLibrarySyntaxError = ::ArgumentError
27
+ end
28
+ end
29
+
30
+ require "bundler/deprecate"
31
+ begin
32
+ Bundler::Deprecate.skip_during do
33
+ require "rubygems/safe_yaml"
34
+ end
35
+ rescue LoadError
36
+ # it's OK if the file isn't there
37
+ end
@@ -0,0 +1,114 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "uri"
4
+
5
+ module Bundler
6
+ # Represents a lazily loaded gem specification, where the full specification
7
+ # is on the source server in rubygems' "quick" index. The proxy object is to
8
+ # be seeded with what we're given from the source's abbreviated index - the
9
+ # full specification will only be fetched when necessary.
10
+ class RemoteSpecification
11
+ include MatchPlatform
12
+ include Comparable
13
+
14
+ attr_reader :name, :version, :platform
15
+ attr_writer :dependencies
16
+ attr_accessor :source, :remote
17
+
18
+ def initialize(name, version, platform, spec_fetcher)
19
+ @name = name
20
+ @version = Gem::Version.create version
21
+ @platform = platform
22
+ @spec_fetcher = spec_fetcher
23
+ @dependencies = nil
24
+ end
25
+
26
+ # Needed before installs, since the arch matters then and quick
27
+ # specs don't bother to include the arch in the platform string
28
+ def fetch_platform
29
+ @platform = _remote_specification.platform
30
+ end
31
+
32
+ def full_name
33
+ if platform == Gem::Platform::RUBY || platform.nil?
34
+ "#{@name}-#{@version}"
35
+ else
36
+ "#{@name}-#{@version}-#{platform}"
37
+ end
38
+ end
39
+
40
+ # Compare this specification against another object. Using sort_obj
41
+ # is compatible with Gem::Specification and other Bundler or RubyGems
42
+ # objects. Otherwise, use the default Object comparison.
43
+ def <=>(other)
44
+ if other.respond_to?(:sort_obj)
45
+ sort_obj <=> other.sort_obj
46
+ else
47
+ super
48
+ end
49
+ end
50
+
51
+ # Because Rubyforge cannot be trusted to provide valid specifications
52
+ # once the remote gem is downloaded, the backend specification will
53
+ # be swapped out.
54
+ def __swap__(spec)
55
+ SharedHelpers.ensure_same_dependencies(self, dependencies, spec.dependencies)
56
+ @_remote_specification = spec
57
+ end
58
+
59
+ # Create a delegate used for sorting. This strategy is copied from
60
+ # RubyGems 2.23 and ensures that Bundler's specifications can be
61
+ # compared and sorted with RubyGems' own specifications.
62
+ #
63
+ # @see #<=>
64
+ # @see Gem::Specification#sort_obj
65
+ #
66
+ # @return [Array] an object you can use to compare and sort this
67
+ # specification against other specifications
68
+ def sort_obj
69
+ [@name, @version, @platform == Gem::Platform::RUBY ? -1 : 1]
70
+ end
71
+
72
+ def to_s
73
+ "#<#{self.class} name=#{name} version=#{version} platform=#{platform}>"
74
+ end
75
+
76
+ def dependencies
77
+ @dependencies ||= begin
78
+ deps = method_missing(:dependencies)
79
+
80
+ # allow us to handle when the specs dependencies are an array of array of string
81
+ # see https://github.com/bundler/bundler/issues/5797
82
+ deps = deps.map {|d| d.is_a?(Gem::Dependency) ? d : Gem::Dependency.new(*d) }
83
+
84
+ deps
85
+ end
86
+ end
87
+
88
+ def git_version
89
+ return unless loaded_from && source.is_a?(Bundler::Source::Git)
90
+ " #{source.revision[0..6]}"
91
+ end
92
+
93
+ private
94
+
95
+ def to_ary
96
+ nil
97
+ end
98
+
99
+ def _remote_specification
100
+ @_remote_specification ||= @spec_fetcher.fetch_spec([@name, @version, @platform])
101
+ @_remote_specification || raise(GemspecError, "Gemspec data for #{full_name} was" \
102
+ " missing from the server! Try installing with `--full-index` as a workaround.")
103
+ end
104
+
105
+ def method_missing(method, *args, &blk)
106
+ _remote_specification.send(method, *args, &blk)
107
+ end
108
+
109
+ def respond_to?(method, include_all = false)
110
+ super || _remote_specification.respond_to?(method, include_all)
111
+ end
112
+ public :respond_to?
113
+ end
114
+ end
@@ -0,0 +1,373 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bundler
4
+ class Resolver
5
+ require "bundler/vendored_molinillo"
6
+ require "bundler/resolver/spec_group"
7
+
8
+ # Figures out the best possible configuration of gems that satisfies
9
+ # the list of passed dependencies and any child dependencies without
10
+ # causing any gem activation errors.
11
+ #
12
+ # ==== Parameters
13
+ # *dependencies<Gem::Dependency>:: The list of dependencies to resolve
14
+ #
15
+ # ==== Returns
16
+ # <GemBundle>,nil:: If the list of dependencies can be resolved, a
17
+ # collection of gemspecs is returned. Otherwise, nil is returned.
18
+ def self.resolve(requirements, index, source_requirements = {}, base = [], gem_version_promoter = GemVersionPromoter.new, additional_base_requirements = [], platforms = nil)
19
+ platforms = Set.new(platforms) if platforms
20
+ base = SpecSet.new(base) unless base.is_a?(SpecSet)
21
+ resolver = new(index, source_requirements, base, gem_version_promoter, additional_base_requirements, platforms)
22
+ result = resolver.start(requirements)
23
+ SpecSet.new(result)
24
+ end
25
+
26
+ def initialize(index, source_requirements, base, gem_version_promoter, additional_base_requirements, platforms)
27
+ @index = index
28
+ @source_requirements = source_requirements
29
+ @base = base
30
+ @resolver = Molinillo::Resolver.new(self, self)
31
+ @search_for = {}
32
+ @base_dg = Molinillo::DependencyGraph.new
33
+ @base.each do |ls|
34
+ dep = Dependency.new(ls.name, ls.version)
35
+ @base_dg.add_vertex(ls.name, DepProxy.new(dep, ls.platform), true)
36
+ end
37
+ additional_base_requirements.each {|d| @base_dg.add_vertex(d.name, d) }
38
+ @platforms = platforms
39
+ @gem_version_promoter = gem_version_promoter
40
+ @allow_bundler_dependency_conflicts = Bundler.feature_flag.allow_bundler_dependency_conflicts?
41
+ @lockfile_uses_separate_rubygems_sources = Bundler.feature_flag.lockfile_uses_separate_rubygems_sources?
42
+ @use_gvp = Bundler.feature_flag.use_gem_version_promoter_for_major_updates? || !@gem_version_promoter.major?
43
+ end
44
+
45
+ def start(requirements)
46
+ @gem_version_promoter.prerelease_specified = @prerelease_specified = {}
47
+ requirements.each {|dep| @prerelease_specified[dep.name] ||= dep.prerelease? }
48
+
49
+ verify_gemfile_dependencies_are_found!(requirements)
50
+ dg = @resolver.resolve(requirements, @base_dg)
51
+ dg.map(&:payload).
52
+ reject {|sg| sg.name.end_with?("\0") }.
53
+ map(&:to_specs).flatten
54
+ rescue Molinillo::VersionConflict => e
55
+ message = version_conflict_message(e)
56
+ raise VersionConflict.new(e.conflicts.keys.uniq, message)
57
+ rescue Molinillo::CircularDependencyError => e
58
+ names = e.dependencies.sort_by(&:name).map {|d| "gem '#{d.name}'" }
59
+ raise CyclicDependencyError, "Your bundle requires gems that depend" \
60
+ " on each other, creating an infinite loop. Please remove" \
61
+ " #{names.count > 1 ? "either " : ""}#{names.join(" or ")}" \
62
+ " and try again."
63
+ end
64
+
65
+ include Molinillo::UI
66
+
67
+ # Conveys debug information to the user.
68
+ #
69
+ # @param [Integer] depth the current depth of the resolution process.
70
+ # @return [void]
71
+ def debug(depth = 0)
72
+ return unless debug?
73
+ debug_info = yield
74
+ debug_info = debug_info.inspect unless debug_info.is_a?(String)
75
+ STDERR.puts debug_info.split("\n").map {|s| " " * depth + s }
76
+ end
77
+
78
+ def debug?
79
+ return @debug_mode if defined?(@debug_mode)
80
+ @debug_mode = ENV["DEBUG_RESOLVER"] || ENV["DEBUG_RESOLVER_TREE"] || false
81
+ end
82
+
83
+ def before_resolution
84
+ Bundler.ui.info "Resolving dependencies...", debug?
85
+ end
86
+
87
+ def after_resolution
88
+ Bundler.ui.info ""
89
+ end
90
+
91
+ def indicate_progress
92
+ Bundler.ui.info ".", false unless debug?
93
+ end
94
+
95
+ include Molinillo::SpecificationProvider
96
+
97
+ def dependencies_for(specification)
98
+ specification.dependencies_for_activated_platforms
99
+ end
100
+
101
+ def search_for(dependency)
102
+ platform = dependency.__platform
103
+ dependency = dependency.dep unless dependency.is_a? Gem::Dependency
104
+ search = @search_for[dependency] ||= begin
105
+ index = index_for(dependency)
106
+ results = index.search(dependency, @base[dependency.name])
107
+
108
+ if vertex = @base_dg.vertex_named(dependency.name)
109
+ locked_requirement = vertex.payload.requirement
110
+ end
111
+
112
+ if !@prerelease_specified[dependency.name] && (!@use_gvp || locked_requirement.nil?)
113
+ # Move prereleases to the beginning of the list, so they're considered
114
+ # last during resolution.
115
+ pre, results = results.partition {|spec| spec.version.prerelease? }
116
+ results = pre + results
117
+ end
118
+
119
+ spec_groups = if results.any?
120
+ nested = []
121
+ results.each do |spec|
122
+ version, specs = nested.last
123
+ if version == spec.version
124
+ specs << spec
125
+ else
126
+ nested << [spec.version, [spec]]
127
+ end
128
+ end
129
+ nested.reduce([]) do |groups, (version, specs)|
130
+ next groups if locked_requirement && !locked_requirement.satisfied_by?(version)
131
+ spec_group = SpecGroup.new(specs)
132
+ spec_group.ignores_bundler_dependencies = @allow_bundler_dependency_conflicts
133
+ groups << spec_group
134
+ end
135
+ else
136
+ []
137
+ end
138
+ # GVP handles major itself, but it's still a bit risky to trust it with it
139
+ # until we get it settled with new behavior. For 2.x it can take over all cases.
140
+ if !@use_gvp
141
+ spec_groups
142
+ else
143
+ @gem_version_promoter.sort_versions(dependency, spec_groups)
144
+ end
145
+ end
146
+ search.select {|sg| sg.for?(platform) }.each {|sg| sg.activate_platform!(platform) }
147
+ end
148
+
149
+ def index_for(dependency)
150
+ source = @source_requirements[dependency.name]
151
+ if source
152
+ source.specs
153
+ elsif @lockfile_uses_separate_rubygems_sources
154
+ Index.build do |idx|
155
+ if dependency.all_sources
156
+ dependency.all_sources.each {|s| idx.add_source(s.specs) if s }
157
+ else
158
+ idx.add_source @source_requirements[:default].specs
159
+ end
160
+ end
161
+ else
162
+ @index
163
+ end
164
+ end
165
+
166
+ def name_for(dependency)
167
+ dependency.name
168
+ end
169
+
170
+ def name_for_explicit_dependency_source
171
+ Bundler.default_gemfile.basename.to_s
172
+ rescue
173
+ "Gemfile"
174
+ end
175
+
176
+ def name_for_locking_dependency_source
177
+ Bundler.default_lockfile.basename.to_s
178
+ rescue
179
+ "Gemfile.lock"
180
+ end
181
+
182
+ def requirement_satisfied_by?(requirement, activated, spec)
183
+ return false unless requirement.matches_spec?(spec) || spec.source.is_a?(Source::Gemspec)
184
+ spec.activate_platform!(requirement.__platform) if !@platforms || @platforms.include?(requirement.__platform)
185
+ true
186
+ end
187
+
188
+ def relevant_sources_for_vertex(vertex)
189
+ if vertex.root?
190
+ [@source_requirements[vertex.name]]
191
+ elsif @lockfile_uses_separate_rubygems_sources
192
+ vertex.recursive_predecessors.map do |v|
193
+ @source_requirements[v.name]
194
+ end << @source_requirements[:default]
195
+ end
196
+ end
197
+
198
+ def sort_dependencies(dependencies, activated, conflicts)
199
+ dependencies.sort_by do |dependency|
200
+ dependency.all_sources = relevant_sources_for_vertex(activated.vertex_named(dependency.name))
201
+ name = name_for(dependency)
202
+ vertex = activated.vertex_named(name)
203
+ [
204
+ @base_dg.vertex_named(name) ? 0 : 1,
205
+ vertex.payload ? 0 : 1,
206
+ vertex.root? ? 0 : 1,
207
+ amount_constrained(dependency),
208
+ conflicts[name] ? 0 : 1,
209
+ vertex.payload ? 0 : search_for(dependency).count,
210
+ self.class.platform_sort_key(dependency.__platform),
211
+ ]
212
+ end
213
+ end
214
+
215
+ # Sort platforms from most general to most specific
216
+ def self.sort_platforms(platforms)
217
+ platforms.sort_by do |platform|
218
+ platform_sort_key(platform)
219
+ end
220
+ end
221
+
222
+ def self.platform_sort_key(platform)
223
+ return ["", "", ""] if Gem::Platform::RUBY == platform
224
+ platform.to_a.map {|part| part || "" }
225
+ end
226
+
227
+ private
228
+
229
+ # returns an integer \in (-\infty, 0]
230
+ # a number closer to 0 means the dependency is less constraining
231
+ #
232
+ # dependencies w/ 0 or 1 possibilities (ignoring version requirements)
233
+ # are given very negative values, so they _always_ sort first,
234
+ # before dependencies that are unconstrained
235
+ def amount_constrained(dependency)
236
+ @amount_constrained ||= {}
237
+ @amount_constrained[dependency.name] ||= begin
238
+ if (base = @base[dependency.name]) && !base.empty?
239
+ dependency.requirement.satisfied_by?(base.first.version) ? 0 : 1
240
+ else
241
+ all = index_for(dependency).search(dependency.name).size
242
+
243
+ if all <= 1
244
+ all - 1_000_000
245
+ else
246
+ search = search_for(dependency)
247
+ search = @prerelease_specified[dependency.name] ? search.count : search.count {|s| !s.version.prerelease? }
248
+ search - all
249
+ end
250
+ end
251
+ end
252
+ end
253
+
254
+ def verify_gemfile_dependencies_are_found!(requirements)
255
+ requirements.each do |requirement|
256
+ name = requirement.name
257
+ next if name == "bundler"
258
+ next unless search_for(requirement).empty?
259
+
260
+ cache_message = begin
261
+ " or in gems cached in #{Bundler.settings.app_cache_path}" if Bundler.app_cache.exist?
262
+ rescue GemfileNotFound
263
+ nil
264
+ end
265
+
266
+ if (base = @base[name]) && !base.empty?
267
+ version = base.first.version
268
+ message = "You have requested:\n" \
269
+ " #{name} #{requirement.requirement}\n\n" \
270
+ "The bundle currently has #{name} locked at #{version}.\n" \
271
+ "Try running `bundle update #{name}`\n\n" \
272
+ "If you are updating multiple gems in your Gemfile at once,\n" \
273
+ "try passing them all to `bundle update`"
274
+ elsif source = @source_requirements[name]
275
+ specs = source.specs[name]
276
+ versions_with_platforms = specs.map {|s| [s.version, s.platform] }
277
+ message = String.new("Could not find gem '#{SharedHelpers.pretty_dependency(requirement)}' in #{source}#{cache_message}.\n")
278
+ message << if versions_with_platforms.any?
279
+ "The source contains '#{name}' at: #{formatted_versions_with_platforms(versions_with_platforms)}"
280
+ else
281
+ "The source does not contain any versions of '#{name}'"
282
+ end
283
+ else
284
+ message = "Could not find gem '#{requirement}' in any of the gem sources " \
285
+ "listed in your Gemfile#{cache_message}."
286
+ end
287
+ raise GemNotFound, message
288
+ end
289
+ end
290
+
291
+ def formatted_versions_with_platforms(versions_with_platforms)
292
+ version_platform_strs = versions_with_platforms.map do |vwp|
293
+ version = vwp.first
294
+ platform = vwp.last
295
+ version_platform_str = String.new(version.to_s)
296
+ version_platform_str << " #{platform}" unless platform.nil? || platform == Gem::Platform::RUBY
297
+ version_platform_str
298
+ end
299
+ version_platform_strs.join(", ")
300
+ end
301
+
302
+ def version_conflict_message(e)
303
+ e.message_with_trees(
304
+ :solver_name => "Bundler",
305
+ :possibility_type => "gem",
306
+ :reduce_trees => lambda do |trees|
307
+ # called first, because we want to reduce the amount of work required to find maximal empty sets
308
+ trees = trees.uniq {|t| t.flatten.map {|dep| [dep.name, dep.requirement] } }
309
+
310
+ # bail out if tree size is too big for Array#combination to make any sense
311
+ return trees if trees.size > 15
312
+ maximal = 1.upto(trees.size).map do |size|
313
+ trees.map(&:last).flatten(1).combination(size).to_a
314
+ end.flatten(1).select do |deps|
315
+ Bundler::VersionRanges.empty?(*Bundler::VersionRanges.for_many(deps.map(&:requirement)))
316
+ end.min_by(&:size)
317
+ trees.reject! {|t| !maximal.include?(t.last) } if maximal
318
+
319
+ trees = trees.sort_by {|t| t.flatten.map(&:to_s) }
320
+ trees.uniq! {|t| t.flatten.map {|dep| [dep.name, dep.requirement] } }
321
+
322
+ trees.sort_by {|t| t.reverse.map(&:name) }
323
+ end,
324
+ :printable_requirement => lambda {|req| SharedHelpers.pretty_dependency(req) },
325
+ :additional_message_for_conflict => lambda do |o, name, conflict|
326
+ if name == "bundler"
327
+ o << %(\n Current Bundler version:\n bundler (#{Bundler::VERSION}))
328
+ other_bundler_required = !conflict.requirement.requirement.satisfied_by?(Gem::Version.new Bundler::VERSION)
329
+ end
330
+
331
+ if name == "bundler" && other_bundler_required
332
+ o << "\n"
333
+ o << "This Gemfile requires a different version of Bundler.\n"
334
+ o << "Perhaps you need to update Bundler by running `gem install bundler`?\n"
335
+ end
336
+ if conflict.locked_requirement
337
+ o << "\n"
338
+ o << %(Running `bundle update` will rebuild your snapshot from scratch, using only\n)
339
+ o << %(the gems in your Gemfile, which may resolve the conflict.\n)
340
+ elsif !conflict.existing
341
+ o << "\n"
342
+
343
+ relevant_sources = if conflict.requirement.source
344
+ [conflict.requirement.source]
345
+ elsif conflict.requirement.all_sources
346
+ conflict.requirement.all_sources
347
+ elsif @lockfile_uses_separate_rubygems_sources
348
+ # every conflict should have an explicit group of sources when we
349
+ # enforce strict pinning
350
+ raise "no source set for #{conflict}"
351
+ else
352
+ []
353
+ end.compact.map(&:to_s).uniq.sort
354
+
355
+ o << "Could not find gem '#{SharedHelpers.pretty_dependency(conflict.requirement)}'"
356
+ if conflict.requirement_trees.first.size > 1
357
+ o << ", which is required by "
358
+ o << "gem '#{SharedHelpers.pretty_dependency(conflict.requirement_trees.first[-2])}',"
359
+ end
360
+ o << " "
361
+
362
+ o << if relevant_sources.empty?
363
+ "in any of the sources.\n"
364
+ else
365
+ "in any of the relevant sources:\n #{relevant_sources * "\n "}\n"
366
+ end
367
+ end
368
+ end,
369
+ :version_for_spec => lambda {|spec| spec.version }
370
+ )
371
+ end
372
+ end
373
+ end