bundler 1.11.1 → 2.2.6
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.
- checksums.yaml +5 -5
- data/CHANGELOG.md +2125 -840
- data/LICENSE.md +18 -19
- data/README.md +33 -11
- data/bundler.gemspec +34 -21
- data/exe/bundle +36 -6
- data/exe/bundler +2 -18
- data/lib/bundler.rb +435 -160
- data/lib/bundler/build_metadata.rb +45 -0
- data/lib/bundler/capistrano.rb +9 -3
- data/lib/bundler/cli.rb +550 -130
- data/lib/bundler/cli/add.rb +47 -0
- data/lib/bundler/cli/binstubs.rb +26 -10
- data/lib/bundler/cli/cache.rb +25 -17
- data/lib/bundler/cli/check.rb +8 -7
- data/lib/bundler/cli/clean.rb +8 -8
- data/lib/bundler/cli/common.rb +69 -9
- data/lib/bundler/cli/config.rb +170 -76
- data/lib/bundler/cli/console.rb +6 -1
- data/lib/bundler/cli/doctor.rb +140 -0
- data/lib/bundler/cli/exec.rb +63 -21
- data/lib/bundler/cli/fund.rb +36 -0
- data/lib/bundler/cli/gem.rb +158 -42
- data/lib/bundler/cli/info.rb +73 -0
- data/lib/bundler/cli/init.rb +22 -7
- data/lib/bundler/cli/inject.rb +38 -10
- data/lib/bundler/cli/install.rb +139 -104
- data/lib/bundler/cli/issue.rb +40 -0
- data/lib/bundler/cli/list.rb +60 -0
- data/lib/bundler/cli/lock.rb +27 -5
- data/lib/bundler/cli/open.rb +13 -5
- data/lib/bundler/cli/outdated.rb +251 -46
- data/lib/bundler/cli/platform.rb +6 -2
- data/lib/bundler/cli/plugin.rb +41 -0
- data/lib/bundler/cli/pristine.rb +52 -0
- data/lib/bundler/cli/remove.rb +18 -0
- data/lib/bundler/cli/show.rb +5 -4
- data/lib/bundler/cli/update.rb +67 -26
- data/lib/bundler/cli/viz.rb +11 -6
- data/lib/bundler/compact_index_client.rb +125 -0
- data/lib/bundler/compact_index_client/cache.rb +110 -0
- data/lib/bundler/compact_index_client/gem_parser.rb +28 -0
- data/lib/bundler/compact_index_client/updater.rb +104 -0
- data/lib/bundler/constants.rb +2 -0
- data/lib/bundler/current_ruby.rb +51 -174
- data/lib/bundler/definition.rb +533 -216
- data/lib/bundler/dep_proxy.rb +18 -8
- data/lib/bundler/dependency.rb +39 -12
- data/lib/bundler/deployment.rb +7 -0
- data/lib/bundler/deprecate.rb +31 -2
- data/lib/bundler/dsl.rb +188 -91
- data/lib/bundler/endpoint_specification.rb +51 -10
- data/lib/bundler/env.rb +116 -48
- data/lib/bundler/environment_preserver.rb +82 -0
- data/lib/bundler/errors.rb +108 -31
- data/lib/bundler/feature_flag.rb +60 -0
- data/lib/bundler/fetcher.rb +81 -52
- data/lib/bundler/fetcher/base.rb +15 -3
- data/lib/bundler/fetcher/compact_index.rb +140 -0
- data/lib/bundler/fetcher/dependency.rb +36 -42
- data/lib/bundler/fetcher/downloader.rb +39 -12
- data/lib/bundler/fetcher/index.rb +34 -9
- data/lib/bundler/friendly_errors.rb +132 -88
- data/lib/bundler/gem_helper.rb +92 -50
- data/lib/bundler/gem_helpers.rb +90 -5
- data/lib/bundler/gem_tasks.rb +3 -1
- data/lib/bundler/gem_version_promoter.rb +190 -0
- data/lib/bundler/gemdeps.rb +29 -0
- data/lib/bundler/graph.rb +20 -41
- data/lib/bundler/index.rb +74 -57
- data/lib/bundler/injector.rb +242 -31
- data/lib/bundler/inline.rb +49 -23
- data/lib/bundler/installer.rb +190 -74
- data/lib/bundler/installer/gem_installer.rb +33 -20
- data/lib/bundler/installer/parallel_installer.rb +201 -97
- data/lib/bundler/installer/standalone.rb +10 -6
- data/lib/bundler/lazy_specification.rb +74 -10
- data/lib/bundler/lockfile_generator.rb +95 -0
- data/lib/bundler/lockfile_parser.rb +126 -74
- data/lib/bundler/{ssl_certs → man}/.document +0 -0
- data/lib/bundler/man/bundle-add.1 +66 -0
- data/lib/bundler/man/bundle-add.1.ronn +46 -0
- data/lib/bundler/man/bundle-binstubs.1 +42 -0
- data/lib/bundler/man/bundle-binstubs.1.ronn +41 -0
- data/lib/bundler/man/bundle-cache.1 +55 -0
- data/{man/bundle-package.ronn → lib/bundler/man/bundle-cache.1.ronn} +22 -16
- data/lib/bundler/man/bundle-check.1 +31 -0
- data/lib/bundler/man/bundle-check.1.ronn +26 -0
- data/lib/bundler/man/bundle-clean.1 +24 -0
- data/lib/bundler/man/bundle-clean.1.ronn +18 -0
- data/lib/bundler/man/bundle-config.1 +488 -0
- data/lib/bundler/man/bundle-config.1.ronn +388 -0
- data/lib/bundler/man/bundle-doctor.1 +44 -0
- data/lib/bundler/man/bundle-doctor.1.ronn +33 -0
- data/lib/bundler/man/bundle-exec.1 +165 -0
- data/{man/bundle-exec.ronn → lib/bundler/man/bundle-exec.1.ronn} +20 -4
- data/lib/bundler/man/bundle-gem.1 +102 -0
- data/{man/bundle-gem.ronn → lib/bundler/man/bundle-gem.1.ronn} +37 -13
- data/lib/bundler/man/bundle-info.1 +20 -0
- data/lib/bundler/man/bundle-info.1.ronn +17 -0
- data/lib/bundler/man/bundle-init.1 +25 -0
- data/lib/bundler/man/bundle-init.1.ronn +29 -0
- data/lib/bundler/man/bundle-inject.1 +33 -0
- data/lib/bundler/man/bundle-inject.1.ronn +22 -0
- data/lib/bundler/man/bundle-install.1 +338 -0
- data/{man/bundle-install.ronn → lib/bundler/man/bundle-install.1.ronn} +82 -76
- data/lib/bundler/man/bundle-list.1 +50 -0
- data/lib/bundler/man/bundle-list.1.ronn +33 -0
- data/lib/bundler/man/bundle-lock.1 +84 -0
- data/{man/bundle-lock.ronn → lib/bundler/man/bundle-lock.1.ronn} +47 -0
- data/lib/bundler/man/bundle-open.1 +32 -0
- data/lib/bundler/man/bundle-open.1.ronn +19 -0
- data/lib/bundler/man/bundle-outdated.1 +155 -0
- data/lib/bundler/man/bundle-outdated.1.ronn +111 -0
- data/lib/bundler/man/bundle-platform.1 +61 -0
- data/{man/bundle-platform.ronn → lib/bundler/man/bundle-platform.1.ronn} +1 -1
- data/lib/bundler/man/bundle-pristine.1 +34 -0
- data/lib/bundler/man/bundle-pristine.1.ronn +34 -0
- data/lib/bundler/man/bundle-remove.1 +31 -0
- data/lib/bundler/man/bundle-remove.1.ronn +23 -0
- data/lib/bundler/man/bundle-show.1 +23 -0
- data/lib/bundler/man/bundle-show.1.ronn +21 -0
- data/lib/bundler/man/bundle-update.1 +394 -0
- data/lib/bundler/man/bundle-update.1.ronn +350 -0
- data/lib/bundler/man/bundle-viz.1 +39 -0
- data/lib/bundler/man/bundle-viz.1.ronn +30 -0
- data/lib/bundler/man/bundle.1 +136 -0
- data/lib/bundler/man/bundle.1.ronn +111 -0
- data/lib/bundler/man/gemfile.5 +686 -0
- data/{man → lib/bundler/man}/gemfile.5.ronn +117 -95
- data/lib/bundler/man/index.txt +25 -0
- data/lib/bundler/match_platform.rb +15 -4
- data/lib/bundler/mirror.rb +223 -0
- data/lib/bundler/plugin.rb +330 -0
- data/lib/bundler/plugin/api.rb +81 -0
- data/lib/bundler/plugin/api/source.rb +304 -0
- data/lib/bundler/plugin/dsl.rb +53 -0
- data/lib/bundler/plugin/events.rb +61 -0
- data/lib/bundler/plugin/index.rb +182 -0
- data/lib/bundler/plugin/installer.rb +109 -0
- data/lib/bundler/plugin/installer/git.rb +38 -0
- data/lib/bundler/plugin/installer/rubygems.rb +27 -0
- data/lib/bundler/plugin/source_list.rb +27 -0
- data/lib/bundler/process_lock.rb +24 -0
- data/lib/bundler/psyched_yaml.rb +2 -6
- data/lib/bundler/remote_specification.rb +42 -9
- data/lib/bundler/resolver.rb +312 -225
- data/lib/bundler/resolver/spec_group.rb +122 -0
- data/lib/bundler/retry.rb +11 -5
- data/lib/bundler/ruby_dsl.rb +9 -2
- data/lib/bundler/ruby_version.rb +84 -61
- data/lib/bundler/rubygems_ext.rb +92 -53
- data/lib/bundler/rubygems_gem_installer.rb +84 -0
- data/lib/bundler/rubygems_integration.rb +320 -395
- data/lib/bundler/runtime.rb +87 -75
- data/lib/bundler/settings.rb +297 -119
- data/lib/bundler/settings/validator.rb +102 -0
- data/lib/bundler/setup.rb +13 -12
- data/lib/bundler/shared_helpers.rb +234 -53
- data/lib/bundler/similarity_detector.rb +5 -3
- data/lib/bundler/source.rb +63 -4
- data/lib/bundler/source/gemspec.rb +18 -0
- data/lib/bundler/source/git.rb +97 -50
- data/lib/bundler/source/git/git_proxy.rb +138 -65
- data/lib/bundler/source/metadata.rb +67 -0
- data/lib/bundler/source/path.rb +83 -47
- data/lib/bundler/source/path/installer.rb +42 -11
- data/lib/bundler/source/rubygems.rb +231 -116
- data/lib/bundler/source/rubygems/remote.rb +30 -1
- data/lib/bundler/source_list.rb +103 -21
- data/lib/bundler/spec_set.rb +96 -51
- data/lib/bundler/stub_specification.rb +87 -4
- data/lib/bundler/templates/.document +1 -0
- data/lib/bundler/templates/Executable +14 -1
- data/lib/bundler/templates/Executable.bundler +114 -0
- data/lib/bundler/templates/Executable.standalone +6 -4
- data/lib/bundler/templates/Gemfile +4 -1
- data/lib/bundler/templates/gems.rb +8 -0
- data/lib/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt +79 -44
- data/lib/bundler/templates/newgem/Gemfile.tt +18 -2
- data/lib/bundler/templates/newgem/LICENSE.txt.tt +1 -1
- data/lib/bundler/templates/newgem/README.md.tt +16 -10
- data/lib/bundler/templates/newgem/Rakefile.tt +22 -8
- data/lib/bundler/templates/newgem/bin/console.tt +2 -1
- data/lib/bundler/templates/newgem/circleci/config.yml.tt +13 -0
- data/lib/bundler/templates/newgem/ext/newgem/extconf.rb.tt +2 -0
- data/lib/bundler/templates/newgem/ext/newgem/newgem.c.tt +4 -4
- data/lib/bundler/templates/newgem/ext/newgem/newgem.h.tt +3 -3
- data/lib/bundler/templates/newgem/github/workflows/main.yml.tt +18 -0
- data/lib/bundler/templates/newgem/gitignore.tt +5 -1
- data/lib/bundler/templates/newgem/gitlab-ci.yml.tt +9 -0
- data/lib/bundler/templates/newgem/lib/newgem.rb.tt +9 -6
- data/lib/bundler/templates/newgem/lib/newgem/version.rb.tt +6 -4
- data/lib/bundler/templates/newgem/newgem.gemspec.tt +27 -28
- data/lib/bundler/templates/newgem/rspec.tt +1 -0
- data/lib/bundler/templates/newgem/rubocop.yml.tt +13 -0
- data/lib/bundler/templates/newgem/spec/newgem_spec.rb.tt +4 -4
- data/lib/bundler/templates/newgem/spec/spec_helper.rb.tt +15 -2
- data/lib/bundler/templates/newgem/test/{newgem_test.rb.tt → minitest/newgem_test.rb.tt} +3 -1
- data/lib/bundler/templates/newgem/test/minitest/test_helper.rb.tt +6 -0
- data/lib/bundler/templates/newgem/test/test-unit/newgem_test.rb.tt +15 -0
- data/lib/bundler/templates/newgem/test/test-unit/test_helper.rb.tt +6 -0
- data/lib/bundler/templates/newgem/{.travis.yml.tt → travis.yml.tt} +2 -0
- data/lib/bundler/ui.rb +5 -3
- data/lib/bundler/ui/rg_proxy.rb +3 -1
- data/lib/bundler/ui/shell.rb +54 -21
- data/lib/bundler/ui/silent.rb +26 -1
- data/lib/bundler/uri_credentials_filter.rb +43 -0
- data/lib/bundler/vendor/connection_pool/lib/connection_pool.rb +161 -0
- data/lib/bundler/vendor/connection_pool/lib/connection_pool/monotonic_time.rb +66 -0
- data/lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb +176 -0
- data/lib/bundler/vendor/connection_pool/lib/connection_pool/version.rb +3 -0
- data/lib/bundler/vendor/fileutils/lib/fileutils.rb +1764 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo.rb +11 -5
- data/lib/bundler/vendor/molinillo/lib/molinillo/delegates/resolution_state.rb +57 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/delegates/specification_provider.rb +81 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb +113 -134
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/action.rb +36 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb +66 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_vertex.rb +62 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/delete_edge.rb +63 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb +61 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/log.rb +126 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/set_payload.rb +46 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/tag.rb +36 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb +158 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/errors.rb +82 -8
- data/lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb +4 -1
- data/lib/bundler/vendor/molinillo/lib/molinillo/modules/specification_provider.rb +2 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/modules/ui.rb +6 -2
- data/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb +555 -150
- data/lib/bundler/vendor/molinillo/lib/molinillo/resolver.rb +6 -3
- data/lib/bundler/vendor/molinillo/lib/molinillo/state.rb +19 -12
- data/lib/bundler/vendor/{net → net-http-persistent/lib/net}/http/persistent.rb +310 -467
- data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/connection.rb +40 -0
- data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/pool.rb +53 -0
- data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/timed_stack_multi.rb +79 -0
- data/lib/bundler/vendor/thor/lib/thor.rb +58 -25
- data/lib/bundler/vendor/thor/lib/thor/actions.rb +50 -33
- data/lib/bundler/vendor/thor/lib/thor/actions/create_file.rb +3 -2
- data/lib/bundler/vendor/thor/lib/thor/actions/create_link.rb +5 -3
- data/lib/bundler/vendor/thor/lib/thor/actions/directory.rb +9 -19
- data/lib/bundler/vendor/thor/lib/thor/actions/empty_directory.rb +16 -8
- data/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb +79 -22
- data/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb +33 -20
- data/lib/bundler/vendor/thor/lib/thor/base.rb +110 -67
- data/lib/bundler/vendor/thor/lib/thor/command.rb +33 -24
- data/lib/bundler/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb +21 -1
- data/lib/bundler/vendor/thor/lib/thor/error.rb +81 -3
- data/lib/bundler/vendor/thor/lib/thor/group.rb +16 -16
- data/lib/bundler/vendor/thor/lib/thor/invocation.rb +5 -5
- data/lib/bundler/vendor/thor/lib/thor/line_editor.rb +2 -2
- data/lib/bundler/vendor/thor/lib/thor/line_editor/basic.rb +2 -0
- data/lib/bundler/vendor/thor/lib/thor/line_editor/readline.rb +6 -6
- data/lib/bundler/vendor/thor/lib/thor/nested_context.rb +29 -0
- data/lib/bundler/vendor/thor/lib/thor/parser.rb +4 -4
- data/lib/bundler/vendor/thor/lib/thor/parser/argument.rb +4 -7
- data/lib/bundler/vendor/thor/lib/thor/parser/arguments.rb +18 -18
- data/lib/bundler/vendor/thor/lib/thor/parser/option.rb +60 -26
- data/lib/bundler/vendor/thor/lib/thor/parser/options.rb +31 -13
- data/lib/bundler/vendor/thor/lib/thor/rake_compat.rb +1 -0
- data/lib/bundler/vendor/thor/lib/thor/runner.rb +42 -39
- data/lib/bundler/vendor/thor/lib/thor/shell.rb +5 -5
- data/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +109 -39
- data/lib/bundler/vendor/thor/lib/thor/shell/color.rb +7 -3
- data/lib/bundler/vendor/thor/lib/thor/shell/html.rb +5 -5
- data/lib/bundler/vendor/thor/lib/thor/util.rb +26 -9
- data/lib/bundler/vendor/thor/lib/thor/version.rb +1 -1
- data/lib/bundler/vendor/tmpdir/lib/tmpdir.rb +154 -0
- data/lib/bundler/vendor/uri/lib/uri.rb +104 -0
- data/lib/bundler/vendor/uri/lib/uri/common.rb +744 -0
- data/lib/bundler/vendor/uri/lib/uri/file.rb +94 -0
- data/lib/bundler/vendor/uri/lib/uri/ftp.rb +267 -0
- data/lib/bundler/vendor/uri/lib/uri/generic.rb +1568 -0
- data/lib/bundler/vendor/uri/lib/uri/http.rb +88 -0
- data/lib/bundler/vendor/uri/lib/uri/https.rb +23 -0
- data/lib/bundler/vendor/uri/lib/uri/ldap.rb +261 -0
- data/lib/bundler/vendor/uri/lib/uri/ldaps.rb +21 -0
- data/lib/bundler/vendor/uri/lib/uri/mailto.rb +294 -0
- data/lib/bundler/vendor/uri/lib/uri/rfc2396_parser.rb +546 -0
- data/lib/bundler/vendor/uri/lib/uri/rfc3986_parser.rb +125 -0
- data/lib/bundler/vendor/uri/lib/uri/version.rb +6 -0
- data/lib/bundler/vendored_fileutils.rb +4 -0
- data/lib/bundler/vendored_molinillo.rb +3 -1
- data/lib/bundler/vendored_persistent.rb +45 -9
- data/lib/bundler/vendored_thor.rb +8 -3
- data/lib/bundler/vendored_tmpdir.rb +4 -0
- data/lib/bundler/vendored_uri.rb +4 -0
- data/lib/bundler/version.rb +7 -4
- data/lib/bundler/version_ranges.rb +122 -0
- data/lib/bundler/vlad.rb +8 -2
- data/lib/bundler/worker.rb +38 -6
- data/lib/bundler/yaml_serializer.rb +89 -0
- metadata +164 -158
- data/.gitignore +0 -16
- data/.rspec +0 -3
- data/.rubocop.yml +0 -105
- data/.rubocop_todo.yml +0 -120
- data/.travis.yml +0 -97
- data/CODE_OF_CONDUCT.md +0 -42
- data/CONTRIBUTING.md +0 -32
- data/DEVELOPMENT.md +0 -118
- data/ISSUES.md +0 -96
- data/Rakefile +0 -309
- data/bin/rake +0 -14
- data/bin/rspec +0 -10
- data/bin/rubocop +0 -11
- data/exe/bundle_ruby +0 -60
- data/lib/bundler/cli/package.rb +0 -45
- data/lib/bundler/environment.rb +0 -41
- data/lib/bundler/gem_path_manipulation.rb +0 -8
- data/lib/bundler/gem_remote_fetcher.rb +0 -41
- data/lib/bundler/ssl_certs/AddTrustExternalCARoot-2048.pem +0 -25
- data/lib/bundler/ssl_certs/AddTrustExternalCARoot.pem +0 -32
- data/lib/bundler/ssl_certs/Class3PublicPrimaryCertificationAuthority.pem +0 -14
- data/lib/bundler/ssl_certs/DigiCertHighAssuranceEVRootCA.pem +0 -23
- data/lib/bundler/ssl_certs/EntrustnetSecureServerCertificationAuthority.pem +0 -28
- data/lib/bundler/ssl_certs/GeoTrustGlobalCA.pem +0 -20
- data/lib/bundler/ssl_certs/certificate_manager.rb +0 -64
- data/lib/bundler/templates/newgem/test/test_helper.rb.tt +0 -4
- data/lib/bundler/vendor/net/http/faster.rb +0 -26
- data/lib/bundler/vendor/net/http/persistent/ssl_reuse.rb +0 -128
- data/lib/bundler/vendor/thor/lib/thor/core_ext/io_binary_read.rb +0 -10
- data/lib/bundler/vendor/thor/lib/thor/core_ext/ordered_hash.rb +0 -98
- data/man/bundle-config.ronn +0 -187
- data/man/bundle-update.ronn +0 -188
- data/man/bundle.ronn +0 -98
- data/man/index.txt +0 -8
data/lib/bundler/resolver.rb
CHANGED
@@ -1,171 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Bundler
|
2
4
|
class Resolver
|
3
|
-
|
4
|
-
|
5
|
-
class Molinillo::VersionConflict
|
6
|
-
def printable_dep(dep)
|
7
|
-
if dep.is_a?(Bundler::Dependency)
|
8
|
-
DepProxy.new(dep, dep.platforms.join(", ")).to_s.strip
|
9
|
-
else
|
10
|
-
dep.to_s
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
def message
|
15
|
-
conflicts.sort.reduce("") do |o, (name, conflict)|
|
16
|
-
o << %(Bundler could not find compatible versions for gem "#{name}":\n)
|
17
|
-
if conflict.locked_requirement
|
18
|
-
o << %( In snapshot (#{Bundler.default_lockfile.basename}):\n)
|
19
|
-
o << %( #{printable_dep(conflict.locked_requirement)}\n)
|
20
|
-
o << %(\n)
|
21
|
-
end
|
22
|
-
o << %( In Gemfile:\n)
|
23
|
-
o << conflict.requirement_trees.sort_by {|t| t.reverse.map(&:name) }.map do |tree|
|
24
|
-
t = ""
|
25
|
-
depth = 2
|
26
|
-
tree.each do |req|
|
27
|
-
t << " " * depth << req.to_s
|
28
|
-
unless tree.last == req
|
29
|
-
if spec = conflict.activated_by_name[req.name]
|
30
|
-
t << %( was resolved to #{spec.version}, which)
|
31
|
-
end
|
32
|
-
t << %( depends on)
|
33
|
-
end
|
34
|
-
t << %(\n)
|
35
|
-
depth += 1
|
36
|
-
end
|
37
|
-
t
|
38
|
-
end.join("\n")
|
39
|
-
|
40
|
-
if name == "bundler"
|
41
|
-
o << %(\n Current Bundler version:\n bundler (#{Bundler::VERSION}))
|
42
|
-
other_bundler_required = !conflict.requirement.requirement.satisfied_by?(Gem::Version.new Bundler::VERSION)
|
43
|
-
end
|
44
|
-
|
45
|
-
if name == "bundler" && other_bundler_required
|
46
|
-
o << "\n"
|
47
|
-
o << "This Gemfile requires a different version of Bundler.\n"
|
48
|
-
o << "Perhaps you need to update Bundler by running `gem install bundler`?\n"
|
49
|
-
end
|
50
|
-
if conflict.locked_requirement
|
51
|
-
o << "\n"
|
52
|
-
o << %(Running `bundle update` will rebuild your snapshot from scratch, using only\n)
|
53
|
-
o << %(the gems in your Gemfile, which may resolve the conflict.\n)
|
54
|
-
elsif !conflict.existing
|
55
|
-
o << "\n"
|
56
|
-
if conflict.requirement_trees.first.size > 1
|
57
|
-
o << "Could not find gem '#{conflict.requirement}', which is required by "
|
58
|
-
o << "gem '#{conflict.requirement_trees.first[-2]}', in any of the sources."
|
59
|
-
else
|
60
|
-
o << "Could not find gem '#{conflict.requirement}' in any of the sources\n"
|
61
|
-
end
|
62
|
-
end
|
63
|
-
o
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
ALL = Bundler::Dependency::PLATFORM_MAP.values.uniq.freeze
|
69
|
-
|
70
|
-
class SpecGroup < Array
|
71
|
-
include GemHelpers
|
72
|
-
|
73
|
-
attr_reader :activated, :required_by
|
74
|
-
|
75
|
-
def initialize(a)
|
76
|
-
super
|
77
|
-
@required_by = []
|
78
|
-
@activated = []
|
79
|
-
@dependencies = nil
|
80
|
-
@specs = {}
|
81
|
-
|
82
|
-
ALL.each do |p|
|
83
|
-
@specs[p] = reverse.find {|s| s.match_platform(p) }
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
def initialize_copy(o)
|
88
|
-
super
|
89
|
-
@required_by = o.required_by.dup
|
90
|
-
@activated = o.activated.dup
|
91
|
-
end
|
92
|
-
|
93
|
-
def to_specs
|
94
|
-
specs = {}
|
95
|
-
|
96
|
-
@activated.each do |p|
|
97
|
-
next unless s = @specs[p]
|
98
|
-
platform = generic(Gem::Platform.new(s.platform))
|
99
|
-
next if specs[platform]
|
100
|
-
|
101
|
-
lazy_spec = LazySpecification.new(name, version, platform, source)
|
102
|
-
lazy_spec.dependencies.replace s.dependencies
|
103
|
-
specs[platform] = lazy_spec
|
104
|
-
end
|
105
|
-
specs.values
|
106
|
-
end
|
107
|
-
|
108
|
-
def activate_platform(platform)
|
109
|
-
unless @activated.include?(platform)
|
110
|
-
if for?(platform, nil)
|
111
|
-
@activated << platform
|
112
|
-
return __dependencies[platform] || []
|
113
|
-
end
|
114
|
-
end
|
115
|
-
[]
|
116
|
-
end
|
117
|
-
|
118
|
-
def name
|
119
|
-
@name ||= first.name
|
120
|
-
end
|
121
|
-
|
122
|
-
def version
|
123
|
-
@version ||= first.version
|
124
|
-
end
|
125
|
-
|
126
|
-
def source
|
127
|
-
@source ||= first.source
|
128
|
-
end
|
129
|
-
|
130
|
-
def for?(platform, required_ruby_version)
|
131
|
-
if spec = @specs[platform]
|
132
|
-
if required_ruby_version && spec_required_ruby_version = spec.required_ruby_version
|
133
|
-
spec_required_ruby_version.satisfied_by?(required_ruby_version)
|
134
|
-
else
|
135
|
-
true
|
136
|
-
end
|
137
|
-
end
|
138
|
-
end
|
139
|
-
|
140
|
-
def to_s
|
141
|
-
"#{name} (#{version})"
|
142
|
-
end
|
143
|
-
|
144
|
-
def dependencies_for_activated_platforms
|
145
|
-
@activated.map {|p| __dependencies[p] }.flatten
|
146
|
-
end
|
147
|
-
|
148
|
-
def platforms_for_dependency_named(dependency)
|
149
|
-
__dependencies.select {|_, deps| deps.map(&:name).include? dependency }.keys
|
150
|
-
end
|
151
|
-
|
152
|
-
private
|
153
|
-
|
154
|
-
def __dependencies
|
155
|
-
@dependencies ||= begin
|
156
|
-
dependencies = {}
|
157
|
-
ALL.each do |p|
|
158
|
-
next unless spec = @specs[p]
|
159
|
-
dependencies[p] = []
|
160
|
-
spec.dependencies.each do |dep|
|
161
|
-
next if dep.type == :development
|
162
|
-
dependencies[p] << DepProxy.new(dep, p)
|
163
|
-
end
|
164
|
-
end
|
165
|
-
dependencies
|
166
|
-
end
|
167
|
-
end
|
168
|
-
end
|
5
|
+
require_relative "vendored_molinillo"
|
6
|
+
require_relative "resolver/spec_group"
|
169
7
|
|
170
8
|
# Figures out the best possible configuration of gems that satisfies
|
171
9
|
# the list of passed dependencies and any child dependencies without
|
@@ -177,30 +15,48 @@ module Bundler
|
|
177
15
|
# ==== Returns
|
178
16
|
# <GemBundle>,nil:: If the list of dependencies can be resolved, a
|
179
17
|
# collection of gemspecs is returned. Otherwise, nil is returned.
|
180
|
-
def self.resolve(requirements, index, source_requirements = {}, base = [],
|
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
|
181
20
|
base = SpecSet.new(base) unless base.is_a?(SpecSet)
|
182
|
-
resolver = new(index, source_requirements, base,
|
21
|
+
resolver = new(index, source_requirements, base, gem_version_promoter, additional_base_requirements, platforms)
|
183
22
|
result = resolver.start(requirements)
|
184
23
|
SpecSet.new(result)
|
185
24
|
end
|
186
25
|
|
187
|
-
def initialize(index, source_requirements, base,
|
26
|
+
def initialize(index, source_requirements, base, gem_version_promoter, additional_base_requirements, platforms)
|
188
27
|
@index = index
|
189
28
|
@source_requirements = source_requirements
|
190
29
|
@base = base
|
191
30
|
@resolver = Molinillo::Resolver.new(self, self)
|
192
31
|
@search_for = {}
|
193
32
|
@base_dg = Molinillo::DependencyGraph.new
|
194
|
-
@base.each
|
195
|
-
|
33
|
+
@base.each do |ls|
|
34
|
+
dep = Dependency.new(ls.name, ls.version)
|
35
|
+
@base_dg.add_vertex(ls.name, DepProxy.get_proxy(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
|
+
@use_gvp = Bundler.feature_flag.use_gem_version_promoter_for_major_updates? || !@gem_version_promoter.major?
|
42
|
+
@lockfile_uses_separate_rubygems_sources = Bundler.feature_flag.disable_multisource?
|
196
43
|
end
|
197
44
|
|
198
45
|
def start(requirements)
|
46
|
+
@gem_version_promoter.prerelease_specified = @prerelease_specified = {}
|
47
|
+
requirements.each {|dep| @prerelease_specified[dep.name] ||= dep.prerelease? }
|
48
|
+
|
199
49
|
verify_gemfile_dependencies_are_found!(requirements)
|
200
50
|
dg = @resolver.resolve(requirements, @base_dg)
|
201
|
-
dg.
|
51
|
+
dg.
|
52
|
+
tap {|resolved| validate_resolved_specs!(resolved) }.
|
53
|
+
map(&:payload).
|
54
|
+
reject {|sg| sg.name.end_with?("\0") }.
|
55
|
+
map(&:to_specs).
|
56
|
+
flatten
|
202
57
|
rescue Molinillo::VersionConflict => e
|
203
|
-
|
58
|
+
message = version_conflict_message(e)
|
59
|
+
raise VersionConflict.new(e.conflicts.keys.uniq, message)
|
204
60
|
rescue Molinillo::CircularDependencyError => e
|
205
61
|
names = e.dependencies.sort_by(&:name).map {|d| "gem '#{d.name}'" }
|
206
62
|
raise CyclicDependencyError, "Your bundle requires gems that depend" \
|
@@ -216,19 +72,24 @@ module Bundler
|
|
216
72
|
# @param [Integer] depth the current depth of the resolution process.
|
217
73
|
# @return [void]
|
218
74
|
def debug(depth = 0)
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
end
|
75
|
+
return unless debug?
|
76
|
+
debug_info = yield
|
77
|
+
debug_info = debug_info.inspect unless debug_info.is_a?(String)
|
78
|
+
puts debug_info.split("\n").map {|s| depth == 0 ? "BUNDLER: #{s}" : "BUNDLER(#{depth}): #{s}" }
|
224
79
|
end
|
225
80
|
|
226
81
|
def debug?
|
227
|
-
|
82
|
+
return @debug_mode if defined?(@debug_mode)
|
83
|
+
@debug_mode =
|
84
|
+
ENV["BUNDLER_DEBUG_RESOLVER"] ||
|
85
|
+
ENV["BUNDLER_DEBUG_RESOLVER_TREE"] ||
|
86
|
+
ENV["DEBUG_RESOLVER"] ||
|
87
|
+
ENV["DEBUG_RESOLVER_TREE"] ||
|
88
|
+
false
|
228
89
|
end
|
229
90
|
|
230
91
|
def before_resolution
|
231
|
-
Bundler.ui.info "Resolving dependencies...",
|
92
|
+
Bundler.ui.info "Resolving dependencies...", debug?
|
232
93
|
end
|
233
94
|
|
234
95
|
def after_resolution
|
@@ -236,43 +97,98 @@ module Bundler
|
|
236
97
|
end
|
237
98
|
|
238
99
|
def indicate_progress
|
239
|
-
Bundler.ui.info ".", false
|
100
|
+
Bundler.ui.info ".", false unless debug?
|
240
101
|
end
|
241
102
|
|
242
|
-
private
|
243
|
-
|
244
103
|
include Molinillo::SpecificationProvider
|
245
104
|
|
246
105
|
def dependencies_for(specification)
|
247
106
|
specification.dependencies_for_activated_platforms
|
248
107
|
end
|
249
108
|
|
250
|
-
def search_for(
|
251
|
-
platform =
|
252
|
-
dependency =
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
109
|
+
def search_for(dependency_proxy)
|
110
|
+
platform = dependency_proxy.__platform
|
111
|
+
dependency = dependency_proxy.dep
|
112
|
+
@search_for[dependency_proxy] ||= begin
|
113
|
+
name = dependency.name
|
114
|
+
index = index_for(dependency)
|
115
|
+
results = index.search(dependency, @base[name])
|
116
|
+
|
117
|
+
if vertex = @base_dg.vertex_named(name)
|
257
118
|
locked_requirement = vertex.payload.requirement
|
258
119
|
end
|
259
|
-
|
260
|
-
|
261
|
-
|
120
|
+
|
121
|
+
if !@prerelease_specified[name] && (!@use_gvp || locked_requirement.nil?)
|
122
|
+
# Move prereleases to the beginning of the list, so they're considered
|
123
|
+
# last during resolution.
|
124
|
+
pre, results = results.partition {|spec| spec.version.prerelease? }
|
125
|
+
results = pre + results
|
126
|
+
end
|
127
|
+
|
128
|
+
spec_groups = if results.any?
|
129
|
+
nested = []
|
262
130
|
results.each do |spec|
|
263
|
-
|
264
|
-
|
265
|
-
|
131
|
+
version, specs = nested.last
|
132
|
+
if version == spec.version
|
133
|
+
specs << spec
|
134
|
+
else
|
135
|
+
nested << [spec.version, [spec]]
|
266
136
|
end
|
267
|
-
nested.last << spec
|
268
137
|
end
|
269
|
-
|
270
|
-
|
138
|
+
nested.reduce([]) do |groups, (version, specs)|
|
139
|
+
next groups if locked_requirement && !locked_requirement.satisfied_by?(version)
|
140
|
+
spec_group = SpecGroup.new(specs)
|
141
|
+
spec_group.ignores_bundler_dependencies = @allow_bundler_dependency_conflicts
|
142
|
+
groups << spec_group
|
143
|
+
end
|
271
144
|
else
|
272
145
|
[]
|
273
146
|
end
|
147
|
+
# GVP handles major itself, but it's still a bit risky to trust it with it
|
148
|
+
# until we get it settled with new behavior. For 2.x it can take over all cases.
|
149
|
+
search = if !@use_gvp
|
150
|
+
spec_groups
|
151
|
+
else
|
152
|
+
@gem_version_promoter.sort_versions(dependency, spec_groups)
|
153
|
+
end
|
154
|
+
selected_sgs = []
|
155
|
+
search.each do |sg|
|
156
|
+
next unless sg.for?(platform)
|
157
|
+
sg_all_platforms = sg.copy_for(self.class.sort_platforms(@platforms).reverse)
|
158
|
+
next unless sg_all_platforms
|
159
|
+
|
160
|
+
selected_sgs << sg_all_platforms
|
161
|
+
|
162
|
+
next if sg_all_platforms.activated_platforms == [Gem::Platform::RUBY]
|
163
|
+
# Add a spec group for "non platform specific spec" as the fallback
|
164
|
+
# spec group.
|
165
|
+
sg_ruby = sg.copy_for([Gem::Platform::RUBY])
|
166
|
+
next unless sg_ruby
|
167
|
+
|
168
|
+
sg_ruby_deps = sg_ruby.dependencies_for_activated_platforms.map(&:dep)
|
169
|
+
sg_all_platforms_deps = sg_all_platforms.dependencies_for_activated_platforms.map(&:dep)
|
170
|
+
|
171
|
+
selected_sgs.insert(-2, sg_ruby) if sg_ruby_deps != sg_all_platforms_deps
|
172
|
+
end
|
173
|
+
selected_sgs
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
def index_for(dependency)
|
178
|
+
source = @source_requirements[dependency.name]
|
179
|
+
if source
|
180
|
+
source.specs
|
181
|
+
elsif @lockfile_uses_separate_rubygems_sources
|
182
|
+
Index.build do |idx|
|
183
|
+
if dependency.all_sources
|
184
|
+
dependency.all_sources.each {|s| idx.add_source(s.specs) if s }
|
185
|
+
else
|
186
|
+
idx.add_source @source_requirements[:default].specs
|
187
|
+
end
|
188
|
+
end
|
189
|
+
else
|
190
|
+
@index
|
274
191
|
end
|
275
|
-
search.select {|sg| sg.for?(platform, @ruby_version) }.each {|sg| sg.activate_platform(platform) }
|
276
192
|
end
|
277
193
|
|
278
194
|
def name_for(dependency)
|
@@ -281,46 +197,82 @@ module Bundler
|
|
281
197
|
|
282
198
|
def name_for_explicit_dependency_source
|
283
199
|
Bundler.default_gemfile.basename.to_s
|
284
|
-
rescue
|
200
|
+
rescue StandardError
|
285
201
|
"Gemfile"
|
286
202
|
end
|
287
203
|
|
288
204
|
def name_for_locking_dependency_source
|
289
205
|
Bundler.default_lockfile.basename.to_s
|
290
|
-
rescue
|
206
|
+
rescue StandardError
|
291
207
|
"Gemfile.lock"
|
292
208
|
end
|
293
209
|
|
294
210
|
def requirement_satisfied_by?(requirement, activated, spec)
|
295
|
-
requirement.matches_spec?(spec)
|
211
|
+
requirement.matches_spec?(spec) || spec.source.is_a?(Source::Gemspec)
|
212
|
+
end
|
213
|
+
|
214
|
+
def relevant_sources_for_vertex(vertex)
|
215
|
+
if vertex.root?
|
216
|
+
[@source_requirements[vertex.name]]
|
217
|
+
elsif @lockfile_uses_separate_rubygems_sources
|
218
|
+
vertex.recursive_predecessors.map do |v|
|
219
|
+
@source_requirements[v.name]
|
220
|
+
end << @source_requirements[:default]
|
221
|
+
end
|
296
222
|
end
|
297
223
|
|
298
224
|
def sort_dependencies(dependencies, activated, conflicts)
|
299
225
|
dependencies.sort_by do |dependency|
|
226
|
+
dependency.all_sources = relevant_sources_for_vertex(activated.vertex_named(dependency.name))
|
300
227
|
name = name_for(dependency)
|
228
|
+
vertex = activated.vertex_named(name)
|
301
229
|
[
|
302
|
-
|
230
|
+
@base_dg.vertex_named(name) ? 0 : 1,
|
231
|
+
vertex.payload ? 0 : 1,
|
232
|
+
vertex.root? ? 0 : 1,
|
303
233
|
amount_constrained(dependency),
|
304
234
|
conflicts[name] ? 0 : 1,
|
305
|
-
|
235
|
+
vertex.payload ? 0 : search_for(dependency).count,
|
236
|
+
self.class.platform_sort_key(dependency.__platform),
|
306
237
|
]
|
307
238
|
end
|
308
239
|
end
|
309
240
|
|
241
|
+
# Sort platforms from most general to most specific
|
242
|
+
def self.sort_platforms(platforms)
|
243
|
+
platforms.sort_by do |platform|
|
244
|
+
platform_sort_key(platform)
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
def self.platform_sort_key(platform)
|
249
|
+
# Prefer specific platform to not specific platform
|
250
|
+
return ["99-LAST", "", "", ""] if Gem::Platform::RUBY == platform
|
251
|
+
["00", *platform.to_a.map {|part| part || "" }]
|
252
|
+
end
|
253
|
+
|
254
|
+
private
|
255
|
+
|
256
|
+
# returns an integer \in (-\infty, 0]
|
257
|
+
# a number closer to 0 means the dependency is less constraining
|
258
|
+
#
|
259
|
+
# dependencies w/ 0 or 1 possibilities (ignoring version requirements)
|
260
|
+
# are given very negative values, so they _always_ sort first,
|
261
|
+
# before dependencies that are unconstrained
|
310
262
|
def amount_constrained(dependency)
|
311
263
|
@amount_constrained ||= {}
|
312
264
|
@amount_constrained[dependency.name] ||= begin
|
313
265
|
if (base = @base[dependency.name]) && !base.empty?
|
314
266
|
dependency.requirement.satisfied_by?(base.first.version) ? 0 : 1
|
315
267
|
else
|
316
|
-
|
317
|
-
|
318
|
-
if all
|
319
|
-
|
320
|
-
elsif (search = search_for(dependency).size.to_f) == all && all == 1
|
321
|
-
0
|
268
|
+
all = index_for(dependency).search(dependency.name).size
|
269
|
+
|
270
|
+
if all <= 1
|
271
|
+
all - 1_000_000
|
322
272
|
else
|
323
|
-
search
|
273
|
+
search = search_for(dependency)
|
274
|
+
search = @prerelease_specified[dependency.name] ? search.count : search.count {|s| !s.version.prerelease? }
|
275
|
+
search - all
|
324
276
|
end
|
325
277
|
end
|
326
278
|
end
|
@@ -328,31 +280,166 @@ module Bundler
|
|
328
280
|
|
329
281
|
def verify_gemfile_dependencies_are_found!(requirements)
|
330
282
|
requirements.each do |requirement|
|
331
|
-
|
283
|
+
name = requirement.name
|
284
|
+
next if name == "bundler"
|
332
285
|
next unless search_for(requirement).empty?
|
333
|
-
|
286
|
+
|
287
|
+
cache_message = begin
|
288
|
+
" or in gems cached in #{Bundler.settings.app_cache_path}" if Bundler.app_cache.exist?
|
289
|
+
rescue GemfileNotFound
|
290
|
+
nil
|
291
|
+
end
|
292
|
+
|
293
|
+
if (base = @base[name]) && !base.empty?
|
334
294
|
version = base.first.version
|
335
295
|
message = "You have requested:\n" \
|
336
|
-
" #{
|
337
|
-
"The bundle currently has #{
|
338
|
-
"Try running `bundle update #{
|
296
|
+
" #{name} #{requirement.requirement}\n\n" \
|
297
|
+
"The bundle currently has #{name} locked at #{version}.\n" \
|
298
|
+
"Try running `bundle update #{name}`\n\n" \
|
339
299
|
"If you are updating multiple gems in your Gemfile at once,\n" \
|
340
300
|
"try passing them all to `bundle update`"
|
341
|
-
elsif
|
342
|
-
|
343
|
-
|
344
|
-
message
|
345
|
-
if
|
346
|
-
|
301
|
+
elsif source = @source_requirements[name]
|
302
|
+
specs = source.specs[name]
|
303
|
+
versions_with_platforms = specs.map {|s| [s.version, s.platform] }
|
304
|
+
message = String.new("Could not find gem '#{SharedHelpers.pretty_dependency(requirement)}' in #{source}#{cache_message}.\n")
|
305
|
+
message << if versions_with_platforms.any?
|
306
|
+
"The source contains the following versions of '#{name}': #{formatted_versions_with_platforms(versions_with_platforms)}"
|
347
307
|
else
|
348
|
-
|
308
|
+
"The source does not contain any versions of '#{name}'"
|
349
309
|
end
|
350
310
|
else
|
351
311
|
message = "Could not find gem '#{requirement}' in any of the gem sources " \
|
352
|
-
"listed in your Gemfile
|
312
|
+
"listed in your Gemfile#{cache_message}."
|
353
313
|
end
|
354
314
|
raise GemNotFound, message
|
355
315
|
end
|
356
316
|
end
|
317
|
+
|
318
|
+
def formatted_versions_with_platforms(versions_with_platforms)
|
319
|
+
version_platform_strs = versions_with_platforms.map do |vwp|
|
320
|
+
version = vwp.first
|
321
|
+
platform = vwp.last
|
322
|
+
version_platform_str = String.new(version.to_s)
|
323
|
+
version_platform_str << " #{platform}" unless platform.nil? || platform == Gem::Platform::RUBY
|
324
|
+
version_platform_str
|
325
|
+
end
|
326
|
+
version_platform_strs.join(", ")
|
327
|
+
end
|
328
|
+
|
329
|
+
def version_conflict_message(e)
|
330
|
+
# only show essential conflicts, if possible
|
331
|
+
conflicts = e.conflicts.dup
|
332
|
+
conflicts.delete_if do |_name, conflict|
|
333
|
+
deps = conflict.requirement_trees.map(&:last).flatten(1)
|
334
|
+
!Bundler::VersionRanges.empty?(*Bundler::VersionRanges.for_many(deps.map(&:requirement)))
|
335
|
+
end
|
336
|
+
e = Molinillo::VersionConflict.new(conflicts, e.specification_provider) unless conflicts.empty?
|
337
|
+
|
338
|
+
solver_name = "Bundler"
|
339
|
+
possibility_type = "gem"
|
340
|
+
e.message_with_trees(
|
341
|
+
:solver_name => solver_name,
|
342
|
+
:possibility_type => possibility_type,
|
343
|
+
:reduce_trees => lambda do |trees|
|
344
|
+
# called first, because we want to reduce the amount of work required to find maximal empty sets
|
345
|
+
trees = trees.uniq {|t| t.flatten.map {|dep| [dep.name, dep.requirement] } }
|
346
|
+
|
347
|
+
# bail out if tree size is too big for Array#combination to make any sense
|
348
|
+
return trees if trees.size > 15
|
349
|
+
maximal = 1.upto(trees.size).map do |size|
|
350
|
+
trees.map(&:last).flatten(1).combination(size).to_a
|
351
|
+
end.flatten(1).select do |deps|
|
352
|
+
Bundler::VersionRanges.empty?(*Bundler::VersionRanges.for_many(deps.map(&:requirement)))
|
353
|
+
end.min_by(&:size)
|
354
|
+
|
355
|
+
trees.reject! {|t| !maximal.include?(t.last) } if maximal
|
356
|
+
|
357
|
+
trees.sort_by {|t| t.reverse.map(&:name) }
|
358
|
+
end,
|
359
|
+
:printable_requirement => lambda {|req| SharedHelpers.pretty_dependency(req) },
|
360
|
+
:additional_message_for_conflict => lambda do |o, name, conflict|
|
361
|
+
if name == "bundler"
|
362
|
+
o << %(\n Current Bundler version:\n bundler (#{Bundler::VERSION}))
|
363
|
+
other_bundler_required = !conflict.requirement.requirement.satisfied_by?(Gem::Version.new(Bundler::VERSION))
|
364
|
+
end
|
365
|
+
|
366
|
+
if name == "bundler" && other_bundler_required
|
367
|
+
o << "\n"
|
368
|
+
o << "This Gemfile requires a different version of Bundler.\n"
|
369
|
+
o << "Perhaps you need to update Bundler by running `gem install bundler`?\n"
|
370
|
+
end
|
371
|
+
if conflict.locked_requirement
|
372
|
+
o << "\n"
|
373
|
+
o << %(Running `bundle update` will rebuild your snapshot from scratch, using only\n)
|
374
|
+
o << %(the gems in your Gemfile, which may resolve the conflict.\n)
|
375
|
+
elsif !conflict.existing
|
376
|
+
o << "\n"
|
377
|
+
|
378
|
+
relevant_sources = if conflict.requirement.source
|
379
|
+
[conflict.requirement.source]
|
380
|
+
elsif conflict.requirement.all_sources
|
381
|
+
conflict.requirement.all_sources
|
382
|
+
elsif @lockfile_uses_separate_rubygems_sources
|
383
|
+
# every conflict should have an explicit group of sources when we
|
384
|
+
# enforce strict pinning
|
385
|
+
raise "no source set for #{conflict}"
|
386
|
+
else
|
387
|
+
[]
|
388
|
+
end.compact.map(&:to_s).uniq.sort
|
389
|
+
|
390
|
+
metadata_requirement = name.end_with?("\0")
|
391
|
+
|
392
|
+
o << "Could not find gem '" unless metadata_requirement
|
393
|
+
o << SharedHelpers.pretty_dependency(conflict.requirement)
|
394
|
+
o << "'" unless metadata_requirement
|
395
|
+
if conflict.requirement_trees.first.size > 1
|
396
|
+
o << ", which is required by "
|
397
|
+
o << "gem '#{SharedHelpers.pretty_dependency(conflict.requirement_trees.first[-2])}',"
|
398
|
+
end
|
399
|
+
o << " "
|
400
|
+
|
401
|
+
o << if relevant_sources.empty?
|
402
|
+
"in any of the sources.\n"
|
403
|
+
elsif metadata_requirement
|
404
|
+
"is not available in #{relevant_sources.join(" or ")}"
|
405
|
+
else
|
406
|
+
"in any of the relevant sources:\n #{relevant_sources * "\n "}\n"
|
407
|
+
end
|
408
|
+
end
|
409
|
+
end,
|
410
|
+
:version_for_spec => lambda {|spec| spec.version },
|
411
|
+
:incompatible_version_message_for_conflict => lambda do |name, _conflict|
|
412
|
+
if name.end_with?("\0")
|
413
|
+
%(#{solver_name} found conflicting requirements for the #{name} version:)
|
414
|
+
else
|
415
|
+
%(#{solver_name} could not find compatible versions for #{possibility_type} "#{name}":)
|
416
|
+
end
|
417
|
+
end
|
418
|
+
)
|
419
|
+
end
|
420
|
+
|
421
|
+
def validate_resolved_specs!(resolved_specs)
|
422
|
+
resolved_specs.each do |v|
|
423
|
+
name = v.name
|
424
|
+
next unless sources = relevant_sources_for_vertex(v)
|
425
|
+
sources.compact!
|
426
|
+
if default_index = sources.index(@source_requirements[:default])
|
427
|
+
sources.delete_at(default_index)
|
428
|
+
end
|
429
|
+
sources.reject! {|s| s.specs[name].empty? }
|
430
|
+
sources.uniq!
|
431
|
+
next if sources.size <= 1
|
432
|
+
|
433
|
+
multisource_disabled = Bundler.feature_flag.disable_multisource?
|
434
|
+
|
435
|
+
msg = ["The gem '#{name}' was found in multiple relevant sources."]
|
436
|
+
msg.concat sources.map {|s| " * #{s}" }.sort
|
437
|
+
msg << "You #{multisource_disabled ? :must : :should} add this gem to the source block for the source you wish it to be installed from."
|
438
|
+
msg = msg.join("\n")
|
439
|
+
|
440
|
+
raise SecurityError, msg if multisource_disabled
|
441
|
+
Bundler.ui.warn "Warning: #{msg}"
|
442
|
+
end
|
443
|
+
end
|
357
444
|
end
|
358
445
|
end
|