bundler 2.6.2 → 2.6.4

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.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +53 -0
  3. data/README.md +2 -2
  4. data/lib/bundler/build_metadata.rb +2 -2
  5. data/lib/bundler/cli/console.rb +8 -6
  6. data/lib/bundler/cli/doctor.rb +9 -5
  7. data/lib/bundler/cli/info.rb +4 -4
  8. data/lib/bundler/cli/issue.rb +1 -1
  9. data/lib/bundler/cli/outdated.rb +6 -4
  10. data/lib/bundler/cli/show.rb +1 -1
  11. data/lib/bundler/current_ruby.rb +23 -33
  12. data/lib/bundler/definition.rb +62 -60
  13. data/lib/bundler/dependency.rb +92 -47
  14. data/lib/bundler/dsl.rb +83 -78
  15. data/lib/bundler/endpoint_specification.rb +10 -3
  16. data/lib/bundler/errors.rb +4 -0
  17. data/lib/bundler/feature_flag.rb +2 -6
  18. data/lib/bundler/gem_helpers.rb +4 -10
  19. data/lib/bundler/gem_version_promoter.rb +0 -2
  20. data/lib/bundler/installer.rb +16 -2
  21. data/lib/bundler/lazy_specification.rb +50 -45
  22. data/lib/bundler/man/bundle-add.1 +3 -3
  23. data/lib/bundler/man/bundle-binstubs.1 +3 -3
  24. data/lib/bundler/man/bundle-cache.1 +3 -3
  25. data/lib/bundler/man/bundle-check.1 +3 -3
  26. data/lib/bundler/man/bundle-clean.1 +3 -3
  27. data/lib/bundler/man/bundle-config.1 +3 -3
  28. data/lib/bundler/man/bundle-console.1 +3 -3
  29. data/lib/bundler/man/bundle-doctor.1 +3 -3
  30. data/lib/bundler/man/bundle-env.1 +3 -3
  31. data/lib/bundler/man/bundle-exec.1 +3 -3
  32. data/lib/bundler/man/bundle-fund.1 +3 -3
  33. data/lib/bundler/man/bundle-gem.1 +3 -3
  34. data/lib/bundler/man/bundle-help.1 +3 -3
  35. data/lib/bundler/man/bundle-info.1 +3 -3
  36. data/lib/bundler/man/bundle-init.1 +3 -3
  37. data/lib/bundler/man/bundle-inject.1 +3 -3
  38. data/lib/bundler/man/bundle-install.1 +3 -3
  39. data/lib/bundler/man/bundle-issue.1 +3 -3
  40. data/lib/bundler/man/bundle-licenses.1 +3 -3
  41. data/lib/bundler/man/bundle-list.1 +3 -3
  42. data/lib/bundler/man/bundle-lock.1 +3 -3
  43. data/lib/bundler/man/bundle-open.1 +3 -3
  44. data/lib/bundler/man/bundle-outdated.1 +3 -3
  45. data/lib/bundler/man/bundle-platform.1 +3 -3
  46. data/lib/bundler/man/bundle-plugin.1 +3 -3
  47. data/lib/bundler/man/bundle-pristine.1 +3 -3
  48. data/lib/bundler/man/bundle-remove.1 +3 -3
  49. data/lib/bundler/man/bundle-show.1 +3 -3
  50. data/lib/bundler/man/bundle-update.1 +3 -3
  51. data/lib/bundler/man/bundle-version.1 +3 -3
  52. data/lib/bundler/man/bundle-viz.1 +3 -3
  53. data/lib/bundler/man/bundle.1 +3 -3
  54. data/lib/bundler/man/gemfile.5 +3 -3
  55. data/lib/bundler/match_metadata.rb +13 -0
  56. data/lib/bundler/plugin/index.rb +4 -0
  57. data/lib/bundler/resolver/base.rb +2 -1
  58. data/lib/bundler/resolver/package.rb +8 -4
  59. data/lib/bundler/resolver/spec_group.rb +1 -25
  60. data/lib/bundler/resolver.rb +13 -3
  61. data/lib/bundler/ruby_dsl.rb +12 -3
  62. data/lib/bundler/rubygems_ext.rb +83 -82
  63. data/lib/bundler/rubygems_integration.rb +2 -15
  64. data/lib/bundler/runtime.rb +19 -24
  65. data/lib/bundler/source/git.rb +1 -0
  66. data/lib/bundler/source/rubygems.rb +19 -4
  67. data/lib/bundler/source.rb +2 -0
  68. data/lib/bundler/source_list.rb +4 -0
  69. data/lib/bundler/spec_set.rb +66 -29
  70. data/lib/bundler/templates/newgem/Gemfile.tt +1 -0
  71. data/lib/bundler/version.rb +1 -1
  72. data/lib/bundler.rb +10 -30
  73. metadata +3 -3
@@ -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..34).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
- @autorequire = nil
35
- @groups = Array(options["group"] || :default).map(&:to_sym)
36
- @source = options["source"]
37
- @path = options["path"]
38
- @git = options["git"]
39
- @github = options["github"]
40
- @branch = options["branch"]
41
- @ref = options["ref"]
42
- @glob = options["glob"]
43
- @platforms = Array(options["platforms"])
44
- @env = options["env"]
45
- @should_include = options.fetch("should_include", true)
46
- @gemfile = options["gemfile"]
47
- @force_ruby_platform = options["force_ruby_platform"] if options.key?("force_ruby_platform")
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
- @autorequire = Array(options["require"] || []) if options.key?("require")
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 @platforms.empty?
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 ||= @platforms.filter_map {|pl| PLATFORM_MAP[pl] }.flatten.uniq
106
+ @expanded_platforms ||= platforms.filter_map {|pl| CurrentRuby::PLATFORM_MAP[pl] }.flatten.uniq
66
107
  end
67
108
 
68
109
  def should_include?
69
- @should_include && current_env? && current_platform?
110
+ should_include && current_env? && current_platform?
70
111
  end
71
112
 
72
113
  def gemspec_dev_dep?
73
- type == :development
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 @env
78
- if @env.is_a?(Hash)
79
- @env.all? do |key, val|
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[@env.to_s]
128
+ ENV[env.to_s]
84
129
  end
85
130
  end
86
131
 
87
132
  def current_platform?
88
- return true if @platforms.empty?
89
- @platforms.any? do |p|
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::Dependency::PLATFORM_MAP.keys.freeze
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 type source install_if gemfile force_ruby_platform].freeze
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
- gem spec.name, name: spec.name, path: path, glob: glob
80
+ path path, "glob" => glob, "name" => spec.name do
81
+ add_dependency spec.name
82
+ end
81
83
 
82
- group(development_group) do
83
- spec.development_dependencies.each do |dep|
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
- dep = Dependency.new(name, version, options)
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
- attr_accessor :remote, :dependencies, :locked_platform
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 = dependencies.map {|dep, reqs| build_dependency(dep, reqs) }
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
- Gem::Dependency.new(name, requirements)
171
+ Dependency.new(name, requirements)
165
172
  end
166
173
  end
167
174
  end
@@ -254,6 +254,10 @@ module Bundler
254
254
  @spec = spec
255
255
  end
256
256
 
257
+ def message
258
+ "Bundler found incorrect dependencies in the lockfile for #{spec.full_name}"
259
+ end
260
+
257
261
  status_code(41)
258
262
  end
259
263
  end
@@ -25,7 +25,7 @@ module Bundler
25
25
  end
26
26
  private_class_method :settings_method
27
27
 
28
- (1..10).each {|v| define_method("bundler_#{v}_mode?") { major_version >= v } }
28
+ (1..10).each {|v| define_method("bundler_#{v}_mode?") { @major_version >= v } }
29
29
 
30
30
  settings_flag(:allow_offline_install) { bundler_3_mode? }
31
31
  settings_flag(:auto_clean_without_path) { bundler_3_mode? }
@@ -44,11 +44,7 @@ module Bundler
44
44
 
45
45
  def initialize(bundler_version)
46
46
  @bundler_version = Gem::Version.create(bundler_version)
47
+ @major_version = @bundler_version.segments.first
47
48
  end
48
-
49
- def major_version
50
- @bundler_version.segments.first
51
- end
52
- private :major_version
53
49
  end
54
50
  end
@@ -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
- [Gem::Platform.new("java"), Gem::Platform.new("java")],
8
- [Gem::Platform.new("mswin32"), Gem::Platform.new("mswin32")],
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
- _, found = GENERICS.find do |match, _generic|
20
- p.os == match.os && (!match.cpu || p.cpu == match.cpu)
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
@@ -79,7 +79,7 @@ module Bundler
79
79
 
80
80
  if @definition.setup_domain!(options)
81
81
  ensure_specs_are_compatible!
82
- Bundler.load_plugins(@definition)
82
+ load_plugins
83
83
  end
84
84
  install(options)
85
85
 
@@ -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|
@@ -209,6 +209,20 @@ module Bundler
209
209
  Bundler.settings.processor_count
210
210
  end
211
211
 
212
+ def load_plugins
213
+ Gem.load_plugins
214
+
215
+ requested_path_gems = @definition.requested_specs.select {|s| s.source.is_a?(Source::Path) }
216
+ path_plugin_files = requested_path_gems.flat_map do |spec|
217
+ spec.matches_for_glob("rubygems_plugin#{Bundler.rubygems.suffix_pattern}")
218
+ rescue TypeError
219
+ error_message = "#{spec.name} #{spec.version} has an invalid gemspec"
220
+ raise Gem::InvalidSpecificationException, error_message
221
+ end
222
+ Gem.load_plugin_files(path_plugin_files)
223
+ Gem.load_env_plugins
224
+ end
225
+
212
226
  def ensure_specs_are_compatible!
213
227
  @definition.specs.each do |spec|
214
228
  unless spec.matches_current_ruby?
@@ -121,13 +121,10 @@ module Bundler
121
121
  out
122
122
  end
123
123
 
124
- def materialize_strictly
125
- source.local!
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
- __materialize__(matching_specs)
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
- materialize_strictly
140
+ materialize(self) do |matching_specs|
141
+ choose_compatible(matching_specs)
142
+ end
144
143
  else
145
- matching_specs = source.specs.search([name, version])
146
- return self if matching_specs.empty?
144
+ materialize([name, version]) do |matching_specs|
145
+ target_platform = source.is_a?(Source::Path) ? platform : local_platform
147
146
 
148
- target_platform = source.is_a?(Source::Path) ? platform : local_platform
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
- __materialize__(installable_candidates)
160
- end
161
- end
149
+ specification = choose_compatible(installable_candidates, fallback_to_non_installable: false)
150
+ return specification unless specification.nil?
162
151
 
163
- # If in frozen mode, we fallback to a non-installable candidate because by
164
- # doing this we avoid re-resolving and potentially end up changing the
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
- search.locked_platform = platform if search.instance_of?(RemoteSpecification) || search.instance_of?(EndpointSpecification)
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
@@ -1,6 +1,6 @@
1
- .\" generated with nRonn/v0.11.1
2
- .\" https://github.com/n-ronn/nronn/tree/0.11.1
3
- .TH "BUNDLE\-ADD" "1" "December 2024" ""
1
+ .\" generated with Ronn-NG/v0.10.1
2
+ .\" http://github.com/apjanke/ronn-ng/tree/0.10.1
3
+ .TH "BUNDLE\-ADD" "1" "January 2025" ""
4
4
  .SH "NAME"
5
5
  \fBbundle\-add\fR \- Add gem to the Gemfile and run bundle install
6
6
  .SH "SYNOPSIS"