bundler 2.6.3 → 2.6.9

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 (104) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +119 -6
  3. data/README.md +1 -1
  4. data/lib/bundler/build_metadata.rb +2 -2
  5. data/lib/bundler/checksum.rb +22 -12
  6. data/lib/bundler/cli/console.rb +8 -6
  7. data/lib/bundler/cli/doctor/diagnose.rb +167 -0
  8. data/lib/bundler/cli/doctor/ssl.rb +249 -0
  9. data/lib/bundler/cli/doctor.rb +27 -151
  10. data/lib/bundler/cli/info.rb +4 -4
  11. data/lib/bundler/cli/inject.rb +2 -2
  12. data/lib/bundler/cli/issue.rb +3 -3
  13. data/lib/bundler/cli/lock.rb +2 -1
  14. data/lib/bundler/cli/show.rb +1 -1
  15. data/lib/bundler/cli.rb +2 -11
  16. data/lib/bundler/compact_index_client/cache.rb +1 -1
  17. data/lib/bundler/compact_index_client/parser.rb +1 -1
  18. data/lib/bundler/compact_index_client/updater.rb +2 -1
  19. data/lib/bundler/current_ruby.rb +23 -33
  20. data/lib/bundler/definition.rb +220 -184
  21. data/lib/bundler/dependency.rb +92 -47
  22. data/lib/bundler/dsl.rb +84 -80
  23. data/lib/bundler/endpoint_specification.rb +10 -3
  24. data/lib/bundler/errors.rb +22 -0
  25. data/lib/bundler/friendly_errors.rb +1 -1
  26. data/lib/bundler/gem_helpers.rb +4 -10
  27. data/lib/bundler/gem_version_promoter.rb +0 -2
  28. data/lib/bundler/injector.rb +9 -9
  29. data/lib/bundler/installer.rb +2 -2
  30. data/lib/bundler/lazy_specification.rb +67 -45
  31. data/lib/bundler/lockfile_parser.rb +8 -5
  32. data/lib/bundler/man/bundle-add.1 +1 -1
  33. data/lib/bundler/man/bundle-binstubs.1 +1 -1
  34. data/lib/bundler/man/bundle-cache.1 +1 -1
  35. data/lib/bundler/man/bundle-check.1 +1 -1
  36. data/lib/bundler/man/bundle-clean.1 +1 -1
  37. data/lib/bundler/man/bundle-config.1 +6 -6
  38. data/lib/bundler/man/bundle-config.1.ronn +9 -4
  39. data/lib/bundler/man/bundle-console.1 +1 -1
  40. data/lib/bundler/man/bundle-doctor.1 +1 -1
  41. data/lib/bundler/man/bundle-env.1 +1 -1
  42. data/lib/bundler/man/bundle-exec.1 +3 -3
  43. data/lib/bundler/man/bundle-exec.1.ronn +2 -2
  44. data/lib/bundler/man/bundle-fund.1 +1 -1
  45. data/lib/bundler/man/bundle-gem.1 +1 -1
  46. data/lib/bundler/man/bundle-help.1 +1 -1
  47. data/lib/bundler/man/bundle-info.1 +1 -1
  48. data/lib/bundler/man/bundle-init.1 +1 -1
  49. data/lib/bundler/man/bundle-inject.1 +1 -1
  50. data/lib/bundler/man/bundle-install.1 +1 -1
  51. data/lib/bundler/man/bundle-issue.1 +1 -1
  52. data/lib/bundler/man/bundle-licenses.1 +1 -1
  53. data/lib/bundler/man/bundle-list.1 +1 -1
  54. data/lib/bundler/man/bundle-lock.1 +1 -1
  55. data/lib/bundler/man/bundle-open.1 +1 -1
  56. data/lib/bundler/man/bundle-outdated.1 +1 -1
  57. data/lib/bundler/man/bundle-platform.1 +1 -1
  58. data/lib/bundler/man/bundle-plugin.1 +1 -1
  59. data/lib/bundler/man/bundle-pristine.1 +1 -1
  60. data/lib/bundler/man/bundle-remove.1 +1 -1
  61. data/lib/bundler/man/bundle-show.1 +1 -1
  62. data/lib/bundler/man/bundle-update.1 +1 -1
  63. data/lib/bundler/man/bundle-version.1 +1 -1
  64. data/lib/bundler/man/bundle-viz.1 +1 -1
  65. data/lib/bundler/man/bundle.1 +1 -1
  66. data/lib/bundler/man/gemfile.5 +1 -1
  67. data/lib/bundler/match_metadata.rb +13 -0
  68. data/lib/bundler/plugin/api/source.rb +1 -1
  69. data/lib/bundler/plugin/index.rb +1 -1
  70. data/lib/bundler/plugin/installer/path.rb +8 -0
  71. data/lib/bundler/plugin.rb +1 -1
  72. data/lib/bundler/resolver/candidate.rb +12 -9
  73. data/lib/bundler/resolver/package.rb +7 -3
  74. data/lib/bundler/resolver/spec_group.rb +1 -25
  75. data/lib/bundler/resolver/strategy.rb +40 -0
  76. data/lib/bundler/resolver.rb +29 -27
  77. data/lib/bundler/rubygems_ext.rb +97 -81
  78. data/lib/bundler/rubygems_integration.rb +2 -3
  79. data/lib/bundler/runtime.rb +27 -29
  80. data/lib/bundler/shared_helpers.rb +4 -0
  81. data/lib/bundler/source/gemspec.rb +1 -4
  82. data/lib/bundler/source/git/git_proxy.rb +14 -3
  83. data/lib/bundler/source/git.rb +5 -1
  84. data/lib/bundler/source/path.rb +2 -2
  85. data/lib/bundler/source/rubygems/remote.rb +11 -3
  86. data/lib/bundler/source/rubygems.rb +19 -4
  87. data/lib/bundler/source.rb +2 -0
  88. data/lib/bundler/source_list.rb +33 -11
  89. data/lib/bundler/spec_set.rb +98 -40
  90. data/lib/bundler/templates/newgem/Gemfile.tt +1 -0
  91. data/lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb +53 -3
  92. data/lib/bundler/vendor/connection_pool/lib/connection_pool/version.rb +1 -1
  93. data/lib/bundler/vendor/connection_pool/lib/connection_pool.rb +11 -0
  94. data/lib/bundler/vendor/pub_grub/lib/pub_grub/basic_package_source.rb +4 -24
  95. data/lib/bundler/vendor/pub_grub/lib/pub_grub/strategy.rb +42 -0
  96. data/lib/bundler/vendor/pub_grub/lib/pub_grub/version_range.rb +20 -8
  97. data/lib/bundler/vendor/pub_grub/lib/pub_grub/version_solver.rb +17 -29
  98. data/lib/bundler/vendor/uri/lib/uri/common.rb +7 -3
  99. data/lib/bundler/vendor/uri/lib/uri/generic.rb +12 -11
  100. data/lib/bundler/vendor/uri/lib/uri/rfc2396_parser.rb +6 -6
  101. data/lib/bundler/vendor/uri/lib/uri/version.rb +1 -1
  102. data/lib/bundler/version.rb +1 -1
  103. metadata +7 -4
  104. data/lib/bundler/compact_index_client/gem_parser.rb +0 -32
@@ -0,0 +1,249 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rubygems/remote_fetcher"
4
+ require "uri"
5
+
6
+ module Bundler
7
+ class CLI::Doctor::SSL
8
+ attr_reader :options
9
+
10
+ def initialize(options)
11
+ @options = options
12
+ end
13
+
14
+ def run
15
+ return unless openssl_installed?
16
+
17
+ output_ssl_environment
18
+ bundler_success = bundler_connection_successful?
19
+ rubygem_success = rubygem_connection_successful?
20
+
21
+ return unless net_http_connection_successful?
22
+
23
+ Explanation.summarize(bundler_success, rubygem_success, host)
24
+ end
25
+
26
+ private
27
+
28
+ def host
29
+ @options[:host] || "rubygems.org"
30
+ end
31
+
32
+ def tls_version
33
+ @options[:"tls-version"].then do |version|
34
+ "TLS#{version.sub(".", "_")}".to_sym if version
35
+ end
36
+ end
37
+
38
+ def verify_mode
39
+ mode = @options[:"verify-mode"] || :peer
40
+
41
+ @verify_mode ||= mode.then {|mod| OpenSSL::SSL.const_get("verify_#{mod}".upcase) }
42
+ end
43
+
44
+ def uri
45
+ @uri ||= URI("https://#{host}")
46
+ end
47
+
48
+ def openssl_installed?
49
+ require "openssl"
50
+
51
+ true
52
+ rescue LoadError
53
+ Bundler.ui.warn(<<~MSG)
54
+ Oh no! Your Ruby doesn't have OpenSSL, so it can't connect to #{host}.
55
+ You'll need to recompile or reinstall Ruby with OpenSSL support and try again.
56
+ MSG
57
+
58
+ false
59
+ end
60
+
61
+ def output_ssl_environment
62
+ Bundler.ui.info(<<~MESSAGE)
63
+ Here's your OpenSSL environment:
64
+
65
+ OpenSSL: #{OpenSSL::VERSION}
66
+ Compiled with: #{OpenSSL::OPENSSL_VERSION}
67
+ Loaded with: #{OpenSSL::OPENSSL_LIBRARY_VERSION}
68
+ MESSAGE
69
+ end
70
+
71
+ def bundler_connection_successful?
72
+ Bundler.ui.info("\nTrying connections to #{uri}:\n")
73
+
74
+ bundler_uri = Gem::URI(uri.to_s)
75
+ Bundler::Fetcher.new(
76
+ Bundler::Source::Rubygems::Remote.new(bundler_uri)
77
+ ).send(:connection).request(bundler_uri)
78
+
79
+ Bundler.ui.info("Bundler: success")
80
+
81
+ true
82
+ rescue StandardError => error
83
+ Bundler.ui.warn("Bundler: failed (#{Explanation.explain_bundler_or_rubygems_error(error)})")
84
+
85
+ false
86
+ end
87
+
88
+ def rubygem_connection_successful?
89
+ Gem::RemoteFetcher.fetcher.fetch_path(uri)
90
+ Bundler.ui.info("RubyGems: success")
91
+
92
+ true
93
+ rescue StandardError => error
94
+ Bundler.ui.warn("RubyGems: failed (#{Explanation.explain_bundler_or_rubygems_error(error)})")
95
+
96
+ false
97
+ end
98
+
99
+ def net_http_connection_successful?
100
+ ::Gem::Net::HTTP.new(uri.host, uri.port).tap do |http|
101
+ http.use_ssl = true
102
+ http.min_version = tls_version
103
+ http.max_version = tls_version
104
+ http.verify_mode = verify_mode
105
+ end.start
106
+
107
+ Bundler.ui.info("Ruby net/http: success")
108
+ warn_on_unsupported_tls12
109
+
110
+ true
111
+ rescue StandardError => error
112
+ Bundler.ui.warn(<<~MSG)
113
+ Ruby net/http: failed
114
+
115
+ Unfortunately, this Ruby can't connect to #{host}.
116
+
117
+ #{Explanation.explain_net_http_error(error, host, tls_version)}
118
+ MSG
119
+
120
+ false
121
+ end
122
+
123
+ def warn_on_unsupported_tls12
124
+ ctx = OpenSSL::SSL::SSLContext.new
125
+ supported = true
126
+
127
+ if ctx.respond_to?(:min_version=)
128
+ begin
129
+ ctx.min_version = ctx.max_version = OpenSSL::SSL::TLS1_2_VERSION
130
+ rescue OpenSSL::SSL::SSLError, NameError
131
+ supported = false
132
+ end
133
+ else
134
+ supported = OpenSSL::SSL::SSLContext::METHODS.include?(:TLSv1_2) # rubocop:disable Naming/VariableNumber
135
+ end
136
+
137
+ Bundler.ui.warn(<<~EOM) unless supported
138
+
139
+ WARNING: Although your Ruby can connect to #{host} today, your OpenSSL is very old!
140
+ WARNING: You will need to upgrade OpenSSL to use #{host}.
141
+
142
+ EOM
143
+ end
144
+
145
+ module Explanation
146
+ extend self
147
+
148
+ def explain_bundler_or_rubygems_error(error)
149
+ case error.message
150
+ when /certificate verify failed/
151
+ "certificate verification"
152
+ when /read server hello A/
153
+ "SSL/TLS protocol version mismatch"
154
+ when /tlsv1 alert protocol version/
155
+ "requested TLS version is too old"
156
+ else
157
+ error.message
158
+ end
159
+ end
160
+
161
+ def explain_net_http_error(error, host, tls_version)
162
+ case error.message
163
+ # Check for certificate errors
164
+ when /certificate verify failed/
165
+ <<~MSG
166
+ #{show_ssl_certs}
167
+ Your Ruby can't connect to #{host} because you are missing the certificate files OpenSSL needs to verify you are connecting to the genuine #{host} servers.
168
+ MSG
169
+ # Check for TLS version errors
170
+ when /read server hello A/, /tlsv1 alert protocol version/
171
+ if tls_version.to_s == "TLS1_3"
172
+ "Your Ruby can't connect to #{host} because #{tls_version} isn't supported yet.\n"
173
+ else
174
+ <<~MSG
175
+ Your Ruby can't connect to #{host} because your version of OpenSSL is too old.
176
+ You'll need to upgrade your OpenSSL install and/or recompile Ruby to use a newer OpenSSL.
177
+ MSG
178
+ end
179
+ # OpenSSL doesn't support TLS version specified by argument
180
+ when /unknown SSL method/
181
+ "Your Ruby can't connect because #{tls_version} isn't supported by your version of OpenSSL."
182
+ else
183
+ <<~MSG
184
+ Even worse, we're not sure why.
185
+
186
+ Here's the full error information:
187
+ #{error.class}: #{error.message}
188
+ #{error.backtrace.join("\n ")}
189
+
190
+ You might have more luck using Mislav's SSL doctor.rb script. You can get it here:
191
+ https://github.com/mislav/ssl-tools/blob/8b3dec4/doctor.rb
192
+
193
+ Read more about the script and how to use it in this blog post:
194
+ https://mislav.net/2013/07/ruby-openssl/
195
+ MSG
196
+ end
197
+ end
198
+
199
+ def summarize(bundler_success, rubygems_success, host)
200
+ guide_url = "http://ruby.to/ssl-check-failed"
201
+
202
+ message = if bundler_success && rubygems_success
203
+ <<~MSG
204
+ Hooray! This Ruby can connect to #{host}.
205
+ You are all set to use Bundler and RubyGems.
206
+
207
+ MSG
208
+ elsif !bundler_success && !rubygems_success
209
+ <<~MSG
210
+ For some reason, your Ruby installation can connect to #{host}, but neither RubyGems nor Bundler can.
211
+ The most likely fix is to manually upgrade RubyGems by following the instructions at #{guide_url}.
212
+ After you've done that, run `gem install bundler` to upgrade Bundler, and then run this script again to make sure everything worked. ❣
213
+
214
+ MSG
215
+ elsif !bundler_success
216
+ <<~MSG
217
+ Although your Ruby installation and RubyGems can both connect to #{host}, Bundler is having trouble.
218
+ The most likely way to fix this is to upgrade Bundler by running `gem install bundler`.
219
+ Run this script again after doing that to make sure everything is all set.
220
+ If you're still having trouble, check out the troubleshooting guide at #{guide_url}.
221
+
222
+ MSG
223
+ else
224
+ <<~MSG
225
+ It looks like Ruby and Bundler can connect to #{host}, but RubyGems itself cannot.
226
+ You can likely solve this by manually downloading and installing a RubyGems update.
227
+ Visit #{guide_url} for instructions on how to manually upgrade RubyGems.
228
+
229
+ MSG
230
+ end
231
+
232
+ Bundler.ui.info("\n#{message}")
233
+ end
234
+
235
+ private
236
+
237
+ def show_ssl_certs
238
+ ssl_cert_file = ENV["SSL_CERT_FILE"] || OpenSSL::X509::DEFAULT_CERT_FILE
239
+ ssl_cert_dir = ENV["SSL_CERT_DIR"] || OpenSSL::X509::DEFAULT_CERT_DIR
240
+
241
+ <<~MSG
242
+ Below affect only Ruby net/http connections:
243
+ SSL_CERT_FILE: #{File.exist?(ssl_cert_file) ? "exists #{ssl_cert_file}" : "is missing #{ssl_cert_file}"}
244
+ SSL_CERT_DIR: #{Dir.exist?(ssl_cert_dir) ? "exists #{ssl_cert_dir}" : "is missing #{ssl_cert_dir}"}
245
+ MSG
246
+ end
247
+ end
248
+ end
249
+ end
@@ -1,157 +1,33 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "rbconfig"
4
- require "shellwords"
5
- require "fiddle"
6
-
7
3
  module Bundler
8
- class CLI::Doctor
9
- DARWIN_REGEX = /\s+(.+) \(compatibility /
10
- LDD_REGEX = /\t\S+ => (\S+) \(\S+\)/
11
-
12
- attr_reader :options
13
-
14
- def initialize(options)
15
- @options = options
16
- end
17
-
18
- def otool_available?
19
- Bundler.which("otool")
20
- end
21
-
22
- def ldd_available?
23
- Bundler.which("ldd")
24
- end
25
-
26
- def dylibs_darwin(path)
27
- output = `/usr/bin/otool -L #{path.shellescape}`.chomp
28
- dylibs = output.split("\n")[1..-1].map {|l| l.match(DARWIN_REGEX).captures[0] }.uniq
29
- # ignore @rpath and friends
30
- dylibs.reject {|dylib| dylib.start_with? "@" }
31
- end
32
-
33
- def dylibs_ldd(path)
34
- output = `/usr/bin/ldd #{path.shellescape}`.chomp
35
- output.split("\n").filter_map do |l|
36
- match = l.match(LDD_REGEX)
37
- next if match.nil?
38
- match.captures[0]
39
- end
40
- end
41
-
42
- def dylibs(path)
43
- case RbConfig::CONFIG["host_os"]
44
- when /darwin/
45
- return [] unless otool_available?
46
- dylibs_darwin(path)
47
- when /(linux|solaris|bsd)/
48
- return [] unless ldd_available?
49
- dylibs_ldd(path)
50
- else # Windows, etc.
51
- Bundler.ui.warn("Dynamic library check not supported on this platform.")
52
- []
53
- end
54
- end
55
-
56
- def bundles_for_gem(spec)
57
- Dir.glob("#{spec.full_gem_path}/**/*.bundle")
58
- end
59
-
60
- def check!
61
- require_relative "check"
62
- Bundler::CLI::Check.new({}).run
63
- end
64
-
65
- def run
66
- Bundler.ui.level = "warn" if options[:quiet]
67
- Bundler.settings.validate!
68
- check!
69
-
70
- definition = Bundler.definition
71
- broken_links = {}
72
-
73
- definition.specs.each do |spec|
74
- bundles_for_gem(spec).each do |bundle|
75
- bad_paths = dylibs(bundle).select do |f|
76
- Fiddle.dlopen(f)
77
- false
78
- rescue Fiddle::DLError
79
- true
80
- end
81
- if bad_paths.any?
82
- broken_links[spec] ||= []
83
- broken_links[spec].concat(bad_paths)
84
- end
85
- end
86
- end
87
-
88
- permissions_valid = check_home_permissions
89
-
90
- if broken_links.any?
91
- message = "The following gems are missing OS dependencies:"
92
- broken_links.flat_map do |spec, paths|
93
- paths.uniq.map do |path|
94
- "\n * #{spec.name}: #{path}"
95
- end
96
- end.sort.each {|m| message += m }
97
- raise ProductionError, message
98
- elsif !permissions_valid
99
- Bundler.ui.info "No issues found with the installed bundle"
100
- end
101
- end
102
-
103
- private
104
-
105
- def check_home_permissions
106
- require "find"
107
- files_not_readable_or_writable = []
108
- files_not_rw_and_owned_by_different_user = []
109
- files_not_owned_by_current_user_but_still_rw = []
110
- broken_symlinks = []
111
- Find.find(Bundler.bundle_path.to_s).each do |f|
112
- if !File.exist?(f)
113
- broken_symlinks << f
114
- elsif !File.writable?(f) || !File.readable?(f)
115
- if File.stat(f).uid != Process.uid
116
- files_not_rw_and_owned_by_different_user << f
117
- else
118
- files_not_readable_or_writable << f
119
- end
120
- elsif File.stat(f).uid != Process.uid
121
- files_not_owned_by_current_user_but_still_rw << f
122
- end
123
- end
124
-
125
- ok = true
126
-
127
- if broken_symlinks.any?
128
- Bundler.ui.warn "Broken links exist in the Bundler home. Please report them to the offending gem's upstream repo. These files are:\n - #{broken_symlinks.join("\n - ")}"
129
-
130
- ok = false
131
- end
132
-
133
- if files_not_owned_by_current_user_but_still_rw.any?
134
- Bundler.ui.warn "Files exist in the Bundler home that are owned by another " \
135
- "user, but are still readable/writable. These files are:\n - #{files_not_owned_by_current_user_but_still_rw.join("\n - ")}"
136
-
137
- ok = false
138
- end
139
-
140
- if files_not_rw_and_owned_by_different_user.any?
141
- Bundler.ui.warn "Files exist in the Bundler home that are owned by another " \
142
- "user, and are not readable/writable. These files are:\n - #{files_not_rw_and_owned_by_different_user.join("\n - ")}"
143
-
144
- ok = false
145
- end
146
-
147
- if files_not_readable_or_writable.any?
148
- Bundler.ui.warn "Files exist in the Bundler home that are not " \
149
- "readable/writable by the current user. These files are:\n - #{files_not_readable_or_writable.join("\n - ")}"
150
-
151
- ok = false
152
- end
153
-
154
- ok
4
+ class CLI::Doctor < Thor
5
+ default_command(:diagnose)
6
+
7
+ desc "diagnose [OPTIONS]", "Checks the bundle for common problems"
8
+ long_desc <<-D
9
+ Doctor scans the OS dependencies of each of the gems requested in the Gemfile. If
10
+ missing dependencies are detected, Bundler prints them and exits status 1.
11
+ Otherwise, Bundler prints a success message and exits with a status of 0.
12
+ D
13
+ method_option "gemfile", type: :string, banner: "Use the specified gemfile instead of Gemfile"
14
+ method_option "quiet", type: :boolean, banner: "Only output warnings and errors."
15
+ method_option "ssl", type: :boolean, default: false, banner: "Diagnose SSL problems."
16
+ def diagnose
17
+ require_relative "doctor/diagnose"
18
+ Diagnose.new(options).run
19
+ end
20
+
21
+ desc "ssl [OPTIONS]", "Diagnose SSL problems"
22
+ long_desc <<-D
23
+ Diagnose SSL problems, especially related to certificates or TLS version while connecting to https://rubygems.org.
24
+ D
25
+ method_option "host", type: :string, banner: "The host to diagnose."
26
+ method_option "tls-version", type: :string, banner: "Specify the SSL/TLS version when running the diagnostic. Accepts either <1.1> or <1.2>"
27
+ method_option "verify-mode", type: :string, banner: "Specify the mode used for certification verification. Accepts either <peer> or <none>"
28
+ def ssl
29
+ require_relative "doctor/ssl"
30
+ SSL.new(options).run
155
31
  end
156
32
  end
157
33
  end
@@ -39,8 +39,8 @@ module Bundler
39
39
  path = File.expand_path("../../..", __dir__)
40
40
  else
41
41
  path = spec.full_gem_path
42
- if spec.deleted_gem?
43
- return Bundler.ui.warn "The gem #{name} has been deleted. It was installed at: #{path}"
42
+ if spec.installation_missing?
43
+ return Bundler.ui.warn "The gem #{name} is missing. It should be installed at #{path}, but was not found"
44
44
  end
45
45
  end
46
46
 
@@ -65,8 +65,8 @@ module Bundler
65
65
  gem_info << "\tDefault Gem: yes\n" if spec.respond_to?(:default_gem?) && spec.default_gem?
66
66
  gem_info << "\tReverse Dependencies: \n\t\t#{gem_dependencies.join("\n\t\t")}" if gem_dependencies.any?
67
67
 
68
- if name != "bundler" && spec.deleted_gem?
69
- return Bundler.ui.warn "The gem #{name} has been deleted. Gemspec information is still available though:\n#{gem_info}"
68
+ if name != "bundler" && spec.installation_missing?
69
+ return Bundler.ui.warn "The gem #{name} is missing. Gemspec information is still available though:\n#{gem_info}"
70
70
  end
71
71
 
72
72
  Bundler.ui.info gem_info
@@ -35,8 +35,8 @@ module Bundler
35
35
  Bundler.ui.confirm(added.map do |d|
36
36
  name = "'#{d.name}'"
37
37
  requirement = ", '#{d.requirement}'"
38
- group = ", :group => #{d.groups.inspect}" if d.groups != Array(:default)
39
- source = ", :source => '#{d.source}'" unless d.source.nil?
38
+ group = ", group: #{d.groups.inspect}" if d.groups != Array(:default)
39
+ source = ", source: '#{d.source}'" unless d.source.nil?
40
40
  %(gem #{name}#{requirement}#{group}#{source})
41
41
  end.join("\n"))
42
42
  else
@@ -10,7 +10,7 @@ module Bundler
10
10
  be sure to check out these resources:
11
11
 
12
12
  1. Check out our troubleshooting guide for quick fixes to common issues:
13
- https://github.com/rubygems/rubygems/blob/master/bundler/doc/TROUBLESHOOTING.md
13
+ https://github.com/rubygems/rubygems/blob/master/doc/bundler/TROUBLESHOOTING.md
14
14
 
15
15
  2. Instructions for common Bundler uses can be found on the documentation
16
16
  site: https://bundler.io/
@@ -34,8 +34,8 @@ module Bundler
34
34
  end
35
35
 
36
36
  def doctor
37
- require_relative "doctor"
38
- Bundler::CLI::Doctor.new({}).run
37
+ require_relative "doctor/diagnose"
38
+ Bundler::CLI::Doctor::Diagnose.new({}).run
39
39
  end
40
40
  end
41
41
  end
@@ -44,7 +44,8 @@ module Bundler
44
44
 
45
45
  Bundler::CLI::Common.configure_gem_version_promoter(definition, options) if options[:update]
46
46
 
47
- options["remove-platform"].each do |platform|
47
+ options["remove-platform"].each do |platform_string|
48
+ platform = Gem::Platform.new(platform_string)
48
49
  definition.remove_platform(platform)
49
50
  end
50
51
 
@@ -24,7 +24,7 @@ module Bundler
24
24
  return unless spec
25
25
  path = spec.full_gem_path
26
26
  unless File.directory?(path)
27
- return Bundler.ui.warn "The gem #{gem_name} has been deleted. It was installed at: #{path}"
27
+ return Bundler.ui.warn "The gem #{gem_name} is missing. It should be installed at #{path}, but was not found"
28
28
  end
29
29
  end
30
30
  return Bundler.ui.info(path)
data/lib/bundler/cli.rb CHANGED
@@ -610,17 +610,8 @@ module Bundler
610
610
  end
611
611
 
612
612
  desc "doctor [OPTIONS]", "Checks the bundle for common problems"
613
- long_desc <<-D
614
- Doctor scans the OS dependencies of each of the gems requested in the Gemfile. If
615
- missing dependencies are detected, Bundler prints them and exits status 1.
616
- Otherwise, Bundler prints a success message and exits with a status of 0.
617
- D
618
- method_option "gemfile", type: :string, banner: "Use the specified gemfile instead of Gemfile"
619
- method_option "quiet", type: :boolean, banner: "Only output warnings and errors."
620
- def doctor
621
- require_relative "cli/doctor"
622
- Doctor.new(options).run
623
- end
613
+ require_relative "cli/doctor"
614
+ subcommand("doctor", Doctor)
624
615
 
625
616
  desc "issue", "Learn how to report an issue in Bundler"
626
617
  def issue
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "gem_parser"
3
+ require "rubygems/resolver/api_set/gem_parser"
4
4
 
5
5
  module Bundler
6
6
  class CompactIndexClient
@@ -64,7 +64,7 @@ module Bundler
64
64
  end
65
65
 
66
66
  def gem_parser
67
- @gem_parser ||= GemParser.new
67
+ @gem_parser ||= Gem::Resolver::APISet::GemParser.new
68
68
  end
69
69
 
70
70
  # This is mostly the same as `split(" ", 3)` but it avoids allocating extra objects.
@@ -37,7 +37,8 @@ module Bundler
37
37
  file.digests = parse_digests(response)
38
38
  # server may ignore Range and return the full response
39
39
  if response.is_a?(Gem::Net::HTTPPartialContent)
40
- break false unless file.append(response.body.byteslice(1..-1))
40
+ tail = response.body.byteslice(1..-1)
41
+ break false unless tail && file.append(tail)
41
42
  else
42
43
  file.write(response.body)
43
44
  end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "rubygems_ext"
4
+
3
5
  module Bundler
4
6
  # Returns current version of Ruby
5
7
  #
@@ -9,38 +11,25 @@ module Bundler
9
11
  end
10
12
 
11
13
  class CurrentRuby
12
- KNOWN_MINOR_VERSIONS = %w[
13
- 1.8
14
- 1.9
15
- 2.0
16
- 2.1
17
- 2.2
18
- 2.3
19
- 2.4
20
- 2.5
21
- 2.6
22
- 2.7
23
- 3.0
24
- 3.1
25
- 3.2
26
- 3.3
27
- ].freeze
28
-
29
- KNOWN_MAJOR_VERSIONS = KNOWN_MINOR_VERSIONS.map {|v| v.split(".", 2).first }.uniq.freeze
30
-
31
- KNOWN_PLATFORMS = %w[
32
- jruby
33
- maglev
34
- mingw
35
- mri
36
- mswin
37
- mswin64
38
- rbx
39
- ruby
40
- truffleruby
41
- windows
42
- x64_mingw
43
- ].freeze
14
+ ALL_RUBY_VERSIONS = (18..27).to_a.concat((30..35).to_a).freeze
15
+ KNOWN_MINOR_VERSIONS = ALL_RUBY_VERSIONS.map {|v| v.digits.reverse.join(".") }.freeze
16
+ KNOWN_MAJOR_VERSIONS = ALL_RUBY_VERSIONS.map {|v| v.digits.last.to_s }.uniq.freeze
17
+ PLATFORM_MAP = {
18
+ ruby: [Gem::Platform::RUBY, CurrentRuby::ALL_RUBY_VERSIONS],
19
+ mri: [Gem::Platform::RUBY, CurrentRuby::ALL_RUBY_VERSIONS],
20
+ rbx: [Gem::Platform::RUBY],
21
+ truffleruby: [Gem::Platform::RUBY],
22
+ jruby: [Gem::Platform::JAVA, [18, 19]],
23
+ windows: [Gem::Platform::WINDOWS, CurrentRuby::ALL_RUBY_VERSIONS],
24
+ # deprecated
25
+ mswin: [Gem::Platform::MSWIN, CurrentRuby::ALL_RUBY_VERSIONS],
26
+ mswin64: [Gem::Platform::MSWIN64, CurrentRuby::ALL_RUBY_VERSIONS - [18]],
27
+ mingw: [Gem::Platform::UNIVERSAL_MINGW, CurrentRuby::ALL_RUBY_VERSIONS],
28
+ x64_mingw: [Gem::Platform::UNIVERSAL_MINGW, CurrentRuby::ALL_RUBY_VERSIONS - [18, 19]],
29
+ }.each_with_object({}) do |(platform, spec), hash|
30
+ hash[platform] = spec[0]
31
+ spec[1]&.each {|version| hash[:"#{platform}_#{version}"] = spec[0] }
32
+ end.freeze
44
33
 
45
34
  def ruby?
46
35
  return true if Bundler::GemHelpers.generic_local_platform_is_ruby?
@@ -82,7 +71,8 @@ module Bundler
82
71
  RUBY_VERSION.start_with?("#{version}.")
83
72
  end
84
73
 
85
- KNOWN_PLATFORMS.each do |platform|
74
+ all_platforms = PLATFORM_MAP.keys << "maglev"
75
+ all_platforms.each do |platform|
86
76
  define_method(:"#{platform}_#{trimmed_version}?") do
87
77
  send(:"#{platform}?") && send(:"on_#{trimmed_version}?")
88
78
  end