bundler 2.2.3 → 2.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +503 -7
- data/README.md +1 -1
- data/bundler.gemspec +2 -3
- data/exe/bundle +7 -8
- data/lib/bundler/.document +1 -0
- data/lib/bundler/build_metadata.rb +2 -2
- data/lib/bundler/cli/cache.rb +2 -1
- data/lib/bundler/cli/check.rb +4 -2
- data/lib/bundler/cli/common.rb +15 -2
- data/lib/bundler/cli/doctor.rb +15 -4
- data/lib/bundler/cli/exec.rb +1 -6
- data/lib/bundler/cli/gem.rb +132 -24
- data/lib/bundler/cli/info.rb +16 -4
- data/lib/bundler/cli/install.rb +12 -27
- data/lib/bundler/cli/issue.rb +4 -3
- data/lib/bundler/cli/list.rb +7 -1
- data/lib/bundler/cli/lock.rb +5 -1
- data/lib/bundler/cli/open.rb +1 -2
- data/lib/bundler/cli/outdated.rb +10 -11
- data/lib/bundler/cli/remove.rb +1 -2
- data/lib/bundler/cli/update.rb +17 -8
- data/lib/bundler/cli.rb +44 -60
- data/lib/bundler/compact_index_client/cache.rb +0 -9
- data/lib/bundler/compact_index_client/updater.rb +10 -19
- data/lib/bundler/compact_index_client.rb +2 -8
- data/lib/bundler/current_ruby.rb +5 -4
- data/lib/bundler/definition.rb +158 -316
- data/lib/bundler/dep_proxy.rb +15 -8
- data/lib/bundler/dependency.rb +5 -7
- data/lib/bundler/digest.rb +71 -0
- data/lib/bundler/dsl.rb +67 -66
- data/lib/bundler/endpoint_specification.rb +21 -11
- data/lib/bundler/environment_preserver.rb +4 -1
- data/lib/bundler/errors.rb +19 -3
- data/lib/bundler/feature_flag.rb +0 -5
- data/lib/bundler/fetcher/compact_index.rb +10 -15
- data/lib/bundler/fetcher/downloader.rb +9 -6
- data/lib/bundler/fetcher/index.rb +0 -27
- data/lib/bundler/fetcher.rb +10 -17
- data/lib/bundler/friendly_errors.rb +5 -32
- data/lib/bundler/gem_helper.rb +28 -21
- data/lib/bundler/gem_version_promoter.rb +2 -2
- data/lib/bundler/index.rb +8 -12
- data/lib/bundler/injector.rb +12 -3
- data/lib/bundler/inline.rb +2 -1
- data/lib/bundler/installer/gem_installer.rb +4 -22
- data/lib/bundler/installer/parallel_installer.rb +36 -15
- data/lib/bundler/installer/standalone.rb +29 -9
- data/lib/bundler/installer.rb +8 -34
- data/lib/bundler/lazy_specification.rb +32 -20
- data/lib/bundler/lockfile_generator.rb +1 -1
- data/lib/bundler/lockfile_parser.rb +16 -45
- data/{man → lib/bundler/man}/bundle-add.1 +10 -2
- data/lib/bundler/man/bundle-add.1.ronn +7 -1
- data/{man → lib/bundler/man}/bundle-binstubs.1 +1 -1
- data/{man → lib/bundler/man}/bundle-cache.1 +1 -1
- data/{man → lib/bundler/man}/bundle-check.1 +1 -1
- data/{man → lib/bundler/man}/bundle-clean.1 +1 -1
- data/{man → lib/bundler/man}/bundle-config.1 +27 -19
- data/lib/bundler/man/bundle-config.1.ronn +33 -25
- data/{man → lib/bundler/man}/bundle-doctor.1 +1 -1
- data/{man → lib/bundler/man}/bundle-exec.1 +1 -1
- data/{man → lib/bundler/man}/bundle-gem.1 +14 -1
- data/lib/bundler/man/bundle-gem.1.ronn +16 -0
- data/{man → lib/bundler/man}/bundle-info.1 +1 -1
- data/{man → lib/bundler/man}/bundle-init.1 +1 -1
- data/{man → lib/bundler/man}/bundle-inject.1 +1 -1
- data/{man → lib/bundler/man}/bundle-install.1 +2 -2
- data/lib/bundler/man/bundle-install.1.ronn +2 -2
- data/{man → lib/bundler/man}/bundle-list.1 +1 -1
- data/{man → lib/bundler/man}/bundle-lock.1 +1 -1
- data/{man → lib/bundler/man}/bundle-open.1 +1 -1
- data/{man → lib/bundler/man}/bundle-outdated.1 +1 -1
- data/{man → lib/bundler/man}/bundle-platform.1 +1 -1
- data/{man → lib/bundler/man}/bundle-pristine.1 +1 -1
- data/{man → lib/bundler/man}/bundle-remove.1 +1 -1
- data/{man → lib/bundler/man}/bundle-show.1 +1 -1
- data/{man → lib/bundler/man}/bundle-update.1 +5 -5
- data/lib/bundler/man/bundle-update.1.ronn +5 -4
- data/{man → lib/bundler/man}/bundle-viz.1 +1 -1
- data/{man → lib/bundler/man}/bundle.1 +1 -1
- data/{man → lib/bundler/man}/gemfile.5 +28 -2
- data/lib/bundler/man/gemfile.5.ronn +9 -1
- data/{man → lib/bundler/man}/index.txt +0 -0
- data/lib/bundler/plugin/api/source.rb +22 -0
- data/lib/bundler/plugin/index.rb +4 -1
- data/lib/bundler/plugin/installer.rb +10 -10
- data/lib/bundler/plugin/source_list.rb +4 -0
- data/lib/bundler/plugin.rb +28 -8
- data/lib/bundler/process_lock.rb +1 -1
- data/lib/bundler/psyched_yaml.rb +1 -13
- data/lib/bundler/resolver/spec_group.rb +36 -48
- data/lib/bundler/resolver.rb +97 -151
- data/lib/bundler/retry.rb +1 -1
- data/lib/bundler/ruby_version.rb +1 -1
- data/lib/bundler/rubygems_ext.rb +46 -8
- data/lib/bundler/rubygems_gem_installer.rb +68 -1
- data/lib/bundler/rubygems_integration.rb +43 -60
- data/lib/bundler/runtime.rb +18 -11
- data/lib/bundler/self_manager.rb +168 -0
- data/lib/bundler/settings.rb +97 -21
- data/lib/bundler/setup.rb +2 -2
- data/lib/bundler/shared_helpers.rb +6 -21
- data/lib/bundler/source/git/git_proxy.rb +60 -53
- data/lib/bundler/source/git.rb +38 -18
- data/lib/bundler/source/metadata.rb +1 -5
- data/lib/bundler/source/path/installer.rb +3 -1
- data/lib/bundler/source/path.rb +3 -1
- data/lib/bundler/source/rubygems.rb +113 -100
- data/lib/bundler/source/rubygems_aggregate.rb +68 -0
- data/lib/bundler/source.rb +21 -0
- data/lib/bundler/source_list.rb +100 -62
- data/lib/bundler/source_map.rb +58 -0
- data/lib/bundler/spec_set.rb +21 -34
- data/lib/bundler/stub_specification.rb +8 -0
- data/lib/bundler/templates/Executable.bundler +7 -7
- data/lib/bundler/templates/Gemfile +0 -2
- data/lib/bundler/templates/gems.rb +0 -3
- data/lib/bundler/templates/newgem/CHANGELOG.md.tt +5 -0
- data/lib/bundler/templates/newgem/Gemfile.tt +5 -2
- data/lib/bundler/templates/newgem/README.md.tt +5 -3
- data/lib/bundler/templates/newgem/Rakefile.tt +15 -2
- data/lib/bundler/templates/newgem/github/workflows/main.yml.tt +15 -6
- data/lib/bundler/templates/newgem/newgem.gemspec.tt +18 -16
- data/lib/bundler/templates/newgem/rubocop.yml.tt +3 -0
- data/lib/bundler/templates/newgem/sig/newgem.rbs.tt +8 -0
- data/lib/bundler/templates/newgem/standard.yml.tt +2 -0
- data/lib/bundler/templates/newgem/test/minitest/{newgem_test.rb.tt → test_newgem.rb.tt} +1 -1
- data/lib/bundler/ui/shell.rb +1 -1
- data/lib/bundler/vendor/.document +1 -0
- data/lib/bundler/vendor/connection_pool/LICENSE +20 -0
- data/lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb +19 -21
- data/lib/bundler/vendor/connection_pool/lib/connection_pool/version.rb +1 -1
- data/lib/bundler/vendor/connection_pool/lib/connection_pool/wrapper.rb +57 -0
- data/lib/bundler/vendor/connection_pool/lib/connection_pool.rb +39 -74
- data/lib/bundler/vendor/fileutils/LICENSE.txt +22 -0
- data/lib/bundler/vendor/molinillo/LICENSE +9 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/delegates/specification_provider.rb +7 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb +11 -5
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb +2 -3
- data/lib/bundler/vendor/molinillo/lib/molinillo/errors.rb +2 -2
- data/lib/bundler/vendor/molinillo/lib/molinillo/modules/specification_provider.rb +12 -1
- data/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb +11 -7
- data/lib/bundler/vendor/net-http-persistent/README.rdoc +82 -0
- data/lib/bundler/vendor/thor/LICENSE.md +20 -0
- data/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb +9 -7
- data/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb +1 -2
- data/lib/bundler/vendor/thor/lib/thor/actions.rb +7 -3
- data/lib/bundler/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb +6 -0
- data/lib/bundler/vendor/thor/lib/thor/error.rb +10 -5
- data/lib/bundler/vendor/thor/lib/thor/parser/arguments.rb +5 -1
- data/lib/bundler/vendor/thor/lib/thor/parser/options.rb +28 -9
- data/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +27 -6
- data/lib/bundler/vendor/thor/lib/thor/shell/color.rb +5 -1
- data/lib/bundler/vendor/thor/lib/thor/shell.rb +1 -1
- data/lib/bundler/vendor/thor/lib/thor/util.rb +1 -1
- data/lib/bundler/vendor/thor/lib/thor/version.rb +1 -1
- data/lib/bundler/vendor/thor/lib/thor.rb +5 -6
- data/lib/bundler/vendor/tmpdir/lib/tmpdir.rb +1 -1
- data/lib/bundler/vendor/tsort/LICENSE.txt +22 -0
- data/lib/bundler/vendor/tsort/lib/tsort.rb +453 -0
- data/lib/bundler/vendor/uri/LICENSE.txt +22 -0
- data/lib/bundler/vendor/uri/lib/uri/common.rb +17 -80
- data/lib/bundler/vendor/uri/lib/uri/ftp.rb +0 -1
- data/lib/bundler/vendor/uri/lib/uri/generic.rb +5 -6
- data/lib/bundler/vendor/uri/lib/uri/http.rb +0 -1
- data/lib/bundler/vendor/uri/lib/uri/https.rb +0 -1
- data/lib/bundler/vendor/uri/lib/uri/ldap.rb +1 -1
- data/lib/bundler/vendor/uri/lib/uri/mailto.rb +0 -1
- data/lib/bundler/vendor/uri/lib/uri/rfc2396_parser.rb +1 -14
- data/lib/bundler/vendor/uri/lib/uri/rfc3986_parser.rb +1 -12
- data/lib/bundler/vendor/uri/lib/uri/version.rb +1 -1
- data/lib/bundler/vendor/uri/lib/uri/ws.rb +84 -0
- data/lib/bundler/vendor/uri/lib/uri/wss.rb +22 -0
- data/lib/bundler/vendor/uri/lib/uri.rb +0 -1
- data/lib/bundler/vendored_tsort.rb +4 -0
- data/lib/bundler/version.rb +1 -1
- data/lib/bundler/worker.rb +19 -4
- data/lib/bundler.rb +29 -33
- metadata +54 -35
- data/lib/bundler/gemdeps.rb +0 -29
- data/lib/bundler/vendor/connection_pool/lib/connection_pool/monotonic_time.rb +0 -66
data/lib/bundler/plugin.rb
CHANGED
|
@@ -13,6 +13,7 @@ module Bundler
|
|
|
13
13
|
class MalformattedPlugin < PluginError; end
|
|
14
14
|
class UndefinedCommandError < PluginError; end
|
|
15
15
|
class UnknownSourceError < PluginError; end
|
|
16
|
+
class PluginInstallError < PluginError; end
|
|
16
17
|
|
|
17
18
|
PLUGIN_FILE_NAME = "plugins.rb".freeze
|
|
18
19
|
|
|
@@ -38,12 +39,11 @@ module Bundler
|
|
|
38
39
|
specs = Installer.new.install(names, options)
|
|
39
40
|
|
|
40
41
|
save_plugins names, specs
|
|
41
|
-
rescue PluginError
|
|
42
|
+
rescue PluginError
|
|
42
43
|
specs_to_delete = specs.select {|k, _v| names.include?(k) && !index.commands.values.include?(k) }
|
|
43
44
|
specs_to_delete.each_value {|spec| Bundler.rm_rf(spec.full_gem_path) }
|
|
44
45
|
|
|
45
|
-
|
|
46
|
-
Bundler.ui.error "Failed to install the following plugins: #{names_list}. The underlying error was: #{e.message}.\n #{e.backtrace.join("\n ")}"
|
|
46
|
+
raise
|
|
47
47
|
end
|
|
48
48
|
|
|
49
49
|
# Uninstalls plugins by the given names
|
|
@@ -105,6 +105,7 @@ module Bundler
|
|
|
105
105
|
else
|
|
106
106
|
builder.eval_gemfile(gemfile)
|
|
107
107
|
end
|
|
108
|
+
builder.check_primary_source_safety
|
|
108
109
|
definition = builder.to_definition(nil, true)
|
|
109
110
|
|
|
110
111
|
return if definition.dependencies.empty?
|
|
@@ -163,7 +164,7 @@ module Bundler
|
|
|
163
164
|
end
|
|
164
165
|
|
|
165
166
|
# To be called from Cli class to pass the command and argument to
|
|
166
|
-
#
|
|
167
|
+
# appropriate plugin class
|
|
167
168
|
def exec_command(command, args)
|
|
168
169
|
raise UndefinedCommandError, "Command `#{command}` not found" unless command? command
|
|
169
170
|
|
|
@@ -182,7 +183,7 @@ module Bundler
|
|
|
182
183
|
!index.source_plugin(name.to_s).nil?
|
|
183
184
|
end
|
|
184
185
|
|
|
185
|
-
# @return [Class] that handles the source. The
|
|
186
|
+
# @return [Class] that handles the source. The class includes API::Source
|
|
186
187
|
def source(name)
|
|
187
188
|
raise UnknownSourceError, "Source #{name} not found" unless source? name
|
|
188
189
|
|
|
@@ -244,10 +245,11 @@ module Bundler
|
|
|
244
245
|
# @param [Array<String>] names of inferred source plugins that can be ignored
|
|
245
246
|
def save_plugins(plugins, specs, optional_plugins = [])
|
|
246
247
|
plugins.each do |name|
|
|
248
|
+
next if index.installed?(name)
|
|
249
|
+
|
|
247
250
|
spec = specs[name]
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
Bundler.ui.info "Installed plugin #{name}" if installed
|
|
251
|
+
|
|
252
|
+
save_plugin(name, spec, optional_plugins.include?(name))
|
|
251
253
|
end
|
|
252
254
|
end
|
|
253
255
|
|
|
@@ -262,6 +264,22 @@ module Bundler
|
|
|
262
264
|
raise MalformattedPlugin, "#{PLUGIN_FILE_NAME} was not found in the plugin." unless plugin_file.file?
|
|
263
265
|
end
|
|
264
266
|
|
|
267
|
+
# Validates and registers a plugin.
|
|
268
|
+
#
|
|
269
|
+
# @param [String] name the name of the plugin
|
|
270
|
+
# @param [Specification] spec of installed plugin
|
|
271
|
+
# @param [Boolean] optional_plugin, removed if there is conflict with any
|
|
272
|
+
# other plugin (used for default source plugins)
|
|
273
|
+
#
|
|
274
|
+
# @raise [PluginInstallError] if validation or registration raises any error
|
|
275
|
+
def save_plugin(name, spec, optional_plugin = false)
|
|
276
|
+
validate_plugin! Pathname.new(spec.full_gem_path)
|
|
277
|
+
installed = register_plugin(name, spec, optional_plugin)
|
|
278
|
+
Bundler.ui.info "Installed plugin #{name}" if installed
|
|
279
|
+
rescue PluginError => e
|
|
280
|
+
raise PluginInstallError, "Failed to install plugin `#{spec.name}`, due to #{e.class} (#{e.message})"
|
|
281
|
+
end
|
|
282
|
+
|
|
265
283
|
# Runs the plugins.rb file in an isolated namespace, records the plugin
|
|
266
284
|
# actions it registers for and then passes the data to index to be stored.
|
|
267
285
|
#
|
|
@@ -308,6 +326,8 @@ module Bundler
|
|
|
308
326
|
#
|
|
309
327
|
# @param [String] name of the plugin
|
|
310
328
|
def load_plugin(name)
|
|
329
|
+
return unless name && !name.empty?
|
|
330
|
+
|
|
311
331
|
# Need to ensure before this that plugin root where the rest of gems
|
|
312
332
|
# are installed to be on load path to support plugin deps. Currently not
|
|
313
333
|
# done to avoid conflicts
|
data/lib/bundler/process_lock.rb
CHANGED
|
@@ -12,7 +12,7 @@ module Bundler
|
|
|
12
12
|
yield
|
|
13
13
|
f.flock(File::LOCK_UN)
|
|
14
14
|
end
|
|
15
|
-
rescue Errno::EACCES, Errno::ENOLCK,
|
|
15
|
+
rescue Errno::EACCES, Errno::ENOLCK, Errno::ENOTSUP
|
|
16
16
|
# In the case the user does not have access to
|
|
17
17
|
# create the lock file or is using NFS where
|
|
18
18
|
# locks are not available we skip locking.
|
data/lib/bundler/psyched_yaml.rb
CHANGED
|
@@ -1,22 +1,10 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# Psych could be in the stdlib
|
|
4
|
-
# but it's too late if Syck is already loaded
|
|
5
3
|
begin
|
|
6
|
-
require "psych"
|
|
4
|
+
require "psych"
|
|
7
5
|
rescue LoadError
|
|
8
6
|
# Apparently Psych wasn't available. Oh well.
|
|
9
7
|
end
|
|
10
8
|
|
|
11
9
|
# At least load the YAML stdlib, whatever that may be
|
|
12
10
|
require "yaml" unless defined?(YAML.dump)
|
|
13
|
-
|
|
14
|
-
module Bundler
|
|
15
|
-
# On encountering invalid YAML,
|
|
16
|
-
# Psych raises Psych::SyntaxError
|
|
17
|
-
if defined?(::Psych::SyntaxError)
|
|
18
|
-
YamlLibrarySyntaxError = ::Psych::SyntaxError
|
|
19
|
-
else # Syck raises ArgumentError
|
|
20
|
-
YamlLibrarySyntaxError = ::ArgumentError
|
|
21
|
-
end
|
|
22
|
-
end
|
|
@@ -3,28 +3,33 @@
|
|
|
3
3
|
module Bundler
|
|
4
4
|
class Resolver
|
|
5
5
|
class SpecGroup
|
|
6
|
-
include GemHelpers
|
|
7
|
-
|
|
8
6
|
attr_accessor :name, :version, :source
|
|
9
|
-
attr_accessor :
|
|
7
|
+
attr_accessor :activated_platforms
|
|
8
|
+
|
|
9
|
+
def self.create_for(specs, all_platforms, specific_platform)
|
|
10
|
+
specific_platform_specs = specs[specific_platform]
|
|
11
|
+
return unless specific_platform_specs.any?
|
|
12
|
+
|
|
13
|
+
platforms = all_platforms.select {|p| specs[p].any? }
|
|
14
|
+
|
|
15
|
+
new(specific_platform_specs.first, specs, platforms)
|
|
16
|
+
end
|
|
10
17
|
|
|
11
|
-
def initialize(
|
|
12
|
-
@
|
|
13
|
-
raise ArgumentError, "cannot initialize with an empty value" unless exemplary_spec = all_specs.first
|
|
18
|
+
def initialize(exemplary_spec, specs, relevant_platforms)
|
|
19
|
+
@exemplary_spec = exemplary_spec
|
|
14
20
|
@name = exemplary_spec.name
|
|
15
21
|
@version = exemplary_spec.version
|
|
16
22
|
@source = exemplary_spec.source
|
|
17
23
|
|
|
18
|
-
@activated_platforms =
|
|
19
|
-
@dependencies =
|
|
20
|
-
|
|
21
|
-
specs[platform] = select_best_platform_match(all_specs, platform)
|
|
24
|
+
@activated_platforms = relevant_platforms
|
|
25
|
+
@dependencies = Hash.new do |dependencies, platforms|
|
|
26
|
+
dependencies[platforms] = dependencies_for(platforms)
|
|
22
27
|
end
|
|
23
|
-
@
|
|
28
|
+
@specs = specs
|
|
24
29
|
end
|
|
25
30
|
|
|
26
31
|
def to_specs
|
|
27
|
-
|
|
32
|
+
activated_platforms.map do |p|
|
|
28
33
|
specs = @specs[p]
|
|
29
34
|
next unless specs.any?
|
|
30
35
|
|
|
@@ -36,31 +41,13 @@ module Bundler
|
|
|
36
41
|
end.flatten.compact.uniq
|
|
37
42
|
end
|
|
38
43
|
|
|
39
|
-
def copy_for(platforms)
|
|
40
|
-
platforms.select! {|p| for?(p) }
|
|
41
|
-
return unless platforms.any?
|
|
42
|
-
|
|
43
|
-
copied_sg = self.class.new(@all_specs)
|
|
44
|
-
copied_sg.ignores_bundler_dependencies = @ignores_bundler_dependencies
|
|
45
|
-
copied_sg.activated_platforms = platforms
|
|
46
|
-
copied_sg
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
def for?(platform)
|
|
50
|
-
@specs[platform].any?
|
|
51
|
-
end
|
|
52
|
-
|
|
53
44
|
def to_s
|
|
54
45
|
activated_platforms_string = sorted_activated_platforms.join(", ")
|
|
55
46
|
"#{name} (#{version}) (#{activated_platforms_string})"
|
|
56
47
|
end
|
|
57
48
|
|
|
58
49
|
def dependencies_for_activated_platforms
|
|
59
|
-
dependencies
|
|
60
|
-
metadata_dependencies = @activated_platforms.map do |platform|
|
|
61
|
-
metadata_dependencies(@specs[platform].first, platform)
|
|
62
|
-
end
|
|
63
|
-
dependencies.concat(metadata_dependencies).flatten
|
|
50
|
+
@dependencies[activated_platforms]
|
|
64
51
|
end
|
|
65
52
|
|
|
66
53
|
def ==(other)
|
|
@@ -86,34 +73,35 @@ module Bundler
|
|
|
86
73
|
protected
|
|
87
74
|
|
|
88
75
|
def sorted_activated_platforms
|
|
89
|
-
|
|
76
|
+
activated_platforms.sort_by(&:to_s)
|
|
90
77
|
end
|
|
91
78
|
|
|
92
79
|
private
|
|
93
80
|
|
|
94
|
-
def
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
dependencies[platform]
|
|
81
|
+
def dependencies_for(platforms)
|
|
82
|
+
platforms.map do |platform|
|
|
83
|
+
__dependencies(platform) + metadata_dependencies(platform)
|
|
84
|
+
end.flatten
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def __dependencies(platform)
|
|
88
|
+
dependencies = []
|
|
89
|
+
@specs[platform].first.dependencies.each do |dep|
|
|
90
|
+
next if dep.type == :development
|
|
91
|
+
dependencies << DepProxy.get_proxy(dep, platform)
|
|
106
92
|
end
|
|
93
|
+
dependencies
|
|
107
94
|
end
|
|
108
95
|
|
|
109
|
-
def metadata_dependencies(
|
|
110
|
-
|
|
96
|
+
def metadata_dependencies(platform)
|
|
97
|
+
spec = @specs[platform].first
|
|
98
|
+
return [] if spec.is_a?(LazySpecification)
|
|
111
99
|
dependencies = []
|
|
112
100
|
if !spec.required_ruby_version.nil? && !spec.required_ruby_version.none?
|
|
113
|
-
dependencies << DepProxy.
|
|
101
|
+
dependencies << DepProxy.get_proxy(Gem::Dependency.new("Ruby\0", spec.required_ruby_version), platform)
|
|
114
102
|
end
|
|
115
103
|
if !spec.required_rubygems_version.nil? && !spec.required_rubygems_version.none?
|
|
116
|
-
dependencies << DepProxy.
|
|
104
|
+
dependencies << DepProxy.get_proxy(Gem::Dependency.new("RubyGems\0", spec.required_rubygems_version), platform)
|
|
117
105
|
end
|
|
118
106
|
dependencies
|
|
119
107
|
end
|
data/lib/bundler/resolver.rb
CHANGED
|
@@ -5,6 +5,8 @@ module Bundler
|
|
|
5
5
|
require_relative "vendored_molinillo"
|
|
6
6
|
require_relative "resolver/spec_group"
|
|
7
7
|
|
|
8
|
+
include GemHelpers
|
|
9
|
+
|
|
8
10
|
# Figures out the best possible configuration of gems that satisfies
|
|
9
11
|
# the list of passed dependencies and any child dependencies without
|
|
10
12
|
# causing any gem activation errors.
|
|
@@ -15,16 +17,14 @@ module Bundler
|
|
|
15
17
|
# ==== Returns
|
|
16
18
|
# <GemBundle>,nil:: If the list of dependencies can be resolved, a
|
|
17
19
|
# collection of gemspecs is returned. Otherwise, nil is returned.
|
|
18
|
-
def self.resolve(requirements,
|
|
19
|
-
platforms = Set.new(platforms) if platforms
|
|
20
|
+
def self.resolve(requirements, source_requirements = {}, base = [], gem_version_promoter = GemVersionPromoter.new, additional_base_requirements = [], platforms = nil)
|
|
20
21
|
base = SpecSet.new(base) unless base.is_a?(SpecSet)
|
|
21
|
-
resolver = new(
|
|
22
|
+
resolver = new(source_requirements, base, gem_version_promoter, additional_base_requirements, platforms)
|
|
22
23
|
result = resolver.start(requirements)
|
|
23
|
-
SpecSet.new(result)
|
|
24
|
+
SpecSet.new(SpecSet.new(result).for(requirements.reject{|dep| dep.name.end_with?("\0") }))
|
|
24
25
|
end
|
|
25
26
|
|
|
26
|
-
def initialize(
|
|
27
|
-
@index = index
|
|
27
|
+
def initialize(source_requirements, base, gem_version_promoter, additional_base_requirements, platforms)
|
|
28
28
|
@source_requirements = source_requirements
|
|
29
29
|
@base = base
|
|
30
30
|
@resolver = Molinillo::Resolver.new(self, self)
|
|
@@ -32,14 +32,13 @@ module Bundler
|
|
|
32
32
|
@base_dg = Molinillo::DependencyGraph.new
|
|
33
33
|
@base.each do |ls|
|
|
34
34
|
dep = Dependency.new(ls.name, ls.version)
|
|
35
|
-
@base_dg.add_vertex(ls.name, DepProxy.
|
|
35
|
+
@base_dg.add_vertex(ls.name, DepProxy.get_proxy(dep, ls.platform), true)
|
|
36
36
|
end
|
|
37
37
|
additional_base_requirements.each {|d| @base_dg.add_vertex(d.name, d) }
|
|
38
|
-
@platforms = platforms
|
|
38
|
+
@platforms = platforms.reject {|p| p != Gem::Platform::RUBY && (platforms - [p]).any? {|pl| generic(pl) == p } }
|
|
39
|
+
@resolving_only_for_ruby = platforms == [Gem::Platform::RUBY]
|
|
39
40
|
@gem_version_promoter = gem_version_promoter
|
|
40
|
-
@allow_bundler_dependency_conflicts = Bundler.feature_flag.allow_bundler_dependency_conflicts?
|
|
41
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?
|
|
43
42
|
end
|
|
44
43
|
|
|
45
44
|
def start(requirements)
|
|
@@ -49,7 +48,6 @@ module Bundler
|
|
|
49
48
|
verify_gemfile_dependencies_are_found!(requirements)
|
|
50
49
|
dg = @resolver.resolve(requirements, @base_dg)
|
|
51
50
|
dg.
|
|
52
|
-
tap {|resolved| validate_resolved_specs!(resolved) }.
|
|
53
51
|
map(&:payload).
|
|
54
52
|
reject {|sg| sg.name.end_with?("\0") }.
|
|
55
53
|
map(&:to_specs).
|
|
@@ -75,7 +73,7 @@ module Bundler
|
|
|
75
73
|
return unless debug?
|
|
76
74
|
debug_info = yield
|
|
77
75
|
debug_info = debug_info.inspect unless debug_info.is_a?(String)
|
|
78
|
-
puts debug_info.split("\n").map {|s| "BUNDLER: "
|
|
76
|
+
puts debug_info.split("\n").map {|s| depth == 0 ? "BUNDLER: #{s}" : "BUNDLER(#{depth}): #{s}" }
|
|
79
77
|
end
|
|
80
78
|
|
|
81
79
|
def debug?
|
|
@@ -109,10 +107,9 @@ module Bundler
|
|
|
109
107
|
def search_for(dependency_proxy)
|
|
110
108
|
platform = dependency_proxy.__platform
|
|
111
109
|
dependency = dependency_proxy.dep
|
|
110
|
+
name = dependency.name
|
|
112
111
|
@search_for[dependency_proxy] ||= begin
|
|
113
|
-
|
|
114
|
-
index = index_for(dependency)
|
|
115
|
-
results = index.search(dependency, @base[name])
|
|
112
|
+
results = results_for(dependency, @base[name])
|
|
116
113
|
|
|
117
114
|
if vertex = @base_dg.vertex_named(name)
|
|
118
115
|
locked_requirement = vertex.payload.requirement
|
|
@@ -137,53 +134,45 @@ module Bundler
|
|
|
137
134
|
end
|
|
138
135
|
nested.reduce([]) do |groups, (version, specs)|
|
|
139
136
|
next groups if locked_requirement && !locked_requirement.satisfied_by?(version)
|
|
140
|
-
|
|
141
|
-
|
|
137
|
+
next groups unless specs.any? {|spec| spec.match_platform(platform) }
|
|
138
|
+
|
|
139
|
+
specs_by_platform = Hash.new do |current_specs, current_platform|
|
|
140
|
+
current_specs[current_platform] = select_best_platform_match(specs, current_platform)
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
spec_group_ruby = SpecGroup.create_for(specs_by_platform, [Gem::Platform::RUBY], Gem::Platform::RUBY)
|
|
144
|
+
groups << spec_group_ruby if spec_group_ruby
|
|
145
|
+
|
|
146
|
+
next groups if @resolving_only_for_ruby
|
|
147
|
+
|
|
148
|
+
spec_group = SpecGroup.create_for(specs_by_platform, @platforms, platform)
|
|
142
149
|
groups << spec_group
|
|
150
|
+
|
|
151
|
+
groups
|
|
143
152
|
end
|
|
144
153
|
else
|
|
145
154
|
[]
|
|
146
155
|
end
|
|
147
156
|
# GVP handles major itself, but it's still a bit risky to trust it with it
|
|
148
157
|
# until we get it settled with new behavior. For 2.x it can take over all cases.
|
|
149
|
-
|
|
158
|
+
if !@use_gvp
|
|
150
159
|
spec_groups
|
|
151
160
|
else
|
|
152
161
|
@gem_version_promoter.sort_versions(dependency, spec_groups)
|
|
153
162
|
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
|
-
selected_sgs.insert(-2, sg_ruby) if sg_ruby
|
|
167
|
-
end
|
|
168
|
-
selected_sgs
|
|
169
163
|
end
|
|
170
164
|
end
|
|
171
165
|
|
|
172
166
|
def index_for(dependency)
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
end
|
|
183
|
-
end
|
|
184
|
-
else
|
|
185
|
-
@index
|
|
186
|
-
end
|
|
167
|
+
source_for(dependency.name).specs
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def source_for(name)
|
|
171
|
+
@source_requirements[name] || @source_requirements[:default]
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
def results_for(dependency, base)
|
|
175
|
+
index_for(dependency).search(dependency, base)
|
|
187
176
|
end
|
|
188
177
|
|
|
189
178
|
def name_for(dependency)
|
|
@@ -206,19 +195,12 @@ module Bundler
|
|
|
206
195
|
requirement.matches_spec?(spec) || spec.source.is_a?(Source::Gemspec)
|
|
207
196
|
end
|
|
208
197
|
|
|
209
|
-
def
|
|
210
|
-
|
|
211
|
-
[@source_requirements[vertex.name]]
|
|
212
|
-
elsif @lockfile_uses_separate_rubygems_sources
|
|
213
|
-
vertex.recursive_predecessors.map do |v|
|
|
214
|
-
@source_requirements[v.name]
|
|
215
|
-
end << @source_requirements[:default]
|
|
216
|
-
end
|
|
198
|
+
def dependencies_equal?(dependencies, other_dependencies)
|
|
199
|
+
dependencies.map(&:dep) == other_dependencies.map(&:dep)
|
|
217
200
|
end
|
|
218
201
|
|
|
219
202
|
def sort_dependencies(dependencies, activated, conflicts)
|
|
220
203
|
dependencies.sort_by do |dependency|
|
|
221
|
-
dependency.all_sources = relevant_sources_for_vertex(activated.vertex_named(dependency.name))
|
|
222
204
|
name = name_for(dependency)
|
|
223
205
|
vertex = activated.vertex_named(name)
|
|
224
206
|
[
|
|
@@ -233,13 +215,6 @@ module Bundler
|
|
|
233
215
|
end
|
|
234
216
|
end
|
|
235
217
|
|
|
236
|
-
# Sort platforms from most general to most specific
|
|
237
|
-
def self.sort_platforms(platforms)
|
|
238
|
-
platforms.sort_by do |platform|
|
|
239
|
-
platform_sort_key(platform)
|
|
240
|
-
end
|
|
241
|
-
end
|
|
242
|
-
|
|
243
218
|
def self.platform_sort_key(platform)
|
|
244
219
|
# Prefer specific platform to not specific platform
|
|
245
220
|
return ["99-LAST", "", "", ""] if Gem::Platform::RUBY == platform
|
|
@@ -279,12 +254,6 @@ module Bundler
|
|
|
279
254
|
next if name == "bundler"
|
|
280
255
|
next unless search_for(requirement).empty?
|
|
281
256
|
|
|
282
|
-
cache_message = begin
|
|
283
|
-
" or in gems cached in #{Bundler.settings.app_cache_path}" if Bundler.app_cache.exist?
|
|
284
|
-
rescue GemfileNotFound
|
|
285
|
-
nil
|
|
286
|
-
end
|
|
287
|
-
|
|
288
257
|
if (base = @base[name]) && !base.empty?
|
|
289
258
|
version = base.first.version
|
|
290
259
|
message = "You have requested:\n" \
|
|
@@ -293,41 +262,53 @@ module Bundler
|
|
|
293
262
|
"Try running `bundle update #{name}`\n\n" \
|
|
294
263
|
"If you are updating multiple gems in your Gemfile at once,\n" \
|
|
295
264
|
"try passing them all to `bundle update`"
|
|
296
|
-
elsif source = @source_requirements[name]
|
|
297
|
-
specs = source.specs[name]
|
|
298
|
-
versions_with_platforms = specs.map {|s| [s.version, s.platform] }
|
|
299
|
-
message = String.new("Could not find gem '#{SharedHelpers.pretty_dependency(requirement)}' in #{source}#{cache_message}.\n")
|
|
300
|
-
message << if versions_with_platforms.any?
|
|
301
|
-
"The source contains the following versions of '#{name}': #{formatted_versions_with_platforms(versions_with_platforms)}"
|
|
302
|
-
else
|
|
303
|
-
"The source does not contain any versions of '#{name}'"
|
|
304
|
-
end
|
|
305
265
|
else
|
|
306
|
-
message =
|
|
307
|
-
"listed in your Gemfile#{cache_message}."
|
|
266
|
+
message = gem_not_found_message(name, requirement, source_for(name))
|
|
308
267
|
end
|
|
309
268
|
raise GemNotFound, message
|
|
310
269
|
end
|
|
311
270
|
end
|
|
312
271
|
|
|
313
|
-
def
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
272
|
+
def gem_not_found_message(name, requirement, source, extra_message = "")
|
|
273
|
+
specs = source.specs.search(name)
|
|
274
|
+
matching_part = name
|
|
275
|
+
requirement_label = SharedHelpers.pretty_dependency(requirement)
|
|
276
|
+
cache_message = begin
|
|
277
|
+
" or in gems cached in #{Bundler.settings.app_cache_path}" if Bundler.app_cache.exist?
|
|
278
|
+
rescue GemfileNotFound
|
|
279
|
+
nil
|
|
280
|
+
end
|
|
281
|
+
specs_matching_requirement = specs.select {| spec| requirement.matches_spec?(spec) }
|
|
282
|
+
|
|
283
|
+
if specs_matching_requirement.any?
|
|
284
|
+
specs = specs_matching_requirement
|
|
285
|
+
matching_part = requirement_label
|
|
286
|
+
requirement_label = "#{requirement_label} #{requirement.__platform}"
|
|
320
287
|
end
|
|
321
|
-
|
|
288
|
+
|
|
289
|
+
message = String.new("Could not find gem '#{requirement_label}'#{extra_message} in #{source}#{cache_message}.\n")
|
|
290
|
+
|
|
291
|
+
if specs.any?
|
|
292
|
+
message << "\nThe source contains the following gems matching '#{matching_part}':\n"
|
|
293
|
+
message << specs.map {|s| " * #{s.full_name}" }.join("\n")
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
message
|
|
322
297
|
end
|
|
323
298
|
|
|
324
299
|
def version_conflict_message(e)
|
|
325
300
|
# only show essential conflicts, if possible
|
|
326
301
|
conflicts = e.conflicts.dup
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
302
|
+
|
|
303
|
+
if conflicts["bundler"]
|
|
304
|
+
conflicts.replace("bundler" => conflicts["bundler"])
|
|
305
|
+
else
|
|
306
|
+
conflicts.delete_if do |_name, conflict|
|
|
307
|
+
deps = conflict.requirement_trees.map(&:last).flatten(1)
|
|
308
|
+
!Bundler::VersionRanges.empty?(*Bundler::VersionRanges.for_many(deps.map(&:requirement)))
|
|
309
|
+
end
|
|
330
310
|
end
|
|
311
|
+
|
|
331
312
|
e = Molinillo::VersionConflict.new(conflicts, e.specification_provider) unless conflicts.empty?
|
|
332
313
|
|
|
333
314
|
solver_name = "Bundler"
|
|
@@ -355,51 +336,40 @@ module Bundler
|
|
|
355
336
|
:additional_message_for_conflict => lambda do |o, name, conflict|
|
|
356
337
|
if name == "bundler"
|
|
357
338
|
o << %(\n Current Bundler version:\n bundler (#{Bundler::VERSION}))
|
|
358
|
-
other_bundler_required = !conflict.requirement.requirement.satisfied_by?(Gem::Version.new(Bundler::VERSION))
|
|
359
|
-
end
|
|
360
339
|
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
340
|
+
conflict_dependency = conflict.requirement
|
|
341
|
+
conflict_requirement = conflict_dependency.requirement
|
|
342
|
+
other_bundler_required = !conflict_requirement.satisfied_by?(Gem::Version.new(Bundler::VERSION))
|
|
343
|
+
|
|
344
|
+
if other_bundler_required
|
|
345
|
+
o << "\n\n"
|
|
346
|
+
|
|
347
|
+
candidate_specs = source_for(:default_bundler).specs.search(conflict_dependency)
|
|
348
|
+
if candidate_specs.any?
|
|
349
|
+
target_version = candidate_specs.last.version
|
|
350
|
+
new_command = [File.basename($PROGRAM_NAME), "_#{target_version}_", *ARGV].join(" ")
|
|
351
|
+
o << "Your bundle requires a different version of Bundler than the one you're running.\n"
|
|
352
|
+
o << "Install the necessary version with `gem install bundler:#{target_version}` and rerun bundler using `#{new_command}`\n"
|
|
353
|
+
else
|
|
354
|
+
o << "Your bundle requires a different version of Bundler than the one you're running, and that version could not be found.\n"
|
|
355
|
+
end
|
|
356
|
+
end
|
|
357
|
+
elsif conflict.locked_requirement
|
|
367
358
|
o << "\n"
|
|
368
359
|
o << %(Running `bundle update` will rebuild your snapshot from scratch, using only\n)
|
|
369
360
|
o << %(the gems in your Gemfile, which may resolve the conflict.\n)
|
|
370
|
-
elsif !conflict.existing
|
|
361
|
+
elsif !conflict.existing && !name.end_with?("\0")
|
|
371
362
|
o << "\n"
|
|
372
363
|
|
|
373
|
-
|
|
374
|
-
[conflict.requirement.source]
|
|
375
|
-
elsif conflict.requirement.all_sources
|
|
376
|
-
conflict.requirement.all_sources
|
|
377
|
-
elsif @lockfile_uses_separate_rubygems_sources
|
|
378
|
-
# every conflict should have an explicit group of sources when we
|
|
379
|
-
# enforce strict pinning
|
|
380
|
-
raise "no source set for #{conflict}"
|
|
381
|
-
else
|
|
382
|
-
[]
|
|
383
|
-
end.compact.map(&:to_s).uniq.sort
|
|
384
|
-
|
|
385
|
-
metadata_requirement = name.end_with?("\0")
|
|
386
|
-
|
|
387
|
-
o << "Could not find gem '" unless metadata_requirement
|
|
388
|
-
o << SharedHelpers.pretty_dependency(conflict.requirement)
|
|
389
|
-
o << "'" unless metadata_requirement
|
|
390
|
-
if conflict.requirement_trees.first.size > 1
|
|
391
|
-
o << ", which is required by "
|
|
392
|
-
o << "gem '#{SharedHelpers.pretty_dependency(conflict.requirement_trees.first[-2])}',"
|
|
393
|
-
end
|
|
394
|
-
o << " "
|
|
364
|
+
relevant_source = conflict.requirement.source || source_for(name)
|
|
395
365
|
|
|
396
|
-
|
|
397
|
-
"
|
|
398
|
-
elsif metadata_requirement
|
|
399
|
-
"is not available in #{relevant_sources.join(" or ")}"
|
|
366
|
+
extra_message = if conflict.requirement_trees.first.size > 1
|
|
367
|
+
", which is required by gem '#{SharedHelpers.pretty_dependency(conflict.requirement_trees.first[-2])}',"
|
|
400
368
|
else
|
|
401
|
-
"
|
|
369
|
+
""
|
|
402
370
|
end
|
|
371
|
+
|
|
372
|
+
o << gem_not_found_message(name, conflict.requirement, relevant_source, extra_message)
|
|
403
373
|
end
|
|
404
374
|
end,
|
|
405
375
|
:version_for_spec => lambda {|spec| spec.version },
|
|
@@ -412,29 +382,5 @@ module Bundler
|
|
|
412
382
|
end
|
|
413
383
|
)
|
|
414
384
|
end
|
|
415
|
-
|
|
416
|
-
def validate_resolved_specs!(resolved_specs)
|
|
417
|
-
resolved_specs.each do |v|
|
|
418
|
-
name = v.name
|
|
419
|
-
next unless sources = relevant_sources_for_vertex(v)
|
|
420
|
-
sources.compact!
|
|
421
|
-
if default_index = sources.index(@source_requirements[:default])
|
|
422
|
-
sources.delete_at(default_index)
|
|
423
|
-
end
|
|
424
|
-
sources.reject! {|s| s.specs[name].empty? }
|
|
425
|
-
sources.uniq!
|
|
426
|
-
next if sources.size <= 1
|
|
427
|
-
|
|
428
|
-
multisource_disabled = Bundler.feature_flag.disable_multisource?
|
|
429
|
-
|
|
430
|
-
msg = ["The gem '#{name}' was found in multiple relevant sources."]
|
|
431
|
-
msg.concat sources.map {|s| " * #{s}" }.sort
|
|
432
|
-
msg << "You #{multisource_disabled ? :must : :should} add this gem to the source block for the source you wish it to be installed from."
|
|
433
|
-
msg = msg.join("\n")
|
|
434
|
-
|
|
435
|
-
raise SecurityError, msg if multisource_disabled
|
|
436
|
-
Bundler.ui.warn "Warning: #{msg}"
|
|
437
|
-
end
|
|
438
|
-
end
|
|
439
385
|
end
|
|
440
386
|
end
|
data/lib/bundler/retry.rb
CHANGED
|
@@ -49,7 +49,7 @@ module Bundler
|
|
|
49
49
|
raise e
|
|
50
50
|
end
|
|
51
51
|
return true unless name
|
|
52
|
-
Bundler.ui.info "" unless Bundler.ui.debug? # Add new line
|
|
52
|
+
Bundler.ui.info "" unless Bundler.ui.debug? # Add new line in case dots preceded this
|
|
53
53
|
Bundler.ui.warn "Retrying #{name} due to error (#{current_run.next}/#{total_runs}): #{e.class} #{e.message}", Bundler.ui.debug?
|
|
54
54
|
end
|
|
55
55
|
|
data/lib/bundler/ruby_version.rb
CHANGED
|
@@ -103,7 +103,7 @@ module Bundler
|
|
|
103
103
|
|
|
104
104
|
def self.system
|
|
105
105
|
ruby_engine = RUBY_ENGINE.dup
|
|
106
|
-
ruby_version =
|
|
106
|
+
ruby_version = RUBY_VERSION.dup
|
|
107
107
|
ruby_engine_version = RUBY_ENGINE_VERSION.dup
|
|
108
108
|
patchlevel = RUBY_PATCHLEVEL.to_s
|
|
109
109
|
|