bundler 2.6.2 → 2.6.6

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 (88) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +91 -0
  3. data/README.md +2 -2
  4. data/lib/bundler/build_metadata.rb +2 -2
  5. data/lib/bundler/checksum.rb +1 -1
  6. data/lib/bundler/cli/console.rb +8 -6
  7. data/lib/bundler/cli/doctor.rb +23 -19
  8. data/lib/bundler/cli/info.rb +4 -4
  9. data/lib/bundler/cli/inject.rb +2 -2
  10. data/lib/bundler/cli/issue.rb +1 -1
  11. data/lib/bundler/cli/lock.rb +2 -1
  12. data/lib/bundler/cli/outdated.rb +6 -4
  13. data/lib/bundler/cli/show.rb +1 -1
  14. data/lib/bundler/compact_index_client/updater.rb +2 -1
  15. data/lib/bundler/current_ruby.rb +23 -33
  16. data/lib/bundler/definition.rb +125 -112
  17. data/lib/bundler/dependency.rb +92 -47
  18. data/lib/bundler/dsl.rb +83 -78
  19. data/lib/bundler/endpoint_specification.rb +10 -3
  20. data/lib/bundler/errors.rb +22 -0
  21. data/lib/bundler/feature_flag.rb +2 -6
  22. data/lib/bundler/gem_helpers.rb +4 -10
  23. data/lib/bundler/gem_version_promoter.rb +0 -2
  24. data/lib/bundler/injector.rb +9 -9
  25. data/lib/bundler/installer.rb +16 -2
  26. data/lib/bundler/lazy_specification.rb +50 -45
  27. data/lib/bundler/man/bundle-add.1 +3 -3
  28. data/lib/bundler/man/bundle-binstubs.1 +3 -3
  29. data/lib/bundler/man/bundle-cache.1 +3 -3
  30. data/lib/bundler/man/bundle-check.1 +3 -3
  31. data/lib/bundler/man/bundle-clean.1 +3 -3
  32. data/lib/bundler/man/bundle-config.1 +8 -8
  33. data/lib/bundler/man/bundle-config.1.ronn +9 -4
  34. data/lib/bundler/man/bundle-console.1 +3 -3
  35. data/lib/bundler/man/bundle-doctor.1 +3 -3
  36. data/lib/bundler/man/bundle-env.1 +3 -3
  37. data/lib/bundler/man/bundle-exec.1 +5 -5
  38. data/lib/bundler/man/bundle-exec.1.ronn +2 -2
  39. data/lib/bundler/man/bundle-fund.1 +3 -3
  40. data/lib/bundler/man/bundle-gem.1 +3 -3
  41. data/lib/bundler/man/bundle-help.1 +3 -3
  42. data/lib/bundler/man/bundle-info.1 +3 -3
  43. data/lib/bundler/man/bundle-init.1 +3 -3
  44. data/lib/bundler/man/bundle-inject.1 +3 -3
  45. data/lib/bundler/man/bundle-install.1 +3 -3
  46. data/lib/bundler/man/bundle-issue.1 +3 -3
  47. data/lib/bundler/man/bundle-licenses.1 +3 -3
  48. data/lib/bundler/man/bundle-list.1 +3 -3
  49. data/lib/bundler/man/bundle-lock.1 +3 -3
  50. data/lib/bundler/man/bundle-open.1 +3 -3
  51. data/lib/bundler/man/bundle-outdated.1 +3 -3
  52. data/lib/bundler/man/bundle-platform.1 +3 -3
  53. data/lib/bundler/man/bundle-plugin.1 +3 -3
  54. data/lib/bundler/man/bundle-pristine.1 +3 -3
  55. data/lib/bundler/man/bundle-remove.1 +3 -3
  56. data/lib/bundler/man/bundle-show.1 +3 -3
  57. data/lib/bundler/man/bundle-update.1 +3 -3
  58. data/lib/bundler/man/bundle-version.1 +3 -3
  59. data/lib/bundler/man/bundle-viz.1 +3 -3
  60. data/lib/bundler/man/bundle.1 +3 -3
  61. data/lib/bundler/man/gemfile.5 +3 -3
  62. data/lib/bundler/match_metadata.rb +13 -0
  63. data/lib/bundler/plugin/index.rb +5 -1
  64. data/lib/bundler/resolver/base.rb +2 -1
  65. data/lib/bundler/resolver/candidate.rb +11 -8
  66. data/lib/bundler/resolver/package.rb +8 -4
  67. data/lib/bundler/resolver/spec_group.rb +1 -25
  68. data/lib/bundler/resolver.rb +14 -4
  69. data/lib/bundler/ruby_dsl.rb +12 -3
  70. data/lib/bundler/rubygems_ext.rb +82 -81
  71. data/lib/bundler/rubygems_integration.rb +2 -15
  72. data/lib/bundler/runtime.rb +19 -24
  73. data/lib/bundler/shared_helpers.rb +4 -0
  74. data/lib/bundler/source/git/git_proxy.rb +6 -0
  75. data/lib/bundler/source/git.rb +6 -1
  76. data/lib/bundler/source/rubygems/remote.rb +11 -3
  77. data/lib/bundler/source/rubygems.rb +19 -4
  78. data/lib/bundler/source.rb +2 -0
  79. data/lib/bundler/source_list.rb +4 -0
  80. data/lib/bundler/spec_set.rb +66 -29
  81. data/lib/bundler/templates/newgem/Gemfile.tt +1 -0
  82. data/lib/bundler/vendor/uri/lib/uri/common.rb +7 -3
  83. data/lib/bundler/vendor/uri/lib/uri/generic.rb +12 -11
  84. data/lib/bundler/vendor/uri/lib/uri/rfc2396_parser.rb +6 -6
  85. data/lib/bundler/vendor/uri/lib/uri/version.rb +1 -1
  86. data/lib/bundler/version.rb +1 -1
  87. data/lib/bundler.rb +10 -30
  88. metadata +3 -3
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
@@ -193,6 +193,24 @@ module Bundler
193
193
  status_code(31)
194
194
  end
195
195
 
196
+ class ReadOnlyFileSystemError < PermissionError
197
+ def message
198
+ "There was an error while trying to #{action} `#{@path}`. " \
199
+ "File system is read-only."
200
+ end
201
+
202
+ status_code(42)
203
+ end
204
+
205
+ class OperationNotPermittedError < PermissionError
206
+ def message
207
+ "There was an error while trying to #{action} `#{@path}`. " \
208
+ "Underlying OS system call raised an EPERM error."
209
+ end
210
+
211
+ status_code(43)
212
+ end
213
+
196
214
  class GenericSystemCallError < BundlerError
197
215
  attr_reader :underlying_error
198
216
 
@@ -254,6 +272,10 @@ module Bundler
254
272
  @spec = spec
255
273
  end
256
274
 
275
+ def message
276
+ "Bundler found incorrect dependencies in the lockfile for #{spec.full_name}"
277
+ end
278
+
257
279
  status_code(41)
258
280
  end
259
281
  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
@@ -108,17 +108,17 @@ module Bundler
108
108
  end
109
109
 
110
110
  if d.groups != Array(:default)
111
- group = d.groups.size == 1 ? ", :group => #{d.groups.first.inspect}" : ", :groups => #{d.groups.inspect}"
111
+ group = d.groups.size == 1 ? ", group: #{d.groups.first.inspect}" : ", groups: #{d.groups.inspect}"
112
112
  end
113
113
 
114
- source = ", :source => \"#{d.source}\"" unless d.source.nil?
115
- path = ", :path => \"#{d.path}\"" unless d.path.nil?
116
- git = ", :git => \"#{d.git}\"" unless d.git.nil?
117
- github = ", :github => \"#{d.github}\"" unless d.github.nil?
118
- branch = ", :branch => \"#{d.branch}\"" unless d.branch.nil?
119
- ref = ", :ref => \"#{d.ref}\"" unless d.ref.nil?
120
- glob = ", :glob => \"#{d.glob}\"" unless d.glob.nil?
121
- require_path = ", :require => #{convert_autorequire(d.autorequire)}" unless d.autorequire.nil?
114
+ source = ", source: \"#{d.source}\"" unless d.source.nil?
115
+ path = ", path: \"#{d.path}\"" unless d.path.nil?
116
+ git = ", git: \"#{d.git}\"" unless d.git.nil?
117
+ github = ", github: \"#{d.github}\"" unless d.github.nil?
118
+ branch = ", branch: \"#{d.branch}\"" unless d.branch.nil?
119
+ ref = ", ref: \"#{d.ref}\"" unless d.ref.nil?
120
+ glob = ", glob: \"#{d.glob}\"" unless d.glob.nil?
121
+ require_path = ", require: #{convert_autorequire(d.autorequire)}" unless d.autorequire.nil?
122
122
 
123
123
  %(gem #{name}#{requirement}#{group}#{source}#{path}#{git}#{github}#{branch}#{ref}#{glob}#{require_path})
124
124
  end.join("\n")
@@ -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" "March 2025" ""
4
4
  .SH "NAME"
5
5
  \fBbundle\-add\fR \- Add gem to the Gemfile and run bundle install
6
6
  .SH "SYNOPSIS"
@@ -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\-BINSTUBS" "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\-BINSTUBS" "1" "March 2025" ""
4
4
  .SH "NAME"
5
5
  \fBbundle\-binstubs\fR \- Install the binstubs of the listed gems
6
6
  .SH "SYNOPSIS"
@@ -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\-CACHE" "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\-CACHE" "1" "March 2025" ""
4
4
  .SH "NAME"
5
5
  \fBbundle\-cache\fR \- Package your needed \fB\.gem\fR files into your application
6
6
  .SH "SYNOPSIS"
@@ -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\-CHECK" "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\-CHECK" "1" "March 2025" ""
4
4
  .SH "NAME"
5
5
  \fBbundle\-check\fR \- Verifies if dependencies are satisfied by installed gems
6
6
  .SH "SYNOPSIS"
@@ -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\-CLEAN" "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\-CLEAN" "1" "March 2025" ""
4
4
  .SH "NAME"
5
5
  \fBbundle\-clean\fR \- Cleans up unused gems in your bundler directory
6
6
  .SH "SYNOPSIS"
@@ -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\-CONFIG" "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\-CONFIG" "1" "March 2025" ""
4
4
  .SH "NAME"
5
5
  \fBbundle\-config\fR \- Set bundler configuration options
6
6
  .SH "SYNOPSIS"
@@ -56,16 +56,16 @@ Creates a directory (defaults to \fB~/bin\fR) and place any executables from the
56
56
  In deployment mode, Bundler will 'roll\-out' the bundle for \fBproduction\fR use\. Please check carefully if you want to have this option enabled in \fBdevelopment\fR or \fBtest\fR environments\.
57
57
  .TP
58
58
  \fBonly\fR
59
- A space\-separated list of groups to install only gems of the specified groups\.
59
+ A space\-separated list of groups to install only gems of the specified groups\. Please check carefully if you want to install also gems without a group, cause they get put inside \fBdefault\fR group\. For example \fBonly test:default\fR will install all gems specified in test group and without one\.
60
60
  .TP
61
61
  \fBpath\fR
62
62
  The location to install the specified gems to\. This defaults to Rubygems' setting\. Bundler shares this location with Rubygems, \fBgem install \|\.\|\.\|\.\fR will have gem installed there, too\. Therefore, gems installed without a \fB\-\-path \|\.\|\.\|\.\fR setting will show up by calling \fBgem list\fR\. Accordingly, gems installed to other locations will not get listed\.
63
63
  .TP
64
64
  \fBwithout\fR
65
- A space\-separated list of groups referencing gems to skip during installation\.
65
+ A space\-separated or \fB:\fR\-separated list of groups referencing gems to skip during installation\.
66
66
  .TP
67
67
  \fBwith\fR
68
- A space\-separated list of \fBoptional\fR groups referencing gems to include during installation\.
68
+ A space\-separated or \fB:\fR\-separated list of \fBoptional\fR groups referencing gems to include during installation\.
69
69
  .SH "BUILD OPTIONS"
70
70
  You can use \fBbundle config\fR to give Bundler the flags to pass to the gem installer every time bundler tries to install a particular gem\.
71
71
  .P
@@ -197,9 +197,9 @@ The following is a list of all configuration keys and their purpose\. You can le
197
197
  .IP "\(bu" 4
198
198
  \fBversion\fR (\fBBUNDLE_VERSION\fR): The version of Bundler to use when running under Bundler environment\. Defaults to \fBlockfile\fR\. You can also specify \fBsystem\fR or \fBx\.y\.z\fR\. \fBlockfile\fR will use the Bundler version specified in the \fBGemfile\.lock\fR, \fBsystem\fR will use the system version of Bundler, and \fBx\.y\.z\fR will use the specified version of Bundler\.
199
199
  .IP "\(bu" 4
200
- \fBwith\fR (\fBBUNDLE_WITH\fR): A \fB:\fR\-separated list of groups whose gems bundler should install\.
200
+ \fBwith\fR (\fBBUNDLE_WITH\fR): A space\-separated or \fB:\fR\-separated list of groups whose gems bundler should install\.
201
201
  .IP "\(bu" 4
202
- \fBwithout\fR (\fBBUNDLE_WITHOUT\fR): A \fB:\fR\-separated list of groups whose gems bundler should not install\.
202
+ \fBwithout\fR (\fBBUNDLE_WITHOUT\fR): A space\-separated or \fB:\fR\-separated list of groups whose gems bundler should not install\.
203
203
  .IP "" 0
204
204
  .SH "LOCAL GIT REPOS"
205
205
  Bundler also allows you to work against a git repository locally instead of using the remote version\. This can be achieved by setting up a local override: