bundler 2.6.5 → 2.7.1
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +1172 -1024
- data/README.md +7 -7
- data/bundler.gemspec +2 -2
- data/lib/bundler/build_metadata.rb +10 -11
- data/lib/bundler/checksum.rb +22 -12
- data/lib/bundler/cli/common.rb +1 -1
- data/lib/bundler/cli/config.rb +2 -2
- data/lib/bundler/cli/doctor/diagnose.rb +167 -0
- data/lib/bundler/cli/doctor/ssl.rb +249 -0
- data/lib/bundler/cli/doctor.rb +27 -155
- data/lib/bundler/cli/gem.rb +62 -30
- data/lib/bundler/cli/inject.rb +2 -2
- data/lib/bundler/cli/install.rb +5 -5
- data/lib/bundler/cli/issue.rb +2 -2
- data/lib/bundler/cli/lock.rb +2 -1
- data/lib/bundler/cli/outdated.rb +1 -1
- data/lib/bundler/cli/update.rb +3 -3
- data/lib/bundler/cli.rb +26 -49
- data/lib/bundler/compact_index_client/cache.rb +1 -1
- data/lib/bundler/compact_index_client/parser.rb +1 -1
- data/lib/bundler/compact_index_client/updater.rb +2 -1
- data/lib/bundler/compact_index_client.rb +1 -5
- data/lib/bundler/current_ruby.rb +27 -3
- data/lib/bundler/definition.rb +184 -151
- data/lib/bundler/dependency.rb +1 -1
- data/lib/bundler/dsl.rb +35 -26
- data/lib/bundler/errors.rb +18 -0
- data/lib/bundler/feature_flag.rb +15 -12
- data/lib/bundler/fetcher/dependency.rb +2 -1
- data/lib/bundler/fetcher/downloader.rb +33 -7
- data/lib/bundler/fetcher.rb +49 -19
- data/lib/bundler/friendly_errors.rb +3 -2
- data/lib/bundler/index.rb +7 -2
- data/lib/bundler/injector.rb +9 -9
- data/lib/bundler/installer.rb +6 -5
- data/lib/bundler/lazy_specification.rb +38 -19
- data/lib/bundler/lockfile_parser.rb +29 -10
- data/lib/bundler/man/bundle-add.1 +1 -1
- data/lib/bundler/man/bundle-binstubs.1 +1 -1
- data/lib/bundler/man/bundle-cache.1 +1 -1
- data/lib/bundler/man/bundle-check.1 +1 -1
- data/lib/bundler/man/bundle-clean.1 +1 -1
- data/lib/bundler/man/bundle-config.1 +175 -129
- data/lib/bundler/man/bundle-config.1.ronn +93 -88
- data/lib/bundler/man/bundle-console.1 +1 -1
- data/lib/bundler/man/bundle-doctor.1 +43 -4
- data/lib/bundler/man/bundle-doctor.1.ronn +48 -4
- data/lib/bundler/man/bundle-env.1 +1 -1
- data/lib/bundler/man/bundle-exec.1 +3 -3
- data/lib/bundler/man/bundle-exec.1.ronn +2 -2
- data/lib/bundler/man/bundle-fund.1 +1 -1
- data/lib/bundler/man/bundle-gem.1 +67 -44
- data/lib/bundler/man/bundle-gem.1.ronn +8 -4
- data/lib/bundler/man/bundle-help.1 +1 -1
- data/lib/bundler/man/bundle-info.1 +1 -1
- data/lib/bundler/man/bundle-init.1 +1 -1
- data/lib/bundler/man/bundle-inject.1 +2 -2
- data/lib/bundler/man/bundle-inject.1.ronn +1 -1
- data/lib/bundler/man/bundle-install.1 +4 -4
- data/lib/bundler/man/bundle-install.1.ronn +3 -4
- data/lib/bundler/man/bundle-issue.1 +1 -1
- data/lib/bundler/man/bundle-licenses.1 +1 -1
- data/lib/bundler/man/bundle-list.1 +1 -1
- data/lib/bundler/man/bundle-lock.1 +1 -1
- data/lib/bundler/man/bundle-open.1 +1 -1
- data/lib/bundler/man/bundle-outdated.1 +1 -1
- data/lib/bundler/man/bundle-platform.1 +1 -1
- data/lib/bundler/man/bundle-plugin.1 +1 -1
- data/lib/bundler/man/bundle-pristine.1 +1 -1
- data/lib/bundler/man/bundle-remove.1 +1 -1
- data/lib/bundler/man/bundle-show.1 +1 -1
- data/lib/bundler/man/bundle-update.1 +5 -5
- data/lib/bundler/man/bundle-update.1.ronn +4 -4
- data/lib/bundler/man/bundle-version.1 +1 -1
- data/lib/bundler/man/bundle-viz.1 +1 -1
- data/lib/bundler/man/bundle.1 +1 -1
- data/lib/bundler/man/gemfile.5 +1 -1
- data/lib/bundler/match_platform.rb +31 -12
- data/lib/bundler/materialization.rb +2 -2
- data/lib/bundler/plugin/api/source.rb +1 -1
- data/lib/bundler/plugin/index.rb +1 -1
- data/lib/bundler/plugin/installer/path.rb +8 -0
- data/lib/bundler/plugin.rb +1 -1
- data/lib/bundler/resolver/candidate.rb +12 -9
- data/lib/bundler/resolver/package.rb +1 -1
- data/lib/bundler/resolver/strategy.rb +40 -0
- data/lib/bundler/resolver.rb +18 -27
- data/lib/bundler/rubygems_ext.rb +131 -120
- data/lib/bundler/rubygems_integration.rb +11 -6
- data/lib/bundler/runtime.rb +9 -6
- data/lib/bundler/self_manager.rb +32 -42
- data/lib/bundler/settings/validator.rb +0 -23
- data/lib/bundler/settings.rb +4 -6
- data/lib/bundler/shared_helpers.rb +10 -4
- data/lib/bundler/source/gemspec.rb +1 -4
- data/lib/bundler/source/git/git_proxy.rb +17 -6
- data/lib/bundler/source/git.rb +5 -1
- data/lib/bundler/source/path.rb +9 -2
- data/lib/bundler/source/rubygems/remote.rb +11 -3
- data/lib/bundler/source_list.rb +30 -16
- data/lib/bundler/source_map.rb +1 -1
- data/lib/bundler/spec_set.rb +55 -16
- data/lib/bundler/templates/Executable +0 -11
- data/lib/bundler/templates/newgem/github/workflows/main.yml.tt +2 -0
- data/lib/bundler/templates/newgem/newgem.gemspec.tt +6 -5
- data/lib/bundler/ui/shell.rb +2 -2
- data/lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb +53 -3
- data/lib/bundler/vendor/connection_pool/lib/connection_pool/version.rb +1 -1
- data/lib/bundler/vendor/connection_pool/lib/connection_pool.rb +11 -0
- data/lib/bundler/vendor/net-http-persistent/README.rdoc +1 -1
- data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/timed_stack_multi.rb +2 -1
- data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb +81 -42
- data/lib/bundler/vendor/pub_grub/lib/pub_grub/basic_package_source.rb +4 -24
- data/lib/bundler/vendor/pub_grub/lib/pub_grub/strategy.rb +42 -0
- data/lib/bundler/vendor/pub_grub/lib/pub_grub/version_range.rb +20 -8
- data/lib/bundler/vendor/pub_grub/lib/pub_grub/version_solver.rb +17 -29
- data/lib/bundler/vendor/uri/lib/uri/common.rb +7 -3
- data/lib/bundler/vendor/uri/lib/uri/generic.rb +12 -11
- data/lib/bundler/vendor/uri/lib/uri/rfc2396_parser.rb +6 -6
- data/lib/bundler/vendor/uri/lib/uri/version.rb +1 -1
- data/lib/bundler/version.rb +10 -2
- data/lib/bundler/worker.rb +1 -1
- data/lib/bundler.rb +14 -12
- metadata +9 -16
- data/lib/bundler/compact_index_client/gem_parser.rb +0 -32
- data/lib/bundler/gem_helpers.rb +0 -144
- data/lib/bundler/templates/Executable.bundler +0 -109
- data/lib/bundler/vendor/connection_pool/.document +0 -1
- data/lib/bundler/vendor/fileutils/.document +0 -1
- data/lib/bundler/vendor/net-http-persistent/.document +0 -1
- data/lib/bundler/vendor/pub_grub/.document +0 -1
- data/lib/bundler/vendor/securerandom/.document +0 -1
- data/lib/bundler/vendor/thor/.document +0 -1
- data/lib/bundler/vendor/tsort/.document +0 -1
- data/lib/bundler/vendor/uri/.document +0 -1
data/lib/bundler/dsl.rb
CHANGED
@@ -73,11 +73,11 @@ module Bundler
|
|
73
73
|
case specs_by_name_and_version.size
|
74
74
|
when 1
|
75
75
|
specs = specs_by_name_and_version.values.first
|
76
|
-
spec = specs.find {|s| s.
|
76
|
+
spec = specs.find {|s| s.installable_on_platform?(Bundler.local_platform) } || specs.first
|
77
77
|
|
78
78
|
@gemspecs << spec
|
79
79
|
|
80
|
-
path path, "glob" => glob, "name" => spec.name do
|
80
|
+
path path, "glob" => glob, "name" => spec.name, "gemspec" => spec do
|
81
81
|
add_dependency spec.name
|
82
82
|
end
|
83
83
|
|
@@ -141,8 +141,7 @@ module Bundler
|
|
141
141
|
def path(path, options = {}, &blk)
|
142
142
|
source_options = normalize_hash(options).merge(
|
143
143
|
"path" => Pathname.new(path),
|
144
|
-
"root_path" => gemfile_root
|
145
|
-
"gemspec" => gemspecs.find {|g| g.name == options["name"] }
|
144
|
+
"root_path" => gemfile_root
|
146
145
|
)
|
147
146
|
|
148
147
|
source_options["global"] = true unless block_given?
|
@@ -241,28 +240,27 @@ module Bundler
|
|
241
240
|
dep = Dependency.new(name, version, options)
|
242
241
|
|
243
242
|
# if there's already a dependency with this name we try to prefer one
|
244
|
-
if current = @dependencies.find {|d| d.name ==
|
243
|
+
if current = @dependencies.find {|d| d.name == name }
|
245
244
|
if current.requirement != dep.requirement
|
246
245
|
current_requirement_open = current.requirements_list.include?(">= 0")
|
247
246
|
|
248
247
|
gemspec_dep = [dep, current].find(&:gemspec_dev_dep?)
|
249
248
|
if gemspec_dep
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
dep = Dependency.new(name, current.requirement.as_list + dep.requirement.as_list, options)
|
249
|
+
require_relative "vendor/pub_grub/lib/pub_grub/version_range"
|
250
|
+
require_relative "vendor/pub_grub/lib/pub_grub/version_constraint"
|
251
|
+
require_relative "vendor/pub_grub/lib/pub_grub/version_union"
|
252
|
+
require_relative "vendor/pub_grub/lib/pub_grub/rubygems"
|
253
|
+
|
254
|
+
current_gemspec_range = PubGrub::RubyGems.requirement_to_range(current.requirement)
|
255
|
+
next_gemspec_range = PubGrub::RubyGems.requirement_to_range(dep.requirement)
|
256
|
+
|
257
|
+
if current_gemspec_range.intersects?(next_gemspec_range)
|
258
|
+
dep = Dependency.new(name, current.requirement.as_list + dep.requirement.as_list, options)
|
259
|
+
else
|
260
|
+
gemfile_dep = [dep, current].find(&:gemfile_dep?)
|
261
|
+
|
262
|
+
if gemfile_dep
|
263
|
+
raise GemfileError, "The #{name} dependency has conflicting requirements in Gemfile (#{gemfile_dep.requirement}) and gemspec (#{gemspec_dep.requirement})"
|
266
264
|
else
|
267
265
|
raise GemfileError, "Two gemspec development dependencies have conflicting requirements on the same gem: #{dep} and #{current}"
|
268
266
|
end
|
@@ -274,14 +272,14 @@ module Bundler
|
|
274
272
|
if dep.requirements_list.include?(">= 0") && !current_requirement_open
|
275
273
|
update_prompt = ". Gem already added"
|
276
274
|
else
|
277
|
-
update_prompt = ". If you want to update the gem version, run `bundle update #{
|
275
|
+
update_prompt = ". If you want to update the gem version, run `bundle update #{name}`"
|
278
276
|
|
279
277
|
update_prompt += ". You may also need to change the version requirement specified in the Gemfile if it's too restrictive." unless current_requirement_open
|
280
278
|
end
|
281
279
|
end
|
282
280
|
|
283
281
|
raise GemfileError, "You cannot specify the same gem twice with different version requirements.\n" \
|
284
|
-
"You specified: #{
|
282
|
+
"You specified: #{name} (#{current.requirement}) and #{name} (#{dep.requirement})" \
|
285
283
|
"#{update_prompt}"
|
286
284
|
end
|
287
285
|
end
|
@@ -294,10 +292,10 @@ module Bundler
|
|
294
292
|
return
|
295
293
|
elsif current.source != dep.source
|
296
294
|
raise GemfileError, "You cannot specify the same gem twice coming from different sources.\n" \
|
297
|
-
"You specified that #{
|
295
|
+
"You specified that #{name} (#{dep.requirement}) should come from " \
|
298
296
|
"#{current.source || "an unspecified source"} and #{dep.source}\n"
|
299
297
|
else
|
300
|
-
Bundler.ui.warn "Your Gemfile lists the gem #{
|
298
|
+
Bundler.ui.warn "Your Gemfile lists the gem #{name} (#{current.requirement}) more than once.\n" \
|
301
299
|
"You should probably keep only one of them.\n" \
|
302
300
|
"Remove any duplicate entries and specify the gem only once.\n" \
|
303
301
|
"While it's not a problem now, it could cause errors if you change the version of one of them later."
|
@@ -413,6 +411,7 @@ module Bundler
|
|
413
411
|
next if VALID_PLATFORMS.include?(p)
|
414
412
|
raise GemfileError, "`#{p}` is not a valid platform. The available options are: #{VALID_PLATFORMS.inspect}"
|
415
413
|
end
|
414
|
+
deprecate_legacy_windows_platforms(platforms)
|
416
415
|
|
417
416
|
# Save sources passed in a key
|
418
417
|
if opts.key?("source")
|
@@ -493,6 +492,16 @@ module Bundler
|
|
493
492
|
end
|
494
493
|
end
|
495
494
|
|
495
|
+
def deprecate_legacy_windows_platforms(platforms)
|
496
|
+
windows_platforms = platforms.select {|pl| pl.to_s.match?(/mingw|mswin/) }
|
497
|
+
return if windows_platforms.empty?
|
498
|
+
|
499
|
+
windows_platforms = windows_platforms.map! {|pl| ":#{pl}" }.join(", ")
|
500
|
+
message = "Platform #{windows_platforms} is deprecated. Please use platform :windows instead."
|
501
|
+
removed_message = "Platform #{windows_platforms} has been removed. Please use platform :windows instead."
|
502
|
+
Bundler::SharedHelpers.major_deprecation 2, message, removed_message: removed_message
|
503
|
+
end
|
504
|
+
|
496
505
|
def check_path_source_safety
|
497
506
|
return if @sources.global_path_source.nil?
|
498
507
|
|
@@ -512,7 +521,7 @@ module Bundler
|
|
512
521
|
end
|
513
522
|
|
514
523
|
def multiple_global_source_warning
|
515
|
-
if Bundler.feature_flag.
|
524
|
+
if Bundler.feature_flag.bundler_4_mode?
|
516
525
|
msg = "This Gemfile contains multiple global sources. " \
|
517
526
|
"Each source after the first must include a block to indicate which gems " \
|
518
527
|
"should come from that source"
|
data/lib/bundler/errors.rb
CHANGED
@@ -193,6 +193,24 @@ module Bundler
|
|
193
193
|
status_code(31)
|
194
194
|
end
|
195
195
|
|
196
|
+
class ReadOnlyFileSystemError < PermissionError
|
197
|
+
def message
|
198
|
+
"There was an error while trying to #{action} `#{@path}`. " \
|
199
|
+
"File system is read-only."
|
200
|
+
end
|
201
|
+
|
202
|
+
status_code(42)
|
203
|
+
end
|
204
|
+
|
205
|
+
class OperationNotPermittedError < PermissionError
|
206
|
+
def message
|
207
|
+
"There was an error while trying to #{action} `#{@path}`. " \
|
208
|
+
"Underlying OS system call raised an EPERM error."
|
209
|
+
end
|
210
|
+
|
211
|
+
status_code(43)
|
212
|
+
end
|
213
|
+
|
196
214
|
class GenericSystemCallError < BundlerError
|
197
215
|
attr_reader :underlying_error
|
198
216
|
|
data/lib/bundler/feature_flag.rb
CHANGED
@@ -27,20 +27,23 @@ module Bundler
|
|
27
27
|
|
28
28
|
(1..10).each {|v| define_method("bundler_#{v}_mode?") { @major_version >= v } }
|
29
29
|
|
30
|
-
settings_flag(:allow_offline_install) {
|
31
|
-
settings_flag(:
|
32
|
-
settings_flag(:
|
33
|
-
settings_flag(:
|
34
|
-
settings_flag(:
|
35
|
-
settings_flag(:global_gem_cache) { bundler_3_mode? }
|
36
|
-
settings_flag(:lockfile_checksums) { bundler_3_mode? }
|
37
|
-
settings_flag(:path_relative_to_cwd) { bundler_3_mode? }
|
30
|
+
settings_flag(:allow_offline_install) { bundler_4_mode? }
|
31
|
+
settings_flag(:cache_all) { bundler_4_mode? }
|
32
|
+
settings_flag(:forget_cli_options) { bundler_4_mode? }
|
33
|
+
settings_flag(:global_gem_cache) { bundler_4_mode? }
|
34
|
+
settings_flag(:lockfile_checksums) { bundler_4_mode? }
|
38
35
|
settings_flag(:plugins) { @bundler_version >= Gem::Version.new("1.14") }
|
39
|
-
settings_flag(:
|
40
|
-
settings_flag(:setup_makes_kernel_gem_public) { !bundler_3_mode? }
|
41
|
-
settings_flag(:update_requires_all_flag) { bundler_4_mode? }
|
36
|
+
settings_flag(:update_requires_all_flag) { bundler_5_mode? }
|
42
37
|
|
43
|
-
settings_option(:default_cli_command) {
|
38
|
+
settings_option(:default_cli_command) { bundler_4_mode? ? :cli_help : :install }
|
39
|
+
|
40
|
+
def removed_major?(target_major_version)
|
41
|
+
@major_version > target_major_version
|
42
|
+
end
|
43
|
+
|
44
|
+
def deprecated_major?(target_major_version)
|
45
|
+
@major_version >= target_major_version
|
46
|
+
end
|
44
47
|
|
45
48
|
def initialize(bundler_version)
|
46
49
|
@bundler_version = Gem::Version.create(bundler_version)
|
@@ -3,6 +3,28 @@
|
|
3
3
|
module Bundler
|
4
4
|
class Fetcher
|
5
5
|
class Downloader
|
6
|
+
HTTP_NON_RETRYABLE_ERRORS = [
|
7
|
+
SocketError,
|
8
|
+
Errno::EADDRNOTAVAIL,
|
9
|
+
Errno::ENETDOWN,
|
10
|
+
Errno::ENETUNREACH,
|
11
|
+
Gem::Net::HTTP::Persistent::Error,
|
12
|
+
Errno::EHOSTUNREACH,
|
13
|
+
].freeze
|
14
|
+
|
15
|
+
HTTP_RETRYABLE_ERRORS = [
|
16
|
+
Gem::Timeout::Error,
|
17
|
+
EOFError,
|
18
|
+
Errno::EINVAL,
|
19
|
+
Errno::ECONNRESET,
|
20
|
+
Errno::ETIMEDOUT,
|
21
|
+
Errno::EAGAIN,
|
22
|
+
Gem::Net::HTTPBadResponse,
|
23
|
+
Gem::Net::HTTPHeaderSyntaxError,
|
24
|
+
Gem::Net::ProtocolError,
|
25
|
+
Zlib::BufError,
|
26
|
+
].freeze
|
27
|
+
|
6
28
|
attr_reader :connection
|
7
29
|
attr_reader :redirect_limit
|
8
30
|
|
@@ -67,15 +89,19 @@ module Bundler
|
|
67
89
|
connection.request(uri, req)
|
68
90
|
rescue OpenSSL::SSL::SSLError
|
69
91
|
raise CertificateFailureError.new(uri)
|
70
|
-
rescue *
|
92
|
+
rescue *HTTP_NON_RETRYABLE_ERRORS => e
|
71
93
|
Bundler.ui.trace e
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
94
|
+
|
95
|
+
host = uri.host
|
96
|
+
host_port = "#{host}:#{uri.port}"
|
97
|
+
host = host_port if filtered_uri.to_s.include?(host_port)
|
98
|
+
raise NetworkDownError, "Could not reach host #{host}. Check your network " \
|
99
|
+
"connection and try again."
|
100
|
+
rescue *HTTP_RETRYABLE_ERRORS => e
|
101
|
+
Bundler.ui.trace e
|
102
|
+
|
103
|
+
raise HTTPError, "Network error while fetching #{filtered_uri}" \
|
77
104
|
" (#{e})"
|
78
|
-
end
|
79
105
|
end
|
80
106
|
|
81
107
|
private
|
data/lib/bundler/fetcher.rb
CHANGED
@@ -2,7 +2,6 @@
|
|
2
2
|
|
3
3
|
require_relative "vendored_persistent"
|
4
4
|
require_relative "vendored_timeout"
|
5
|
-
require "cgi"
|
6
5
|
require_relative "vendored_securerandom"
|
7
6
|
require "zlib"
|
8
7
|
|
@@ -73,19 +72,57 @@ module Bundler
|
|
73
72
|
end
|
74
73
|
end
|
75
74
|
|
75
|
+
HTTP_ERRORS = (Downloader::HTTP_RETRYABLE_ERRORS + Downloader::HTTP_NON_RETRYABLE_ERRORS).freeze
|
76
|
+
deprecate_constant :HTTP_ERRORS
|
77
|
+
|
78
|
+
NET_ERRORS = [
|
79
|
+
:HTTPBadGateway,
|
80
|
+
:HTTPBadRequest,
|
81
|
+
:HTTPFailedDependency,
|
82
|
+
:HTTPForbidden,
|
83
|
+
:HTTPInsufficientStorage,
|
84
|
+
:HTTPMethodNotAllowed,
|
85
|
+
:HTTPMovedPermanently,
|
86
|
+
:HTTPNoContent,
|
87
|
+
:HTTPNotFound,
|
88
|
+
:HTTPNotImplemented,
|
89
|
+
:HTTPPreconditionFailed,
|
90
|
+
:HTTPRequestEntityTooLarge,
|
91
|
+
:HTTPRequestURITooLong,
|
92
|
+
:HTTPUnauthorized,
|
93
|
+
:HTTPUnprocessableEntity,
|
94
|
+
:HTTPUnsupportedMediaType,
|
95
|
+
:HTTPVersionNotSupported,
|
96
|
+
].freeze
|
97
|
+
deprecate_constant :NET_ERRORS
|
98
|
+
|
76
99
|
# Exceptions classes that should bypass retry attempts. If your password didn't work the
|
77
100
|
# first time, it's not going to the third time.
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
101
|
+
FAIL_ERRORS = [
|
102
|
+
AuthenticationRequiredError,
|
103
|
+
BadAuthenticationError,
|
104
|
+
AuthenticationForbiddenError,
|
105
|
+
FallbackError,
|
106
|
+
SecurityError,
|
107
|
+
Gem::Requirement::BadRequirementError,
|
108
|
+
Gem::Net::HTTPBadGateway,
|
109
|
+
Gem::Net::HTTPBadRequest,
|
110
|
+
Gem::Net::HTTPFailedDependency,
|
111
|
+
Gem::Net::HTTPForbidden,
|
112
|
+
Gem::Net::HTTPInsufficientStorage,
|
113
|
+
Gem::Net::HTTPMethodNotAllowed,
|
114
|
+
Gem::Net::HTTPMovedPermanently,
|
115
|
+
Gem::Net::HTTPNoContent,
|
116
|
+
Gem::Net::HTTPNotFound,
|
117
|
+
Gem::Net::HTTPNotImplemented,
|
118
|
+
Gem::Net::HTTPPreconditionFailed,
|
119
|
+
Gem::Net::HTTPRequestEntityTooLarge,
|
120
|
+
Gem::Net::HTTPRequestURITooLong,
|
121
|
+
Gem::Net::HTTPUnauthorized,
|
122
|
+
Gem::Net::HTTPUnprocessableEntity,
|
123
|
+
Gem::Net::HTTPUnsupportedMediaType,
|
124
|
+
Gem::Net::HTTPVersionNotSupported,
|
125
|
+
].freeze
|
89
126
|
|
90
127
|
class << self
|
91
128
|
attr_accessor :disable_endpoint, :api_timeout, :redirect_limit, :max_retries
|
@@ -294,13 +331,6 @@ module Bundler
|
|
294
331
|
paths.find {|path| File.file? path }
|
295
332
|
end
|
296
333
|
|
297
|
-
HTTP_ERRORS = [
|
298
|
-
Gem::Timeout::Error, EOFError, SocketError, Errno::ENETDOWN, Errno::ENETUNREACH,
|
299
|
-
Errno::EINVAL, Errno::ECONNRESET, Errno::ETIMEDOUT, Errno::EAGAIN,
|
300
|
-
Gem::Net::HTTPBadResponse, Gem::Net::HTTPHeaderSyntaxError, Gem::Net::ProtocolError,
|
301
|
-
Gem::Net::HTTP::Persistent::Error, Zlib::BufError, Errno::EHOSTUNREACH
|
302
|
-
].freeze
|
303
|
-
|
304
334
|
def bundler_cert_store
|
305
335
|
store = OpenSSL::X509::Store.new
|
306
336
|
ssl_ca_cert = Bundler.settings[:ssl_ca_cert] ||
|
@@ -80,7 +80,7 @@ module Bundler
|
|
80
80
|
First, try this link to see if there are any existing issue reports for this error:
|
81
81
|
#{issues_url(e)}
|
82
82
|
|
83
|
-
If there aren't any reports for this error yet, please fill in the new issue form located at #{new_issue_url}
|
83
|
+
If there aren't any reports for this error yet, please fill in the new issue form located at #{new_issue_url}. Make sure to copy and paste the full output of this command under the "What happened instead?" section.
|
84
84
|
EOS
|
85
85
|
end
|
86
86
|
|
@@ -102,7 +102,8 @@ module Bundler
|
|
102
102
|
def issues_url(exception)
|
103
103
|
message = exception.message.lines.first.tr(":", " ").chomp
|
104
104
|
message = message.split("-").first if exception.is_a?(Errno)
|
105
|
-
require "cgi"
|
105
|
+
require "cgi/escape"
|
106
|
+
require "cgi/util" unless defined?(CGI::EscapeExt)
|
106
107
|
"https://github.com/rubygems/rubygems/search?q=" \
|
107
108
|
"#{CGI.escape(message)}&type=Issues"
|
108
109
|
end
|
data/lib/bundler/index.rb
CHANGED
@@ -131,6 +131,11 @@ module Bundler
|
|
131
131
|
return unless other
|
132
132
|
other.each do |spec|
|
133
133
|
if existing = find_by_spec(spec)
|
134
|
+
unless dependencies_eql?(existing, spec)
|
135
|
+
Bundler.ui.warn "Local specification for #{spec.full_name} has different dependencies than the remote gem, ignoring it"
|
136
|
+
next
|
137
|
+
end
|
138
|
+
|
134
139
|
add_duplicate(existing)
|
135
140
|
end
|
136
141
|
add spec
|
@@ -153,8 +158,8 @@ module Bundler
|
|
153
158
|
end
|
154
159
|
|
155
160
|
def dependencies_eql?(spec, other_spec)
|
156
|
-
deps = spec.
|
157
|
-
other_deps = other_spec.
|
161
|
+
deps = spec.runtime_dependencies
|
162
|
+
other_deps = other_spec.runtime_dependencies
|
158
163
|
deps.sort == other_deps.sort
|
159
164
|
end
|
160
165
|
|
data/lib/bundler/injector.rb
CHANGED
@@ -108,17 +108,17 @@ module Bundler
|
|
108
108
|
end
|
109
109
|
|
110
110
|
if d.groups != Array(:default)
|
111
|
-
group = d.groups.size == 1 ? ", :
|
111
|
+
group = d.groups.size == 1 ? ", group: #{d.groups.first.inspect}" : ", groups: #{d.groups.inspect}"
|
112
112
|
end
|
113
113
|
|
114
|
-
source = ", :
|
115
|
-
path = ", :
|
116
|
-
git = ", :
|
117
|
-
github = ", :
|
118
|
-
branch = ", :
|
119
|
-
ref = ", :
|
120
|
-
glob = ", :
|
121
|
-
require_path = ", :
|
114
|
+
source = ", source: \"#{d.source}\"" unless d.source.nil?
|
115
|
+
path = ", path: \"#{d.path}\"" unless d.path.nil?
|
116
|
+
git = ", git: \"#{d.git}\"" unless d.git.nil?
|
117
|
+
github = ", github: \"#{d.github}\"" unless d.github.nil?
|
118
|
+
branch = ", branch: \"#{d.branch}\"" unless d.branch.nil?
|
119
|
+
ref = ", ref: \"#{d.ref}\"" unless d.ref.nil?
|
120
|
+
glob = ", glob: \"#{d.glob}\"" unless d.glob.nil?
|
121
|
+
require_path = ", require: #{convert_autorequire(d.autorequire)}" unless d.autorequire.nil?
|
122
122
|
|
123
123
|
%(gem #{name}#{requirement}#{group}#{source}#{path}#{git}#{github}#{branch}#{ref}#{glob}#{require_path})
|
124
124
|
end.join("\n")
|
data/lib/bundler/installer.rb
CHANGED
@@ -91,6 +91,11 @@ module Bundler
|
|
91
91
|
end
|
92
92
|
|
93
93
|
def generate_bundler_executable_stubs(spec, options = {})
|
94
|
+
if spec.name == "bundler"
|
95
|
+
Bundler.ui.warn "Bundler itself does not use binstubs because its version is selected by RubyGems"
|
96
|
+
return
|
97
|
+
end
|
98
|
+
|
94
99
|
if options[:binstubs_cmd] && spec.executables.empty?
|
95
100
|
options = {}
|
96
101
|
spec.runtime_dependencies.each do |dep|
|
@@ -115,10 +120,6 @@ module Bundler
|
|
115
120
|
ruby_command = Thor::Util.ruby_command
|
116
121
|
ruby_command = ruby_command
|
117
122
|
template_path = File.expand_path("templates/Executable", __dir__)
|
118
|
-
if spec.name == "bundler"
|
119
|
-
template_path += ".bundler"
|
120
|
-
spec.executables = %(bundle)
|
121
|
-
end
|
122
123
|
template = File.read(template_path)
|
123
124
|
|
124
125
|
exists = []
|
@@ -212,7 +213,7 @@ module Bundler
|
|
212
213
|
def load_plugins
|
213
214
|
Gem.load_plugins
|
214
215
|
|
215
|
-
requested_path_gems = @definition.
|
216
|
+
requested_path_gems = @definition.specs.select {|s| s.source.is_a?(Source::Path) }
|
216
217
|
path_plugin_files = requested_path_gems.flat_map do |spec|
|
217
218
|
spec.matches_for_glob("rubygems_plugin#{Bundler.rubygems.suffix_pattern}")
|
218
219
|
rescue TypeError
|
@@ -33,7 +33,7 @@ module Bundler
|
|
33
33
|
lazy_spec
|
34
34
|
end
|
35
35
|
|
36
|
-
def initialize(name, version, platform, source = nil)
|
36
|
+
def initialize(name, version, platform, source = nil, **materialization_options)
|
37
37
|
@name = name
|
38
38
|
@version = version
|
39
39
|
@dependencies = []
|
@@ -43,6 +43,7 @@ module Bundler
|
|
43
43
|
|
44
44
|
@original_source = source
|
45
45
|
@source = source
|
46
|
+
@materialization_options = materialization_options
|
46
47
|
|
47
48
|
@force_ruby_platform = default_force_ruby_platform
|
48
49
|
@most_specific_locked_platform = nil
|
@@ -142,15 +143,15 @@ module Bundler
|
|
142
143
|
end
|
143
144
|
else
|
144
145
|
materialize([name, version]) do |matching_specs|
|
145
|
-
target_platform = source.is_a?(Source::Path) ? platform : local_platform
|
146
|
+
target_platform = source.is_a?(Source::Path) ? platform : Bundler.local_platform
|
146
147
|
|
147
|
-
installable_candidates =
|
148
|
+
installable_candidates = MatchPlatform.select_best_platform_match(matching_specs, target_platform)
|
148
149
|
|
149
150
|
specification = choose_compatible(installable_candidates, fallback_to_non_installable: false)
|
150
151
|
return specification unless specification.nil?
|
151
152
|
|
152
153
|
if target_platform != platform
|
153
|
-
installable_candidates =
|
154
|
+
installable_candidates = MatchPlatform.select_best_platform_match(matching_specs, platform)
|
154
155
|
end
|
155
156
|
|
156
157
|
choose_compatible(installable_candidates)
|
@@ -175,6 +176,14 @@ module Bundler
|
|
175
176
|
@force_ruby_platform = true
|
176
177
|
end
|
177
178
|
|
179
|
+
def replace_source_with!(gemfile_source)
|
180
|
+
return unless gemfile_source.can_lock?(self)
|
181
|
+
|
182
|
+
@source = gemfile_source
|
183
|
+
|
184
|
+
true
|
185
|
+
end
|
186
|
+
|
178
187
|
private
|
179
188
|
|
180
189
|
def use_exact_resolved_specifications?
|
@@ -182,7 +191,7 @@ module Bundler
|
|
182
191
|
end
|
183
192
|
|
184
193
|
def ruby_platform_materializes_to_ruby_platform?
|
185
|
-
generic_platform = generic_local_platform == Gem::Platform::JAVA ? Gem::Platform::JAVA : Gem::Platform::RUBY
|
194
|
+
generic_platform = Bundler.generic_local_platform == Gem::Platform::JAVA ? Gem::Platform::JAVA : Gem::Platform::RUBY
|
186
195
|
|
187
196
|
(most_specific_locked_platform != generic_platform) || force_ruby_platform || Bundler.settings[:force_ruby_platform]
|
188
197
|
end
|
@@ -196,7 +205,7 @@ module Bundler
|
|
196
205
|
|
197
206
|
# If in frozen mode, we fallback to a non-installable candidate because by
|
198
207
|
# doing this we avoid re-resolving and potentially end up changing the
|
199
|
-
#
|
208
|
+
# lockfile, which is not allowed. In that case, we will give a proper error
|
200
209
|
# about the mismatch higher up the stack, right before trying to install the
|
201
210
|
# bad gem.
|
202
211
|
def choose_compatible(candidates, fallback_to_non_installable: Bundler.frozen_bundle?)
|
@@ -205,22 +214,32 @@ module Bundler
|
|
205
214
|
end
|
206
215
|
if search.nil? && fallback_to_non_installable
|
207
216
|
search = candidates.last
|
208
|
-
|
209
|
-
# We don't validate locally installed dependencies but accept what's in
|
210
|
-
# the lockfile instead for performance, since loading locally installed
|
211
|
-
# dependencies would mean evaluating all gemspecs, which would affect
|
212
|
-
# `bundler/setup` performance
|
213
|
-
if search.is_a?(StubSpecification)
|
214
|
-
search.dependencies = dependencies
|
215
|
-
else
|
216
|
-
if !source.is_a?(Source::Path) && search.runtime_dependencies.sort != dependencies.sort
|
217
|
-
raise IncorrectLockfileDependencies.new(self)
|
218
|
-
end
|
217
|
+
end
|
219
218
|
|
220
|
-
|
221
|
-
|
219
|
+
if search
|
220
|
+
validate_dependencies(search) if search.platform == platform
|
221
|
+
|
222
|
+
search.locked_platform = platform if search.instance_of?(RemoteSpecification) || search.instance_of?(EndpointSpecification)
|
222
223
|
end
|
223
224
|
search
|
224
225
|
end
|
226
|
+
|
227
|
+
# Validate dependencies of this locked spec are consistent with dependencies
|
228
|
+
# of the actual spec that was materialized.
|
229
|
+
#
|
230
|
+
# Note that unless we are in strict mode (which we set during installation)
|
231
|
+
# we don't validate dependencies of locally installed gems but
|
232
|
+
# accept what's in the lockfile instead for performance, since loading
|
233
|
+
# dependencies of locally installed gems would mean evaluating all gemspecs,
|
234
|
+
# which would affect `bundler/setup` performance.
|
235
|
+
def validate_dependencies(spec)
|
236
|
+
if !@materialization_options[:strict] && spec.is_a?(StubSpecification)
|
237
|
+
spec.dependencies = dependencies
|
238
|
+
else
|
239
|
+
if !source.is_a?(Source::Path) && spec.runtime_dependencies.sort != dependencies.sort
|
240
|
+
raise IncorrectLockfileDependencies.new(self)
|
241
|
+
end
|
242
|
+
end
|
243
|
+
end
|
225
244
|
end
|
226
245
|
end
|
@@ -1,9 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative "shared_helpers"
|
4
|
+
|
3
5
|
module Bundler
|
4
6
|
class LockfileParser
|
5
|
-
include GemHelpers
|
6
|
-
|
7
7
|
class Position
|
8
8
|
attr_reader :line, :column
|
9
9
|
def initialize(line, column)
|
@@ -94,7 +94,7 @@ module Bundler
|
|
94
94
|
lockfile_contents.split(BUNDLED).last.strip
|
95
95
|
end
|
96
96
|
|
97
|
-
def initialize(lockfile)
|
97
|
+
def initialize(lockfile, strict: false)
|
98
98
|
@platforms = []
|
99
99
|
@sources = []
|
100
100
|
@dependencies = {}
|
@@ -106,6 +106,7 @@ module Bundler
|
|
106
106
|
"Gemfile.lock"
|
107
107
|
end
|
108
108
|
@pos = Position.new(1, 1)
|
109
|
+
@strict = strict
|
109
110
|
|
110
111
|
if lockfile.match?(/<<<<<<<|=======|>>>>>>>|\|\|\|\|\|\|\|/)
|
111
112
|
raise LockfileError, "Your #{@lockfile_path} contains merge conflicts.\n" \
|
@@ -139,8 +140,23 @@ module Bundler
|
|
139
140
|
end
|
140
141
|
@pos.advance!(line)
|
141
142
|
end
|
143
|
+
|
144
|
+
if !Bundler.frozen_bundle? && @platforms.include?(Gem::Platform::X64_MINGW_LEGACY)
|
145
|
+
if @platforms.include?(Gem::Platform::X64_MINGW)
|
146
|
+
@platforms.delete(Gem::Platform::X64_MINGW_LEGACY)
|
147
|
+
SharedHelpers.major_deprecation(2,
|
148
|
+
"Found x64-mingw32 in lockfile, which is deprecated. Removing it. Support for x64-mingw32 will be removed in Bundler 4.0.",
|
149
|
+
removed_message: "Found x64-mingw32 in lockfile, which is no longer supported as of Bundler 4.0.")
|
150
|
+
else
|
151
|
+
@platforms[@platforms.index(Gem::Platform::X64_MINGW_LEGACY)] = Gem::Platform::X64_MINGW
|
152
|
+
SharedHelpers.major_deprecation(2,
|
153
|
+
"Found x64-mingw32 in lockfile, which is deprecated. Using x64-mingw-ucrt, the replacement for x64-mingw32 in modern rubies, instead. Support for x64-mingw32 will be removed in Bundler 4.0.",
|
154
|
+
removed_message: "Found x64-mingw32 in lockfile, which is no longer supported as of Bundler 4.0.")
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
142
158
|
@most_specific_locked_platform = @platforms.min_by do |bundle_platform|
|
143
|
-
platform_specificity_match(bundle_platform, local_platform)
|
159
|
+
Gem::Platform.platform_specificity_match(bundle_platform, Bundler.local_platform)
|
144
160
|
end
|
145
161
|
@specs = @specs.values.sort_by!(&:full_name).each do |spec|
|
146
162
|
spec.most_specific_locked_platform = @most_specific_locked_platform
|
@@ -239,7 +255,6 @@ module Bundler
|
|
239
255
|
spaces = $1
|
240
256
|
return unless spaces.size == 2
|
241
257
|
checksums = $6
|
242
|
-
return unless checksums
|
243
258
|
name = $2
|
244
259
|
version = $3
|
245
260
|
platform = $4
|
@@ -249,10 +264,14 @@ module Bundler
|
|
249
264
|
full_name = Gem::NameTuple.new(name, version, platform).full_name
|
250
265
|
return unless spec = @specs[full_name]
|
251
266
|
|
252
|
-
checksums
|
253
|
-
|
254
|
-
|
255
|
-
|
267
|
+
if checksums
|
268
|
+
checksums.split(",") do |lock_checksum|
|
269
|
+
column = line.index(lock_checksum) + 1
|
270
|
+
checksum = Checksum.from_lock(lock_checksum, "#{@lockfile_path}:#{@pos.line}:#{column}")
|
271
|
+
spec.source.checksum_store.register(spec, checksum)
|
272
|
+
end
|
273
|
+
else
|
274
|
+
spec.source.checksum_store.register(spec, nil)
|
256
275
|
end
|
257
276
|
end
|
258
277
|
|
@@ -268,7 +287,7 @@ module Bundler
|
|
268
287
|
|
269
288
|
version = Gem::Version.new(version)
|
270
289
|
platform = platform ? Gem::Platform.new(platform) : Gem::Platform::RUBY
|
271
|
-
@current_spec = LazySpecification.new(name, version, platform, @current_source)
|
290
|
+
@current_spec = LazySpecification.new(name, version, platform, @current_source, strict: @strict)
|
272
291
|
@current_source.add_dependency_names(name)
|
273
292
|
|
274
293
|
@specs[@current_spec.full_name] = @current_spec
|