bundler 2.2.22 → 2.2.26

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.

Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +65 -0
  3. data/lib/bundler.rb +4 -9
  4. data/lib/bundler/build_metadata.rb +2 -2
  5. data/lib/bundler/cli.rb +12 -9
  6. data/lib/bundler/cli/cache.rb +1 -1
  7. data/lib/bundler/cli/check.rb +1 -1
  8. data/lib/bundler/cli/doctor.rb +1 -1
  9. data/lib/bundler/cli/exec.rb +1 -6
  10. data/lib/bundler/cli/gem.rb +3 -2
  11. data/lib/bundler/cli/install.rb +4 -17
  12. data/lib/bundler/cli/list.rb +7 -1
  13. data/lib/bundler/cli/open.rb +1 -2
  14. data/lib/bundler/cli/update.rb +1 -1
  15. data/lib/bundler/definition.rb +38 -53
  16. data/lib/bundler/dsl.rb +22 -12
  17. data/lib/bundler/errors.rb +1 -1
  18. data/lib/bundler/index.rb +1 -5
  19. data/lib/bundler/installer/gem_installer.rb +3 -16
  20. data/lib/bundler/installer/standalone.rb +14 -9
  21. data/lib/bundler/lockfile_parser.rb +1 -0
  22. data/lib/bundler/plugin.rb +2 -0
  23. data/lib/bundler/plugin/index.rb +4 -1
  24. data/lib/bundler/plugin/installer.rb +1 -1
  25. data/lib/bundler/resolver.rb +10 -17
  26. data/lib/bundler/rubygems_ext.rb +22 -6
  27. data/lib/bundler/rubygems_gem_installer.rb +5 -1
  28. data/lib/bundler/runtime.rb +16 -9
  29. data/lib/bundler/settings.rb +6 -6
  30. data/lib/bundler/setup.rb +2 -2
  31. data/lib/bundler/shared_helpers.rb +0 -7
  32. data/lib/bundler/source.rb +4 -2
  33. data/lib/bundler/source/git/git_proxy.rb +1 -2
  34. data/lib/bundler/source/rubygems.rb +21 -7
  35. data/lib/bundler/source/rubygems_aggregate.rb +4 -0
  36. data/lib/bundler/source_list.rb +16 -7
  37. data/lib/bundler/spec_set.rb +14 -37
  38. data/lib/bundler/templates/Executable.bundler +6 -6
  39. data/lib/bundler/templates/newgem/github/workflows/main.yml.tt +12 -2
  40. data/lib/bundler/templates/newgem/newgem.gemspec.tt +3 -1
  41. data/lib/bundler/version.rb +1 -1
  42. data/lib/bundler/worker.rb +17 -2
  43. metadata +3 -3
data/lib/bundler/dsl.rb CHANGED
@@ -103,8 +103,8 @@ module Bundler
103
103
  if current = @dependencies.find {|d| d.name == dep.name }
104
104
  deleted_dep = @dependencies.delete(current) if current.type == :development
105
105
 
106
- if current.requirement != dep.requirement
107
- unless deleted_dep
106
+ unless deleted_dep
107
+ if current.requirement != dep.requirement
108
108
  return if dep.type == :development
109
109
 
110
110
  update_prompt = ""
@@ -122,17 +122,14 @@ module Bundler
122
122
  raise GemfileError, "You cannot specify the same gem twice with different version requirements.\n" \
123
123
  "You specified: #{current.name} (#{current.requirement}) and #{dep.name} (#{dep.requirement})" \
124
124
  "#{update_prompt}"
125
+ else
126
+ Bundler.ui.warn "Your Gemfile lists the gem #{current.name} (#{current.requirement}) more than once.\n" \
127
+ "You should probably keep only one of them.\n" \
128
+ "Remove any duplicate entries and specify the gem only once.\n" \
129
+ "While it's not a problem now, it could cause errors if you change the version of one of them later."
125
130
  end
126
131
 
127
- else
128
- Bundler.ui.warn "Your Gemfile lists the gem #{current.name} (#{current.requirement}) more than once.\n" \
129
- "You should probably keep only one of them.\n" \
130
- "Remove any duplicate entries and specify the gem only once.\n" \
131
- "While it's not a problem now, it could cause errors if you change the version of one of them later."
132
- end
133
-
134
- if current.source != dep.source
135
- unless deleted_dep
132
+ if current.source != dep.source
136
133
  return if dep.type == :development
137
134
  raise GemfileError, "You cannot specify the same gem twice coming from different sources.\n" \
138
135
  "You specified that #{dep.name} (#{dep.requirement}) should come from " \
@@ -450,8 +447,21 @@ repo_name ||= user_name
450
447
  end
451
448
 
452
449
  def check_rubygems_source_safety
453
- return unless @sources.aggregate_global_source?
450
+ if @sources.implicit_global_source?
451
+ implicit_global_source_warning
452
+ elsif @sources.aggregate_global_source?
453
+ multiple_global_source_warning
454
+ end
455
+ end
456
+
457
+ def implicit_global_source_warning
458
+ Bundler::SharedHelpers.major_deprecation 2, "This Gemfile does not include an explicit global source. " \
459
+ "Not using an explicit global source may result in a different lockfile being generated depending on " \
460
+ "the gems you have installed locally before bundler is run. " \
461
+ "Instead, define a global source in your Gemfile like this: source \"https://rubygems.org\"."
462
+ end
454
463
 
464
+ def multiple_global_source_warning
455
465
  if Bundler.feature_flag.bundler_3_mode?
456
466
  msg = "This Gemfile contains multiple primary sources. " \
457
467
  "Each source after the first must include a block to indicate which gems " \
@@ -122,7 +122,7 @@ module Bundler
122
122
 
123
123
  class VirtualProtocolError < BundlerError
124
124
  def message
125
- "There was an error relating to virtualization and file access." \
125
+ "There was an error relating to virtualization and file access. " \
126
126
  "It is likely that you need to grant access to or mount some file system correctly."
127
127
  end
128
128
 
data/lib/bundler/index.rb CHANGED
@@ -195,11 +195,7 @@ module Bundler
195
195
  if base # allow all platforms when searching from a lockfile
196
196
  dependency.matches_spec?(spec)
197
197
  else
198
- if Gem::Platform.respond_to? :match_spec?
199
- dependency.matches_spec?(spec) && Gem::Platform.match_spec?(spec)
200
- else
201
- dependency.matches_spec?(spec) && Gem::Platform.match(spec.platform)
202
- end
198
+ dependency.matches_spec?(spec) && Gem::Platform.match_spec?(spec)
203
199
  end
204
200
  end
205
201
 
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "shellwords"
4
-
5
3
  module Bundler
6
4
  class GemInstaller
7
5
  attr_reader :spec, :standalone, :worker, :force, :installer
@@ -31,34 +29,23 @@ module Bundler
31
29
 
32
30
  def specific_failure_message(e)
33
31
  message = "#{e.class}: #{e.message}\n"
34
- message += " " + e.backtrace.join("\n ") + "\n\n" if Bundler.ui.debug?
32
+ message += " " + e.backtrace.join("\n ") + "\n\n"
35
33
  message = message.lines.first + Bundler.ui.add_color(message.lines.drop(1).join, :clear)
36
34
  message + Bundler.ui.add_color(failure_message, :red)
37
35
  end
38
36
 
39
37
  def failure_message
40
- return install_error_message if spec.source.options["git"]
41
- "#{install_error_message}\n#{gem_install_message}"
38
+ install_error_message
42
39
  end
43
40
 
44
41
  def install_error_message
45
42
  "An error occurred while installing #{spec.name} (#{spec.version}), and Bundler cannot continue."
46
43
  end
47
44
 
48
- def gem_install_message
49
- source = spec.source
50
- return unless source.respond_to?(:remotes)
51
-
52
- if source.remotes.size == 1
53
- "Make sure that `gem install #{spec.name} -v '#{spec.version}' --source '#{source.remotes.first}'` succeeds before bundling."
54
- else
55
- "Make sure that `gem install #{spec.name} -v '#{spec.version}'` succeeds before bundling."
56
- end
57
- end
58
-
59
45
  def spec_settings
60
46
  # Fetch the build settings, if there are any
61
47
  if settings = Bundler.settings["build.#{spec.name}"]
48
+ require "shellwords"
62
49
  Shellwords.shellsplit(settings)
63
50
  end
64
51
  end
@@ -3,7 +3,7 @@
3
3
  module Bundler
4
4
  class Standalone
5
5
  def initialize(groups, definition)
6
- @specs = groups.empty? ? definition.requested_specs : definition.specs_for(groups.map(&:to_sym))
6
+ @specs = definition.specs_for(groups)
7
7
  end
8
8
 
9
9
  def generate
@@ -12,12 +12,13 @@ module Bundler
12
12
  end
13
13
  File.open File.join(bundler_path, "setup.rb"), "w" do |file|
14
14
  file.puts "require 'rbconfig'"
15
- file.puts "ruby_engine = RUBY_ENGINE"
16
- file.puts "ruby_version = RbConfig::CONFIG[\"ruby_version\"]"
17
- file.puts "path = File.expand_path('..', __FILE__)"
18
15
  file.puts reverse_rubygems_kernel_mixin
19
16
  paths.each do |path|
20
- file.puts %($:.unshift File.expand_path("\#{path}/#{path}"))
17
+ if Pathname.new(path).absolute?
18
+ file.puts %($:.unshift "#{path}")
19
+ else
20
+ file.puts %($:.unshift File.expand_path("\#{__dir__}/#{path}"))
21
+ end
21
22
  end
22
23
  end
23
24
  end
@@ -28,14 +29,14 @@ module Bundler
28
29
  @specs.map do |spec|
29
30
  next if spec.name == "bundler"
30
31
  Array(spec.require_paths).map do |path|
31
- gem_path(path, spec).sub(version_dir, '#{ruby_engine}/#{ruby_version}')
32
+ gem_path(path, spec).sub(version_dir, '#{RUBY_ENGINE}/#{RbConfig::CONFIG["ruby_version"]}')
32
33
  # This is a static string intentionally. It's interpolated at a later time.
33
34
  end
34
- end.flatten
35
+ end.flatten.compact
35
36
  end
36
37
 
37
38
  def version_dir
38
- "#{Bundler::RubyVersion.system.engine}/#{RbConfig::CONFIG["ruby_version"]}"
39
+ "#{RUBY_ENGINE}/#{RbConfig::CONFIG["ruby_version"]}"
39
40
  end
40
41
 
41
42
  def bundler_path
@@ -44,7 +45,11 @@ module Bundler
44
45
 
45
46
  def gem_path(path, spec)
46
47
  full_path = Pathname.new(path).absolute? ? path : File.join(spec.full_gem_path, path)
47
- Pathname.new(full_path).relative_path_from(Bundler.root.join(bundler_path)).to_s
48
+ if spec.source.instance_of?(Source::Path)
49
+ full_path
50
+ else
51
+ Pathname.new(full_path).relative_path_from(Bundler.root.join(bundler_path)).to_s
52
+ end
48
53
  rescue TypeError
49
54
  error_message = "#{spec.name} #{spec.version} has an invalid gemspec"
50
55
  raise Gem::InvalidSpecificationException.new(error_message)
@@ -195,6 +195,7 @@ module Bundler
195
195
  platform = platform ? Gem::Platform.new(platform) : Gem::Platform::RUBY
196
196
  @current_spec = LazySpecification.new(name, version, platform)
197
197
  @current_spec.source = @current_source
198
+ @current_source.add_dependency_names(name)
198
199
 
199
200
  @specs[@current_spec.identifier] = @current_spec
200
201
  elsif spaces.size == 6
@@ -309,6 +309,8 @@ module Bundler
309
309
  #
310
310
  # @param [String] name of the plugin
311
311
  def load_plugin(name)
312
+ return unless name && !name.empty?
313
+
312
314
  # Need to ensure before this that plugin root where the rest of gems
313
315
  # are installed to be on load path to support plugin deps. Currently not
314
316
  # done to avoid conflicts
@@ -74,7 +74,10 @@ module Bundler
74
74
  def unregister_plugin(name)
75
75
  @commands.delete_if {|_, v| v == name }
76
76
  @sources.delete_if {|_, v| v == name }
77
- @hooks.each {|_, plugin_names| plugin_names.delete(name) }
77
+ @hooks.each do |hook, names|
78
+ names.delete(name)
79
+ @hooks.delete(hook) if names.empty?
80
+ end
78
81
  @plugin_paths.delete(name)
79
82
  @load_paths.delete(name)
80
83
  save_index
@@ -77,7 +77,7 @@ module Bundler
77
77
  source_list = SourceList.new
78
78
 
79
79
  source_list.add_git_source(git_source_options) if git_source_options
80
- source_list.add_global_rubygems_remote(rubygems_source) if rubygems_source
80
+ Array(rubygems_source).each {|remote| source_list.add_global_rubygems_remote(remote) } if rubygems_source
81
81
 
82
82
  deps = names.map {|name| Dependency.new name, version }
83
83
 
@@ -255,12 +255,6 @@ module Bundler
255
255
  next if name == "bundler"
256
256
  next unless search_for(requirement).empty?
257
257
 
258
- cache_message = begin
259
- " or in gems cached in #{Bundler.settings.app_cache_path}" if Bundler.app_cache.exist?
260
- rescue GemfileNotFound
261
- nil
262
- end
263
-
264
258
  if (base = @base[name]) && !base.empty?
265
259
  version = base.first.version
266
260
  message = "You have requested:\n" \
@@ -269,18 +263,17 @@ module Bundler
269
263
  "Try running `bundle update #{name}`\n\n" \
270
264
  "If you are updating multiple gems in your Gemfile at once,\n" \
271
265
  "try passing them all to `bundle update`"
272
- elsif source = @source_requirements[name]
266
+ else
267
+ source = source_for(name)
273
268
  specs = source.specs.search(name)
274
269
  versions_with_platforms = specs.map {|s| [s.version, s.platform] }
275
- message = String.new("Could not find gem '#{SharedHelpers.pretty_dependency(requirement)}' in #{source}#{cache_message}.\n")
276
- message << if versions_with_platforms.any?
277
- "The source contains the following versions of '#{name}': #{formatted_versions_with_platforms(versions_with_platforms)}"
278
- else
279
- "The source does not contain any versions of '#{name}'"
280
- end
281
- else
282
- message = "Could not find gem '#{SharedHelpers.pretty_dependency(requirement)}' in any of the gem sources " \
283
- "listed in your Gemfile#{cache_message}."
270
+ cache_message = begin
271
+ " or in gems cached in #{Bundler.settings.app_cache_path}" if Bundler.app_cache.exist?
272
+ rescue GemfileNotFound
273
+ nil
274
+ end
275
+ message = String.new("Could not find gem '#{SharedHelpers.pretty_dependency(requirement)}' in #{source.to_err}#{cache_message}.\n")
276
+ message << "The source contains the following versions of '#{name}': #{formatted_versions_with_platforms(versions_with_platforms)}" if versions_with_platforms.any?
284
277
  end
285
278
  raise GemNotFound, message
286
279
  end
@@ -378,7 +371,7 @@ module Bundler
378
371
  o << if metadata_requirement
379
372
  "is not available in #{relevant_source}"
380
373
  else
381
- "in #{relevant_source}.\n"
374
+ "in #{relevant_source.to_err}.\n"
382
375
  end
383
376
  end
384
377
  end,
@@ -174,20 +174,36 @@ module Gem
174
174
  end
175
175
  end
176
176
 
177
+ require "rubygems/platform"
178
+
177
179
  class Platform
178
180
  JAVA = Gem::Platform.new("java") unless defined?(JAVA)
179
181
  MSWIN = Gem::Platform.new("mswin32") unless defined?(MSWIN)
180
182
  MSWIN64 = Gem::Platform.new("mswin64") unless defined?(MSWIN64)
181
183
  MINGW = Gem::Platform.new("x86-mingw32") unless defined?(MINGW)
182
184
  X64_MINGW = Gem::Platform.new("x64-mingw32") unless defined?(X64_MINGW)
185
+ end
183
186
 
184
- undef_method :hash if method_defined? :hash
185
- def hash
186
- @cpu.hash ^ @os.hash ^ @version.hash
187
- end
187
+ Platform.singleton_class.module_eval do
188
+ unless Platform.singleton_methods.include?(:match_spec?)
189
+ def match_spec?(spec)
190
+ match_gem?(spec.platform, spec.name)
191
+ end
188
192
 
189
- undef_method :eql? if method_defined? :eql?
190
- alias_method :eql?, :==
193
+ def match_gem?(platform, gem_name)
194
+ match_platforms?(platform, Gem.platforms)
195
+ end
196
+
197
+ private
198
+
199
+ def match_platforms?(platform, platforms)
200
+ platforms.any? do |local_platform|
201
+ platform.nil? ||
202
+ local_platform == platform ||
203
+ (local_platform != Gem::Platform::RUBY && local_platform =~ platform)
204
+ end
205
+ end
206
+ end
191
207
  end
192
208
 
193
209
  require "rubygems/util"
@@ -61,7 +61,10 @@ module Bundler
61
61
 
62
62
  def build_extensions
63
63
  extension_cache_path = options[:bundler_extension_cache_path]
64
- return super unless extension_cache_path && extension_dir = spec.extension_dir
64
+ unless extension_cache_path && extension_dir = spec.extension_dir
65
+ require "shellwords" # compensate missing require in rubygems before version 3.2.25
66
+ return super
67
+ end
65
68
 
66
69
  extension_dir = Pathname.new(extension_dir)
67
70
  build_complete = SharedHelpers.filesystem_access(extension_cache_path.join("gem.build_complete"), :read, &:file?)
@@ -71,6 +74,7 @@ module Bundler
71
74
  FileUtils.cp_r extension_cache_path, spec.extension_dir
72
75
  end
73
76
  else
77
+ require "shellwords" # compensate missing require in rubygems before version 3.2.25
74
78
  super
75
79
  if extension_dir.directory? # not made for gems without extensions
76
80
  SharedHelpers.filesystem_access(extension_cache_path.parent, &:mkpath)
@@ -12,22 +12,16 @@ module Bundler
12
12
  def setup(*groups)
13
13
  @definition.ensure_equivalent_gemfile_and_lockfile if Bundler.frozen_bundle?
14
14
 
15
- groups.map!(&:to_sym)
16
-
17
15
  # Has to happen first
18
16
  clean_load_path
19
17
 
20
- specs = groups.any? ? @definition.specs_for(groups) : requested_specs
18
+ specs = @definition.specs_for(groups)
21
19
 
22
20
  SharedHelpers.set_bundle_environment
23
21
  Bundler.rubygems.replace_entrypoints(specs)
24
22
 
25
23
  # Activate the specs
26
24
  load_paths = specs.map do |spec|
27
- unless spec.loaded_from
28
- raise GemNotFound, "#{spec.full_name} is missing. Run `bundle install` to get it."
29
- end
30
-
31
25
  check_for_activated_spec!(spec)
32
26
 
33
27
  Bundler.rubygems.mark_loaded(spec)
@@ -106,7 +100,7 @@ module Bundler
106
100
 
107
101
  alias_method :gems, :specs
108
102
 
109
- def cache(custom_path = nil)
103
+ def cache(custom_path = nil, local = false)
110
104
  cache_path = Bundler.app_cache(custom_path)
111
105
  SharedHelpers.filesystem_access(cache_path) do |p|
112
106
  FileUtils.mkdir_p(p)
@@ -114,7 +108,20 @@ module Bundler
114
108
 
115
109
  Bundler.ui.info "Updating files in #{Bundler.settings.app_cache_path}"
116
110
 
117
- specs_to_cache = Bundler.settings[:cache_all_platforms] ? @definition.resolve.materialized_for_all_platforms : specs
111
+ specs_to_cache = if Bundler.settings[:cache_all_platforms]
112
+ @definition.resolve.materialized_for_all_platforms
113
+ else
114
+ begin
115
+ specs
116
+ rescue GemNotFound
117
+ if local
118
+ Bundler.ui.warn "Some gems seem to be missing from your #{Bundler.settings.app_cache_path} directory."
119
+ end
120
+
121
+ raise
122
+ end
123
+ end
124
+
118
125
  specs_to_cache.each do |spec|
119
126
  next if spec.name == "bundler"
120
127
  next if spec.source.is_a?(Source::Gemspec)
@@ -428,12 +428,12 @@ module Bundler
428
428
  def global_config_file
429
429
  if ENV["BUNDLE_CONFIG"] && !ENV["BUNDLE_CONFIG"].empty?
430
430
  Pathname.new(ENV["BUNDLE_CONFIG"])
431
- else
432
- begin
433
- Bundler.user_bundle_path("config")
434
- rescue PermissionError, GenericSystemCallError
435
- nil
436
- end
431
+ elsif ENV["BUNDLE_USER_CONFIG"] && !ENV["BUNDLE_USER_CONFIG"].empty?
432
+ Pathname.new(ENV["BUNDLE_USER_CONFIG"])
433
+ elsif ENV["BUNDLE_USER_HOME"] && !ENV["BUNDLE_USER_HOME"].empty?
434
+ Pathname.new(ENV["BUNDLE_USER_HOME"]).join("config")
435
+ elsif Bundler.rubygems.user_home && !Bundler.rubygems.user_home.empty?
436
+ Pathname.new(Bundler.rubygems.user_home).join(".bundle/config")
437
437
  end
438
438
  end
439
439
 
data/lib/bundler/setup.rb CHANGED
@@ -9,10 +9,10 @@ if Bundler::SharedHelpers.in_bundle?
9
9
  begin
10
10
  Bundler.ui.silence { Bundler.setup }
11
11
  rescue Bundler::BundlerError => e
12
- Bundler.ui.warn "\e[31m#{e.message}\e[0m"
12
+ Bundler.ui.error e.message
13
13
  Bundler.ui.warn e.backtrace.join("\n") if ENV["DEBUG"]
14
14
  if e.is_a?(Bundler::GemNotFound)
15
- Bundler.ui.warn "\e[33mRun `bundle install` to install missing gems.\e[0m"
15
+ Bundler.ui.warn "Run `bundle install` to install missing gems."
16
16
  end
17
17
  exit e.status_code
18
18
  end
@@ -152,13 +152,6 @@ module Bundler
152
152
  Bundler.ui.warn message
153
153
  end
154
154
 
155
- def trap(signal, override = false, &block)
156
- prior = Signal.trap(signal) do
157
- block.call
158
- prior.call unless override
159
- end
160
- end
161
-
162
155
  def ensure_same_dependencies(spec, old_deps, new_deps)
163
156
  new_deps = new_deps.reject {|d| d.type == :development }
164
157
  old_deps = old_deps.reject {|d| d.type == :development }
@@ -36,8 +36,6 @@ module Bundler
36
36
 
37
37
  def local!; end
38
38
 
39
- def local_only!; end
40
-
41
39
  def cached!; end
42
40
 
43
41
  def remote!; end
@@ -67,6 +65,10 @@ module Bundler
67
65
  "#<#{self.class}:0x#{object_id} #{self}>"
68
66
  end
69
67
 
68
+ def to_err
69
+ to_s
70
+ end
71
+
70
72
  def path?
71
73
  instance_of?(Bundler::Source::Path)
72
74
  end