bundler 4.0.11 → 4.0.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +32 -0
- data/lib/bundler/build_metadata.rb +1 -1
- data/lib/bundler/cli/add.rb +3 -0
- data/lib/bundler/cli/common.rb +6 -0
- data/lib/bundler/cli/config.rb +8 -3
- data/lib/bundler/cli/install.rb +3 -0
- data/lib/bundler/cli/outdated.rb +42 -2
- data/lib/bundler/cli/update.rb +2 -0
- data/lib/bundler/cli.rb +16 -12
- data/lib/bundler/compact_index_client/parser.rb +4 -1
- data/lib/bundler/definition.rb +26 -4
- data/lib/bundler/dsl.rb +6 -2
- data/lib/bundler/endpoint_specification.rb +11 -1
- data/lib/bundler/installer.rb +5 -0
- data/lib/bundler/lockfile_parser.rb +15 -0
- data/lib/bundler/man/bundle-add.1 +4 -1
- data/lib/bundler/man/bundle-add.1.ronn +6 -1
- data/lib/bundler/man/bundle-config.1 +120 -156
- data/lib/bundler/man/bundle-config.1.ronn +30 -0
- data/lib/bundler/man/bundle-install.1 +4 -1
- data/lib/bundler/man/bundle-install.1.ronn +9 -1
- data/lib/bundler/man/bundle-outdated.1 +16 -13
- data/lib/bundler/man/bundle-outdated.1.ronn +19 -12
- data/lib/bundler/man/bundle-update.1 +4 -1
- data/lib/bundler/man/bundle-update.1.ronn +8 -0
- data/lib/bundler/remote_specification.rb +1 -1
- data/lib/bundler/resolver.rb +42 -1
- data/lib/bundler/rubygems_ext.rb +22 -0
- data/lib/bundler/rubygems_gem_installer.rb +1 -1
- data/lib/bundler/settings.rb +1 -0
- data/lib/bundler/source/git/git_proxy.rb +7 -2
- data/lib/bundler/source/path.rb +3 -2
- data/lib/bundler/source/rubygems/remote.rb +12 -2
- data/lib/bundler/source/rubygems.rb +51 -3
- data/lib/bundler/source_list.rb +6 -2
- data/lib/bundler/version.rb +1 -1
- data/lib/bundler.rb +10 -0
- metadata +2 -2
data/lib/bundler/resolver.rb
CHANGED
|
@@ -184,6 +184,9 @@ module Bundler
|
|
|
184
184
|
|
|
185
185
|
platforms_explanation = specs_matching_other_platforms.any? ? " for any resolution platforms (#{package.platforms.join(", ")})" : ""
|
|
186
186
|
custom_explanation = "#{constraint} could not be found in #{repository_for(package)}#{platforms_explanation}"
|
|
187
|
+
if hint = cooldown_hint(specs_matching_other_platforms)
|
|
188
|
+
custom_explanation += " (#{hint})"
|
|
189
|
+
end
|
|
187
190
|
|
|
188
191
|
label = "#{name} (#{constraint_string})"
|
|
189
192
|
extended_explanation = other_specs_matching_message(specs_matching_other_platforms, label) if specs_matching_other_platforms.any?
|
|
@@ -353,6 +356,10 @@ module Bundler
|
|
|
353
356
|
message << "\n#{other_specs_matching_message(specs, matching_part)}"
|
|
354
357
|
end
|
|
355
358
|
|
|
359
|
+
if hint = cooldown_hint(specs_matching_requirement)
|
|
360
|
+
message << "\n\n#{hint}."
|
|
361
|
+
end
|
|
362
|
+
|
|
356
363
|
if specs_matching_requirement.any? && (hint = platform_mismatch_hint)
|
|
357
364
|
message << "\n\n#{hint}"
|
|
358
365
|
end
|
|
@@ -396,7 +403,7 @@ module Bundler
|
|
|
396
403
|
end
|
|
397
404
|
|
|
398
405
|
def filter_specs(specs, package)
|
|
399
|
-
filter_remote_specs(filter_prereleases(specs, package), package)
|
|
406
|
+
filter_remote_specs(filter_cooldown(filter_prereleases(specs, package)), package)
|
|
400
407
|
end
|
|
401
408
|
|
|
402
409
|
def filter_prereleases(specs, package)
|
|
@@ -405,6 +412,40 @@ module Bundler
|
|
|
405
412
|
specs.reject {|s| s.version.prerelease? }
|
|
406
413
|
end
|
|
407
414
|
|
|
415
|
+
def filter_cooldown(specs)
|
|
416
|
+
return specs if specs.empty?
|
|
417
|
+
excluded_versions = cooldown_excluded_versions(specs)
|
|
418
|
+
return specs if excluded_versions.empty?
|
|
419
|
+
specs.reject {|s| excluded_versions.include?([s.name, s.version]) }
|
|
420
|
+
end
|
|
421
|
+
|
|
422
|
+
def cooldown_excluded_versions(specs)
|
|
423
|
+
excluded = {}
|
|
424
|
+
specs.each do |spec|
|
|
425
|
+
next unless cooldown_excluded?(spec)
|
|
426
|
+
excluded[[spec.name, spec.version]] = true
|
|
427
|
+
end
|
|
428
|
+
excluded
|
|
429
|
+
end
|
|
430
|
+
|
|
431
|
+
def cooldown_hint(specs)
|
|
432
|
+
excluded_versions = cooldown_excluded_versions(specs)
|
|
433
|
+
return nil if excluded_versions.empty?
|
|
434
|
+
"#{excluded_versions.size} version#{"s" if excluded_versions.size > 1} excluded by the cooldown setting; pass `--cooldown 0` to bypass"
|
|
435
|
+
end
|
|
436
|
+
|
|
437
|
+
def cooldown_excluded?(spec)
|
|
438
|
+
return false unless spec.respond_to?(:created_at) && spec.created_at
|
|
439
|
+
return false unless spec.respond_to?(:remote) && spec.remote
|
|
440
|
+
days = spec.remote.effective_cooldown
|
|
441
|
+
return false if days.nil? || days <= 0
|
|
442
|
+
(cooldown_now - spec.created_at) < (days * 86_400)
|
|
443
|
+
end
|
|
444
|
+
|
|
445
|
+
def cooldown_now
|
|
446
|
+
@cooldown_now ||= Time.now
|
|
447
|
+
end
|
|
448
|
+
|
|
408
449
|
def filter_remote_specs(specs, package)
|
|
409
450
|
if package.prefer_local?
|
|
410
451
|
local_specs = specs.select {|s| s.is_a?(StubSpecification) }
|
data/lib/bundler/rubygems_ext.rb
CHANGED
|
@@ -465,6 +465,28 @@ module Gem
|
|
|
465
465
|
Resolver::APISet::GemParser.prepend(UnfreezeCompactIndexParsedResponse)
|
|
466
466
|
end
|
|
467
467
|
|
|
468
|
+
# RubyGems before 4.0.13 split compact index dependency/requirement entries
|
|
469
|
+
# on every colon, which mangles metadata values that contain colons such as
|
|
470
|
+
# the `created_at` timestamps the cooldown feature relies on. Split only on
|
|
471
|
+
# the first colon so those values survive on older RubyGems.
|
|
472
|
+
#
|
|
473
|
+
# The module is defined unconditionally so it stays testable on any RubyGems,
|
|
474
|
+
# but only prepended when the host RubyGems still has the buggy behavior.
|
|
475
|
+
module SplitCompactIndexEntryOnFirstColon
|
|
476
|
+
private
|
|
477
|
+
|
|
478
|
+
def parse_dependency(string)
|
|
479
|
+
dependency = string.split(":", 2)
|
|
480
|
+
dependency[-1] = dependency[-1].split("&") if dependency.size > 1
|
|
481
|
+
dependency[0] = -dependency[0]
|
|
482
|
+
dependency
|
|
483
|
+
end
|
|
484
|
+
end
|
|
485
|
+
|
|
486
|
+
unless Gem.rubygems_version >= Gem::Version.new("4.0.13")
|
|
487
|
+
Resolver::APISet::GemParser.prepend(SplitCompactIndexEntryOnFirstColon)
|
|
488
|
+
end
|
|
489
|
+
|
|
468
490
|
if Gem.rubygems_version < Gem::Version.new("3.6.0")
|
|
469
491
|
class Package; end
|
|
470
492
|
require "rubygems/package/tar_reader"
|
data/lib/bundler/settings.rb
CHANGED
|
@@ -432,9 +432,14 @@ module Bundler
|
|
|
432
432
|
end
|
|
433
433
|
|
|
434
434
|
def capture3_args_for(cmd, dir)
|
|
435
|
-
|
|
435
|
+
# Disable automatic maintenance so a background commit-graph write in
|
|
436
|
+
# the source repo can't race the hardlinking local clone and fail with
|
|
437
|
+
# "hardlink different from source".
|
|
438
|
+
opts = ["-c", "gc.auto=0", "-c", "maintenance.auto=false"]
|
|
436
439
|
|
|
437
|
-
["git",
|
|
440
|
+
return ["git", *opts, *cmd] unless dir
|
|
441
|
+
|
|
442
|
+
["git", "-C", dir.to_s, *opts, *cmd]
|
|
438
443
|
end
|
|
439
444
|
|
|
440
445
|
def extra_clone_args
|
data/lib/bundler/source/path.rb
CHANGED
|
@@ -220,10 +220,11 @@ module Bundler
|
|
|
220
220
|
# Some gem authors put absolute paths in their gemspec
|
|
221
221
|
# and we have to save them from themselves
|
|
222
222
|
spec.files = spec.files.filter_map do |path|
|
|
223
|
-
|
|
223
|
+
pathname = Pathname.new(path)
|
|
224
|
+
next path unless pathname.absolute?
|
|
224
225
|
next if File.directory?(path)
|
|
225
226
|
begin
|
|
226
|
-
|
|
227
|
+
pathname.relative_path_from(gem_dir).to_s
|
|
227
228
|
rescue ArgumentError
|
|
228
229
|
path
|
|
229
230
|
end
|
|
@@ -4,9 +4,9 @@ module Bundler
|
|
|
4
4
|
class Source
|
|
5
5
|
class Rubygems
|
|
6
6
|
class Remote
|
|
7
|
-
attr_reader :uri, :anonymized_uri, :original_uri
|
|
7
|
+
attr_reader :uri, :anonymized_uri, :original_uri, :cooldown
|
|
8
8
|
|
|
9
|
-
def initialize(uri)
|
|
9
|
+
def initialize(uri, cooldown: nil)
|
|
10
10
|
orig_uri = uri
|
|
11
11
|
uri = Bundler.settings.mirror_for(uri)
|
|
12
12
|
@original_uri = orig_uri if orig_uri != uri
|
|
@@ -14,6 +14,16 @@ module Bundler
|
|
|
14
14
|
|
|
15
15
|
@uri = apply_auth(uri, fallback_auth).freeze
|
|
16
16
|
@anonymized_uri = remove_auth(@uri).freeze
|
|
17
|
+
@cooldown = cooldown
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Returns the cooldown days that apply to this remote, resolving the
|
|
21
|
+
# precedence CLI > config > Gemfile per-source. Returns nil if no
|
|
22
|
+
# cooldown applies.
|
|
23
|
+
def effective_cooldown
|
|
24
|
+
override = Bundler.settings[:cooldown]
|
|
25
|
+
return override if override
|
|
26
|
+
@cooldown
|
|
17
27
|
end
|
|
18
28
|
|
|
19
29
|
MAX_CACHE_SLUG_HOST_SIZE = 255 - 1 - 32 # 255 minus dot minus MD5 length
|
|
@@ -16,6 +16,7 @@ module Bundler
|
|
|
16
16
|
def initialize(options = {})
|
|
17
17
|
@options = options
|
|
18
18
|
@remotes = []
|
|
19
|
+
@remote_cooldowns = {}
|
|
19
20
|
@dependency_names = []
|
|
20
21
|
@allow_remote = false
|
|
21
22
|
@allow_cached = false
|
|
@@ -25,7 +26,8 @@ module Bundler
|
|
|
25
26
|
@gem_installers = {}
|
|
26
27
|
@gem_installers_mutex = Mutex.new
|
|
27
28
|
|
|
28
|
-
|
|
29
|
+
cooldown = options["cooldown"]
|
|
30
|
+
Array(options["remotes"]).reverse_each {|r| add_remote(r, cooldown: cooldown) }
|
|
29
31
|
|
|
30
32
|
@lockfile_remotes = @remotes if options["from_lockfile"]
|
|
31
33
|
end
|
|
@@ -148,6 +150,13 @@ module Bundler
|
|
|
148
150
|
# sources, and large_idx.merge! small_idx is way faster than
|
|
149
151
|
# small_idx.merge! large_idx.
|
|
150
152
|
index = @allow_remote ? remote_specs.dup : Index.new
|
|
153
|
+
|
|
154
|
+
# Snapshot per-version `created_at` from the remote info before installed
|
|
155
|
+
# / cached specs overwrite the EndpointSpecification objects that carry
|
|
156
|
+
# it. The cooldown filter consults `created_at` on every candidate, so
|
|
157
|
+
# local stubs need the published date back-filled to participate.
|
|
158
|
+
remote_created_at = collect_remote_created_at(index)
|
|
159
|
+
|
|
151
160
|
index.merge!(cached_specs) if @allow_cached
|
|
152
161
|
index.merge!(installed_specs) if @allow_local
|
|
153
162
|
|
|
@@ -161,6 +170,8 @@ module Bundler
|
|
|
161
170
|
end
|
|
162
171
|
end
|
|
163
172
|
|
|
173
|
+
backfill_created_at(index, remote_created_at) unless remote_created_at.empty?
|
|
174
|
+
|
|
164
175
|
index
|
|
165
176
|
end
|
|
166
177
|
end
|
|
@@ -243,9 +254,14 @@ module Bundler
|
|
|
243
254
|
cached_path
|
|
244
255
|
end
|
|
245
256
|
|
|
246
|
-
def add_remote(source)
|
|
257
|
+
def add_remote(source, cooldown: nil)
|
|
247
258
|
uri = normalize_uri(source)
|
|
248
259
|
@remotes.unshift(uri) unless @remotes.include?(uri)
|
|
260
|
+
@remote_cooldowns[uri] = cooldown if cooldown
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
def cooldown_for(uri)
|
|
264
|
+
@remote_cooldowns[uri]
|
|
249
265
|
end
|
|
250
266
|
|
|
251
267
|
def spec_names
|
|
@@ -266,7 +282,7 @@ module Bundler
|
|
|
266
282
|
|
|
267
283
|
def remote_fetchers
|
|
268
284
|
@remote_fetchers ||= remotes.to_h do |uri|
|
|
269
|
-
remote = Source::Rubygems::Remote.new(uri)
|
|
285
|
+
remote = Source::Rubygems::Remote.new(uri, cooldown: cooldown_for(uri))
|
|
270
286
|
[remote, Bundler::Fetcher.new(remote)]
|
|
271
287
|
end.freeze
|
|
272
288
|
end
|
|
@@ -314,6 +330,13 @@ module Bundler
|
|
|
314
330
|
@allow_remote && api_fetchers.any?
|
|
315
331
|
end
|
|
316
332
|
|
|
333
|
+
def clear_cache
|
|
334
|
+
@specs = nil
|
|
335
|
+
@installed_specs = nil
|
|
336
|
+
@default_specs = nil
|
|
337
|
+
@cached_specs = nil
|
|
338
|
+
end
|
|
339
|
+
|
|
317
340
|
protected
|
|
318
341
|
|
|
319
342
|
def remote_names
|
|
@@ -456,6 +479,31 @@ module Bundler
|
|
|
456
479
|
|
|
457
480
|
private
|
|
458
481
|
|
|
482
|
+
def collect_remote_created_at(index)
|
|
483
|
+
return {} unless @allow_remote
|
|
484
|
+
|
|
485
|
+
snapshot = {}
|
|
486
|
+
index.each do |spec|
|
|
487
|
+
next unless spec.respond_to?(:created_at) && spec.created_at
|
|
488
|
+
# Remember the remote that supplied the date too: when a source has
|
|
489
|
+
# several remotes with different per-URI cooldown settings we must
|
|
490
|
+
# restore the same one during backfill so `effective_cooldown` agrees.
|
|
491
|
+
snapshot[[spec.name, spec.version]] = [spec.created_at, spec.remote]
|
|
492
|
+
end
|
|
493
|
+
snapshot
|
|
494
|
+
end
|
|
495
|
+
|
|
496
|
+
def backfill_created_at(index, snapshot)
|
|
497
|
+
index.each do |spec|
|
|
498
|
+
next unless spec.respond_to?(:created_at=)
|
|
499
|
+
next if spec.created_at
|
|
500
|
+
remote_created_at, remote = snapshot[[spec.name, spec.version]]
|
|
501
|
+
next unless remote_created_at
|
|
502
|
+
spec.created_at = remote_created_at
|
|
503
|
+
spec.remote ||= remote if remote && spec.respond_to?(:remote=)
|
|
504
|
+
end
|
|
505
|
+
end
|
|
506
|
+
|
|
459
507
|
def lockfile_remotes
|
|
460
508
|
@lockfile_remotes || credless_remotes
|
|
461
509
|
end
|
data/lib/bundler/source_list.rb
CHANGED
|
@@ -59,8 +59,8 @@ module Bundler
|
|
|
59
59
|
add_source_to_list Plugin.source(source).new(options), @plugin_sources
|
|
60
60
|
end
|
|
61
61
|
|
|
62
|
-
def add_global_rubygems_remote(uri)
|
|
63
|
-
global_rubygems_source.add_remote(uri)
|
|
62
|
+
def add_global_rubygems_remote(uri, cooldown: nil)
|
|
63
|
+
global_rubygems_source.add_remote(uri, cooldown: cooldown)
|
|
64
64
|
global_rubygems_source
|
|
65
65
|
end
|
|
66
66
|
|
|
@@ -136,6 +136,10 @@ module Bundler
|
|
|
136
136
|
all_sources.each(&:remote!)
|
|
137
137
|
end
|
|
138
138
|
|
|
139
|
+
def clear_cache
|
|
140
|
+
rubygems_sources.each(&:clear_cache)
|
|
141
|
+
end
|
|
142
|
+
|
|
139
143
|
private
|
|
140
144
|
|
|
141
145
|
def map_sources(replacement_sources)
|
data/lib/bundler/version.rb
CHANGED
data/lib/bundler.rb
CHANGED
|
@@ -156,6 +156,7 @@ module Bundler
|
|
|
156
156
|
# Return if all groups are already loaded
|
|
157
157
|
return @setup if defined?(@setup) && @setup
|
|
158
158
|
|
|
159
|
+
configure_custom_gemfile
|
|
159
160
|
definition.validate_runtime!
|
|
160
161
|
|
|
161
162
|
SharedHelpers.print_major_deprecations!
|
|
@@ -586,6 +587,15 @@ module Bundler
|
|
|
586
587
|
Bundler.rubygems.clear_paths
|
|
587
588
|
end
|
|
588
589
|
|
|
590
|
+
def configure_custom_gemfile(custom_gemfile = nil)
|
|
591
|
+
custom_gemfile ||= Bundler.settings[:gemfile]
|
|
592
|
+
|
|
593
|
+
if custom_gemfile && !custom_gemfile.empty?
|
|
594
|
+
Bundler::SharedHelpers.set_env "BUNDLE_GEMFILE", File.expand_path(custom_gemfile)
|
|
595
|
+
reset_settings_and_root!
|
|
596
|
+
end
|
|
597
|
+
end
|
|
598
|
+
|
|
589
599
|
def self_manager
|
|
590
600
|
@self_manager ||= begin
|
|
591
601
|
require_relative "bundler/self_manager"
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: bundler
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 4.0.
|
|
4
|
+
version: 4.0.13
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- André Arko
|
|
@@ -402,7 +402,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
402
402
|
- !ruby/object:Gem::Version
|
|
403
403
|
version: 3.4.1
|
|
404
404
|
requirements: []
|
|
405
|
-
rubygems_version: 4.0.
|
|
405
|
+
rubygems_version: 4.0.10
|
|
406
406
|
specification_version: 4
|
|
407
407
|
summary: The best way to manage your application's dependencies
|
|
408
408
|
test_files: []
|