bundler 1.15.1 → 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.
- checksums.yaml +5 -5
- data/CHANGELOG.md +320 -0
- data/README.md +17 -8
- data/bundler.gemspec +25 -9
- data/exe/bundle +1 -6
- data/exe/bundle_ruby +4 -3
- data/lib/bundler/build_metadata.rb +53 -0
- data/lib/bundler/capistrano.rb +5 -0
- data/lib/bundler/cli/add.rb +15 -6
- data/lib/bundler/cli/binstubs.rb +17 -9
- data/lib/bundler/cli/cache.rb +5 -4
- data/lib/bundler/cli/check.rb +3 -5
- data/lib/bundler/cli/clean.rb +5 -6
- data/lib/bundler/cli/common.rb +11 -2
- data/lib/bundler/cli/config.rb +2 -1
- data/lib/bundler/cli/console.rb +2 -1
- data/lib/bundler/cli/doctor.rb +48 -1
- data/lib/bundler/cli/exec.rb +6 -5
- data/lib/bundler/cli/gem.rb +13 -8
- data/lib/bundler/cli/info.rb +0 -1
- data/lib/bundler/cli/init.rb +18 -6
- data/lib/bundler/cli/inject.rb +1 -0
- data/lib/bundler/cli/install.rb +64 -77
- data/lib/bundler/cli/issue.rb +1 -1
- data/lib/bundler/cli/list.rb +58 -0
- data/lib/bundler/cli/lock.rb +0 -1
- data/lib/bundler/cli/open.rb +2 -2
- data/lib/bundler/cli/outdated.rb +20 -9
- data/lib/bundler/cli/package.rb +9 -6
- data/lib/bundler/cli/platform.rb +1 -0
- data/lib/bundler/cli/plugin.rb +1 -0
- data/lib/bundler/cli/pristine.rb +20 -6
- data/lib/bundler/cli/remove.rb +18 -0
- data/lib/bundler/cli/show.rb +0 -1
- data/lib/bundler/cli/update.rb +35 -7
- data/lib/bundler/cli/viz.rb +4 -0
- data/lib/bundler/cli.rb +234 -90
- data/lib/bundler/compact_index_client/cache.rb +1 -2
- data/lib/bundler/compact_index_client/updater.rb +35 -7
- data/lib/bundler/compact_index_client.rb +1 -0
- data/lib/bundler/compatibility_guard.rb +14 -0
- data/lib/bundler/constants.rb +1 -0
- data/lib/bundler/current_ruby.rb +13 -5
- data/lib/bundler/definition.rb +192 -139
- data/lib/bundler/dep_proxy.rb +3 -1
- data/lib/bundler/dependency.rb +9 -9
- data/lib/bundler/deployment.rb +1 -1
- data/lib/bundler/deprecate.rb +15 -3
- data/lib/bundler/dsl.rb +115 -64
- data/lib/bundler/endpoint_specification.rb +10 -1
- data/lib/bundler/env.rb +90 -29
- data/lib/bundler/environment_preserver.rb +27 -6
- data/lib/bundler/errors.rb +1 -0
- data/lib/bundler/feature_flag.rb +46 -4
- data/lib/bundler/fetcher/base.rb +1 -0
- data/lib/bundler/fetcher/compact_index.rb +2 -11
- data/lib/bundler/fetcher/dependency.rb +2 -1
- data/lib/bundler/fetcher/downloader.rb +11 -5
- data/lib/bundler/fetcher/index.rb +3 -2
- data/lib/bundler/fetcher.rb +18 -11
- data/lib/bundler/friendly_errors.rb +6 -1
- data/lib/bundler/gem_helper.rb +19 -10
- data/lib/bundler/gem_helpers.rb +1 -0
- data/lib/bundler/gem_remote_fetcher.rb +1 -0
- data/lib/bundler/gem_tasks.rb +1 -0
- data/lib/bundler/gem_version_promoter.rb +17 -2
- data/lib/bundler/gemdeps.rb +1 -0
- data/lib/bundler/graph.rb +1 -0
- data/lib/bundler/index.rb +8 -8
- data/lib/bundler/injector.rb +192 -30
- data/lib/bundler/inline.rb +10 -10
- data/lib/bundler/installer/gem_installer.rb +12 -2
- data/lib/bundler/installer/parallel_installer.rb +78 -42
- data/lib/bundler/installer/standalone.rb +1 -0
- data/lib/bundler/installer.rb +138 -53
- data/lib/bundler/lazy_specification.rb +3 -2
- data/lib/bundler/lockfile_generator.rb +95 -0
- data/lib/bundler/lockfile_parser.rb +10 -4
- data/lib/bundler/match_platform.rb +1 -0
- data/lib/bundler/mirror.rb +8 -5
- data/lib/bundler/plugin/api/source.rb +9 -2
- data/lib/bundler/plugin/events.rb +61 -0
- data/lib/bundler/plugin/index.rb +7 -2
- data/lib/bundler/plugin/installer.rb +7 -6
- data/lib/bundler/plugin/source_list.rb +7 -8
- data/lib/bundler/plugin.rb +13 -5
- data/lib/bundler/process_lock.rb +24 -0
- data/lib/bundler/psyched_yaml.rb +10 -0
- data/lib/bundler/remote_specification.rb +10 -1
- data/lib/bundler/resolver/spec_group.rb +106 -0
- data/lib/bundler/resolver.rb +158 -195
- data/lib/bundler/retry.rb +1 -0
- data/lib/bundler/ruby_dsl.rb +1 -0
- data/lib/bundler/ruby_version.rb +2 -1
- data/lib/bundler/rubygems_ext.rb +5 -4
- data/lib/bundler/rubygems_gem_installer.rb +31 -1
- data/lib/bundler/rubygems_integration.rb +71 -32
- data/lib/bundler/runtime.rb +11 -9
- data/lib/bundler/settings/validator.rb +102 -0
- data/lib/bundler/settings.rb +213 -86
- data/lib/bundler/setup.rb +4 -7
- data/lib/bundler/shared_helpers.rb +131 -26
- data/lib/bundler/similarity_detector.rb +1 -0
- data/lib/bundler/source/gemspec.rb +1 -0
- data/lib/bundler/source/git/git_proxy.rb +21 -11
- data/lib/bundler/source/git.rb +24 -19
- data/lib/bundler/source/metadata.rb +62 -0
- data/lib/bundler/source/path/installer.rb +2 -0
- data/lib/bundler/source/path.rb +11 -7
- data/lib/bundler/source/rubygems/remote.rb +8 -2
- data/lib/bundler/source/rubygems.rb +161 -84
- data/lib/bundler/source.rb +36 -0
- data/lib/bundler/source_list.rb +75 -15
- data/lib/bundler/spec_set.rb +12 -6
- data/lib/bundler/ssl_certs/certificate_manager.rb +2 -1
- data/lib/bundler/stub_specification.rb +1 -0
- data/lib/bundler/templates/.document +1 -0
- data/lib/bundler/templates/Executable +12 -0
- data/lib/bundler/templates/Executable.bundler +105 -0
- data/lib/bundler/templates/Gemfile +3 -0
- data/lib/bundler/templates/gems.rb +8 -0
- data/lib/bundler/templates/newgem/Gemfile.tt +2 -0
- data/lib/bundler/templates/newgem/README.md.tt +1 -1
- data/lib/bundler/templates/newgem/gitignore.tt +0 -1
- data/lib/bundler/templates/newgem/lib/newgem.rb.tt +1 -0
- data/lib/bundler/templates/newgem/newgem.gemspec.tt +12 -3
- data/lib/bundler/templates/newgem/rspec.tt +1 -0
- data/lib/bundler/templates/newgem/spec/newgem_spec.rb.tt +0 -2
- data/lib/bundler/templates/newgem/{.travis.yml.tt → travis.yml.tt} +2 -0
- data/lib/bundler/ui/rg_proxy.rb +1 -0
- data/lib/bundler/ui/shell.rb +17 -4
- data/lib/bundler/ui/silent.rb +1 -0
- data/lib/bundler/ui.rb +1 -0
- data/lib/bundler/uri_credentials_filter.rb +1 -0
- data/lib/bundler/vendor/fileutils/lib/fileutils.rb +1638 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/compatibility.rb +26 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/delegates/resolution_state.rb +7 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/delegates/specification_provider.rb +1 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/action.rb +1 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb +1 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_vertex.rb +1 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/delete_edge.rb +1 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb +1 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/log.rb +1 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/set_payload.rb +1 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/tag.rb +1 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb +15 -4
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb +3 -2
- data/lib/bundler/vendor/molinillo/lib/molinillo/errors.rb +75 -7
- data/lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb +2 -1
- data/lib/bundler/vendor/molinillo/lib/molinillo/modules/specification_provider.rb +1 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/modules/ui.rb +3 -1
- data/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb +491 -148
- data/lib/bundler/vendor/molinillo/lib/molinillo/resolver.rb +1 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/state.rb +8 -4
- data/lib/bundler/vendor/molinillo/lib/molinillo.rb +2 -0
- data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb +3 -1
- data/lib/bundler/vendor/thor/lib/thor/actions/create_file.rb +1 -0
- data/lib/bundler/vendor/thor/lib/thor/actions/create_link.rb +1 -0
- data/lib/bundler/vendor/thor/lib/thor/actions/empty_directory.rb +9 -1
- data/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb +45 -8
- data/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb +9 -3
- data/lib/bundler/vendor/thor/lib/thor/actions.rb +6 -3
- data/lib/bundler/vendor/thor/lib/thor/base.rb +27 -4
- data/lib/bundler/vendor/thor/lib/thor/command.rb +9 -7
- data/lib/bundler/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb +12 -0
- data/lib/bundler/vendor/thor/lib/thor/group.rb +1 -1
- data/lib/bundler/vendor/thor/lib/thor/line_editor/basic.rb +2 -0
- data/lib/bundler/vendor/thor/lib/thor/parser/option.rb +5 -5
- data/lib/bundler/vendor/thor/lib/thor/parser/options.rb +6 -5
- data/lib/bundler/vendor/thor/lib/thor/runner.rb +6 -4
- data/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +10 -9
- data/lib/bundler/vendor/thor/lib/thor/version.rb +1 -1
- data/lib/bundler/vendor/thor/lib/thor.rb +25 -8
- data/lib/bundler/vendored_fileutils.rb +9 -0
- data/lib/bundler/vendored_molinillo.rb +1 -0
- data/lib/bundler/vendored_persistent.rb +35 -0
- data/lib/bundler/vendored_thor.rb +1 -0
- data/lib/bundler/version.rb +6 -2
- data/lib/bundler/version_ranges.rb +1 -0
- data/lib/bundler/vlad.rb +5 -0
- data/lib/bundler/worker.rb +1 -0
- data/lib/bundler/yaml_serializer.rb +3 -3
- data/lib/bundler.rb +86 -52
- data/man/bundle-add.1 +18 -3
- data/man/bundle-add.1.txt +26 -14
- data/man/bundle-add.ronn +13 -2
- data/man/bundle-binstubs.1 +11 -1
- data/man/bundle-binstubs.1.txt +33 -18
- data/man/bundle-binstubs.ronn +15 -1
- data/man/bundle-check.1 +4 -4
- data/man/bundle-check.1.txt +15 -14
- data/man/bundle-check.ronn +3 -3
- data/man/bundle-clean.1 +1 -1
- data/man/bundle-clean.1.txt +10 -10
- data/man/bundle-config.1 +129 -29
- data/man/bundle-config.1.txt +285 -174
- data/man/bundle-config.ronn +167 -88
- data/man/bundle-doctor.1 +44 -0
- data/man/bundle-doctor.1.txt +44 -0
- data/man/bundle-doctor.ronn +33 -0
- data/man/bundle-exec.1 +6 -3
- data/man/bundle-exec.1.txt +78 -71
- data/man/bundle-exec.ronn +10 -3
- data/man/bundle-gem.1 +4 -4
- data/man/bundle-gem.1.txt +41 -40
- data/man/bundle-gem.ronn +3 -2
- data/man/bundle-info.1 +1 -1
- data/man/bundle-info.1.txt +8 -8
- data/man/bundle-init.1 +9 -4
- data/man/bundle-init.1.txt +23 -13
- data/man/bundle-init.ronn +15 -4
- data/man/bundle-inject.1 +4 -4
- data/man/bundle-inject.1.txt +10 -10
- data/man/bundle-inject.ronn +3 -3
- data/man/bundle-install.1 +31 -28
- data/man/bundle-install.1.txt +205 -194
- data/man/bundle-install.ronn +44 -35
- data/man/bundle-list.1 +50 -0
- data/man/bundle-list.1.txt +43 -0
- data/man/bundle-list.ronn +33 -0
- data/man/bundle-lock.1 +1 -1
- data/man/bundle-lock.1.txt +47 -47
- data/man/bundle-lock.ronn +1 -1
- data/man/bundle-open.1 +1 -1
- data/man/bundle-open.1.txt +7 -7
- data/man/bundle-outdated.1 +7 -3
- data/man/bundle-outdated.1.txt +40 -36
- data/man/bundle-outdated.ronn +6 -2
- data/man/bundle-package.1 +6 -3
- data/man/bundle-package.1.txt +44 -39
- data/man/bundle-package.ronn +7 -2
- data/man/bundle-platform.1 +1 -1
- data/man/bundle-platform.1.txt +13 -13
- data/man/bundle-pristine.1 +21 -3
- data/man/bundle-pristine.1.txt +33 -10
- data/man/bundle-pristine.ronn +24 -3
- data/man/bundle-remove.1 +31 -0
- data/man/bundle-remove.1.txt +34 -0
- data/man/bundle-remove.ronn +23 -0
- data/man/bundle-show.1 +3 -3
- data/man/bundle-show.1.txt +14 -12
- data/man/bundle-show.ronn +3 -2
- data/man/bundle-update.1 +13 -9
- data/man/bundle-update.1.txt +133 -130
- data/man/bundle-update.ronn +21 -17
- data/man/bundle-viz.1 +7 -7
- data/man/bundle-viz.1.txt +17 -15
- data/man/bundle-viz.ronn +6 -6
- data/man/bundle.1 +31 -32
- data/man/bundle.1.txt +63 -75
- data/man/bundle.ronn +35 -47
- data/man/gemfile.5 +44 -8
- data/man/gemfile.5.ronn +54 -8
- data/man/gemfile.5.txt +218 -165
- data/man/index.txt +25 -15
- metadata +36 -44
- data/.codeclimate.yml +0 -25
- data/.gitignore +0 -18
- data/.rspec +0 -3
- data/.rubocop.yml +0 -131
- data/.rubocop_todo.yml +0 -418
- data/.travis.yml +0 -122
- data/CODE_OF_CONDUCT.md +0 -42
- data/CONTRIBUTING.md +0 -17
- data/Rakefile +0 -346
- data/bin/rake +0 -19
- data/bin/rspec +0 -15
- data/bin/rubocop +0 -17
- data/bin/with_rubygems +0 -39
- data/doc/README.md +0 -30
- data/doc/TROUBLESHOOTING.md +0 -64
- data/doc/contributing/BUG_TRIAGE.md +0 -36
- data/doc/contributing/COMMUNITY.md +0 -13
- data/doc/contributing/GETTING_HELP.md +0 -11
- data/doc/contributing/HOW_YOU_CAN_HELP.md +0 -27
- data/doc/contributing/ISSUES.md +0 -51
- data/doc/contributing/README.md +0 -38
- data/doc/development/NEW_FEATURES.md +0 -10
- data/doc/development/PULL_REQUESTS.md +0 -40
- data/doc/development/README.md +0 -19
- data/doc/development/RELEASING.md +0 -9
- data/doc/development/SETUP.md +0 -29
- data/doc/documentation/README.md +0 -29
- data/doc/documentation/VISION.md +0 -26
- data/doc/documentation/WRITING.md +0 -54
- data/lib/bundler/postit_trampoline.rb +0 -73
- data/lib/bundler/vendor/postit/lib/postit/environment.rb +0 -44
- data/lib/bundler/vendor/postit/lib/postit/installer.rb +0 -28
- data/lib/bundler/vendor/postit/lib/postit/parser.rb +0 -21
- data/lib/bundler/vendor/postit/lib/postit/setup.rb +0 -12
- data/lib/bundler/vendor/postit/lib/postit/version.rb +0 -3
- data/lib/bundler/vendor/postit/lib/postit.rb +0 -15
- data/task/release.rake +0 -116
data/lib/bundler/plugin.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require "bundler/plugin/api"
|
3
4
|
|
4
5
|
module Bundler
|
5
6
|
module Plugin
|
6
7
|
autoload :DSL, "bundler/plugin/dsl"
|
8
|
+
autoload :Events, "bundler/plugin/events"
|
7
9
|
autoload :Index, "bundler/plugin/index"
|
8
10
|
autoload :Installer, "bundler/plugin/installer"
|
9
11
|
autoload :SourceList, "bundler/plugin/source_list"
|
@@ -65,7 +67,7 @@ module Bundler
|
|
65
67
|
installed_specs = Installer.new.install_definition(definition)
|
66
68
|
|
67
69
|
save_plugins plugins, installed_specs, builder.inferred_plugins
|
68
|
-
rescue => e
|
70
|
+
rescue RuntimeError => e
|
69
71
|
unless e.is_a?(GemfileError)
|
70
72
|
Bundler.ui.error "Failed to install plugin: #{e.message}\n #{e.backtrace[0]}"
|
71
73
|
end
|
@@ -79,8 +81,8 @@ module Bundler
|
|
79
81
|
|
80
82
|
# The directory root for all plugin related data
|
81
83
|
#
|
82
|
-
#
|
83
|
-
# in user_bundle_path
|
84
|
+
# If run in an app, points to local root, in app_config_path
|
85
|
+
# Otherwise, points to global root, in Bundler.user_bundle_path("plugin")
|
84
86
|
def root
|
85
87
|
@root ||= if SharedHelpers.in_bundle?
|
86
88
|
local_root
|
@@ -95,7 +97,7 @@ module Bundler
|
|
95
97
|
|
96
98
|
# The global directory root for all plugin related data
|
97
99
|
def global_root
|
98
|
-
Bundler.user_bundle_path
|
100
|
+
Bundler.user_bundle_path("plugin")
|
99
101
|
end
|
100
102
|
|
101
103
|
# The cache directory for plugin stuffs
|
@@ -154,6 +156,9 @@ module Bundler
|
|
154
156
|
# To be called via the API to register a hooks and corresponding block that
|
155
157
|
# will be called to handle the hook
|
156
158
|
def add_hook(event, &block)
|
159
|
+
unless Events.defined_event?(event)
|
160
|
+
raise ArgumentError, "Event '#{event}' not defined in Bundler::Plugin::Events"
|
161
|
+
end
|
157
162
|
@hooks_by_event[event.to_s] << block
|
158
163
|
end
|
159
164
|
|
@@ -165,6 +170,9 @@ module Bundler
|
|
165
170
|
# @param [String] event
|
166
171
|
def hook(event, *args, &arg_blk)
|
167
172
|
return unless Bundler.feature_flag.plugins?
|
173
|
+
unless Events.defined_event?(event)
|
174
|
+
raise ArgumentError, "Event '#{event}' not defined in Bundler::Plugin::Events"
|
175
|
+
end
|
168
176
|
|
169
177
|
plugins = index.hook_plugins(event)
|
170
178
|
return unless plugins.any?
|
@@ -263,7 +271,7 @@ module Bundler
|
|
263
271
|
load path.join(PLUGIN_FILE_NAME)
|
264
272
|
|
265
273
|
@loaded_plugin_names << name
|
266
|
-
rescue => e
|
274
|
+
rescue RuntimeError => e
|
267
275
|
Bundler.ui.error "Failed loading plugin #{name}: #{e.message}"
|
268
276
|
raise
|
269
277
|
end
|
@@ -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
|
data/lib/bundler/psyched_yaml.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
# Psych could be a gem, so try to ask for it
|
3
4
|
begin
|
4
5
|
gem "psych"
|
@@ -25,3 +26,12 @@ module Bundler
|
|
25
26
|
YamlLibrarySyntaxError = ::ArgumentError
|
26
27
|
end
|
27
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
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require "uri"
|
3
4
|
|
4
5
|
module Bundler
|
@@ -73,7 +74,15 @@ module Bundler
|
|
73
74
|
end
|
74
75
|
|
75
76
|
def dependencies
|
76
|
-
@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
|
77
86
|
end
|
78
87
|
|
79
88
|
def git_version
|
@@ -0,0 +1,106 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Bundler
|
4
|
+
class Resolver
|
5
|
+
class SpecGroup
|
6
|
+
include GemHelpers
|
7
|
+
|
8
|
+
attr_accessor :name, :version, :source
|
9
|
+
attr_accessor :ignores_bundler_dependencies
|
10
|
+
|
11
|
+
def initialize(all_specs)
|
12
|
+
raise ArgumentError, "cannot initialize with an empty value" unless exemplary_spec = all_specs.first
|
13
|
+
@name = exemplary_spec.name
|
14
|
+
@version = exemplary_spec.version
|
15
|
+
@source = exemplary_spec.source
|
16
|
+
|
17
|
+
@activated_platforms = []
|
18
|
+
@dependencies = nil
|
19
|
+
@specs = Hash.new do |specs, platform|
|
20
|
+
specs[platform] = select_best_platform_match(all_specs, platform)
|
21
|
+
end
|
22
|
+
@ignores_bundler_dependencies = true
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_specs
|
26
|
+
@activated_platforms.map do |p|
|
27
|
+
next unless s = @specs[p]
|
28
|
+
lazy_spec = LazySpecification.new(name, version, s.platform, source)
|
29
|
+
lazy_spec.dependencies.replace s.dependencies
|
30
|
+
lazy_spec
|
31
|
+
end.compact
|
32
|
+
end
|
33
|
+
|
34
|
+
def activate_platform!(platform)
|
35
|
+
return unless for?(platform)
|
36
|
+
return if @activated_platforms.include?(platform)
|
37
|
+
@activated_platforms << platform
|
38
|
+
end
|
39
|
+
|
40
|
+
def for?(platform)
|
41
|
+
spec = @specs[platform]
|
42
|
+
!spec.nil?
|
43
|
+
end
|
44
|
+
|
45
|
+
def to_s
|
46
|
+
@to_s ||= "#{name} (#{version})"
|
47
|
+
end
|
48
|
+
|
49
|
+
def dependencies_for_activated_platforms
|
50
|
+
dependencies = @activated_platforms.map {|p| __dependencies[p] }
|
51
|
+
metadata_dependencies = @activated_platforms.map do |platform|
|
52
|
+
metadata_dependencies(@specs[platform], platform)
|
53
|
+
end
|
54
|
+
dependencies.concat(metadata_dependencies).flatten
|
55
|
+
end
|
56
|
+
|
57
|
+
def ==(other)
|
58
|
+
return unless other.is_a?(SpecGroup)
|
59
|
+
name == other.name &&
|
60
|
+
version == other.version &&
|
61
|
+
source == other.source
|
62
|
+
end
|
63
|
+
|
64
|
+
def eql?(other)
|
65
|
+
name.eql?(other.name) &&
|
66
|
+
version.eql?(other.version) &&
|
67
|
+
source.eql?(other.source)
|
68
|
+
end
|
69
|
+
|
70
|
+
def hash
|
71
|
+
to_s.hash ^ source.hash
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
def __dependencies
|
77
|
+
@dependencies = Hash.new do |dependencies, platform|
|
78
|
+
dependencies[platform] = []
|
79
|
+
if spec = @specs[platform]
|
80
|
+
spec.dependencies.each do |dep|
|
81
|
+
next if dep.type == :development
|
82
|
+
next if @ignores_bundler_dependencies && dep.name == "bundler".freeze
|
83
|
+
dependencies[platform] << DepProxy.new(dep, platform)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
dependencies[platform]
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def metadata_dependencies(spec, platform)
|
91
|
+
return [] unless spec
|
92
|
+
# Only allow endpoint specifications since they won't hit the network to
|
93
|
+
# fetch the full gemspec when calling required_ruby_version
|
94
|
+
return [] if !spec.is_a?(EndpointSpecification) && !spec.is_a?(Gem::Specification)
|
95
|
+
dependencies = []
|
96
|
+
if !spec.required_ruby_version.nil? && !spec.required_ruby_version.none?
|
97
|
+
dependencies << DepProxy.new(Gem::Dependency.new("ruby\0", spec.required_ruby_version), platform)
|
98
|
+
end
|
99
|
+
if !spec.required_rubygems_version.nil? && !spec.required_rubygems_version.none?
|
100
|
+
dependencies << DepProxy.new(Gem::Dependency.new("rubygems\0", spec.required_rubygems_version), platform)
|
101
|
+
end
|
102
|
+
dependencies
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
data/lib/bundler/resolver.rb
CHANGED
@@ -1,178 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module Bundler
|
3
4
|
class Resolver
|
4
5
|
require "bundler/vendored_molinillo"
|
5
|
-
|
6
|
-
class Molinillo::VersionConflict
|
7
|
-
def printable_dep(dep)
|
8
|
-
if dep.is_a?(Bundler::Dependency)
|
9
|
-
DepProxy.new(dep, dep.platforms.join(", ")).to_s.strip
|
10
|
-
else
|
11
|
-
dep.to_s
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
def message
|
16
|
-
conflicts.sort.reduce(String.new) do |o, (name, conflict)|
|
17
|
-
o << %(\nBundler could not find compatible versions for gem "#{name}":\n)
|
18
|
-
if conflict.locked_requirement
|
19
|
-
o << %( In snapshot (#{Bundler.default_lockfile.basename}):\n)
|
20
|
-
o << %( #{printable_dep(conflict.locked_requirement)}\n)
|
21
|
-
o << %(\n)
|
22
|
-
end
|
23
|
-
o << %( In Gemfile:\n)
|
24
|
-
trees = conflict.requirement_trees
|
25
|
-
|
26
|
-
maximal = 1.upto(trees.size).map do |size|
|
27
|
-
trees.map(&:last).flatten(1).combination(size).to_a
|
28
|
-
end.flatten(1).select do |deps|
|
29
|
-
Bundler::VersionRanges.empty?(*Bundler::VersionRanges.for_many(deps.map(&:requirement)))
|
30
|
-
end.min_by(&:size)
|
31
|
-
trees.reject! {|t| !maximal.include?(t.last) } if maximal
|
32
|
-
|
33
|
-
o << trees.sort_by {|t| t.reverse.map(&:name) }.map do |tree|
|
34
|
-
t = String.new
|
35
|
-
depth = 2
|
36
|
-
tree.each do |req|
|
37
|
-
t << " " * depth << req.to_s
|
38
|
-
unless tree.last == req
|
39
|
-
if spec = conflict.activated_by_name[req.name]
|
40
|
-
t << %( was resolved to #{spec.version}, which)
|
41
|
-
end
|
42
|
-
t << %( depends on)
|
43
|
-
end
|
44
|
-
t << %(\n)
|
45
|
-
depth += 1
|
46
|
-
end
|
47
|
-
t
|
48
|
-
end.join("\n")
|
49
|
-
|
50
|
-
if name == "bundler"
|
51
|
-
o << %(\n Current Bundler version:\n bundler (#{Bundler::VERSION}))
|
52
|
-
other_bundler_required = !conflict.requirement.requirement.satisfied_by?(Gem::Version.new Bundler::VERSION)
|
53
|
-
end
|
54
|
-
|
55
|
-
if name == "bundler" && other_bundler_required
|
56
|
-
o << "\n"
|
57
|
-
o << "This Gemfile requires a different version of Bundler.\n"
|
58
|
-
o << "Perhaps you need to update Bundler by running `gem install bundler`?\n"
|
59
|
-
end
|
60
|
-
if conflict.locked_requirement
|
61
|
-
o << "\n"
|
62
|
-
o << %(Running `bundle update` will rebuild your snapshot from scratch, using only\n)
|
63
|
-
o << %(the gems in your Gemfile, which may resolve the conflict.\n)
|
64
|
-
elsif !conflict.existing
|
65
|
-
o << "\n"
|
66
|
-
if conflict.requirement_trees.first.size > 1
|
67
|
-
o << "Could not find gem '#{conflict.requirement}', which is required by "
|
68
|
-
o << "gem '#{conflict.requirement_trees.first[-2]}', in any of the sources."
|
69
|
-
else
|
70
|
-
o << "Could not find gem '#{conflict.requirement}' in any of the sources\n"
|
71
|
-
end
|
72
|
-
end
|
73
|
-
o
|
74
|
-
end.strip
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
class SpecGroup < Array
|
79
|
-
include GemHelpers
|
80
|
-
|
81
|
-
attr_reader :activated
|
82
|
-
|
83
|
-
def initialize(a)
|
84
|
-
super
|
85
|
-
@required_by = []
|
86
|
-
@activated_platforms = []
|
87
|
-
@dependencies = nil
|
88
|
-
@specs = Hash.new do |specs, platform|
|
89
|
-
specs[platform] = select_best_platform_match(self, platform)
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
|
-
def initialize_copy(o)
|
94
|
-
super
|
95
|
-
@activated_platforms = o.activated.dup
|
96
|
-
end
|
97
|
-
|
98
|
-
def to_specs
|
99
|
-
@activated_platforms.map do |p|
|
100
|
-
next unless s = @specs[p]
|
101
|
-
lazy_spec = LazySpecification.new(name, version, s.platform, source)
|
102
|
-
lazy_spec.dependencies.replace s.dependencies
|
103
|
-
lazy_spec
|
104
|
-
end.compact
|
105
|
-
end
|
106
|
-
|
107
|
-
def activate_platform!(platform)
|
108
|
-
return unless for?(platform)
|
109
|
-
return if @activated_platforms.include?(platform)
|
110
|
-
@activated_platforms << platform
|
111
|
-
end
|
112
|
-
|
113
|
-
def name
|
114
|
-
@name ||= first.name
|
115
|
-
end
|
116
|
-
|
117
|
-
def version
|
118
|
-
@version ||= first.version
|
119
|
-
end
|
120
|
-
|
121
|
-
def source
|
122
|
-
@source ||= first.source
|
123
|
-
end
|
124
|
-
|
125
|
-
def for?(platform)
|
126
|
-
spec = @specs[platform]
|
127
|
-
!spec.nil?
|
128
|
-
end
|
129
|
-
|
130
|
-
def to_s
|
131
|
-
"#{name} (#{version})"
|
132
|
-
end
|
133
|
-
|
134
|
-
def dependencies_for_activated_platforms
|
135
|
-
dependencies = @activated_platforms.map {|p| __dependencies[p] }
|
136
|
-
metadata_dependencies = @activated_platforms.map do |platform|
|
137
|
-
metadata_dependencies(@specs[platform], platform)
|
138
|
-
end
|
139
|
-
dependencies.concat(metadata_dependencies).flatten
|
140
|
-
end
|
141
|
-
|
142
|
-
def platforms_for_dependency_named(dependency)
|
143
|
-
__dependencies.select {|_, deps| deps.map(&:name).include? dependency }.keys
|
144
|
-
end
|
145
|
-
|
146
|
-
private
|
147
|
-
|
148
|
-
def __dependencies
|
149
|
-
@dependencies = Hash.new do |dependencies, platform|
|
150
|
-
dependencies[platform] = []
|
151
|
-
if spec = @specs[platform]
|
152
|
-
spec.dependencies.each do |dep|
|
153
|
-
next if dep.type == :development
|
154
|
-
dependencies[platform] << DepProxy.new(dep, platform)
|
155
|
-
end
|
156
|
-
end
|
157
|
-
dependencies[platform]
|
158
|
-
end
|
159
|
-
end
|
160
|
-
|
161
|
-
def metadata_dependencies(spec, platform)
|
162
|
-
return [] unless spec
|
163
|
-
# Only allow endpoint specifications since they won't hit the network to
|
164
|
-
# fetch the full gemspec when calling required_ruby_version
|
165
|
-
return [] if !spec.is_a?(EndpointSpecification) && !spec.is_a?(Gem::Specification)
|
166
|
-
dependencies = []
|
167
|
-
if !spec.required_ruby_version.nil? && !spec.required_ruby_version.none?
|
168
|
-
dependencies << DepProxy.new(Gem::Dependency.new("ruby\0", spec.required_ruby_version), platform)
|
169
|
-
end
|
170
|
-
if !spec.required_rubygems_version.nil? && !spec.required_rubygems_version.none?
|
171
|
-
dependencies << DepProxy.new(Gem::Dependency.new("rubygems\0", spec.required_rubygems_version), platform)
|
172
|
-
end
|
173
|
-
dependencies
|
174
|
-
end
|
175
|
-
end
|
6
|
+
require "bundler/resolver/spec_group"
|
176
7
|
|
177
8
|
# Figures out the best possible configuration of gems that satisfies
|
178
9
|
# the list of passed dependencies and any child dependencies without
|
@@ -206,16 +37,23 @@ module Bundler
|
|
206
37
|
additional_base_requirements.each {|d| @base_dg.add_vertex(d.name, d) }
|
207
38
|
@platforms = platforms
|
208
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?
|
209
43
|
end
|
210
44
|
|
211
45
|
def start(requirements)
|
46
|
+
@gem_version_promoter.prerelease_specified = @prerelease_specified = {}
|
47
|
+
requirements.each {|dep| @prerelease_specified[dep.name] ||= dep.prerelease? }
|
48
|
+
|
212
49
|
verify_gemfile_dependencies_are_found!(requirements)
|
213
50
|
dg = @resolver.resolve(requirements, @base_dg)
|
214
51
|
dg.map(&:payload).
|
215
52
|
reject {|sg| sg.name.end_with?("\0") }.
|
216
53
|
map(&:to_specs).flatten
|
217
54
|
rescue Molinillo::VersionConflict => e
|
218
|
-
|
55
|
+
message = version_conflict_message(e)
|
56
|
+
raise VersionConflict.new(e.conflicts.keys.uniq, message)
|
219
57
|
rescue Molinillo::CircularDependencyError => e
|
220
58
|
names = e.dependencies.sort_by(&:name).map {|d| "gem '#{d.name}'" }
|
221
59
|
raise CyclicDependencyError, "Your bundle requires gems that depend" \
|
@@ -266,9 +104,18 @@ module Bundler
|
|
266
104
|
search = @search_for[dependency] ||= begin
|
267
105
|
index = index_for(dependency)
|
268
106
|
results = index.search(dependency, @base[dependency.name])
|
107
|
+
|
269
108
|
if vertex = @base_dg.vertex_named(dependency.name)
|
270
109
|
locked_requirement = vertex.payload.requirement
|
271
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
|
+
|
272
119
|
spec_groups = if results.any?
|
273
120
|
nested = []
|
274
121
|
results.each do |spec|
|
@@ -281,14 +128,16 @@ module Bundler
|
|
281
128
|
end
|
282
129
|
nested.reduce([]) do |groups, (version, specs)|
|
283
130
|
next groups if locked_requirement && !locked_requirement.satisfied_by?(version)
|
284
|
-
|
131
|
+
spec_group = SpecGroup.new(specs)
|
132
|
+
spec_group.ignores_bundler_dependencies = @allow_bundler_dependency_conflicts
|
133
|
+
groups << spec_group
|
285
134
|
end
|
286
135
|
else
|
287
136
|
[]
|
288
137
|
end
|
289
138
|
# GVP handles major itself, but it's still a bit risky to trust it with it
|
290
139
|
# until we get it settled with new behavior. For 2.x it can take over all cases.
|
291
|
-
if
|
140
|
+
if !@use_gvp
|
292
141
|
spec_groups
|
293
142
|
else
|
294
143
|
@gem_version_promoter.sort_versions(dependency, spec_groups)
|
@@ -298,7 +147,20 @@ module Bundler
|
|
298
147
|
end
|
299
148
|
|
300
149
|
def index_for(dependency)
|
301
|
-
@source_requirements[dependency.name]
|
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
|
302
164
|
end
|
303
165
|
|
304
166
|
def name_for(dependency)
|
@@ -323,19 +185,45 @@ module Bundler
|
|
323
185
|
true
|
324
186
|
end
|
325
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
|
+
|
326
198
|
def sort_dependencies(dependencies, activated, conflicts)
|
327
199
|
dependencies.sort_by do |dependency|
|
200
|
+
dependency.all_sources = relevant_sources_for_vertex(activated.vertex_named(dependency.name))
|
328
201
|
name = name_for(dependency)
|
202
|
+
vertex = activated.vertex_named(name)
|
329
203
|
[
|
330
204
|
@base_dg.vertex_named(name) ? 0 : 1,
|
331
|
-
|
205
|
+
vertex.payload ? 0 : 1,
|
206
|
+
vertex.root? ? 0 : 1,
|
332
207
|
amount_constrained(dependency),
|
333
208
|
conflicts[name] ? 0 : 1,
|
334
|
-
|
209
|
+
vertex.payload ? 0 : search_for(dependency).count,
|
210
|
+
self.class.platform_sort_key(dependency.__platform),
|
335
211
|
]
|
336
212
|
end
|
337
213
|
end
|
338
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
|
+
|
339
227
|
private
|
340
228
|
|
341
229
|
# returns an integer \in (-\infty, 0]
|
@@ -355,7 +243,8 @@ module Bundler
|
|
355
243
|
if all <= 1
|
356
244
|
all - 1_000_000
|
357
245
|
else
|
358
|
-
search = search_for(dependency)
|
246
|
+
search = search_for(dependency)
|
247
|
+
search = @prerelease_specified[dependency.name] ? search.count : search.count {|s| !s.version.prerelease? }
|
359
248
|
search - all
|
360
249
|
end
|
361
250
|
end
|
@@ -364,32 +253,34 @@ module Bundler
|
|
364
253
|
|
365
254
|
def verify_gemfile_dependencies_are_found!(requirements)
|
366
255
|
requirements.each do |requirement|
|
367
|
-
|
256
|
+
name = requirement.name
|
257
|
+
next if name == "bundler"
|
368
258
|
next unless search_for(requirement).empty?
|
369
|
-
|
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?
|
370
267
|
version = base.first.version
|
371
268
|
message = "You have requested:\n" \
|
372
|
-
" #{
|
373
|
-
"The bundle currently has #{
|
374
|
-
"Try running `bundle update #{
|
269
|
+
" #{name} #{requirement.requirement}\n\n" \
|
270
|
+
"The bundle currently has #{name} locked at #{version}.\n" \
|
271
|
+
"Try running `bundle update #{name}`\n\n" \
|
375
272
|
"If you are updating multiple gems in your Gemfile at once,\n" \
|
376
273
|
"try passing them all to `bundle update`"
|
377
|
-
elsif
|
378
|
-
|
379
|
-
specs = @source_requirements[name][name]
|
274
|
+
elsif source = @source_requirements[name]
|
275
|
+
specs = source.specs[name]
|
380
276
|
versions_with_platforms = specs.map {|s| [s.version, s.platform] }
|
381
|
-
message = String.new("Could not find gem '#{requirement}' in #{
|
277
|
+
message = String.new("Could not find gem '#{SharedHelpers.pretty_dependency(requirement)}' in #{source}#{cache_message}.\n")
|
382
278
|
message << if versions_with_platforms.any?
|
383
|
-
"
|
279
|
+
"The source contains '#{name}' at: #{formatted_versions_with_platforms(versions_with_platforms)}"
|
384
280
|
else
|
385
|
-
"
|
281
|
+
"The source does not contain any versions of '#{name}'"
|
386
282
|
end
|
387
283
|
else
|
388
|
-
cache_message = begin
|
389
|
-
" or in gems cached in #{Bundler.settings.app_cache_path}" if Bundler.app_cache.exist?
|
390
|
-
rescue GemfileNotFound
|
391
|
-
nil
|
392
|
-
end
|
393
284
|
message = "Could not find gem '#{requirement}' in any of the gem sources " \
|
394
285
|
"listed in your Gemfile#{cache_message}."
|
395
286
|
end
|
@@ -402,9 +293,81 @@ module Bundler
|
|
402
293
|
version = vwp.first
|
403
294
|
platform = vwp.last
|
404
295
|
version_platform_str = String.new(version.to_s)
|
405
|
-
version_platform_str << " #{platform}" unless platform.nil?
|
296
|
+
version_platform_str << " #{platform}" unless platform.nil? || platform == Gem::Platform::RUBY
|
297
|
+
version_platform_str
|
406
298
|
end
|
407
299
|
version_platform_strs.join(", ")
|
408
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
|
409
372
|
end
|
410
373
|
end
|