bundler 2.2.22 → 2.2.25

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of bundler might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dd506f45451a29ba6416b7b97ee93f67f40e71b8ef9c9db79484ff6f840d6189
4
- data.tar.gz: bb18e91f6cfbd8c62febba280ebcb91de345e9fdc5599a7a44245ff47364a141
3
+ metadata.gz: 42284d8028f6f07937bba73b6c9e55c511c9d14c599b5b2e3b951599a6cff7e7
4
+ data.tar.gz: dcda6b29a424bc079333e3a9f5f02f679e7cae039b3dd07e25cb6da6ebf29b4c
5
5
  SHA512:
6
- metadata.gz: 1d9dc3b77ecff1849b900a3164578eb40371afeb49f2f1c557485b9647f71292fbf43dd61501416afdfdd9cd50d6da581606aec5c349550a1ea97153e3f94b98
7
- data.tar.gz: ae00d5fa66bd664d65915cf15df9431512dc6a77b35f4b60f7faf649962fbd06d56f0b7b7a0659b7ef9ff2c23860c862d8b5b888d43714c714a6af6fbd5b524a
6
+ metadata.gz: 9cb7f2e44d450503a5c0786dcc9e3972cfa830180a518de00c5733965c9fe790ab1090611e1da3d2a8cffbd911e2a3c7531b0707a3712efd8c162b95723e827b
7
+ data.tar.gz: 0dc46959901b2edf345dbb4b0b448a9762caa91179011899d36939f927379af22b8406ddf4bb17e67c410a7d65c76c43f3c4fcb9c3ec6a4b92dcce82364cdf91
data/CHANGELOG.md CHANGED
@@ -1,3 +1,50 @@
1
+ # 2.2.25 (July 30, 2021)
2
+
3
+ ## Deprecations:
4
+
5
+ - Deprecate Gemfile without an explicit global source [#4779](https://github.com/rubygems/rubygems/pull/4779)
6
+ - Deprecate `bundle cache --path` [#4496](https://github.com/rubygems/rubygems/pull/4496)
7
+
8
+ ## Enhancements:
9
+
10
+ - Give better errors when materialization fails [#4788](https://github.com/rubygems/rubygems/pull/4788)
11
+ - Lazily load `shellwords` library [#4786](https://github.com/rubygems/rubygems/pull/4786)
12
+ - Show original error and backtrace directly on `bundle install` errors instead of a more brittle `gem install` hint [#4778](https://github.com/rubygems/rubygems/pull/4778)
13
+ - Remove LoadError message in regards to requiring a relative file [#4772](https://github.com/rubygems/rubygems/pull/4772)
14
+
15
+ ## Bug fixes:
16
+
17
+ - Fix `BUNDLE_USER_CONFIG` no longer respected as config location [#4797](https://github.com/rubygems/rubygems/pull/4797)
18
+ - Fix `--standalone` installation of default gems [#4782](https://github.com/rubygems/rubygems/pull/4782)
19
+ - Fix `--quiet` flag not printing warnings [#4781](https://github.com/rubygems/rubygems/pull/4781)
20
+ - Fix bundler binstub version selection [#4775](https://github.com/rubygems/rubygems/pull/4775)
21
+ - Fix interrupt handling in Bundler workers [#4767](https://github.com/rubygems/rubygems/pull/4767)
22
+
23
+ # 2.2.24 (July 15, 2021)
24
+
25
+ ## Bug fixes:
26
+
27
+ - Fix development gem unintentionally removed on an edge case [#4751](https://github.com/rubygems/rubygems/pull/4751)
28
+ - Fix dangling empty plugin hooks [#4755](https://github.com/rubygems/rubygems/pull/4755)
29
+ - Fix `bundle plugin install --help` showing `bundle install`'s help [#4756](https://github.com/rubygems/rubygems/pull/4756)
30
+ - Make sure `bundle check` shows uniq missing gems [#4749](https://github.com/rubygems/rubygems/pull/4749)
31
+
32
+ ## Performance:
33
+
34
+ - Slightly speed up `bundler/setup` [#4750](https://github.com/rubygems/rubygems/pull/4750)
35
+
36
+ # 2.2.23 (July 9, 2021)
37
+
38
+ ## Enhancements:
39
+
40
+ - Fix `bundle install` on truffleruby selecting incorrect variant for `sorbet-static` gem [#4625](https://github.com/rubygems/rubygems/pull/4625)
41
+ - Spare meaningless warning on read-only bundle invocations [#4724](https://github.com/rubygems/rubygems/pull/4724)
42
+
43
+ ## Bug fixes:
44
+
45
+ - Fix incorrect warning about duplicated gems in the Gemfile [#4732](https://github.com/rubygems/rubygems/pull/4732)
46
+ - Fix `bundle plugin install foo` crashing [#4734](https://github.com/rubygems/rubygems/pull/4734)
47
+
1
48
  # 2.2.22 (July 6, 2021)
2
49
 
3
50
  ## Enhancements:
@@ -4,8 +4,8 @@ module Bundler
4
4
  # Represents metadata from when the Bundler gem was built.
5
5
  module BuildMetadata
6
6
  # begin ivars
7
- @built_at = "2021-07-06".freeze
8
- @git_commit_sha = "0bdd3e8e71".freeze
7
+ @built_at = "2021-07-30".freeze
8
+ @git_commit_sha = "7f0f257c7a".freeze
9
9
  @release = true
10
10
  # end ivars
11
11
 
@@ -9,7 +9,7 @@ module Bundler
9
9
  end
10
10
 
11
11
  def run
12
- Bundler.ui.level = "error" if options[:quiet]
12
+ Bundler.ui.level = "warn" if options[:quiet]
13
13
  Bundler.settings.set_command_option_if_given :path, options[:path]
14
14
  Bundler.settings.set_command_option_if_given :cache_path, options["cache-path"]
15
15
 
@@ -61,7 +61,7 @@ module Bundler
61
61
  end
62
62
 
63
63
  def run
64
- Bundler.ui.level = "error" if options[:quiet]
64
+ Bundler.ui.level = "warn" if options[:quiet]
65
65
  Bundler.settings.validate!
66
66
  check!
67
67
 
@@ -8,7 +8,7 @@ module Bundler
8
8
  end
9
9
 
10
10
  def run
11
- Bundler.ui.level = "error" if options[:quiet]
11
+ Bundler.ui.level = "warn" if options[:quiet]
12
12
 
13
13
  warn_if_root
14
14
 
@@ -60,7 +60,7 @@ module Bundler
60
60
  installer = Installer.install(Bundler.root, definition, options)
61
61
 
62
62
  Bundler.settings.temporary(:cache_all_platforms => options[:local] ? false : Bundler.settings[:cache_all_platforms]) do
63
- Bundler.load.cache if Bundler.app_cache.exist? && !options["no-cache"] && !Bundler.frozen_bundle?
63
+ Bundler.load.cache(nil, options[:local]) if Bundler.app_cache.exist? && !options["no-cache"] && !Bundler.frozen_bundle?
64
64
  end
65
65
 
66
66
  Bundler.ui.confirm "Bundle complete! #{dependencies_count_for(definition)}, #{gems_installed_for(definition)}."
@@ -83,22 +83,9 @@ module Bundler
83
83
  end
84
84
 
85
85
  Bundler::CLI::Common.output_fund_metadata_summary
86
- rescue GemNotFound, VersionConflict => e
87
- if options[:local] && Bundler.app_cache.exist?
88
- Bundler.ui.warn "Some gems seem to be missing from your #{Bundler.settings.app_cache_path} directory."
89
- end
90
-
91
- unless Bundler.definition.has_rubygems_remotes?
92
- Bundler.ui.warn <<-WARN, :wrap => true
93
- Your Gemfile has no gem server sources. If you need gems that are \
94
- not already on your machine, add a line like this to your Gemfile:
95
- source 'https://rubygems.org'
96
- WARN
97
- end
98
- raise e
99
- rescue Gem::InvalidSpecificationException => e
86
+ rescue Gem::InvalidSpecificationException
100
87
  Bundler.ui.warn "You have one or more invalid gemspecs that need to be fixed."
101
- raise e
88
+ raise
102
89
  end
103
90
 
104
91
  private
@@ -16,7 +16,13 @@ module Bundler
16
16
  specs = if @only_group.any? || @without_group.any?
17
17
  filtered_specs_by_groups
18
18
  else
19
- Bundler.load.specs
19
+ begin
20
+ Bundler.load.specs
21
+ rescue GemNotFound => e
22
+ Bundler.ui.error e.message
23
+ Bundler.ui.warn "Install missing gems with `bundle install`."
24
+ exit 1
25
+ end
20
26
  end.reject {|s| s.name == "bundler" }.sort_by(&:name)
21
27
 
22
28
  return Bundler.ui.info "No gems in the Gemfile" if specs.empty?
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "shellwords"
4
-
5
3
  module Bundler
6
4
  class CLI::Open
7
5
  attr_reader :options, :name
@@ -19,6 +17,7 @@ module Bundler
19
17
  else
20
18
  path = spec.full_gem_path
21
19
  Dir.chdir(path) do
20
+ require "shellwords"
22
21
  command = Shellwords.split(editor) + [path]
23
22
  Bundler.with_original_env do
24
23
  system(*command)
@@ -9,7 +9,7 @@ module Bundler
9
9
  end
10
10
 
11
11
  def run
12
- Bundler.ui.level = "error" if options[:quiet]
12
+ Bundler.ui.level = "warn" if options[:quiet]
13
13
 
14
14
  Plugin.gemfile_install(Bundler.default_gemfile) if Bundler.feature_flag.plugins?
15
15
 
data/lib/bundler/cli.rb CHANGED
@@ -14,6 +14,7 @@ module Bundler
14
14
  COMMAND_ALIASES = {
15
15
  "check" => "c",
16
16
  "install" => "i",
17
+ "plugin" => "",
17
18
  "list" => "ls",
18
19
  "exec" => ["e", "ex", "exe"],
19
20
  "cache" => ["package", "pack"],
@@ -455,6 +456,12 @@ module Bundler
455
456
  "do in future versions. Instead please use `bundle config set cache_all true`, " \
456
457
  "and stop using this flag" if ARGV.include?("--all")
457
458
 
459
+ SharedHelpers.major_deprecation 2,
460
+ "The `--path` flag is deprecated because its semantics are unclear. " \
461
+ "Use `bundle config cache_path` to configure the path of your cache of gems, " \
462
+ "and `bundle config path` to configure the path where your gems are installed, " \
463
+ "and stop using this flag" if ARGV.include?("--path")
464
+
458
465
  require_relative "cli/cache"
459
466
  Cache.new(options).run
460
467
  end
@@ -133,7 +133,7 @@ module Bundler
133
133
  @unlock[:gems] ||= @dependencies.map(&:name)
134
134
  else
135
135
  eager_unlock = expand_dependencies(@unlock[:gems] || [], true)
136
- @unlock[:gems] = @locked_specs.for(eager_unlock, [], false, false, false).map(&:name)
136
+ @unlock[:gems] = @locked_specs.for(eager_unlock, false, false).map(&:name)
137
137
  end
138
138
 
139
139
  @dependency_changes = converge_dependencies
@@ -185,25 +185,7 @@ module Bundler
185
185
  #
186
186
  # @return [Bundler::SpecSet]
187
187
  def specs
188
- @specs ||= begin
189
- begin
190
- specs = resolve.materialize(requested_dependencies)
191
- rescue GemNotFound => e # Handle yanked gem
192
- gem_name, gem_version = extract_gem_info(e)
193
- locked_gem = @locked_specs[gem_name].last
194
- raise if locked_gem.nil? || locked_gem.version.to_s != gem_version || !@remote
195
- raise GemNotFound, "Your bundle is locked to #{locked_gem} from #{locked_gem.source}, but that version can " \
196
- "no longer be found in that source. That means the author of #{locked_gem} has removed it. " \
197
- "You'll need to update your bundle to a version other than #{locked_gem} that hasn't been " \
198
- "removed in order to install."
199
- end
200
- unless specs["bundler"].any?
201
- bundler = sources.metadata_source.specs.search(Gem::Dependency.new("bundler", VERSION)).last
202
- specs["bundler"] = bundler
203
- end
204
-
205
- specs
206
- end
188
+ @specs ||= materialize(requested_dependencies)
207
189
  end
208
190
 
209
191
  def new_specs
@@ -215,9 +197,7 @@ module Bundler
215
197
  end
216
198
 
217
199
  def missing_specs
218
- missing = []
219
- resolve.materialize(requested_dependencies, missing)
220
- missing
200
+ resolve.materialize(requested_dependencies).missing_specs
221
201
  end
222
202
 
223
203
  def missing_specs?
@@ -235,17 +215,11 @@ module Bundler
235
215
  end
236
216
 
237
217
  def requested_specs
238
- @requested_specs ||= begin
239
- groups = requested_groups
240
- groups.map!(&:to_sym)
241
- specs_for(groups)
242
- end
218
+ specs_for(requested_groups)
243
219
  end
244
220
 
245
221
  def requested_dependencies
246
- groups = requested_groups
247
- groups.map!(&:to_sym)
248
- dependencies_for(groups)
222
+ dependencies_for(requested_groups)
249
223
  end
250
224
 
251
225
  def current_dependencies
@@ -255,11 +229,13 @@ module Bundler
255
229
  end
256
230
 
257
231
  def specs_for(groups)
232
+ groups = requested_groups if groups.empty?
258
233
  deps = dependencies_for(groups)
259
- SpecSet.new(specs.for(expand_dependencies(deps)))
234
+ materialize(expand_dependencies(deps))
260
235
  end
261
236
 
262
237
  def dependencies_for(groups)
238
+ groups.map!(&:to_sym)
263
239
  current_dependencies.reject do |d|
264
240
  (d.groups & groups).empty?
265
241
  end
@@ -288,10 +264,6 @@ module Bundler
288
264
  end
289
265
  end
290
266
 
291
- def has_rubygems_remotes?
292
- sources.rubygems_sources.any? {|s| s.remotes.any? }
293
- end
294
-
295
267
  def spec_git_paths
296
268
  sources.git_sources.map {|s| File.realpath(s.path) if File.exist?(s.path) }.compact
297
269
  end
@@ -507,6 +479,31 @@ module Bundler
507
479
 
508
480
  private
509
481
 
482
+ def materialize(dependencies)
483
+ specs = resolve.materialize(dependencies)
484
+ missing_specs = specs.missing_specs
485
+
486
+ if missing_specs.any?
487
+ missing_specs.each do |s|
488
+ locked_gem = @locked_specs[s.name].last
489
+ next if locked_gem.nil? || locked_gem.version != s.version || !@remote
490
+ raise GemNotFound, "Your bundle is locked to #{locked_gem} from #{locked_gem.source}, but that version can " \
491
+ "no longer be found in that source. That means the author of #{locked_gem} has removed it. " \
492
+ "You'll need to update your bundle to a version other than #{locked_gem} that hasn't been " \
493
+ "removed in order to install."
494
+ end
495
+
496
+ raise GemNotFound, "Could not find #{missing_specs.map(&:full_name).join(", ")} in any of the sources"
497
+ end
498
+
499
+ unless specs["bundler"].any?
500
+ bundler = sources.metadata_source.specs.search(Gem::Dependency.new("bundler", VERSION)).last
501
+ specs["bundler"] = bundler
502
+ end
503
+
504
+ specs
505
+ end
506
+
510
507
  def precompute_source_requirements_for_indirect_dependencies?
511
508
  sources.non_global_rubygems_sources.all?(&:dependency_api_available?) && !sources.aggregate_global_source?
512
509
  end
@@ -717,7 +714,7 @@ module Bundler
717
714
  @locked_specs.each do |s|
718
715
  # Replace the locked dependency's source with the equivalent source from the Gemfile
719
716
  dep = @dependencies.find {|d| s.satisfies?(d) }
720
- s.source = (dep && dep.source) || sources.get(s.source)
717
+ s.source = (dep && dep.source) || sources.get(s.source) unless multisource_allowed?
721
718
 
722
719
  # Don't add a spec to the list if its source is expired. For example,
723
720
  # if you change a Git gem to RubyGems.
@@ -735,7 +732,7 @@ module Bundler
735
732
  # if we won't need the source (according to the lockfile),
736
733
  # don't error if the path/git source isn't available
737
734
  next if @locked_specs.
738
- for(requested_dependencies, [], false, true, false).
735
+ for(requested_dependencies, false, true).
739
736
  none? {|locked_spec| locked_spec.source == s.source }
740
737
 
741
738
  raise
@@ -754,8 +751,8 @@ module Bundler
754
751
  end
755
752
 
756
753
  resolve = SpecSet.new(converged)
757
- @locked_specs_incomplete_for_platform = !resolve.for(expand_dependencies(requested_dependencies & deps), @unlock[:gems], true, true)
758
- resolve = SpecSet.new(resolve.for(expand_dependencies(deps, true), [], false, false, false).reject{|s| @unlock[:gems].include?(s.name) })
754
+ @locked_specs_incomplete_for_platform = !resolve.for(expand_dependencies(requested_dependencies & deps), true, true)
755
+ resolve = SpecSet.new(resolve.for(expand_dependencies(deps, true), false, false).reject{|s| @unlock[:gems].include?(s.name) })
759
756
  diff = nil
760
757
 
761
758
  # Now, we unlock any sources that do not have anymore gems pinned to it
@@ -859,12 +856,6 @@ module Bundler
859
856
  current == proposed
860
857
  end
861
858
 
862
- def extract_gem_info(error)
863
- # This method will extract the error message like "Could not find foo-1.2.3 in any of the sources"
864
- # to an array. The first element will be the gem name (e.g. foo), the second will be the version number.
865
- error.message.scan(/Could not find (\w+)-(\d+(?:\.\d+)+)/).flatten
866
- end
867
-
868
859
  def compute_requires
869
860
  dependencies.reduce({}) do |requires, dep|
870
861
  next requires unless dep.should_include?
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 " \
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
@@ -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
@@ -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
 
@@ -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
@@ -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,10 @@ 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 Bundler.rubygems.user_home && !Bundler.rubygems.user_home.empty?
434
+ Pathname.new(Bundler.rubygems.user_home).join(".bundle/config")
437
435
  end
438
436
  end
439
437
 
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 }
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "shellwords"
4
-
5
3
  module Bundler
6
4
  class Source
7
5
  class Git
@@ -224,6 +222,7 @@ module Bundler
224
222
  end
225
223
 
226
224
  def check_allowed(command)
225
+ require "shellwords"
227
226
  command_with_no_credentials = URICredentialsFilter.credential_filtered_string("git #{command.shelljoin}", uri)
228
227
  raise GitNotAllowedError.new(command_with_no_credentials) unless allow?
229
228
  command_with_no_credentials
@@ -71,6 +71,10 @@ module Bundler
71
71
  @remotes.size > 1
72
72
  end
73
73
 
74
+ def no_remotes?
75
+ @remotes.size == 0
76
+ end
77
+
74
78
  def can_lock?(spec)
75
79
  return super unless multiple_remotes?
76
80
  include?(spec.source)
@@ -37,6 +37,10 @@ module Bundler
37
37
  global_rubygems_source.multiple_remotes?
38
38
  end
39
39
 
40
+ def implicit_global_source?
41
+ global_rubygems_source.no_remotes?
42
+ end
43
+
40
44
  def add_path_source(options = {})
41
45
  if options["gemspec"]
42
46
  add_source_to_list Source::Gemspec.new(options), path_sources
@@ -117,7 +121,8 @@ module Bundler
117
121
  def replace_sources!(replacement_sources)
118
122
  return false if replacement_sources.empty?
119
123
 
120
- @path_sources, @git_sources, @plugin_sources = map_sources(replacement_sources)
124
+ @rubygems_sources, @path_sources, @git_sources, @plugin_sources = map_sources(replacement_sources)
125
+ @global_rubygems_source = global_replacement_source(replacement_sources)
121
126
 
122
127
  different_sources?(lock_sources, replacement_sources)
123
128
  end
@@ -152,13 +157,21 @@ module Bundler
152
157
  end
153
158
 
154
159
  def map_sources(replacement_sources)
155
- [path_sources, git_sources, plugin_sources].map do |sources|
160
+ [@rubygems_sources, @path_sources, @git_sources, @plugin_sources].map do |sources|
156
161
  sources.map do |source|
157
162
  replacement_sources.find {|s| s == source } || source
158
163
  end
159
164
  end
160
165
  end
161
166
 
167
+ def global_replacement_source(replacement_sources)
168
+ replacement_source = replacement_sources.find {|s| s == global_rubygems_source }
169
+ return global_rubygems_source unless replacement_source
170
+
171
+ replacement_source.local!
172
+ replacement_source
173
+ end
174
+
162
175
  def different_sources?(lock_sources, replacement_sources)
163
176
  !equal_sources?(lock_sources, replacement_sources) && !equivalent_sources?(lock_sources, replacement_sources)
164
177
  end
@@ -202,7 +215,7 @@ module Bundler
202
215
  end
203
216
 
204
217
  def equal_source?(source, other_source)
205
- return source.include?(other_source) if source.is_a?(Source::Rubygems) && other_source.is_a?(Source::Rubygems) && !merged_gem_lockfile_sections?
218
+ return source.include?(other_source) if source.is_a?(Source::Rubygems) && other_source.is_a?(Source::Rubygems)
206
219
 
207
220
  source == other_source
208
221
  end
@@ -11,15 +11,14 @@ module Bundler
11
11
  @specs = specs
12
12
  end
13
13
 
14
- def for(dependencies, skip = [], check = false, match_current_platform = false, raise_on_missing = true)
14
+ def for(dependencies, check = false, match_current_platform = false)
15
15
  handled = []
16
16
  deps = dependencies.dup
17
17
  specs = []
18
- skip += ["bundler"]
19
18
 
20
19
  loop do
21
20
  break unless dep = deps.shift
22
- next if handled.include?(dep) || skip.include?(dep.name)
21
+ next if handled.any?{|d| d.name == dep.name && (match_current_platform || d.__platform == dep.__platform) } || dep.name == "bundler"
23
22
 
24
23
  handled << dep
25
24
 
@@ -34,11 +33,6 @@ module Bundler
34
33
  end
35
34
  elsif check
36
35
  return false
37
- elsif raise_on_missing
38
- others = lookup[dep.name] if match_current_platform
39
- message = "Unable to find a spec satisfying #{dep} in the set. Perhaps the lockfile is corrupted?"
40
- message += " Found #{others.join(", ")} that did not match the current platform." if others && !others.empty?
41
- raise GemNotFound, message
42
36
  end
43
37
  end
44
38
 
@@ -72,52 +66,35 @@ module Bundler
72
66
  lookup.dup
73
67
  end
74
68
 
75
- def materialize(deps, missing_specs = nil)
76
- materialized = self.for(deps, [], false, true, !missing_specs)
77
-
78
- materialized.group_by(&:source).each do |source, specs|
79
- next unless specs.any?{|s| s.is_a?(LazySpecification) }
80
-
81
- source.local!
82
- names = -> { specs.map(&:name).uniq }
83
- source.double_check_for(names)
84
- end
69
+ def materialize(deps)
70
+ materialized = self.for(deps, false, true)
85
71
 
86
72
  materialized.map! do |s|
87
73
  next s unless s.is_a?(LazySpecification)
88
- spec = s.__materialize__
89
- unless spec
90
- unless missing_specs
91
- raise GemNotFound, "Could not find #{s.full_name} in any of the sources"
92
- end
93
- missing_specs << s
94
- end
95
- spec
74
+ s.source.local!
75
+ s.__materialize__ || s
96
76
  end
97
- SpecSet.new(missing_specs ? materialized.compact : materialized)
77
+ SpecSet.new(materialized)
98
78
  end
99
79
 
100
80
  # Materialize for all the specs in the spec set, regardless of what platform they're for
101
81
  # This is in contrast to how for does platform filtering (and specifically different from how `materialize` calls `for` only for the current platform)
102
82
  # @return [Array<Gem::Specification>]
103
83
  def materialized_for_all_platforms
104
- @specs.group_by(&:source).each do |source, specs|
105
- next unless specs.any?{|s| s.is_a?(LazySpecification) }
106
-
107
- source.local!
108
- source.remote!
109
- names = -> { specs.map(&:name).uniq }
110
- source.double_check_for(names)
111
- end
112
-
113
84
  @specs.map do |s|
114
85
  next s unless s.is_a?(LazySpecification)
86
+ s.source.local!
87
+ s.source.remote!
115
88
  spec = s.__materialize__
116
89
  raise GemNotFound, "Could not find #{s.full_name} in any of the sources" unless spec
117
90
  spec
118
91
  end
119
92
  end
120
93
 
94
+ def missing_specs
95
+ @specs.select {|s| s.is_a?(LazySpecification) }
96
+ end
97
+
121
98
  def merge(set)
122
99
  arr = sorted.dup
123
100
  set.each do |set_spec|
@@ -195,7 +172,7 @@ module Bundler
195
172
  def spec_for_dependency(dep, match_current_platform)
196
173
  specs_for_platforms = lookup[dep.name]
197
174
  if match_current_platform
198
- GemHelpers.select_best_platform_match(specs_for_platforms, Bundler.local_platform)
175
+ GemHelpers.select_best_platform_match(specs_for_platforms.select{|s| Gem::Platform.match_spec?(s) }, Bundler.local_platform)
199
176
  else
200
177
  GemHelpers.select_best_platform_match(specs_for_platforms, dep.__platform)
201
178
  end
@@ -60,16 +60,16 @@ m = Module.new do
60
60
  Regexp.last_match(1)
61
61
  end
62
62
 
63
- def bundler_version
64
- @bundler_version ||=
63
+ def bundler_requirement
64
+ @bundler_requirement ||=
65
65
  env_var_version || cli_arg_version ||
66
- lockfile_version
66
+ bundler_requirement_for(lockfile_version)
67
67
  end
68
68
 
69
- def bundler_requirement
70
- return "#{Gem::Requirement.default}.a" unless bundler_version
69
+ def bundler_requirement_for(version)
70
+ return "#{Gem::Requirement.default}.a" unless version
71
71
 
72
- bundler_gem_version = Gem::Version.new(bundler_version)
72
+ bundler_gem_version = Gem::Version.new(version)
73
73
 
74
74
  requirement = bundler_gem_version.approximate_recommendation
75
75
 
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: false
2
2
 
3
3
  module Bundler
4
- VERSION = "2.2.22".freeze
4
+ VERSION = "2.2.25".freeze
5
5
 
6
6
  def self.bundler_major_version
7
7
  @bundler_major_version ||= VERSION.split(".").first.to_i
@@ -26,7 +26,7 @@ module Bundler
26
26
  @func = func
27
27
  @size = size
28
28
  @threads = nil
29
- SharedHelpers.trap("INT") { abort_threads }
29
+ @previous_interrupt_handler = nil
30
30
  end
31
31
 
32
32
  # Enqueue a request to be executed in the worker pool
@@ -68,13 +68,16 @@ module Bundler
68
68
  # so as worker threads after retrieving it, shut themselves down
69
69
  def stop_threads
70
70
  return unless @threads
71
+
71
72
  @threads.each { @request_queue.enq POISON }
72
73
  @threads.each(&:join)
74
+
75
+ remove_interrupt_handler
76
+
73
77
  @threads = nil
74
78
  end
75
79
 
76
80
  def abort_threads
77
- return unless @threads
78
81
  Bundler.ui.debug("\n#{caller.join("\n")}")
79
82
  @threads.each(&:exit)
80
83
  exit 1
@@ -94,11 +97,23 @@ module Bundler
94
97
  end
95
98
  end.compact
96
99
 
100
+ add_interrupt_handler unless @threads.empty?
101
+
97
102
  return if creation_errors.empty?
98
103
 
99
104
  message = "Failed to create threads for the #{name} worker: #{creation_errors.map(&:to_s).uniq.join(", ")}"
100
105
  raise ThreadCreationError, message if @threads.empty?
101
106
  Bundler.ui.info message
102
107
  end
108
+
109
+ def add_interrupt_handler
110
+ @previous_interrupt_handler = trap("INT") { abort_threads }
111
+ end
112
+
113
+ def remove_interrupt_handler
114
+ return unless @previous_interrupt_handler
115
+
116
+ trap "INT", @previous_interrupt_handler
117
+ end
103
118
  end
104
119
  end
data/lib/bundler.rb CHANGED
@@ -236,8 +236,9 @@ module Bundler
236
236
  end
237
237
 
238
238
  if warning
239
- user_home = tmp_home_path(warning)
240
- Bundler.ui.warn "#{warning}\nBundler will use `#{user_home}' as your home directory temporarily.\n"
239
+ Bundler.ui.warn "#{warning}\n"
240
+ user_home = tmp_home_path
241
+ Bundler.ui.warn "Bundler will use `#{user_home}' as your home directory temporarily.\n"
241
242
  user_home
242
243
  else
243
244
  Pathname.new(home)
@@ -652,10 +653,6 @@ EOF
652
653
  rescue ScriptError, StandardError => e
653
654
  msg = "There was an error while loading `#{path.basename}`: #{e.message}"
654
655
 
655
- if e.is_a?(LoadError)
656
- msg += "\nDoes it try to require a relative path? That's been removed in Ruby 1.9"
657
- end
658
-
659
656
  raise GemspecError, Dsl::DSLError.new(msg, path, e.backtrace, contents)
660
657
  end
661
658
 
@@ -684,15 +681,13 @@ EOF
684
681
  Bundler.rubygems.clear_paths
685
682
  end
686
683
 
687
- def tmp_home_path(warning)
684
+ def tmp_home_path
688
685
  Kernel.send(:require, "tmpdir")
689
686
  SharedHelpers.filesystem_access(Dir.tmpdir) do
690
687
  path = Bundler.tmp
691
688
  at_exit { Bundler.rm_rf(path) }
692
689
  path
693
690
  end
694
- rescue RuntimeError => e
695
- raise e.exception("#{warning}\nBundler also failed to create a temporary home directory':\n#{e}")
696
691
  end
697
692
 
698
693
  # @param env [Hash]
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bundler
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.22
4
+ version: 2.2.25
5
5
  platform: ruby
6
6
  authors:
7
7
  - André Arko
@@ -22,7 +22,7 @@ authors:
22
22
  autorequire:
23
23
  bindir: exe
24
24
  cert_chain: []
25
- date: 2021-07-06 00:00:00.000000000 Z
25
+ date: 2021-07-30 00:00:00.000000000 Z
26
26
  dependencies: []
27
27
  description: Bundler manages an application's dependencies through its entire life,
28
28
  across many machines, systematically and repeatably
@@ -354,7 +354,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
354
354
  - !ruby/object:Gem::Version
355
355
  version: 2.5.2
356
356
  requirements: []
357
- rubygems_version: 3.2.22
357
+ rubygems_version: 3.2.25
358
358
  signing_key:
359
359
  specification_version: 4
360
360
  summary: The best way to manage your application's dependencies