rubygems-update 3.2.10 → 3.2.15

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 (44) 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 +46 -0
  6. data/bundler/lib/bundler/build_metadata.rb +2 -2
  7. data/bundler/lib/bundler/cli/gem.rb +23 -17
  8. data/bundler/lib/bundler/compact_index_client/updater.rb +1 -1
  9. data/bundler/lib/bundler/definition.rb +6 -13
  10. data/bundler/lib/bundler/dsl.rb +2 -4
  11. data/bundler/lib/bundler/feature_flag.rb +1 -0
  12. data/bundler/lib/bundler/installer.rb +2 -0
  13. data/bundler/lib/bundler/installer/parallel_installer.rb +36 -15
  14. data/bundler/lib/bundler/lazy_specification.rb +6 -1
  15. data/bundler/lib/bundler/lockfile_parser.rb +2 -16
  16. data/bundler/lib/bundler/man/bundle-config.1 +6 -0
  17. data/bundler/lib/bundler/man/bundle-config.1.ronn +8 -0
  18. data/bundler/lib/bundler/plugin/api/source.rb +7 -0
  19. data/bundler/lib/bundler/plugin/installer.rb +1 -2
  20. data/bundler/lib/bundler/plugin/source_list.rb +4 -0
  21. data/bundler/lib/bundler/resolver.rb +19 -17
  22. data/bundler/lib/bundler/rubygems_gem_installer.rb +47 -0
  23. data/bundler/lib/bundler/settings.rb +1 -0
  24. data/bundler/lib/bundler/source.rb +6 -0
  25. data/bundler/lib/bundler/source/metadata.rb +0 -4
  26. data/bundler/lib/bundler/source/path.rb +3 -1
  27. data/bundler/lib/bundler/source/path/installer.rb +1 -1
  28. data/bundler/lib/bundler/source/rubygems.rb +16 -9
  29. data/bundler/lib/bundler/source_list.rb +8 -12
  30. data/bundler/lib/bundler/spec_set.rb +2 -0
  31. data/bundler/lib/bundler/stub_specification.rb +8 -0
  32. data/bundler/lib/bundler/templates/newgem/README.md.tt +5 -3
  33. data/bundler/lib/bundler/version.rb +1 -1
  34. data/lib/rubygems.rb +1 -1
  35. data/lib/rubygems/commands/update_command.rb +21 -3
  36. data/lib/rubygems/config_file.rb +9 -0
  37. data/lib/rubygems/core_ext/tcpsocket_init.rb +52 -0
  38. data/lib/rubygems/remote_fetcher.rb +4 -8
  39. data/lib/rubygems/security/trust_dir.rb +1 -0
  40. data/rubygems-update.gemspec +1 -1
  41. data/test/rubygems/test_gem_commands_update_command.rb +28 -1
  42. data/test/rubygems/test_gem_config_file.rb +10 -0
  43. data/test/rubygems/test_gem_remote_fetcher.rb +38 -0
  44. metadata +4 -3
@@ -82,6 +82,7 @@ module Bundler
82
82
  materialized.map! do |s|
83
83
  next s unless s.is_a?(LazySpecification)
84
84
  s.source.dependency_names = deps if s.source.respond_to?(:dependency_names=)
85
+ s.source.local!
85
86
  spec = s.__materialize__
86
87
  unless spec
87
88
  unless missing_specs
@@ -102,6 +103,7 @@ module Bundler
102
103
  @specs.map do |s|
103
104
  next s unless s.is_a?(LazySpecification)
104
105
  s.source.dependency_names = names if s.source.respond_to?(:dependency_names=)
106
+ s.source.local!
105
107
  s.source.remote!
106
108
  spec = s.__materialize__
107
109
  raise GemNotFound, "Could not find #{s.full_name} in any of the sources" unless spec
@@ -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.10".freeze
4
+ VERSION = "2.2.15".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.10".freeze
11
+ VERSION = "3.2.15".freeze
12
12
  end
13
13
 
14
14
  # Must be first since it unloads the prelude from 1.9.2
@@ -76,7 +76,7 @@ command to remove old versions.
76
76
 
77
77
  def check_oldest_rubygems(version) # :nodoc:
78
78
  if oldest_supported_version > version
79
- alert_error "rubygems #{version} is not supported. The oldest supported version is #{oldest_supported_version}"
79
+ alert_error "rubygems #{version} is not supported on #{RUBY_VERSION}. The oldest version supported by this ruby is #{oldest_supported_version}"
80
80
  terminate_interaction 1
81
81
  end
82
82
  end
@@ -322,8 +322,26 @@ command to remove old versions.
322
322
 
323
323
  private
324
324
 
325
+ #
326
+ # Oldest version we support downgrading to. This is the version that
327
+ # originally ships with the first patch version of each ruby, because we never
328
+ # test each ruby against older rubygems, so we can't really guarantee it
329
+ # works. Version list can be checked here: https://stdgems.org/rubygems
330
+ #
325
331
  def oldest_supported_version
326
- # for Ruby 2.3
327
- @oldest_supported_version ||= Gem::Version.new("2.5.2")
332
+ @oldest_supported_version ||=
333
+ if Gem.ruby_version > Gem::Version.new("3.0.a")
334
+ Gem::Version.new("3.2.3")
335
+ elsif Gem.ruby_version > Gem::Version.new("2.7.a")
336
+ Gem::Version.new("3.1.2")
337
+ elsif Gem.ruby_version > Gem::Version.new("2.6.a")
338
+ Gem::Version.new("3.0.1")
339
+ elsif Gem.ruby_version > Gem::Version.new("2.5.a")
340
+ Gem::Version.new("2.7.3")
341
+ elsif Gem.ruby_version > Gem::Version.new("2.4.a")
342
+ Gem::Version.new("2.6.8")
343
+ else
344
+ Gem::Version.new("2.5.2")
345
+ end
328
346
  end
329
347
  end
@@ -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
@@ -51,6 +51,7 @@ class Gem::RemoteFetcher
51
51
 
52
52
  class UnknownHostError < FetchError
53
53
  end
54
+ deprecate_constant(:UnknownHostError)
54
55
 
55
56
  @fetcher = nil
56
57
 
@@ -78,6 +79,7 @@ class Gem::RemoteFetcher
78
79
  # fetching the gem.
79
80
 
80
81
  def initialize(proxy=nil, dns=nil, headers={})
82
+ require 'rubygems/core_ext/tcpsocket_init' if Gem.configuration.ipv4_fallback_enabled
81
83
  require 'net/http'
82
84
  require 'stringio'
83
85
  require 'uri'
@@ -261,15 +263,9 @@ class Gem::RemoteFetcher
261
263
  end
262
264
 
263
265
  data
264
- rescue Timeout::Error
265
- raise UnknownHostError.new('timed out', uri)
266
- rescue IOError, SocketError, SystemCallError,
266
+ rescue Timeout::Error, IOError, SocketError, SystemCallError,
267
267
  *(OpenSSL::SSL::SSLError if Gem::HAVE_OPENSSL) => e
268
- if e.message =~ /getaddrinfo/
269
- raise UnknownHostError.new('no such name', uri)
270
- else
271
- raise FetchError.new("#{e.class}: #{e}", uri)
272
- end
268
+ raise FetchError.new("#{e.class}: #{e}", uri)
273
269
  end
274
270
 
275
271
  def fetch_s3(uri, mtime = nil, head = false)
@@ -104,6 +104,7 @@ class Gem::Security::TrustDir
104
104
  # permissions.
105
105
 
106
106
  def verify
107
+ require 'fileutils'
107
108
  if File.exist? @dir
108
109
  raise Gem::Security::Exception,
109
110
  "trust directory #{@dir} is not a directory" unless
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = "rubygems-update"
5
- s.version = "3.2.10"
5
+ s.version = "3.2.15"
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
 
@@ -168,6 +168,15 @@ class TestGemCommandsUpdateCommand < Gem::TestCase
168
168
  @cmd.options[:args] = []
169
169
  @cmd.options[:system] = "2.5.1"
170
170
 
171
+ oldest_version_mod = Module.new do
172
+ def oldest_supported_version
173
+ Gem::Version.new("2.5.2")
174
+ end
175
+ private :oldest_supported_version
176
+ end
177
+
178
+ @cmd.extend(oldest_version_mod)
179
+
171
180
  assert_raises Gem::MockGemUi::TermError do
172
181
  use_ui @ui do
173
182
  @cmd.execute
@@ -175,7 +184,7 @@ class TestGemCommandsUpdateCommand < Gem::TestCase
175
184
  end
176
185
 
177
186
  assert_empty @ui.output
178
- assert_equal "ERROR: rubygems 2.5.1 is not supported. The oldest supported version is 2.5.2\n", @ui.error
187
+ assert_equal "ERROR: rubygems 2.5.1 is not supported on #{RUBY_VERSION}. The oldest version supported by this ruby is 2.5.2\n", @ui.error
179
188
  end
180
189
 
181
190
  def test_execute_system_specific_older_than_3_2_removes_plugins_dir
@@ -185,6 +194,15 @@ class TestGemCommandsUpdateCommand < Gem::TestCase
185
194
  end
186
195
  end
187
196
 
197
+ oldest_version_mod = Module.new do
198
+ def oldest_supported_version
199
+ Gem::Version.new("2.5.2")
200
+ end
201
+ private :oldest_supported_version
202
+ end
203
+
204
+ @cmd.extend(oldest_version_mod)
205
+
188
206
  @cmd.options[:args] = []
189
207
  @cmd.options[:system] = "3.1"
190
208
 
@@ -203,6 +221,15 @@ class TestGemCommandsUpdateCommand < Gem::TestCase
203
221
  end
204
222
  end
205
223
 
224
+ oldest_version_mod = Module.new do
225
+ def oldest_supported_version
226
+ Gem::Version.new("2.5.2")
227
+ end
228
+ private :oldest_supported_version
229
+ end
230
+
231
+ @cmd.extend(oldest_version_mod)
232
+
206
233
  @cmd.options[:args] = []
207
234
  @cmd.options[:system] = "3.2.a"
208
235
 
@@ -41,6 +41,7 @@ class TestGemConfigFile < Gem::TestCase
41
41
  assert_equal true, @cfg.verbose
42
42
  assert_equal [@gem_repo], Gem.sources
43
43
  assert_equal 365, @cfg.cert_expiration_length_days
44
+ assert_equal false, @cfg.ipv4_fallback_enabled
44
45
 
45
46
  File.open @temp_conf, 'w' do |fp|
46
47
  fp.puts ":backtrace: true"
@@ -56,6 +57,7 @@ class TestGemConfigFile < Gem::TestCase
56
57
  fp.puts ":ssl_verify_mode: 0"
57
58
  fp.puts ":ssl_ca_cert: /etc/ssl/certs"
58
59
  fp.puts ":cert_expiration_length_days: 28"
60
+ fp.puts ":ipv4_fallback_enabled: true"
59
61
  end
60
62
 
61
63
  util_config_file
@@ -70,6 +72,14 @@ class TestGemConfigFile < Gem::TestCase
70
72
  assert_equal 0, @cfg.ssl_verify_mode
71
73
  assert_equal '/etc/ssl/certs', @cfg.ssl_ca_cert
72
74
  assert_equal 28, @cfg.cert_expiration_length_days
75
+ assert_equal true, @cfg.ipv4_fallback_enabled
76
+ end
77
+
78
+ def test_initialize_ipv4_fallback_enabled_env
79
+ ENV['IPV4_FALLBACK_ENABLED'] = 'true'
80
+ util_config_file %W[--config-file #{@temp_conf}]
81
+
82
+ assert_equal true, @cfg.ipv4_fallback_enabled
73
83
  end
74
84
 
75
85
  def test_initialize_handle_arguments_config_file
@@ -496,6 +496,44 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
496
496
  assert_equal url, e.uri
497
497
  end
498
498
 
499
+ def test_fetch_path_timeout_error
500
+ fetcher = Gem::RemoteFetcher.new nil
501
+ @fetcher = fetcher
502
+
503
+ def fetcher.fetch_http(uri, mtime = nil, head = nil)
504
+ raise Timeout::Error, 'timed out'
505
+ end
506
+
507
+ url = 'http://example.com/uri'
508
+
509
+ e = assert_raises Gem::RemoteFetcher::FetchError do
510
+ fetcher.fetch_path url
511
+ end
512
+
513
+ assert_match %r{Timeout::Error: timed out \(#{Regexp.escape url}\)\z},
514
+ e.message
515
+ assert_equal url, e.uri
516
+ end
517
+
518
+ def test_fetch_path_getaddrinfo_error
519
+ fetcher = Gem::RemoteFetcher.new nil
520
+ @fetcher = fetcher
521
+
522
+ def fetcher.fetch_http(uri, mtime = nil, head = nil)
523
+ raise SocketError, 'getaddrinfo: nodename nor servname provided'
524
+ end
525
+
526
+ url = 'http://example.com/uri'
527
+
528
+ e = assert_raises Gem::RemoteFetcher::FetchError do
529
+ fetcher.fetch_path url
530
+ end
531
+
532
+ assert_match %r{SocketError: getaddrinfo: nodename nor servname provided \(#{Regexp.escape url}\)\z},
533
+ e.message
534
+ assert_equal url, e.uri
535
+ end
536
+
499
537
  def test_fetch_path_openssl_ssl_sslerror
500
538
  fetcher = Gem::RemoteFetcher.new nil
501
539
  @fetcher = fetcher
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubygems-update
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.2.10
4
+ version: 3.2.15
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jim Weirich
@@ -16,7 +16,7 @@ authors:
16
16
  autorequire:
17
17
  bindir: bin
18
18
  cert_chain: []
19
- date: 2021-02-15 00:00:00.000000000 Z
19
+ date: 2021-03-19 00:00:00.000000000 Z
20
20
  dependencies: []
21
21
  description: |-
22
22
  A package (also known as a library) contains a set of functionality
@@ -410,6 +410,7 @@ files:
410
410
  - lib/rubygems/core_ext/kernel_gem.rb
411
411
  - lib/rubygems/core_ext/kernel_require.rb
412
412
  - lib/rubygems/core_ext/kernel_warn.rb
413
+ - lib/rubygems/core_ext/tcpsocket_init.rb
413
414
  - lib/rubygems/defaults.rb
414
415
  - lib/rubygems/dependency.rb
415
416
  - lib/rubygems/dependency_installer.rb
@@ -767,7 +768,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
767
768
  - !ruby/object:Gem::Version
768
769
  version: '0'
769
770
  requirements: []
770
- rubygems_version: 3.2.10
771
+ rubygems_version: 3.2.15
771
772
  signing_key:
772
773
  specification_version: 4
773
774
  summary: RubyGems is a package management framework for Ruby.