rubygems-update 3.2.8 → 3.2.13

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 (43) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +42 -0
  3. data/Manifest.txt +1 -0
  4. data/Rakefile +6 -0
  5. data/bundler/CHANGELOG.md +48 -0
  6. data/bundler/lib/bundler.rb +1 -1
  7. data/bundler/lib/bundler/build_metadata.rb +2 -2
  8. data/bundler/lib/bundler/cli/gem.rb +23 -17
  9. data/bundler/lib/bundler/definition.rb +26 -29
  10. data/bundler/lib/bundler/dsl.rb +36 -22
  11. data/bundler/lib/bundler/inline.rb +1 -0
  12. data/bundler/lib/bundler/installer.rb +2 -0
  13. data/bundler/lib/bundler/lockfile_parser.rb +12 -8
  14. data/bundler/lib/bundler/man/bundle-config.1 +4 -4
  15. data/bundler/lib/bundler/man/bundle-config.1.ronn +8 -7
  16. data/bundler/lib/bundler/plugin.rb +1 -0
  17. data/bundler/lib/bundler/plugin/installer.rb +8 -10
  18. data/bundler/lib/bundler/plugin/source_list.rb +4 -0
  19. data/bundler/lib/bundler/resolver.rb +36 -38
  20. data/bundler/lib/bundler/rubygems_gem_installer.rb +47 -0
  21. data/bundler/lib/bundler/source_list.rb +15 -18
  22. data/bundler/lib/bundler/stub_specification.rb +8 -0
  23. data/bundler/lib/bundler/templates/newgem/README.md.tt +5 -3
  24. data/bundler/lib/bundler/version.rb +1 -1
  25. data/lib/rubygems.rb +2 -2
  26. data/lib/rubygems/command.rb +1 -0
  27. data/lib/rubygems/config_file.rb +9 -0
  28. data/lib/rubygems/core_ext/tcpsocket_init.rb +52 -0
  29. data/lib/rubygems/dependency.rb +5 -1
  30. data/lib/rubygems/platform.rb +7 -3
  31. data/lib/rubygems/remote_fetcher.rb +1 -0
  32. data/lib/rubygems/specification.rb +13 -11
  33. data/lib/rubygems/test_case.rb +5 -6
  34. data/rubygems-update.gemspec +1 -1
  35. data/test/rubygems/test_gem.rb +80 -8
  36. data/test/rubygems/test_gem_commands_outdated_command.rb +18 -0
  37. data/test/rubygems/test_gem_config_file.rb +10 -0
  38. data/test/rubygems/test_gem_dependency_installer.rb +2 -18
  39. data/test/rubygems/test_gem_platform.rb +29 -0
  40. data/test/rubygems/test_gem_remote_fetcher.rb +6 -0
  41. data/test/rubygems/test_gem_specification.rb +10 -15
  42. data/test/rubygems/test_gem_util.rb +4 -4
  43. metadata +4 -3
@@ -26,11 +26,19 @@ module Bundler
26
26
 
27
27
  # @!group Stub Delegates
28
28
 
29
+ def manually_installed?
30
+ # This is for manually installed gems which are gems that were fixed in place after a
31
+ # failed installation. Once the issue was resolved, the user then manually created
32
+ # the gem specification using the instructions provided by `gem help install`
33
+ installed_by_version == Gem::Version.new(0)
34
+ end
35
+
29
36
  # This is defined directly to avoid having to loading the full spec
30
37
  def missing_extensions?
31
38
  return false if default_gem?
32
39
  return false if extensions.empty?
33
40
  return false if File.exist? gem_build_complete_path
41
+ return false if manually_installed?
34
42
 
35
43
  true
36
44
  end
@@ -29,19 +29,21 @@ TODO: Write usage instructions here
29
29
  After checking out the repo, run `bin/setup` to install dependencies.<% if config[:test] %> Then, run `rake <%= config[:test].sub('mini', '').sub('rspec', 'spec') %>` to run the tests.<% end %> You can also run `bin/console` for an interactive prompt that will allow you to experiment.<% if config[:bin] %> Run `bundle exec <%= config[:name] %>` to use the gem in this directory, ignoring other installed copies of this gem.<% end %>
30
30
 
31
31
  To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
+ <% if config[:git] -%>
32
33
 
33
34
  ## Contributing
34
35
 
35
- Bug reports and pull requests are welcome on GitHub at https://github.com/<%= config[:github_username] %>/<%= config[:name] %>.<% if config[:coc] %> This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/<%= config[:github_username] %>/<%= config[:name] %>/blob/master/CODE_OF_CONDUCT.md).<% end %>
36
+ Bug reports and pull requests are welcome on GitHub at https://github.com/<%= config[:github_username] %>/<%= config[:name] %>.<% if config[:coc] %> This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/<%= config[:github_username] %>/<%= config[:name] %>/blob/<%= config[:git_default_branch] %>/CODE_OF_CONDUCT.md).<% end %>
37
+ <% end -%>
36
38
  <% if config[:mit] -%>
37
39
 
38
40
  ## License
39
41
 
40
42
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
41
43
  <% end -%>
42
- <% if config[:coc] -%>
44
+ <% if config[:git] && config[:coc] -%>
43
45
 
44
46
  ## Code of Conduct
45
47
 
46
- Everyone interacting in the <%= config[:constant_name] %> project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/<%= config[:github_username] %>/<%= config[:name] %>/blob/master/CODE_OF_CONDUCT.md).
48
+ Everyone interacting in the <%= config[:constant_name] %> project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/<%= config[:github_username] %>/<%= config[:name] %>/blob/<%= config[:git_default_branch] %>/CODE_OF_CONDUCT.md).
47
49
  <% end -%>
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: false
2
2
 
3
3
  module Bundler
4
- VERSION = "2.2.8".freeze
4
+ VERSION = "2.2.13".freeze
5
5
 
6
6
  def self.bundler_major_version
7
7
  @bundler_major_version ||= VERSION.split(".").first.to_i
data/lib/rubygems.rb CHANGED
@@ -8,7 +8,7 @@
8
8
  require 'rbconfig'
9
9
 
10
10
  module Gem
11
- VERSION = "3.2.8".freeze
11
+ VERSION = "3.2.13".freeze
12
12
  end
13
13
 
14
14
  # Must be first since it unloads the prelude from 1.9.2
@@ -275,7 +275,7 @@ module Gem
275
275
 
276
276
  unless spec = specs.first
277
277
  msg = "can't find gem #{dep} with executable #{exec_name}"
278
- if name == "bundler" && bundler_message = Gem::BundlerVersionFinder.missing_version_message
278
+ if dep.filters_bundler? && bundler_message = Gem::BundlerVersionFinder.missing_version_message
279
279
  msg = bundler_message
280
280
  end
281
281
  raise Gem::GemNotFoundException, msg
@@ -634,6 +634,7 @@ RubyGems is a package manager for Ruby.
634
634
  gem install rake
635
635
  gem list --local
636
636
  gem build package.gemspec
637
+ gem push package-0.0.1.gem
637
638
  gem help install
638
639
 
639
640
  Further help:
@@ -45,6 +45,7 @@ class Gem::ConfigFile
45
45
  DEFAULT_UPDATE_SOURCES = true
46
46
  DEFAULT_CONCURRENT_DOWNLOADS = 8
47
47
  DEFAULT_CERT_EXPIRATION_LENGTH_DAYS = 365
48
+ DEFAULT_IPV4_FALLBACK_ENABLED = false
48
49
 
49
50
  ##
50
51
  # For Ruby packagers to set configuration defaults. Set in
@@ -140,6 +141,12 @@ class Gem::ConfigFile
140
141
 
141
142
  attr_accessor :cert_expiration_length_days
142
143
 
144
+ ##
145
+ # == Experimental ==
146
+ # Fallback to IPv4 when IPv6 is not reachable or slow (default: false)
147
+
148
+ attr_accessor :ipv4_fallback_enabled
149
+
143
150
  ##
144
151
  # Path name of directory or file of openssl client certificate, used for remote https connection with client authentication
145
152
 
@@ -175,6 +182,7 @@ class Gem::ConfigFile
175
182
  @update_sources = DEFAULT_UPDATE_SOURCES
176
183
  @concurrent_downloads = DEFAULT_CONCURRENT_DOWNLOADS
177
184
  @cert_expiration_length_days = DEFAULT_CERT_EXPIRATION_LENGTH_DAYS
185
+ @ipv4_fallback_enabled = ENV['IPV4_FALLBACK_ENABLED'] == 'true' || DEFAULT_IPV4_FALLBACK_ENABLED
178
186
 
179
187
  operating_system_config = Marshal.load Marshal.dump(OPERATING_SYSTEM_DEFAULTS)
180
188
  platform_config = Marshal.load Marshal.dump(PLATFORM_DEFAULTS)
@@ -203,6 +211,7 @@ class Gem::ConfigFile
203
211
  @disable_default_gem_server = @hash[:disable_default_gem_server] if @hash.key? :disable_default_gem_server
204
212
  @sources = @hash[:sources] if @hash.key? :sources
205
213
  @cert_expiration_length_days = @hash[:cert_expiration_length_days] if @hash.key? :cert_expiration_length_days
214
+ @ipv4_fallback_enabled = @hash[:ipv4_fallback_enabled] if @hash.key? :ipv4_fallback_enabled
206
215
 
207
216
  @ssl_verify_mode = @hash[:ssl_verify_mode] if @hash.key? :ssl_verify_mode
208
217
  @ssl_ca_cert = @hash[:ssl_ca_cert] if @hash.key? :ssl_ca_cert
@@ -0,0 +1,52 @@
1
+ require 'socket'
2
+
3
+ module CoreExtensions
4
+ module TCPSocketExt
5
+ def self.prepended(base)
6
+ base.prepend Initializer
7
+ end
8
+
9
+ module Initializer
10
+ CONNECTION_TIMEOUT = 5
11
+ IPV4_DELAY_SECONDS = 0.1
12
+
13
+ def initialize(host, serv, *rest)
14
+ mutex = Mutex.new
15
+ addrs = []
16
+ threads = []
17
+ cond_var = ConditionVariable.new
18
+
19
+ Addrinfo.foreach(host, serv, nil, :STREAM) do |addr|
20
+ Thread.report_on_exception = false if defined? Thread.report_on_exception = ()
21
+
22
+ threads << Thread.new(addr) do
23
+ # give head start to ipv6 addresses
24
+ sleep IPV4_DELAY_SECONDS if addr.ipv4?
25
+
26
+ # raises Errno::ECONNREFUSED when ip:port is unreachable
27
+ Socket.tcp(addr.ip_address, serv, connect_timeout: CONNECTION_TIMEOUT).close
28
+ mutex.synchronize do
29
+ addrs << addr.ip_address
30
+ cond_var.signal
31
+ end
32
+ end
33
+ end
34
+
35
+ mutex.synchronize do
36
+ timeout_time = CONNECTION_TIMEOUT + Time.now.to_f
37
+ while addrs.empty? && (remaining_time = timeout_time - Time.now.to_f) > 0
38
+ cond_var.wait(mutex, remaining_time)
39
+ end
40
+
41
+ host = addrs.shift unless addrs.empty?
42
+ end
43
+
44
+ threads.each {|t| t.kill.join if t.alive? }
45
+
46
+ super(host, serv, *rest)
47
+ end
48
+ end
49
+ end
50
+ end
51
+
52
+ TCPSocket.prepend CoreExtensions::TCPSocketExt
@@ -277,7 +277,7 @@ class Gem::Dependency
277
277
  requirement.satisfied_by?(spec.version) && env_req.satisfied_by?(spec.version)
278
278
  end.map(&:to_spec)
279
279
 
280
- Gem::BundlerVersionFinder.filter!(matches) if name == "bundler".freeze && !requirement.specific?
280
+ Gem::BundlerVersionFinder.filter!(matches) if filters_bundler?
281
281
 
282
282
  if platform_only
283
283
  matches.reject! do |spec|
@@ -295,6 +295,10 @@ class Gem::Dependency
295
295
  @requirement.specific?
296
296
  end
297
297
 
298
+ def filters_bundler?
299
+ name == "bundler".freeze && !specific?
300
+ end
301
+
298
302
  def to_specs
299
303
  matches = matching_specs true
300
304
 
@@ -66,7 +66,7 @@ class Gem::Platform
66
66
  when String then
67
67
  arch = arch.split '-'
68
68
 
69
- if arch.length > 2 and arch.last !~ /\d/ # reassemble x86-linux-gnu
69
+ if arch.length > 2 and arch.last !~ /\d+(\.\d+)?$/ # reassemble x86-linux-{libc}
70
70
  extra = arch.pop
71
71
  arch.last << "-#{extra}"
72
72
  end
@@ -146,7 +146,8 @@ class Gem::Platform
146
146
  ##
147
147
  # Does +other+ match this platform? Two platforms match if they have the
148
148
  # same CPU, or either has a CPU of 'universal', they have the same OS, and
149
- # they have the same version, or either has no version.
149
+ # they have the same version, or either has no version (except for 'linux'
150
+ # where the version is the libc name, with no version standing for 'gnu')
150
151
  #
151
152
  # Additionally, the platform will match if the local CPU is 'arm' and the
152
153
  # other CPU starts with "arm" (for generic ARM family support).
@@ -162,7 +163,10 @@ class Gem::Platform
162
163
  @os == other.os and
163
164
 
164
165
  # version
165
- (@version.nil? or other.version.nil? or @version == other.version)
166
+ (
167
+ (@os != 'linux' and (@version.nil? or other.version.nil?)) or
168
+ @version == other.version
169
+ )
166
170
  end
167
171
 
168
172
  ##
@@ -78,6 +78,7 @@ class Gem::RemoteFetcher
78
78
  # fetching the gem.
79
79
 
80
80
  def initialize(proxy=nil, dns=nil, headers={})
81
+ require 'rubygems/core_ext/tcpsocket_init' if Gem.configuration.ipv4_fallback_enabled
81
82
  require 'net/http'
82
83
  require 'stringio'
83
84
  require 'uri'
@@ -666,6 +666,9 @@ class Gem::Specification < Gem::BasicSpecification
666
666
  #
667
667
  # # Only prereleases or final releases after 2.6.0.preview2
668
668
  # spec.required_ruby_version = '> 2.6.0.preview2'
669
+ #
670
+ # # This gem will work with 2.3.0 or greater, including major version 3, but lesser than 4.0.0
671
+ # spec.required_ruby_version = '>= 2.3', '< 4'
669
672
 
670
673
  def required_ruby_version=(req)
671
674
  @required_ruby_version = Gem::Requirement.create req
@@ -827,7 +830,9 @@ class Gem::Specification < Gem::BasicSpecification
827
830
  if @@stubs
828
831
  @@stubs_by_name[name] || []
829
832
  else
830
- @@stubs_by_name[name] ||= stubs_for_pattern("#{name}-*.gemspec")
833
+ @@stubs_by_name[name] ||= stubs_for_pattern("#{name}-*.gemspec").select do |s|
834
+ s.name == name
835
+ end
831
836
  end
832
837
  end
833
838
 
@@ -848,7 +853,9 @@ class Gem::Specification < Gem::BasicSpecification
848
853
  specs.sort! do |a, b|
849
854
  names = a.name <=> b.name
850
855
  next names if names.nonzero?
851
- b.version <=> a.version
856
+ versions = b.version <=> a.version
857
+ next versions if versions.nonzero?
858
+ b.platform == Gem::Platform::RUBY ? -1 : 1
852
859
  end
853
860
  end
854
861
 
@@ -1084,20 +1091,15 @@ class Gem::Specification < Gem::BasicSpecification
1084
1091
  end
1085
1092
 
1086
1093
  def self._latest_specs(specs, prerelease = false) # :nodoc:
1087
- result = Hash.new {|h,k| h[k] = {} }
1088
- native = {}
1094
+ result = {}
1089
1095
 
1090
1096
  specs.reverse_each do |spec|
1091
1097
  next if spec.version.prerelease? unless prerelease
1092
1098
 
1093
- native[spec.name] = spec.version if spec.platform == Gem::Platform::RUBY
1094
- result[spec.name][spec.platform] = spec
1099
+ result[spec.name] = spec
1095
1100
  end
1096
1101
 
1097
- result.map(&:last).map(&:values).flatten.reject do |spec|
1098
- minimum = native[spec.name]
1099
- minimum && spec.version < minimum
1100
- end.sort_by{|tup| tup.name }
1102
+ result.map(&:last).flatten.sort_by{|tup| tup.name }
1101
1103
  end
1102
1104
 
1103
1105
  ##
@@ -2552,7 +2554,7 @@ class Gem::Specification < Gem::BasicSpecification
2552
2554
  begin
2553
2555
  dependencies.each do |dep|
2554
2556
  next unless dep.runtime?
2555
- dep.to_specs.each do |dep_spec|
2557
+ dep.matching_specs(true).each do |dep_spec|
2556
2558
  next if visited.has_key?(dep_spec)
2557
2559
  visited[dep_spec] = true
2558
2560
  trail.push(dep_spec)
@@ -311,7 +311,7 @@ class Gem::TestCase < Minitest::Test
311
311
  ENV['XDG_CONFIG_HOME'] = nil
312
312
  ENV['XDG_DATA_HOME'] = nil
313
313
  ENV['SOURCE_DATE_EPOCH'] = nil
314
- ENV["TMPDIR"] = @tmp
314
+ ENV['BUNDLER_VERSION'] = nil
315
315
 
316
316
  @current_dir = Dir.pwd
317
317
  @fetcher = nil
@@ -322,13 +322,10 @@ class Gem::TestCase < Minitest::Test
322
322
  # capture output
323
323
  Gem::DefaultUserInteraction.ui = Gem::MockGemUi.new
324
324
 
325
- tmpdir = File.realpath Dir.tmpdir
326
- tmpdir.tap(&Gem::UNTAINT)
327
-
328
- @tempdir = File.join(tmpdir, "test_rubygems_#{$$}")
325
+ @tempdir = Dir.mktmpdir("test_rubygems_", @tmp)
329
326
  @tempdir.tap(&Gem::UNTAINT)
330
327
 
331
- FileUtils.mkdir_p @tempdir
328
+ ENV["TMPDIR"] = @tempdir
332
329
 
333
330
  @orig_SYSTEM_WIDE_CONFIG_FILE = Gem::ConfigFile::SYSTEM_WIDE_CONFIG_FILE
334
331
  Gem::ConfigFile.send :remove_const, :SYSTEM_WIDE_CONFIG_FILE
@@ -367,7 +364,9 @@ class Gem::TestCase < Minitest::Test
367
364
  Dir.chdir @tempdir
368
365
 
369
366
  ENV['HOME'] = @userhome
367
+ Gem.instance_variable_set :@config_file, nil
370
368
  Gem.instance_variable_set :@user_home, nil
369
+ Gem.instance_variable_set :@config_home, nil
371
370
  Gem.instance_variable_set :@data_home, nil
372
371
  Gem.instance_variable_set :@gemdeps, nil
373
372
  Gem.instance_variable_set :@env_requirements_by_name, nil
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = "rubygems-update"
5
- s.version = "3.2.8"
5
+ s.version = "3.2.13"
6
6
  s.authors = ["Jim Weirich", "Chad Fowler", "Eric Hodel", "Luis Lavena", "Aaron Patterson", "Samuel Giddins", "André Arko", "Evan Phoenix", "Hiroshi SHIBATA"]
7
7
  s.email = ["", "", "drbrain@segment7.net", "luislavena@gmail.com", "aaron@tenderlovemaking.com", "segiddins@segiddins.me", "andre@arko.net", "evan@phx.io", "hsbt@ruby-lang.org"]
8
8
 
@@ -297,6 +297,58 @@ class TestGem < Gem::TestCase
297
297
  assert_equal %w[a-1 b-2 c-1], loaded_spec_names
298
298
  end
299
299
 
300
+ def test_activate_bin_path_does_not_error_if_a_gem_thats_not_finally_activated_has_orphaned_dependencies
301
+ a1 = util_spec 'a', '1' do |s|
302
+ s.executables = ['exec']
303
+ s.add_dependency 'b'
304
+ end
305
+
306
+ b1 = util_spec 'b', '1' do |s|
307
+ s.add_dependency 'c', '1'
308
+ end
309
+
310
+ b2 = util_spec 'b', '2' do |s|
311
+ s.add_dependency 'c', '2'
312
+ end
313
+
314
+ c2 = util_spec 'c', '2'
315
+
316
+ install_specs c2, b1, b2, a1
317
+
318
+ # c1 is missing, but not needed for activation, so we should not get any errors here
319
+
320
+ Gem.activate_bin_path("a", "exec", ">= 0")
321
+
322
+ assert_equal %w[a-1 b-2 c-2], loaded_spec_names
323
+ end
324
+
325
+ def test_activate_bin_path_raises_a_meaningful_error_if_a_gem_thats_finally_activated_has_orphaned_dependencies
326
+ a1 = util_spec 'a', '1' do |s|
327
+ s.executables = ['exec']
328
+ s.add_dependency 'b'
329
+ end
330
+
331
+ b1 = util_spec 'b', '1' do |s|
332
+ s.add_dependency 'c', '1'
333
+ end
334
+
335
+ b2 = util_spec 'b', '2' do |s|
336
+ s.add_dependency 'c', '2'
337
+ end
338
+
339
+ c1 = util_spec 'c', '1'
340
+
341
+ install_specs c1, b1, b2, a1
342
+
343
+ # c2 is missing, and b2 which has it as a dependency will be activated, so we should get an error about the orphaned dependency
344
+
345
+ e = assert_raises Gem::UnsatisfiableDependencyError do
346
+ load Gem.activate_bin_path("a", "exec", ">= 0")
347
+ end
348
+
349
+ assert_equal "Unable to resolve dependency: 'b (>= 0)' requires 'c (= 2)'", e.message
350
+ end
351
+
300
352
  def test_activate_bin_path_in_debug_mode
301
353
  a1 = util_spec 'a', '1' do |s|
302
354
  s.executables = ['exec']
@@ -416,6 +468,32 @@ class TestGem < Gem::TestCase
416
468
  assert_equal %w[bundler-1.17.3], loaded_spec_names
417
469
  end
418
470
 
471
+ def test_activate_bin_path_gives_proper_error_for_bundler_when_underscore_selection_given
472
+ File.open("Gemfile.lock", "w") do |f|
473
+ f.write <<-L.gsub(/ {8}/, "")
474
+ GEM
475
+ remote: https://rubygems.org/
476
+ specs:
477
+
478
+ PLATFORMS
479
+ ruby
480
+
481
+ DEPENDENCIES
482
+
483
+ BUNDLED WITH
484
+ 2.1.4
485
+ L
486
+ end
487
+
488
+ File.open("Gemfile", "w") {|f| f.puts('source "https://rubygems.org"') }
489
+
490
+ e = assert_raises Gem::GemNotFoundException do
491
+ load Gem.activate_bin_path("bundler", "bundle", "= 2.2.8")
492
+ end
493
+
494
+ assert_equal "can't find gem bundler (= 2.2.8) with executable bundle", e.message
495
+ end
496
+
419
497
  def test_self_bin_path_no_exec_name
420
498
  e = assert_raises ArgumentError do
421
499
  Gem.bin_path 'a'
@@ -1880,15 +1958,9 @@ class TestGem < Gem::TestCase
1880
1958
  io.write 'gem "a"'
1881
1959
  end
1882
1960
 
1883
- platform = Bundler::GemHelpers.generic_local_platform
1884
- if platform == Gem::Platform::RUBY
1885
- platform = ''
1886
- else
1887
- platform = " #{platform}"
1888
- end
1889
-
1890
1961
  expected = <<-EXPECTED
1891
- Could not find gem 'a#{platform}' in any of the gem sources listed in your Gemfile.
1962
+ Could not find gem 'a' in locally installed gems.
1963
+ The source does not contain any versions of 'a'
1892
1964
  You may need to `gem install -g` to install missing gems
1893
1965
 
1894
1966
  EXPECTED