bundler 2.6.3 → 2.6.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +31 -0
- data/README.md +1 -1
- data/lib/bundler/build_metadata.rb +2 -2
- data/lib/bundler/cli/console.rb +8 -6
- data/lib/bundler/cli/doctor.rb +9 -5
- data/lib/bundler/cli/info.rb +4 -4
- data/lib/bundler/cli/issue.rb +1 -1
- data/lib/bundler/cli/show.rb +1 -1
- data/lib/bundler/current_ruby.rb +23 -33
- data/lib/bundler/definition.rb +60 -58
- data/lib/bundler/dependency.rb +92 -47
- data/lib/bundler/dsl.rb +83 -78
- data/lib/bundler/endpoint_specification.rb +10 -3
- data/lib/bundler/errors.rb +4 -0
- data/lib/bundler/gem_helpers.rb +4 -10
- data/lib/bundler/gem_version_promoter.rb +0 -2
- data/lib/bundler/installer.rb +1 -1
- data/lib/bundler/lazy_specification.rb +50 -45
- data/lib/bundler/match_metadata.rb +13 -0
- data/lib/bundler/resolver/package.rb +7 -3
- data/lib/bundler/resolver/spec_group.rb +1 -25
- data/lib/bundler/resolver.rb +11 -2
- data/lib/bundler/rubygems_ext.rb +83 -82
- data/lib/bundler/rubygems_integration.rb +2 -3
- data/lib/bundler/runtime.rb +19 -24
- data/lib/bundler/source/rubygems.rb +19 -4
- data/lib/bundler/source.rb +2 -0
- data/lib/bundler/source_list.rb +4 -0
- data/lib/bundler/spec_set.rb +50 -27
- data/lib/bundler/templates/newgem/Gemfile.tt +1 -0
- data/lib/bundler/version.rb +1 -1
- metadata +3 -3
data/lib/bundler/dependency.rb
CHANGED
@@ -2,51 +2,92 @@
|
|
2
2
|
|
3
3
|
require "rubygems/dependency"
|
4
4
|
require_relative "shared_helpers"
|
5
|
-
require_relative "rubygems_ext"
|
6
5
|
|
7
6
|
module Bundler
|
8
7
|
class Dependency < Gem::Dependency
|
9
|
-
attr_reader :autorequire
|
10
|
-
attr_reader :groups, :platforms, :gemfile, :path, :git, :github, :branch, :ref, :glob
|
11
|
-
|
12
|
-
ALL_RUBY_VERSIONS = (18..27).to_a.concat((30..35).to_a).freeze
|
13
|
-
PLATFORM_MAP = {
|
14
|
-
ruby: [Gem::Platform::RUBY, ALL_RUBY_VERSIONS],
|
15
|
-
mri: [Gem::Platform::RUBY, ALL_RUBY_VERSIONS],
|
16
|
-
rbx: [Gem::Platform::RUBY],
|
17
|
-
truffleruby: [Gem::Platform::RUBY],
|
18
|
-
jruby: [Gem::Platform::JAVA, [18, 19]],
|
19
|
-
windows: [Gem::Platform::WINDOWS, ALL_RUBY_VERSIONS],
|
20
|
-
# deprecated
|
21
|
-
mswin: [Gem::Platform::MSWIN, ALL_RUBY_VERSIONS],
|
22
|
-
mswin64: [Gem::Platform::MSWIN64, ALL_RUBY_VERSIONS - [18]],
|
23
|
-
mingw: [Gem::Platform::MINGW, ALL_RUBY_VERSIONS],
|
24
|
-
x64_mingw: [Gem::Platform::X64_MINGW, ALL_RUBY_VERSIONS - [18, 19]],
|
25
|
-
}.each_with_object({}) do |(platform, spec), hash|
|
26
|
-
hash[platform] = spec[0]
|
27
|
-
spec[1]&.each {|version| hash[:"#{platform}_#{version}"] = spec[0] }
|
28
|
-
end.freeze
|
29
|
-
|
30
8
|
def initialize(name, version, options = {}, &blk)
|
31
9
|
type = options["type"] || :runtime
|
32
10
|
super(name, version, type)
|
33
11
|
|
34
|
-
@
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
@
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
@
|
43
|
-
|
44
|
-
@
|
45
|
-
|
46
|
-
|
47
|
-
|
12
|
+
@options = options
|
13
|
+
end
|
14
|
+
|
15
|
+
def groups
|
16
|
+
@groups ||= Array(@options["group"] || :default).map(&:to_sym)
|
17
|
+
end
|
18
|
+
|
19
|
+
def source
|
20
|
+
return @source if defined?(@source)
|
21
|
+
|
22
|
+
@source = @options["source"]
|
23
|
+
end
|
24
|
+
|
25
|
+
def path
|
26
|
+
return @path if defined?(@path)
|
27
|
+
|
28
|
+
@path = @options["path"]
|
29
|
+
end
|
30
|
+
|
31
|
+
def git
|
32
|
+
return @git if defined?(@git)
|
48
33
|
|
49
|
-
@
|
34
|
+
@git = @options["git"]
|
35
|
+
end
|
36
|
+
|
37
|
+
def github
|
38
|
+
return @github if defined?(@github)
|
39
|
+
|
40
|
+
@github = @options["github"]
|
41
|
+
end
|
42
|
+
|
43
|
+
def branch
|
44
|
+
return @branch if defined?(@branch)
|
45
|
+
|
46
|
+
@branch = @options["branch"]
|
47
|
+
end
|
48
|
+
|
49
|
+
def ref
|
50
|
+
return @ref if defined?(@ref)
|
51
|
+
|
52
|
+
@ref = @options["ref"]
|
53
|
+
end
|
54
|
+
|
55
|
+
def glob
|
56
|
+
return @glob if defined?(@glob)
|
57
|
+
|
58
|
+
@glob = @options["glob"]
|
59
|
+
end
|
60
|
+
|
61
|
+
def platforms
|
62
|
+
@platforms ||= Array(@options["platforms"])
|
63
|
+
end
|
64
|
+
|
65
|
+
def env
|
66
|
+
return @env if defined?(@env)
|
67
|
+
|
68
|
+
@env = @options["env"]
|
69
|
+
end
|
70
|
+
|
71
|
+
def should_include
|
72
|
+
@should_include ||= @options.fetch("should_include", true)
|
73
|
+
end
|
74
|
+
|
75
|
+
def gemfile
|
76
|
+
return @gemfile if defined?(@gemfile)
|
77
|
+
|
78
|
+
@gemfile = @options["gemfile"]
|
79
|
+
end
|
80
|
+
|
81
|
+
def force_ruby_platform
|
82
|
+
return @force_ruby_platform if defined?(@force_ruby_platform)
|
83
|
+
|
84
|
+
@force_ruby_platform = @options["force_ruby_platform"]
|
85
|
+
end
|
86
|
+
|
87
|
+
def autorequire
|
88
|
+
return @autorequire if defined?(@autorequire)
|
89
|
+
|
90
|
+
@autorequire = Array(@options["require"] || []) if @options.key?("require")
|
50
91
|
end
|
51
92
|
|
52
93
|
RUBY_PLATFORM_ARRAY = [Gem::Platform::RUBY].freeze
|
@@ -56,37 +97,41 @@ module Bundler
|
|
56
97
|
# passed in the `valid_platforms` parameter
|
57
98
|
def gem_platforms(valid_platforms)
|
58
99
|
return RUBY_PLATFORM_ARRAY if force_ruby_platform
|
59
|
-
return valid_platforms if
|
100
|
+
return valid_platforms if platforms.empty?
|
60
101
|
|
61
102
|
valid_platforms.select {|p| expanded_platforms.include?(GemHelpers.generic(p)) }
|
62
103
|
end
|
63
104
|
|
64
105
|
def expanded_platforms
|
65
|
-
@expanded_platforms ||=
|
106
|
+
@expanded_platforms ||= platforms.filter_map {|pl| CurrentRuby::PLATFORM_MAP[pl] }.flatten.uniq
|
66
107
|
end
|
67
108
|
|
68
109
|
def should_include?
|
69
|
-
|
110
|
+
should_include && current_env? && current_platform?
|
70
111
|
end
|
71
112
|
|
72
113
|
def gemspec_dev_dep?
|
73
|
-
|
114
|
+
@gemspec_dev_dep ||= @options.fetch("gemspec_dev_dep", false)
|
115
|
+
end
|
116
|
+
|
117
|
+
def gemfile_dep?
|
118
|
+
!gemspec_dev_dep?
|
74
119
|
end
|
75
120
|
|
76
121
|
def current_env?
|
77
|
-
return true unless
|
78
|
-
if
|
79
|
-
|
122
|
+
return true unless env
|
123
|
+
if env.is_a?(Hash)
|
124
|
+
env.all? do |key, val|
|
80
125
|
ENV[key.to_s] && (val.is_a?(String) ? ENV[key.to_s] == val : ENV[key.to_s] =~ val)
|
81
126
|
end
|
82
127
|
else
|
83
|
-
ENV[
|
128
|
+
ENV[env.to_s]
|
84
129
|
end
|
85
130
|
end
|
86
131
|
|
87
132
|
def current_platform?
|
88
|
-
return true if
|
89
|
-
|
133
|
+
return true if platforms.empty?
|
134
|
+
platforms.any? do |p|
|
90
135
|
Bundler.current_ruby.send("#{p}?")
|
91
136
|
end
|
92
137
|
end
|
data/lib/bundler/dsl.rb
CHANGED
@@ -13,10 +13,10 @@ module Bundler
|
|
13
13
|
builder.to_definition(lockfile, unlock)
|
14
14
|
end
|
15
15
|
|
16
|
-
VALID_PLATFORMS = Bundler::
|
16
|
+
VALID_PLATFORMS = Bundler::CurrentRuby::PLATFORM_MAP.keys.freeze
|
17
17
|
|
18
18
|
VALID_KEYS = %w[group groups git path glob name branch ref tag require submodules
|
19
|
-
platform platforms
|
19
|
+
platform platforms source install_if force_ruby_platform].freeze
|
20
20
|
|
21
21
|
GITHUB_PULL_REQUEST_URL = %r{\Ahttps://github\.com/([A-Za-z0-9_\-\.]+/[A-Za-z0-9_\-\.]+)/pull/(\d+)\z}
|
22
22
|
GITLAB_MERGE_REQUEST_URL = %r{\Ahttps://gitlab\.com/([A-Za-z0-9_\-\./]+)/-/merge_requests/(\d+)\z}
|
@@ -77,12 +77,12 @@ module Bundler
|
|
77
77
|
|
78
78
|
@gemspecs << spec
|
79
79
|
|
80
|
-
|
80
|
+
path path, "glob" => glob, "name" => spec.name do
|
81
|
+
add_dependency spec.name
|
82
|
+
end
|
81
83
|
|
82
|
-
|
83
|
-
|
84
|
-
gem dep.name, *(dep.requirement.as_list + [type: :development])
|
85
|
-
end
|
84
|
+
spec.development_dependencies.each do |dep|
|
85
|
+
add_dependency dep.name, dep.requirement.as_list, "gemspec_dev_dep" => true, "group" => development_group
|
86
86
|
end
|
87
87
|
when 0
|
88
88
|
raise InvalidOption, "There are no gemspecs at #{expanded_path}"
|
@@ -94,79 +94,11 @@ module Bundler
|
|
94
94
|
|
95
95
|
def gem(name, *args)
|
96
96
|
options = args.last.is_a?(Hash) ? args.pop.dup : {}
|
97
|
-
options["gemfile"] = @gemfile
|
98
97
|
version = args || [">= 0"]
|
99
98
|
|
100
99
|
normalize_options(name, version, options)
|
101
100
|
|
102
|
-
|
103
|
-
|
104
|
-
# if there's already a dependency with this name we try to prefer one
|
105
|
-
if current = @dependencies.find {|d| d.name == dep.name }
|
106
|
-
if current.requirement != dep.requirement
|
107
|
-
current_requirement_open = current.requirements_list.include?(">= 0")
|
108
|
-
|
109
|
-
gemspec_dep = [dep, current].find(&:gemspec_dev_dep?)
|
110
|
-
if gemspec_dep
|
111
|
-
gemfile_dep = [dep, current].find(&:runtime?)
|
112
|
-
|
113
|
-
if gemfile_dep && !current_requirement_open
|
114
|
-
Bundler.ui.warn "A gemspec development dependency (#{gemspec_dep.name}, #{gemspec_dep.requirement}) is being overridden by a Gemfile dependency (#{gemfile_dep.name}, #{gemfile_dep.requirement}).\n" \
|
115
|
-
"This behaviour may change in the future. Please remove either of them, or make sure they both have the same requirement\n"
|
116
|
-
elsif gemfile_dep.nil?
|
117
|
-
require_relative "vendor/pub_grub/lib/pub_grub/version_range"
|
118
|
-
require_relative "vendor/pub_grub/lib/pub_grub/version_constraint"
|
119
|
-
require_relative "vendor/pub_grub/lib/pub_grub/version_union"
|
120
|
-
require_relative "vendor/pub_grub/lib/pub_grub/rubygems"
|
121
|
-
|
122
|
-
current_gemspec_range = PubGrub::RubyGems.requirement_to_range(current.requirement)
|
123
|
-
next_gemspec_range = PubGrub::RubyGems.requirement_to_range(dep.requirement)
|
124
|
-
|
125
|
-
if current_gemspec_range.intersects?(next_gemspec_range)
|
126
|
-
dep = Dependency.new(name, current.requirement.as_list + dep.requirement.as_list, options)
|
127
|
-
else
|
128
|
-
raise GemfileError, "Two gemspecs have conflicting requirements on the same gem: #{dep} and #{current}"
|
129
|
-
end
|
130
|
-
end
|
131
|
-
else
|
132
|
-
update_prompt = ""
|
133
|
-
|
134
|
-
if File.basename(@gemfile) == Injector::INJECTED_GEMS
|
135
|
-
if dep.requirements_list.include?(">= 0") && !current_requirement_open
|
136
|
-
update_prompt = ". Gem already added"
|
137
|
-
else
|
138
|
-
update_prompt = ". If you want to update the gem version, run `bundle update #{current.name}`"
|
139
|
-
|
140
|
-
update_prompt += ". You may also need to change the version requirement specified in the Gemfile if it's too restrictive." unless current_requirement_open
|
141
|
-
end
|
142
|
-
end
|
143
|
-
|
144
|
-
raise GemfileError, "You cannot specify the same gem twice with different version requirements.\n" \
|
145
|
-
"You specified: #{current.name} (#{current.requirement}) and #{dep.name} (#{dep.requirement})" \
|
146
|
-
"#{update_prompt}"
|
147
|
-
end
|
148
|
-
end
|
149
|
-
|
150
|
-
unless current.gemspec_dev_dep? && dep.gemspec_dev_dep?
|
151
|
-
# Always prefer the dependency from the Gemfile
|
152
|
-
if current.gemspec_dev_dep?
|
153
|
-
@dependencies.delete(current)
|
154
|
-
elsif dep.gemspec_dev_dep?
|
155
|
-
return
|
156
|
-
elsif current.source != dep.source
|
157
|
-
raise GemfileError, "You cannot specify the same gem twice coming from different sources.\n" \
|
158
|
-
"You specified that #{dep.name} (#{dep.requirement}) should come from " \
|
159
|
-
"#{current.source || "an unspecified source"} and #{dep.source}\n"
|
160
|
-
else
|
161
|
-
Bundler.ui.warn "Your Gemfile lists the gem #{current.name} (#{current.requirement}) more than once.\n" \
|
162
|
-
"You should probably keep only one of them.\n" \
|
163
|
-
"Remove any duplicate entries and specify the gem only once.\n" \
|
164
|
-
"While it's not a problem now, it could cause errors if you change the version of one of them later."
|
165
|
-
end
|
166
|
-
end
|
167
|
-
end
|
168
|
-
|
169
|
-
@dependencies << dep
|
101
|
+
add_dependency(name, version, options)
|
170
102
|
end
|
171
103
|
|
172
104
|
def source(source, *args, &blk)
|
@@ -301,6 +233,81 @@ module Bundler
|
|
301
233
|
|
302
234
|
private
|
303
235
|
|
236
|
+
def add_dependency(name, version = nil, options = {})
|
237
|
+
options["gemfile"] = @gemfile
|
238
|
+
options["source"] ||= @source
|
239
|
+
options["env"] ||= @env
|
240
|
+
|
241
|
+
dep = Dependency.new(name, version, options)
|
242
|
+
|
243
|
+
# if there's already a dependency with this name we try to prefer one
|
244
|
+
if current = @dependencies.find {|d| d.name == dep.name }
|
245
|
+
if current.requirement != dep.requirement
|
246
|
+
current_requirement_open = current.requirements_list.include?(">= 0")
|
247
|
+
|
248
|
+
gemspec_dep = [dep, current].find(&:gemspec_dev_dep?)
|
249
|
+
if gemspec_dep
|
250
|
+
gemfile_dep = [dep, current].find(&:gemfile_dep?)
|
251
|
+
|
252
|
+
if gemfile_dep && !current_requirement_open
|
253
|
+
Bundler.ui.warn "A gemspec development dependency (#{gemspec_dep.name}, #{gemspec_dep.requirement}) is being overridden by a Gemfile dependency (#{gemfile_dep.name}, #{gemfile_dep.requirement}).\n" \
|
254
|
+
"This behaviour may change in the future. Please remove either of them, or make sure they both have the same requirement\n"
|
255
|
+
elsif gemfile_dep.nil?
|
256
|
+
require_relative "vendor/pub_grub/lib/pub_grub/version_range"
|
257
|
+
require_relative "vendor/pub_grub/lib/pub_grub/version_constraint"
|
258
|
+
require_relative "vendor/pub_grub/lib/pub_grub/version_union"
|
259
|
+
require_relative "vendor/pub_grub/lib/pub_grub/rubygems"
|
260
|
+
|
261
|
+
current_gemspec_range = PubGrub::RubyGems.requirement_to_range(current.requirement)
|
262
|
+
next_gemspec_range = PubGrub::RubyGems.requirement_to_range(dep.requirement)
|
263
|
+
|
264
|
+
if current_gemspec_range.intersects?(next_gemspec_range)
|
265
|
+
dep = Dependency.new(name, current.requirement.as_list + dep.requirement.as_list, options)
|
266
|
+
else
|
267
|
+
raise GemfileError, "Two gemspec development dependencies have conflicting requirements on the same gem: #{dep} and #{current}"
|
268
|
+
end
|
269
|
+
end
|
270
|
+
else
|
271
|
+
update_prompt = ""
|
272
|
+
|
273
|
+
if File.basename(@gemfile) == Injector::INJECTED_GEMS
|
274
|
+
if dep.requirements_list.include?(">= 0") && !current_requirement_open
|
275
|
+
update_prompt = ". Gem already added"
|
276
|
+
else
|
277
|
+
update_prompt = ". If you want to update the gem version, run `bundle update #{current.name}`"
|
278
|
+
|
279
|
+
update_prompt += ". You may also need to change the version requirement specified in the Gemfile if it's too restrictive." unless current_requirement_open
|
280
|
+
end
|
281
|
+
end
|
282
|
+
|
283
|
+
raise GemfileError, "You cannot specify the same gem twice with different version requirements.\n" \
|
284
|
+
"You specified: #{current.name} (#{current.requirement}) and #{dep.name} (#{dep.requirement})" \
|
285
|
+
"#{update_prompt}"
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
289
|
+
unless current.gemspec_dev_dep? && dep.gemspec_dev_dep?
|
290
|
+
# Always prefer the dependency from the Gemfile
|
291
|
+
if current.gemspec_dev_dep?
|
292
|
+
@dependencies.delete(current)
|
293
|
+
elsif dep.gemspec_dev_dep?
|
294
|
+
return
|
295
|
+
elsif current.source != dep.source
|
296
|
+
raise GemfileError, "You cannot specify the same gem twice coming from different sources.\n" \
|
297
|
+
"You specified that #{dep.name} (#{dep.requirement}) should come from " \
|
298
|
+
"#{current.source || "an unspecified source"} and #{dep.source}\n"
|
299
|
+
else
|
300
|
+
Bundler.ui.warn "Your Gemfile lists the gem #{current.name} (#{current.requirement}) more than once.\n" \
|
301
|
+
"You should probably keep only one of them.\n" \
|
302
|
+
"Remove any duplicate entries and specify the gem only once.\n" \
|
303
|
+
"While it's not a problem now, it could cause errors if you change the version of one of them later."
|
304
|
+
end
|
305
|
+
end
|
306
|
+
end
|
307
|
+
|
308
|
+
@dependencies << dep
|
309
|
+
end
|
310
|
+
|
304
311
|
def with_gemfile(gemfile)
|
305
312
|
expanded_gemfile_path = Pathname.new(gemfile).expand_path(@gemfile&.parent)
|
306
313
|
original_gemfile = @gemfile
|
@@ -433,8 +440,6 @@ module Bundler
|
|
433
440
|
opts["source"] = source
|
434
441
|
end
|
435
442
|
|
436
|
-
opts["source"] ||= @source
|
437
|
-
opts["env"] ||= @env
|
438
443
|
opts["platforms"] = platforms.dup
|
439
444
|
opts["group"] = groups
|
440
445
|
opts["should_include"] = install_if
|
@@ -6,7 +6,8 @@ module Bundler
|
|
6
6
|
include MatchRemoteMetadata
|
7
7
|
|
8
8
|
attr_reader :name, :version, :platform, :checksum
|
9
|
-
|
9
|
+
attr_writer :dependencies
|
10
|
+
attr_accessor :remote, :locked_platform
|
10
11
|
|
11
12
|
def initialize(name, version, platform, spec_fetcher, dependencies, metadata = nil)
|
12
13
|
super()
|
@@ -14,7 +15,8 @@ module Bundler
|
|
14
15
|
@version = Gem::Version.create version
|
15
16
|
@platform = Gem::Platform.new(platform)
|
16
17
|
@spec_fetcher = spec_fetcher
|
17
|
-
@dependencies =
|
18
|
+
@dependencies = nil
|
19
|
+
@unbuilt_dependencies = dependencies
|
18
20
|
|
19
21
|
@loaded_from = nil
|
20
22
|
@remote_specification = nil
|
@@ -31,6 +33,11 @@ module Bundler
|
|
31
33
|
@platform
|
32
34
|
end
|
33
35
|
|
36
|
+
def dependencies
|
37
|
+
@dependencies ||= @unbuilt_dependencies.map! {|dep, reqs| build_dependency(dep, reqs) }
|
38
|
+
end
|
39
|
+
alias_method :runtime_dependencies, :dependencies
|
40
|
+
|
34
41
|
# needed for standalone, load required_paths from local gemspec
|
35
42
|
# after the gem is installed
|
36
43
|
def require_paths
|
@@ -161,7 +168,7 @@ module Bundler
|
|
161
168
|
end
|
162
169
|
|
163
170
|
def build_dependency(name, requirements)
|
164
|
-
|
171
|
+
Dependency.new(name, requirements)
|
165
172
|
end
|
166
173
|
end
|
167
174
|
end
|
data/lib/bundler/errors.rb
CHANGED
data/lib/bundler/gem_helpers.rb
CHANGED
@@ -4,20 +4,14 @@ module Bundler
|
|
4
4
|
module GemHelpers
|
5
5
|
GENERIC_CACHE = { Gem::Platform::RUBY => Gem::Platform::RUBY } # rubocop:disable Style/MutableConstant
|
6
6
|
GENERICS = [
|
7
|
-
|
8
|
-
|
9
|
-
[Gem::Platform.new("mswin64"), Gem::Platform.new("mswin64")],
|
10
|
-
[Gem::Platform.new("universal-mingw32"), Gem::Platform.new("universal-mingw32")],
|
11
|
-
[Gem::Platform.new("x64-mingw32"), Gem::Platform.new("x64-mingw32")],
|
12
|
-
[Gem::Platform.new("x86_64-mingw32"), Gem::Platform.new("x64-mingw32")],
|
13
|
-
[Gem::Platform.new("x64-mingw-ucrt"), Gem::Platform.new("x64-mingw-ucrt")],
|
14
|
-
[Gem::Platform.new("mingw32"), Gem::Platform.new("x86-mingw32")],
|
7
|
+
Gem::Platform::JAVA,
|
8
|
+
*Gem::Platform::WINDOWS,
|
15
9
|
].freeze
|
16
10
|
|
17
11
|
def generic(p)
|
18
12
|
GENERIC_CACHE[p] ||= begin
|
19
|
-
|
20
|
-
p
|
13
|
+
found = GENERICS.find do |match|
|
14
|
+
p === match
|
21
15
|
end
|
22
16
|
found || Gem::Platform::RUBY
|
23
17
|
end
|
@@ -132,8 +132,6 @@ module Bundler
|
|
132
132
|
# Specific version moves can't always reliably be done during sorting
|
133
133
|
# as not all elements are compared against each other.
|
134
134
|
def post_sort(result, unlock, locked_version)
|
135
|
-
# default :major behavior in Bundler does not do this
|
136
|
-
return result if major?
|
137
135
|
if unlock || locked_version.nil?
|
138
136
|
result
|
139
137
|
else
|
data/lib/bundler/installer.rb
CHANGED
@@ -193,7 +193,7 @@ module Bundler
|
|
193
193
|
def install(options)
|
194
194
|
standalone = options[:standalone]
|
195
195
|
force = options[:force]
|
196
|
-
local = options[:local]
|
196
|
+
local = options[:local] || options[:"prefer-local"]
|
197
197
|
jobs = installation_parallelization
|
198
198
|
spec_installations = ParallelInstaller.call(self, @definition.specs, jobs, standalone, force, local: local)
|
199
199
|
spec_installations.each do |installation|
|
@@ -121,13 +121,10 @@ module Bundler
|
|
121
121
|
out
|
122
122
|
end
|
123
123
|
|
124
|
-
def
|
125
|
-
source.
|
126
|
-
|
127
|
-
matching_specs = source.specs.search(self)
|
128
|
-
return self if matching_specs.empty?
|
124
|
+
def materialize_for_cache
|
125
|
+
source.remote!
|
129
126
|
|
130
|
-
|
127
|
+
materialize(self, &:first)
|
131
128
|
end
|
132
129
|
|
133
130
|
def materialized_for_installation
|
@@ -140,53 +137,25 @@ module Bundler
|
|
140
137
|
source.local!
|
141
138
|
|
142
139
|
if use_exact_resolved_specifications?
|
143
|
-
|
140
|
+
materialize(self) do |matching_specs|
|
141
|
+
choose_compatible(matching_specs)
|
142
|
+
end
|
144
143
|
else
|
145
|
-
|
146
|
-
|
144
|
+
materialize([name, version]) do |matching_specs|
|
145
|
+
target_platform = source.is_a?(Source::Path) ? platform : local_platform
|
147
146
|
|
148
|
-
|
149
|
-
|
150
|
-
installable_candidates = GemHelpers.select_best_platform_match(matching_specs, target_platform)
|
151
|
-
|
152
|
-
specification = __materialize__(installable_candidates, fallback_to_non_installable: false)
|
153
|
-
return specification unless specification.nil?
|
154
|
-
|
155
|
-
if target_platform != platform
|
156
|
-
installable_candidates = GemHelpers.select_best_platform_match(matching_specs, platform)
|
157
|
-
end
|
147
|
+
installable_candidates = GemHelpers.select_best_platform_match(matching_specs, target_platform)
|
158
148
|
|
159
|
-
|
160
|
-
|
161
|
-
end
|
149
|
+
specification = choose_compatible(installable_candidates, fallback_to_non_installable: false)
|
150
|
+
return specification unless specification.nil?
|
162
151
|
|
163
|
-
|
164
|
-
|
165
|
-
# lock file, which is not allowed. In that case, we will give a proper error
|
166
|
-
# about the mismatch higher up the stack, right before trying to install the
|
167
|
-
# bad gem.
|
168
|
-
def __materialize__(candidates, fallback_to_non_installable: Bundler.frozen_bundle?)
|
169
|
-
search = candidates.reverse.find do |spec|
|
170
|
-
spec.is_a?(StubSpecification) || spec.matches_current_metadata?
|
171
|
-
end
|
172
|
-
if search.nil? && fallback_to_non_installable
|
173
|
-
search = candidates.last
|
174
|
-
elsif search && search.full_name == full_name
|
175
|
-
# We don't validate locally installed dependencies but accept what's in
|
176
|
-
# the lockfile instead for performance, since loading locally installed
|
177
|
-
# dependencies would mean evaluating all gemspecs, which would affect
|
178
|
-
# `bundler/setup` performance
|
179
|
-
if search.is_a?(StubSpecification)
|
180
|
-
search.dependencies = dependencies
|
181
|
-
else
|
182
|
-
if !source.is_a?(Source::Path) && search.runtime_dependencies.sort != dependencies.sort
|
183
|
-
raise IncorrectLockfileDependencies.new(self)
|
152
|
+
if target_platform != platform
|
153
|
+
installable_candidates = GemHelpers.select_best_platform_match(matching_specs, platform)
|
184
154
|
end
|
185
155
|
|
186
|
-
|
156
|
+
choose_compatible(installable_candidates)
|
187
157
|
end
|
188
158
|
end
|
189
|
-
search
|
190
159
|
end
|
191
160
|
|
192
161
|
def inspect
|
@@ -217,5 +186,41 @@ module Bundler
|
|
217
186
|
|
218
187
|
(most_specific_locked_platform != generic_platform) || force_ruby_platform || Bundler.settings[:force_ruby_platform]
|
219
188
|
end
|
189
|
+
|
190
|
+
def materialize(query)
|
191
|
+
matching_specs = source.specs.search(query)
|
192
|
+
return self if matching_specs.empty?
|
193
|
+
|
194
|
+
yield matching_specs
|
195
|
+
end
|
196
|
+
|
197
|
+
# If in frozen mode, we fallback to a non-installable candidate because by
|
198
|
+
# doing this we avoid re-resolving and potentially end up changing the
|
199
|
+
# lock file, which is not allowed. In that case, we will give a proper error
|
200
|
+
# about the mismatch higher up the stack, right before trying to install the
|
201
|
+
# bad gem.
|
202
|
+
def choose_compatible(candidates, fallback_to_non_installable: Bundler.frozen_bundle?)
|
203
|
+
search = candidates.reverse.find do |spec|
|
204
|
+
spec.is_a?(StubSpecification) || spec.matches_current_metadata?
|
205
|
+
end
|
206
|
+
if search.nil? && fallback_to_non_installable
|
207
|
+
search = candidates.last
|
208
|
+
elsif search && search.full_name == full_name
|
209
|
+
# We don't validate locally installed dependencies but accept what's in
|
210
|
+
# the lockfile instead for performance, since loading locally installed
|
211
|
+
# dependencies would mean evaluating all gemspecs, which would affect
|
212
|
+
# `bundler/setup` performance
|
213
|
+
if search.is_a?(StubSpecification)
|
214
|
+
search.dependencies = dependencies
|
215
|
+
else
|
216
|
+
if !source.is_a?(Source::Path) && search.runtime_dependencies.sort != dependencies.sort
|
217
|
+
raise IncorrectLockfileDependencies.new(self)
|
218
|
+
end
|
219
|
+
|
220
|
+
search.locked_platform = platform if search.instance_of?(RemoteSpecification) || search.instance_of?(EndpointSpecification)
|
221
|
+
end
|
222
|
+
end
|
223
|
+
search
|
224
|
+
end
|
220
225
|
end
|
221
226
|
end
|
@@ -13,5 +13,18 @@ module Bundler
|
|
13
13
|
def matches_current_rubygems?
|
14
14
|
@required_rubygems_version.satisfied_by?(Gem.rubygems_version)
|
15
15
|
end
|
16
|
+
|
17
|
+
def expanded_dependencies
|
18
|
+
runtime_dependencies + [
|
19
|
+
metadata_dependency("Ruby", @required_ruby_version),
|
20
|
+
metadata_dependency("RubyGems", @required_rubygems_version),
|
21
|
+
].compact
|
22
|
+
end
|
23
|
+
|
24
|
+
def metadata_dependency(name, requirement)
|
25
|
+
return if requirement.nil? || requirement.none?
|
26
|
+
|
27
|
+
Gem::Dependency.new("#{name}\0", requirement)
|
28
|
+
end
|
16
29
|
end
|
17
30
|
end
|
@@ -15,7 +15,7 @@ module Bundler
|
|
15
15
|
class Package
|
16
16
|
attr_reader :name, :platforms, :dependency, :locked_version
|
17
17
|
|
18
|
-
def initialize(name, platforms, locked_specs:, unlock:, prerelease: false, prefer_local: false, dependency: nil)
|
18
|
+
def initialize(name, platforms, locked_specs:, unlock:, prerelease: false, prefer_local: false, dependency: nil, new_platforms: [])
|
19
19
|
@name = name
|
20
20
|
@platforms = platforms
|
21
21
|
@locked_version = locked_specs.version_for(name)
|
@@ -24,10 +24,14 @@ module Bundler
|
|
24
24
|
@top_level = !dependency.nil?
|
25
25
|
@prerelease = @dependency.prerelease? || @locked_version&.prerelease? || prerelease ? :consider_first : :ignore
|
26
26
|
@prefer_local = prefer_local
|
27
|
+
@new_platforms = new_platforms
|
27
28
|
end
|
28
29
|
|
29
30
|
def platform_specs(specs)
|
30
|
-
platforms.map
|
31
|
+
platforms.map do |platform|
|
32
|
+
prefer_locked = @new_platforms.include?(platform) ? false : !unlock?
|
33
|
+
GemHelpers.select_best_platform_match(specs, platform, prefer_locked: prefer_locked)
|
34
|
+
end
|
31
35
|
end
|
32
36
|
|
33
37
|
def to_s
|
@@ -55,7 +59,7 @@ module Bundler
|
|
55
59
|
end
|
56
60
|
|
57
61
|
def unlock?
|
58
|
-
@unlock
|
62
|
+
@unlock == true || @unlock.include?(name)
|
59
63
|
end
|
60
64
|
|
61
65
|
def ignores_prereleases?
|