bundler 1.13.7 → 1.14.0.pre.1
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 +4 -4
- data/.gitignore +2 -0
- data/.rubocop_todo.yml +100 -18
- data/.travis.yml +32 -18
- data/CHANGELOG.md +64 -2
- data/DEVELOPMENT.md +5 -3
- data/ISSUES.md +17 -0
- data/README.md +7 -0
- data/Rakefile +34 -23
- data/bin/rubocop +1 -1
- data/bundler.gemspec +2 -2
- data/exe/bundle +4 -6
- data/lib/bundler.rb +57 -5
- data/lib/bundler/cli.rb +51 -38
- data/lib/bundler/cli/binstubs.rb +1 -1
- data/lib/bundler/cli/cache.rb +1 -1
- data/lib/bundler/cli/check.rb +1 -1
- data/lib/bundler/cli/clean.rb +1 -1
- data/lib/bundler/cli/common.rb +30 -0
- data/lib/bundler/cli/doctor.rb +17 -19
- data/lib/bundler/cli/exec.rb +6 -0
- data/lib/bundler/cli/gem.rb +18 -4
- data/lib/bundler/cli/install.rb +9 -25
- data/lib/bundler/cli/lock.rb +8 -7
- data/lib/bundler/cli/outdated.rb +163 -56
- data/lib/bundler/cli/platform.rb +1 -1
- data/lib/bundler/cli/show.rb +1 -1
- data/lib/bundler/cli/update.rb +10 -23
- data/lib/bundler/compact_index_client.rb +108 -0
- data/lib/bundler/compact_index_client/cache.rb +119 -0
- data/lib/bundler/compact_index_client/updater.rb +88 -0
- data/lib/bundler/current_ruby.rb +4 -3
- data/lib/bundler/definition.rb +107 -17
- data/lib/bundler/dependency.rb +6 -0
- data/lib/bundler/dsl.rb +3 -2
- data/lib/bundler/env.rb +27 -18
- data/lib/bundler/errors.rb +22 -0
- data/lib/bundler/feature_flag.rb +32 -0
- data/lib/bundler/fetcher.rb +2 -2
- data/lib/bundler/fetcher/compact_index.rb +17 -5
- data/lib/bundler/fetcher/dependency.rb +1 -1
- data/lib/bundler/fetcher/downloader.rb +11 -0
- data/lib/bundler/friendly_errors.rb +28 -7
- data/lib/bundler/gem_helper.rb +1 -1
- data/lib/bundler/gem_helpers.rb +69 -1
- data/lib/bundler/gemdeps.rb +28 -0
- data/lib/bundler/index.rb +9 -4
- data/lib/bundler/inline.rb +3 -3
- data/lib/bundler/installer.rb +3 -2
- data/lib/bundler/installer/gem_installer.rb +2 -2
- data/lib/bundler/installer/parallel_installer.rb +40 -9
- data/lib/bundler/lazy_specification.rb +16 -1
- data/lib/bundler/lockfile_parser.rb +1 -2
- data/lib/bundler/match_platform.rb +12 -3
- data/lib/bundler/plugin.rb +4 -2
- data/lib/bundler/plugin/api.rb +2 -1
- data/lib/bundler/plugin/api/source.rb +1 -1
- data/lib/bundler/postit_trampoline.rb +12 -7
- data/lib/bundler/remote_specification.rb +5 -0
- data/lib/bundler/resolver.rb +59 -49
- data/lib/bundler/retry.rb +4 -1
- data/lib/bundler/ruby_version.rb +5 -0
- data/lib/bundler/rubygems_ext.rb +5 -0
- data/lib/bundler/rubygems_gem_installer.rb +60 -0
- data/lib/bundler/rubygems_integration.rb +28 -2
- data/lib/bundler/runtime.rb +2 -1
- data/lib/bundler/settings.rb +29 -5
- data/lib/bundler/setup.rb +1 -1
- data/lib/bundler/shared_helpers.rb +26 -15
- data/lib/bundler/source.rb +5 -0
- data/lib/bundler/source/git.rb +1 -1
- data/lib/bundler/source/git/git_proxy.rb +5 -0
- data/lib/bundler/source/path.rb +6 -1
- data/lib/bundler/source/rubygems.rb +11 -1
- data/lib/bundler/spec_set.rb +32 -13
- data/lib/bundler/templates/newgem/README.md.tt +1 -1
- data/lib/bundler/templates/newgem/bin/console.tt +1 -1
- data/lib/bundler/templates/newgem/gitignore.tt +5 -0
- data/lib/bundler/templates/newgem/spec/newgem_spec.rb.tt +1 -1
- data/lib/bundler/templates/newgem/spec/spec_helper.rb.tt +10 -1
- data/lib/bundler/ui/shell.rb +4 -0
- data/lib/bundler/ui/silent.rb +9 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb +7 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/action.rb +1 -1
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb +2 -2
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_vertex.rb +2 -2
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/delete_edge.rb +62 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb +1 -1
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/log.rb +12 -1
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/set_payload.rb +2 -2
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/tag.rb +2 -2
- data/lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb +1 -1
- data/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb +22 -13
- data/lib/bundler/vendor/{net → net-http-persistent/lib/net}/http/faster.rb +1 -0
- data/lib/bundler/vendor/{net → net-http-persistent/lib/net}/http/persistent.rb +24 -23
- data/lib/bundler/vendor/{net → net-http-persistent/lib/net}/http/persistent/ssl_reuse.rb +2 -1
- data/lib/bundler/vendored_persistent.rb +9 -4
- data/lib/bundler/version.rb +1 -1
- data/lib/bundler/worker.rb +27 -5
- data/lib/bundler/yaml_serializer.rb +1 -1
- data/man/bundle-config.ronn +29 -2
- data/man/bundle-install.ronn +1 -1
- data/man/bundle-lock.ronn +47 -0
- data/man/bundle-outdated.ronn +107 -0
- data/man/bundle-update.ronn +152 -3
- data/man/bundle.ronn +27 -9
- data/man/gemfile.5.ronn +8 -0
- metadata +37 -31
- data/lib/bundler/vendor/compact_index_client/lib/compact_index_client.rb +0 -79
- data/lib/bundler/vendor/compact_index_client/lib/compact_index_client/cache.rb +0 -112
- data/lib/bundler/vendor/compact_index_client/lib/compact_index_client/updater.rb +0 -80
- data/lib/bundler/vendor/compact_index_client/lib/compact_index_client/version.rb +0 -4
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Bundler
|
3
|
+
class Gemdeps
|
4
|
+
def initialize(runtime)
|
5
|
+
@runtime = runtime
|
6
|
+
end
|
7
|
+
|
8
|
+
def requested_specs
|
9
|
+
@runtime.requested_specs
|
10
|
+
end
|
11
|
+
|
12
|
+
def specs
|
13
|
+
@runtime.specs
|
14
|
+
end
|
15
|
+
|
16
|
+
def dependencies
|
17
|
+
@runtime.dependencies
|
18
|
+
end
|
19
|
+
|
20
|
+
def current_dependencies
|
21
|
+
@runtime.current_dependencies
|
22
|
+
end
|
23
|
+
|
24
|
+
def requires
|
25
|
+
@runtime.requires
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/bundler/index.rb
CHANGED
@@ -109,14 +109,19 @@ module Bundler
|
|
109
109
|
|
110
110
|
# returns a list of the dependencies
|
111
111
|
def unmet_dependency_names
|
112
|
-
|
113
|
-
|
114
|
-
|
112
|
+
dependency_names.select do |name|
|
113
|
+
name != "bundler" && search(name).empty?
|
114
|
+
end
|
115
115
|
end
|
116
116
|
|
117
117
|
def dependency_names
|
118
118
|
names = []
|
119
|
-
each
|
119
|
+
each do |spec|
|
120
|
+
spec.dependencies.each do |dep|
|
121
|
+
next if dep.type == :development
|
122
|
+
names << dep.name
|
123
|
+
end
|
124
|
+
end
|
120
125
|
names.uniq
|
121
126
|
end
|
122
127
|
|
data/lib/bundler/inline.rb
CHANGED
@@ -41,13 +41,13 @@ def gemfile(install = false, options = {}, &gemfile)
|
|
41
41
|
end
|
42
42
|
ENV["BUNDLE_GEMFILE"] ||= "Gemfile"
|
43
43
|
|
44
|
-
Bundler::Plugin.gemfile_install(&gemfile) if Bundler.
|
44
|
+
Bundler::Plugin.gemfile_install(&gemfile) if Bundler.feature_flag.plugins?
|
45
45
|
builder = Bundler::Dsl.new
|
46
46
|
builder.instance_eval(&gemfile)
|
47
47
|
|
48
48
|
definition = builder.to_definition(nil, true)
|
49
49
|
def definition.lock(*); end
|
50
|
-
definition.
|
50
|
+
definition.validate_runtime!
|
51
51
|
|
52
52
|
missing_specs = proc do
|
53
53
|
begin
|
@@ -60,7 +60,7 @@ def gemfile(install = false, options = {}, &gemfile)
|
|
60
60
|
|
61
61
|
Bundler.ui = ui if install
|
62
62
|
if install || missing_specs.call
|
63
|
-
installer = Bundler::Installer.install(Bundler.root, definition, :system => true)
|
63
|
+
installer = Bundler::Installer.install(Bundler.root, definition, :system => true, :inline => true)
|
64
64
|
installer.post_install_messages.each do |name, message|
|
65
65
|
Bundler.ui.info "Post-install message from #{name}:\n#{message}"
|
66
66
|
end
|
data/lib/bundler/installer.rb
CHANGED
@@ -159,6 +159,7 @@ module Bundler
|
|
159
159
|
# that said, it's a rare situation (other than rake), and parallel
|
160
160
|
# installation is SO MUCH FASTER. so we let people opt in.
|
161
161
|
def install(options)
|
162
|
+
Bundler.rubygems.load_plugins
|
162
163
|
force = options["force"]
|
163
164
|
jobs = 1
|
164
165
|
jobs = [Bundler.settings[:jobs].to_i - 1, 1].max if can_install_in_parallel?
|
@@ -207,11 +208,11 @@ module Bundler
|
|
207
208
|
end unless Bundler.bundle_path.exist?
|
208
209
|
rescue Errno::EEXIST
|
209
210
|
raise PathError, "Could not install to path `#{Bundler.settings[:path]}` " \
|
210
|
-
"because
|
211
|
+
"because a file already exists at that path. Either remove or rename the file so the directory can be created."
|
211
212
|
end
|
212
213
|
|
213
214
|
def resolve_if_need(options)
|
214
|
-
if Bundler.default_lockfile.exist? && !options["update"]
|
215
|
+
if Bundler.default_lockfile.exist? && !options["update"] && !options[:inline]
|
215
216
|
local = Bundler.ui.silence do
|
216
217
|
begin
|
217
218
|
tmpdef = Definition.build(Bundler.default_gemfile, Bundler.default_lockfile, nil)
|
@@ -52,12 +52,12 @@ module Bundler
|
|
52
52
|
end
|
53
53
|
|
54
54
|
def install
|
55
|
-
spec.source.install(spec, :force => force, :ensure_builtin_gems_cached => standalone)
|
55
|
+
spec.source.install(spec, :force => force, :ensure_builtin_gems_cached => standalone, :build_args => [spec_settings])
|
56
56
|
end
|
57
57
|
|
58
58
|
def install_with_settings
|
59
59
|
# Build arguments are global, so this is mutexed
|
60
|
-
Bundler.rubygems.
|
60
|
+
Bundler.rubygems.install_with_build_args([spec_settings]) { install }
|
61
61
|
end
|
62
62
|
|
63
63
|
def out_of_space_message
|
@@ -47,23 +47,22 @@ module Bundler
|
|
47
47
|
# sure needed dependencies have been installed.
|
48
48
|
def dependencies_installed?(all_specs)
|
49
49
|
installed_specs = all_specs.select(&:installed?).map(&:name)
|
50
|
-
dependencies
|
50
|
+
dependencies.all? {|d| installed_specs.include? d.name }
|
51
51
|
end
|
52
52
|
|
53
53
|
# Represents only the non-development dependencies, the ones that are
|
54
54
|
# itself and are in the total list.
|
55
|
-
def dependencies
|
55
|
+
def dependencies
|
56
56
|
@dependencies ||= begin
|
57
|
-
|
58
|
-
missing = deps.reject {|dep| all_spec_names.include? dep.name }
|
59
|
-
unless missing.empty?
|
60
|
-
raise Bundler::LockfileError, "Your Gemfile.lock is corrupt. The following #{missing.size > 1 ? "gems are" : "gem is"} missing " \
|
61
|
-
"from the DEPENDENCIES section: '#{missing.map(&:name).join('\' \'')}'"
|
62
|
-
end
|
63
|
-
deps
|
57
|
+
all_dependencies.reject {|dep| ignorable_dependency? dep }
|
64
58
|
end
|
65
59
|
end
|
66
60
|
|
61
|
+
def missing_lockfile_dependencies(all_spec_names)
|
62
|
+
deps = all_dependencies.reject {|dep| ignorable_dependency? dep }
|
63
|
+
deps.reject {|dep| all_spec_names.include? dep.name }
|
64
|
+
end
|
65
|
+
|
67
66
|
# Represents all dependencies
|
68
67
|
def all_dependencies
|
69
68
|
@spec.dependencies
|
@@ -79,6 +78,8 @@ module Bundler
|
|
79
78
|
[Bundler.settings[:jobs].to_i - 1, 1].max
|
80
79
|
end
|
81
80
|
|
81
|
+
attr_reader :size
|
82
|
+
|
82
83
|
def initialize(installer, all_specs, size, standalone, force)
|
83
84
|
@installer = installer
|
84
85
|
@size = size
|
@@ -88,6 +89,11 @@ module Bundler
|
|
88
89
|
end
|
89
90
|
|
90
91
|
def call
|
92
|
+
# Since `autoload` has the potential for threading issues on 1.8.7
|
93
|
+
# TODO: remove in bundler 2.0
|
94
|
+
require "bundler/gem_remote_fetcher" if RUBY_VERSION < "1.9"
|
95
|
+
|
96
|
+
check_for_corrupt_lockfile
|
91
97
|
enqueue_specs
|
92
98
|
process_specs until @specs.all?(&:installed?) || @specs.any?(&:failed?)
|
93
99
|
handle_error if @specs.any?(&:failed?)
|
@@ -131,6 +137,31 @@ module Bundler
|
|
131
137
|
raise Bundler::InstallError, errors.map(&:to_s).join("\n\n")
|
132
138
|
end
|
133
139
|
|
140
|
+
def check_for_corrupt_lockfile
|
141
|
+
missing_dependencies = @specs.map do |s|
|
142
|
+
[
|
143
|
+
s,
|
144
|
+
s.missing_lockfile_dependencies(@specs.map(&:name)),
|
145
|
+
]
|
146
|
+
end.reject { |a| a.last.empty? }
|
147
|
+
return if missing_dependencies.empty?
|
148
|
+
|
149
|
+
warning = []
|
150
|
+
warning << "Your lockfile was created by an old Bundler that left some things out."
|
151
|
+
if @size != 1
|
152
|
+
warning << "Because of the missing DEPENDENCIES, we can only install gems one at a time, instead of installing #{@size} at a time."
|
153
|
+
@size = 1
|
154
|
+
end
|
155
|
+
warning << "You can fix this by adding the missing gems to your Gemfile, running bundle install, and then removing the gems from your Gemfile."
|
156
|
+
warning << "The missing gems are:"
|
157
|
+
|
158
|
+
missing_dependencies.each do |spec, missing|
|
159
|
+
warning << "* #{missing.map(&:name).join(", ")} depended upon by #{spec.name}"
|
160
|
+
end
|
161
|
+
|
162
|
+
Bundler.ui.warn(warning.join("\n"))
|
163
|
+
end
|
164
|
+
|
134
165
|
# Keys in the remains hash represent uninstalled gems specs.
|
135
166
|
# We enqueue all gem specs that do not have any dependencies.
|
136
167
|
# Later we call this lambda again to install specs that depended on
|
@@ -6,6 +6,20 @@ require "bundler/match_platform"
|
|
6
6
|
module Bundler
|
7
7
|
class LazySpecification
|
8
8
|
Identifier = Struct.new(:name, :version, :source, :platform, :dependencies)
|
9
|
+
class Identifier
|
10
|
+
include Comparable
|
11
|
+
def <=>(other)
|
12
|
+
return unless other.is_a?(Identifier)
|
13
|
+
[name, version, platform_string] <=> [other.name, other.version, other.platform_string]
|
14
|
+
end
|
15
|
+
|
16
|
+
protected
|
17
|
+
|
18
|
+
def platform_string
|
19
|
+
platform_string = platform.to_s
|
20
|
+
platform_string == Index::RUBY ? Index::NULL : platform_string
|
21
|
+
end
|
22
|
+
end
|
9
23
|
|
10
24
|
include MatchPlatform
|
11
25
|
|
@@ -55,10 +69,11 @@ module Bundler
|
|
55
69
|
end
|
56
70
|
|
57
71
|
def __materialize__
|
72
|
+
search_object = Bundler.settings[:specific_platform] || Bundler.settings[:force_ruby_platform] ? self : Dependency.new(name, version)
|
58
73
|
@specification = if source.is_a?(Source::Gemspec) && source.gemspec.name == name
|
59
74
|
source.gemspec.tap {|s| s.source = source }
|
60
75
|
else
|
61
|
-
source.specs.search(
|
76
|
+
source.specs.search(search_object).last
|
62
77
|
end
|
63
78
|
end
|
64
79
|
|
@@ -1,5 +1,4 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
require "strscan"
|
3
2
|
|
4
3
|
# Some versions of the Bundler 1.1 RC series introduced corrupted
|
5
4
|
# lockfiles. There were two major problems:
|
@@ -92,7 +91,7 @@ module Bundler
|
|
92
91
|
end
|
93
92
|
end
|
94
93
|
@sources << @rubygems_aggregate
|
95
|
-
@specs = @specs.values
|
94
|
+
@specs = @specs.values.sort_by(&:identifier)
|
96
95
|
warn_for_outdated_bundler_version
|
97
96
|
rescue ArgumentError => e
|
98
97
|
Bundler.ui.debug(e)
|
@@ -6,9 +6,18 @@ module Bundler
|
|
6
6
|
include GemHelpers
|
7
7
|
|
8
8
|
def match_platform(p)
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
MatchPlatform.platforms_match?(platform, p)
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.platforms_match?(gemspec_platform, local_platform)
|
13
|
+
return true if gemspec_platform.nil?
|
14
|
+
return true if Gem::Platform::RUBY == gemspec_platform
|
15
|
+
return true if local_platform == gemspec_platform
|
16
|
+
gemspec_platform = Gem::Platform.new(gemspec_platform)
|
17
|
+
return true if GemHelpers.generic(gemspec_platform) === local_platform
|
18
|
+
return true if gemspec_platform === local_platform
|
19
|
+
|
20
|
+
false
|
12
21
|
end
|
13
22
|
end
|
14
23
|
end
|
data/lib/bundler/plugin.rb
CHANGED
@@ -62,7 +62,9 @@ module Bundler
|
|
62
62
|
|
63
63
|
save_plugins plugins, installed_specs, builder.inferred_plugins
|
64
64
|
rescue => e
|
65
|
-
|
65
|
+
unless e.is_a?(GemfileError)
|
66
|
+
Bundler.ui.error "Failed to install plugin: #{e.message}\n #{e.backtrace[0]}"
|
67
|
+
end
|
66
68
|
raise
|
67
69
|
end
|
68
70
|
|
@@ -158,7 +160,7 @@ module Bundler
|
|
158
160
|
#
|
159
161
|
# @param [String] event
|
160
162
|
def hook(event, *args, &arg_blk)
|
161
|
-
return unless Bundler.
|
163
|
+
return unless Bundler.feature_flag.plugins?
|
162
164
|
|
163
165
|
plugins = index.hook_plugins(event)
|
164
166
|
return unless plugins.any?
|
data/lib/bundler/plugin/api.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
require "bundler/plugin/api/source"
|
3
2
|
|
4
3
|
module Bundler
|
5
4
|
# This is the interfacing class represents the API that we intend to provide
|
@@ -24,6 +23,8 @@ module Bundler
|
|
24
23
|
# and hooks).
|
25
24
|
module Plugin
|
26
25
|
class API
|
26
|
+
autoload :Source, "bundler/plugin/api/source"
|
27
|
+
|
27
28
|
# The plugins should declare that they handle a command through this helper.
|
28
29
|
#
|
29
30
|
# @param [String] command being handled by them
|
@@ -93,7 +93,7 @@ module Bundler
|
|
93
93
|
# It should be called in `install` after the plugin is done placing the
|
94
94
|
# gem at correct install location.
|
95
95
|
#
|
96
|
-
# It also runs Gem hooks `
|
96
|
+
# It also runs Gem hooks `pre_install`, `post_build` and `post_install`
|
97
97
|
#
|
98
98
|
# Note: Do not override if you don't know what you are doing.
|
99
99
|
def post_install(spec, disable_exts = false)
|
@@ -1,13 +1,18 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
if ENV["BUNDLE_ENABLE_TRAMPOLINE"]
|
3
2
|
|
4
|
-
|
5
|
-
|
6
|
-
|
3
|
+
module BundlerVendoredPostIt; end
|
4
|
+
require "bundler/vendor/postit/lib/postit"
|
5
|
+
require "rubygems"
|
7
6
|
|
8
|
-
|
9
|
-
|
7
|
+
environment = BundlerVendoredPostIt::PostIt::Environment.new([])
|
8
|
+
version = Gem::Requirement.new(environment.bundler_version)
|
9
|
+
if version.requirements.size == 1 && version.requirements.first.first == "=" # version.exact?
|
10
|
+
if version.requirements.first.last.segments.first >= 2
|
11
|
+
ENV["BUNDLE_TRAMPOLINE_FORCE"] = "true"
|
12
|
+
end
|
13
|
+
end
|
10
14
|
|
15
|
+
if ENV["BUNDLE_TRAMPOLINE_FORCE"] && !ENV["BUNDLE_TRAMPOLINE_DISABLE"]
|
11
16
|
installed_version =
|
12
17
|
if defined?(Bundler::VERSION)
|
13
18
|
Bundler::VERSION
|
@@ -65,4 +70,4 @@ You're running Bundler #{installed_version} but this project uses #{running_vers
|
|
65
70
|
abort "The running bundler (#{running_version}) does not match the required `#{version}`"
|
66
71
|
end
|
67
72
|
|
68
|
-
end #
|
73
|
+
end # if ENV["BUNDLE_TRAMPOLINE_FORCE"] && !ENV["BUNDLE_TRAMPOLINE_DISABLE"]
|
@@ -81,5 +81,10 @@ module Bundler
|
|
81
81
|
def method_missing(method, *args, &blk)
|
82
82
|
_remote_specification.send(method, *args, &blk)
|
83
83
|
end
|
84
|
+
|
85
|
+
def respond_to?(method, include_all = false)
|
86
|
+
super || _remote_specification.respond_to?(method, include_all)
|
87
|
+
end
|
88
|
+
public :respond_to?
|
84
89
|
end
|
85
90
|
end
|
data/lib/bundler/resolver.rb
CHANGED
@@ -66,48 +66,39 @@ module Bundler
|
|
66
66
|
end
|
67
67
|
end
|
68
68
|
|
69
|
-
ALL = Bundler::Dependency::PLATFORM_MAP.values.uniq.freeze
|
70
|
-
|
71
69
|
class SpecGroup < Array
|
72
70
|
include GemHelpers
|
73
71
|
|
74
|
-
attr_reader :activated
|
72
|
+
attr_reader :activated
|
75
73
|
|
76
74
|
def initialize(a)
|
77
75
|
super
|
78
|
-
@required_by
|
79
|
-
@
|
76
|
+
@required_by = []
|
77
|
+
@activated_platforms = []
|
80
78
|
@dependencies = nil
|
81
|
-
@specs =
|
82
|
-
|
83
|
-
ALL.each do |p|
|
84
|
-
@specs[p] = reverse.find {|s| s.match_platform(p) }
|
79
|
+
@specs = Hash.new do |specs, platform|
|
80
|
+
specs[platform] = select_best_platform_match(self, platform)
|
85
81
|
end
|
86
82
|
end
|
87
83
|
|
88
84
|
def initialize_copy(o)
|
89
85
|
super
|
90
|
-
@
|
91
|
-
@activated = o.activated.dup
|
86
|
+
@activated_platforms = o.activated.dup
|
92
87
|
end
|
93
88
|
|
94
89
|
def to_specs
|
95
|
-
|
96
|
-
|
97
|
-
@activated.each do |p|
|
90
|
+
@activated_platforms.map do |p|
|
98
91
|
next unless s = @specs[p]
|
99
|
-
|
100
|
-
next if specs[platform]
|
101
|
-
|
102
|
-
lazy_spec = LazySpecification.new(name, version, platform, source)
|
92
|
+
lazy_spec = LazySpecification.new(name, version, s.platform, source)
|
103
93
|
lazy_spec.dependencies.replace s.dependencies
|
104
|
-
|
105
|
-
end
|
106
|
-
specs.values
|
94
|
+
lazy_spec
|
95
|
+
end.compact
|
107
96
|
end
|
108
97
|
|
109
98
|
def activate_platform!(platform)
|
110
|
-
|
99
|
+
return unless for?(platform)
|
100
|
+
return if @activated_platforms.include?(platform)
|
101
|
+
@activated_platforms << platform
|
111
102
|
end
|
112
103
|
|
113
104
|
def name
|
@@ -122,17 +113,9 @@ module Bundler
|
|
122
113
|
@source ||= first.source
|
123
114
|
end
|
124
115
|
|
125
|
-
def for?(platform
|
116
|
+
def for?(platform)
|
126
117
|
spec = @specs[platform]
|
127
|
-
|
128
|
-
|
129
|
-
return true if ruby_version.nil?
|
130
|
-
# Only allow endpoint specifications since they won't hit the network to
|
131
|
-
# fetch the full gemspec when calling required_ruby_version
|
132
|
-
return true if !spec.is_a?(EndpointSpecification) && !spec.is_a?(Gem::Specification)
|
133
|
-
return true if spec.required_ruby_version.nil?
|
134
|
-
|
135
|
-
spec.required_ruby_version.satisfied_by?(ruby_version.to_gem_version_with_patchlevel)
|
118
|
+
!spec.nil?
|
136
119
|
end
|
137
120
|
|
138
121
|
def to_s
|
@@ -140,7 +123,11 @@ module Bundler
|
|
140
123
|
end
|
141
124
|
|
142
125
|
def dependencies_for_activated_platforms
|
143
|
-
@
|
126
|
+
dependencies = @activated_platforms.map {|p| __dependencies[p] }
|
127
|
+
metadata_dependencies = @activated_platforms.map do |platform|
|
128
|
+
metadata_dependencies(@specs[platform], platform)
|
129
|
+
end
|
130
|
+
dependencies.concat(metadata_dependencies).flatten
|
144
131
|
end
|
145
132
|
|
146
133
|
def platforms_for_dependency_named(dependency)
|
@@ -150,18 +137,31 @@ module Bundler
|
|
150
137
|
private
|
151
138
|
|
152
139
|
def __dependencies
|
153
|
-
@dependencies
|
154
|
-
dependencies =
|
155
|
-
|
156
|
-
next unless spec = @specs[p]
|
157
|
-
dependencies[p] = []
|
140
|
+
@dependencies = Hash.new do |dependencies, platform|
|
141
|
+
dependencies[platform] = []
|
142
|
+
if spec = @specs[platform]
|
158
143
|
spec.dependencies.each do |dep|
|
159
144
|
next if dep.type == :development
|
160
|
-
dependencies[
|
145
|
+
dependencies[platform] << DepProxy.new(dep, platform)
|
161
146
|
end
|
162
147
|
end
|
163
|
-
dependencies
|
148
|
+
dependencies[platform]
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
def metadata_dependencies(spec, platform)
|
153
|
+
return [] unless spec
|
154
|
+
# Only allow endpoint specifications since they won't hit the network to
|
155
|
+
# fetch the full gemspec when calling required_ruby_version
|
156
|
+
return [] if !spec.is_a?(EndpointSpecification) && !spec.is_a?(Gem::Specification)
|
157
|
+
dependencies = []
|
158
|
+
if !spec.required_ruby_version.nil? && !spec.required_ruby_version.none?
|
159
|
+
dependencies << DepProxy.new(Gem::Dependency.new("ruby\0", spec.required_ruby_version), platform)
|
164
160
|
end
|
161
|
+
if !spec.required_rubygems_version.nil? && !spec.required_rubygems_version.none?
|
162
|
+
dependencies << DepProxy.new(Gem::Dependency.new("rubygems\0", spec.required_rubygems_version), platform)
|
163
|
+
end
|
164
|
+
dependencies
|
165
165
|
end
|
166
166
|
end
|
167
167
|
|
@@ -175,30 +175,34 @@ module Bundler
|
|
175
175
|
# ==== Returns
|
176
176
|
# <GemBundle>,nil:: If the list of dependencies can be resolved, a
|
177
177
|
# collection of gemspecs is returned. Otherwise, nil is returned.
|
178
|
-
def self.resolve(requirements, index, source_requirements = {}, base = [],
|
178
|
+
def self.resolve(requirements, index, source_requirements = {}, base = [], gem_version_promoter = GemVersionPromoter.new, additional_base_requirements = [])
|
179
179
|
base = SpecSet.new(base) unless base.is_a?(SpecSet)
|
180
|
-
resolver = new(index, source_requirements, base,
|
180
|
+
resolver = new(index, source_requirements, base, gem_version_promoter, additional_base_requirements)
|
181
181
|
result = resolver.start(requirements)
|
182
182
|
SpecSet.new(result)
|
183
183
|
end
|
184
184
|
|
185
|
-
def initialize(index, source_requirements, base,
|
185
|
+
def initialize(index, source_requirements, base, gem_version_promoter, additional_base_requirements)
|
186
186
|
@index = index
|
187
187
|
@source_requirements = source_requirements
|
188
188
|
@base = base
|
189
189
|
@resolver = Molinillo::Resolver.new(self, self)
|
190
190
|
@search_for = {}
|
191
191
|
@base_dg = Molinillo::DependencyGraph.new
|
192
|
-
@base.each
|
192
|
+
@base.each do |ls|
|
193
|
+
dep = Dependency.new(ls.name, ls.version)
|
194
|
+
@base_dg.add_vertex(ls.name, DepProxy.new(dep, ls.platform), true)
|
195
|
+
end
|
193
196
|
additional_base_requirements.each {|d| @base_dg.add_vertex(d.name, d) }
|
194
|
-
@ruby_version = ruby_version
|
195
197
|
@gem_version_promoter = gem_version_promoter
|
196
198
|
end
|
197
199
|
|
198
200
|
def start(requirements)
|
199
201
|
verify_gemfile_dependencies_are_found!(requirements)
|
200
202
|
dg = @resolver.resolve(requirements, @base_dg)
|
201
|
-
dg.map(&:payload).
|
203
|
+
dg.map(&:payload).
|
204
|
+
reject {|sg| sg.name.end_with?("\0") }.
|
205
|
+
map(&:to_specs).flatten
|
202
206
|
rescue Molinillo::VersionConflict => e
|
203
207
|
raise VersionConflict.new(e.conflicts.keys.uniq, e.message)
|
204
208
|
rescue Molinillo::CircularDependencyError => e
|
@@ -279,7 +283,7 @@ module Bundler
|
|
279
283
|
@gem_version_promoter.sort_versions(dependency, spec_groups)
|
280
284
|
end
|
281
285
|
end
|
282
|
-
search.select {|sg| sg.for?(platform
|
286
|
+
search.select {|sg| sg.for?(platform) }.each {|sg| sg.activate_platform!(platform) }
|
283
287
|
end
|
284
288
|
|
285
289
|
def index_for(dependency)
|
@@ -303,7 +307,8 @@ module Bundler
|
|
303
307
|
end
|
304
308
|
|
305
309
|
def requirement_satisfied_by?(requirement, activated, spec)
|
306
|
-
requirement.matches_spec?(spec) || spec.source.is_a?(Source::Gemspec)
|
310
|
+
return false unless requirement.matches_spec?(spec) || spec.source.is_a?(Source::Gemspec)
|
311
|
+
spec.activate_platform!(requirement.__platform) || spec.for?(requirement.__platform)
|
307
312
|
end
|
308
313
|
|
309
314
|
def sort_dependencies(dependencies, activated, conflicts)
|
@@ -360,8 +365,13 @@ module Bundler
|
|
360
365
|
"Source does not contain any versions of '#{requirement}'"
|
361
366
|
end
|
362
367
|
else
|
368
|
+
cache_message = begin
|
369
|
+
" or in gems cached in #{Bundler.settings.app_cache_path}" if Bundler.app_cache.exist?
|
370
|
+
rescue GemfileNotFound
|
371
|
+
nil
|
372
|
+
end
|
363
373
|
message = "Could not find gem '#{requirement}' in any of the gem sources " \
|
364
|
-
"listed in your Gemfile
|
374
|
+
"listed in your Gemfile#{cache_message}."
|
365
375
|
end
|
366
376
|
raise GemNotFound, message
|
367
377
|
end
|