bundler 4.1.0.beta1 → 4.1.0.beta3
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/lib/bundler/build_metadata.rb +2 -2
- data/lib/bundler/cli/common.rb +4 -0
- data/lib/bundler/cli/doctor/ssl.rb +4 -8
- data/lib/bundler/cli/info.rb +1 -1
- data/lib/bundler/cli/lock.rb +19 -4
- data/lib/bundler/cli/open.rb +7 -1
- data/lib/bundler/cli/outdated.rb +8 -10
- data/lib/bundler/cli/platform.rb +15 -1
- data/lib/bundler/cli/show.rb +5 -1
- data/lib/bundler/cli/update.rb +1 -1
- data/lib/bundler/cli.rb +22 -7
- data/lib/bundler/constants.rb +1 -1
- data/lib/bundler/definition.rb +102 -16
- data/lib/bundler/dsl.rb +76 -5
- data/lib/bundler/fetcher/downloader.rb +14 -4
- data/lib/bundler/fetcher.rb +4 -1
- data/lib/bundler/gem_helper.rb +1 -1
- data/lib/bundler/installer/parallel_installer.rb +2 -1
- data/lib/bundler/installer.rb +5 -1
- data/lib/bundler/lazy_specification.rb +1 -1
- data/lib/bundler/lockfile_generator.rb +6 -0
- data/lib/bundler/lockfile_parser.rb +18 -2
- data/lib/bundler/man/bundle-info.1 +4 -1
- data/lib/bundler/man/bundle-info.1.ronn +4 -0
- data/lib/bundler/man/bundle-lock.1 +2 -2
- data/lib/bundler/man/bundle-lock.1.ronn +4 -3
- data/lib/bundler/man/bundle-open.1 +4 -1
- data/lib/bundler/man/bundle-open.1.ronn +4 -1
- data/lib/bundler/man/bundle-outdated.1 +1 -1
- data/lib/bundler/man/bundle-outdated.1.ronn +1 -1
- data/lib/bundler/man/bundle-show.1 +4 -1
- data/lib/bundler/man/bundle-show.1.ronn +4 -0
- data/lib/bundler/man/bundle-update.1 +3 -3
- data/lib/bundler/man/bundle-update.1.ronn +5 -3
- data/lib/bundler/man/gemfile.5 +43 -2
- data/lib/bundler/man/gemfile.5.ronn +69 -4
- data/lib/bundler/match_platform.rb +12 -3
- data/lib/bundler/materialization.rb +3 -1
- data/lib/bundler/override.rb +83 -2
- data/lib/bundler/resolver.rb +28 -4
- data/lib/bundler/rubygems_ext.rb +15 -4
- data/lib/bundler/self_manager.rb +15 -9
- data/lib/bundler/settings.rb +10 -26
- data/lib/bundler/source/git/git_proxy.rb +39 -2
- data/lib/bundler/source/git.rb +34 -7
- data/lib/bundler/source/rubygems.rb +2 -2
- data/lib/bundler/source/rubygems_aggregate.rb +1 -1
- data/lib/bundler/source_map.rb +7 -3
- data/lib/bundler/spec_set.rb +8 -4
- data/lib/bundler/templates/newgem/ext/newgem/Cargo.toml.tt +1 -1
- data/lib/bundler/vendor/fileutils/lib/fileutils.rb +54 -29
- data/lib/bundler/version.rb +1 -1
- data/lib/bundler.rb +1 -3
- data/lib/rubygems/compact_index_client/http_fetcher.rb +5 -3
- data/lib/rubygems/compact_index_client/parser.rb +1 -0
- data/lib/rubygems/vendor/uri/lib/uri/common.rb +1 -1
- data/lib/rubygems/vendor/uri/lib/uri/generic.rb +15 -3
- data/lib/rubygems/vendor/uri/lib/uri/version.rb +1 -1
- data/lib/rubygems/yaml_serializer.rb +131 -103
- metadata +391 -390
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6be81cd8812d25bec243ccd7e0ebf5c5ca61ff4dbfa3cc312ee38dd5f4199576
|
|
4
|
+
data.tar.gz: 44ff77dfafe81511dd56a2c7eb508ecccfcfffca1985aab4a048adeaf063f061
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9b8ed99236c76ef3e8c24778dfd06f7c35bb13700b22fab1f025996c712f50517e011323f0bf25066a919b5d5b4c4e685c229227a1210e30134fa8aa259b7d66
|
|
7
|
+
data.tar.gz: 4291294d5cee7e331dc8b6626908fa7aeff05bce9379ab59b97a3e0552aaa6c8fb136113151db97105f9e527a541ff1362a5bf14077dd136ed455d46b18d2759
|
|
@@ -4,8 +4,8 @@ module Bundler
|
|
|
4
4
|
# Represents metadata from when the Bundler gem was built.
|
|
5
5
|
module BuildMetadata
|
|
6
6
|
# begin ivars
|
|
7
|
-
@built_at = "2026-
|
|
8
|
-
@git_commit_sha = "
|
|
7
|
+
@built_at = "2026-10-28".freeze
|
|
8
|
+
@git_commit_sha = "cd7536a".freeze
|
|
9
9
|
# end ivars
|
|
10
10
|
|
|
11
11
|
# A hash representation of the build metadata.
|
data/lib/bundler/cli/common.rb
CHANGED
|
@@ -122,6 +122,10 @@ module Bundler
|
|
|
122
122
|
raise GemNotFound, gem_not_found_message(name, Bundler.definition.dependencies)
|
|
123
123
|
end
|
|
124
124
|
|
|
125
|
+
def self.select_spec_with_match_type(name, options)
|
|
126
|
+
select_spec(name, options["exact-match"] ? nil : :regex_match)
|
|
127
|
+
end
|
|
128
|
+
|
|
125
129
|
def self.default_gem_spec(name)
|
|
126
130
|
gem_spec = Gem::Specification.find_all_by_name(name).last
|
|
127
131
|
gem_spec if gem_spec&.default_gem?
|
|
@@ -124,14 +124,10 @@ module Bundler
|
|
|
124
124
|
ctx = OpenSSL::SSL::SSLContext.new
|
|
125
125
|
supported = true
|
|
126
126
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
supported = false
|
|
132
|
-
end
|
|
133
|
-
else
|
|
134
|
-
supported = OpenSSL::SSL::SSLContext::METHODS.include?(:TLSv1_2) # rubocop:disable Naming/VariableNumber
|
|
127
|
+
begin
|
|
128
|
+
ctx.min_version = ctx.max_version = OpenSSL::SSL::TLS1_2_VERSION
|
|
129
|
+
rescue OpenSSL::SSL::SSLError, NameError
|
|
130
|
+
supported = false
|
|
135
131
|
end
|
|
136
132
|
|
|
137
133
|
Bundler.ui.warn(<<~EOM) unless supported
|
data/lib/bundler/cli/info.rb
CHANGED
data/lib/bundler/cli/lock.rb
CHANGED
|
@@ -42,7 +42,6 @@ module Bundler
|
|
|
42
42
|
|
|
43
43
|
Bundler.settings.temporary(frozen: false) do
|
|
44
44
|
definition = Bundler.definition(update, Bundler.default_lockfile)
|
|
45
|
-
definition.add_checksums if options["add-checksums"]
|
|
46
45
|
|
|
47
46
|
Bundler::CLI::Common.configure_gem_version_promoter(definition, options) if options[:update]
|
|
48
47
|
|
|
@@ -64,6 +63,11 @@ module Bundler
|
|
|
64
63
|
raise InvalidOption, "Removing all platforms from the bundle is not allowed"
|
|
65
64
|
end
|
|
66
65
|
|
|
66
|
+
# Adding checksums resolves the bundle to fetch them, so it has to
|
|
67
|
+
# run after every platform change above has been recorded, or the
|
|
68
|
+
# new platforms are listed in the lockfile without their specs.
|
|
69
|
+
definition.add_checksums if options["add-checksums"]
|
|
70
|
+
|
|
67
71
|
definition.remotely! unless options[:local]
|
|
68
72
|
|
|
69
73
|
if options["normalize-platforms"]
|
|
@@ -74,10 +78,21 @@ module Bundler
|
|
|
74
78
|
puts definition.to_lock
|
|
75
79
|
else
|
|
76
80
|
file = options[:lockfile]
|
|
77
|
-
file =
|
|
81
|
+
file = if file
|
|
82
|
+
Pathname.new(file).expand_path
|
|
83
|
+
elsif ENV["BUNDLE_LOCKFILE"].to_s.empty?
|
|
84
|
+
definition.lockfile
|
|
85
|
+
else
|
|
86
|
+
# BUNDLE_LOCKFILE outranks the lockfile method in the Gemfile, see gemfile(5)
|
|
87
|
+
Bundler.default_lockfile
|
|
88
|
+
end
|
|
78
89
|
|
|
79
|
-
|
|
80
|
-
|
|
90
|
+
if file
|
|
91
|
+
puts "Writing lockfile to #{file}"
|
|
92
|
+
definition.write_lock(file, false)
|
|
93
|
+
else
|
|
94
|
+
Bundler.ui.warn "Not writing a lockfile because the Gemfile sets `lockfile false`"
|
|
95
|
+
end
|
|
81
96
|
end
|
|
82
97
|
|
|
83
98
|
Bundler::CLI::Common.output_cooldown_skipped_summary(definition)
|
data/lib/bundler/cli/open.rb
CHANGED
|
@@ -13,7 +13,7 @@ module Bundler
|
|
|
13
13
|
raise InvalidOption, "Cannot specify `--path` option without a value" if !@path.nil? && @path.empty?
|
|
14
14
|
editor = [ENV["BUNDLER_EDITOR"], ENV["VISUAL"], ENV["EDITOR"]].find {|e| !e.nil? && !e.empty? }
|
|
15
15
|
return Bundler.ui.info("To open a bundled gem, set $EDITOR or $BUNDLER_EDITOR") unless editor
|
|
16
|
-
return unless spec =
|
|
16
|
+
return unless spec = spec_for_gem(name)
|
|
17
17
|
if spec.default_gem?
|
|
18
18
|
Bundler.ui.info "Unable to open #{name} because it's a default gem, so the directory it would normally be installed to does not exist."
|
|
19
19
|
else
|
|
@@ -35,5 +35,11 @@ module Bundler
|
|
|
35
35
|
require "shellwords"
|
|
36
36
|
Shellwords.split(editor)
|
|
37
37
|
end
|
|
38
|
+
|
|
39
|
+
private
|
|
40
|
+
|
|
41
|
+
def spec_for_gem(name)
|
|
42
|
+
Bundler::CLI::Common.select_spec_with_match_type(name, options)
|
|
43
|
+
end
|
|
38
44
|
end
|
|
39
45
|
end
|
data/lib/bundler/cli/outdated.rb
CHANGED
|
@@ -90,7 +90,9 @@ module Bundler
|
|
|
90
90
|
dependency = current_dependencies[current_spec.name]
|
|
91
91
|
groups = ""
|
|
92
92
|
if dependency && !options[:parseable]
|
|
93
|
-
groups = dependency.groups
|
|
93
|
+
groups = dependency.groups
|
|
94
|
+
groups = groups.sort if options_include_groups
|
|
95
|
+
groups = groups.join(", ")
|
|
94
96
|
end
|
|
95
97
|
|
|
96
98
|
outdated_gems << {
|
|
@@ -101,13 +103,11 @@ module Bundler
|
|
|
101
103
|
}
|
|
102
104
|
end
|
|
103
105
|
|
|
104
|
-
relevant_outdated_gems = if
|
|
105
|
-
outdated_gems.
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
gems
|
|
110
|
-
end.compact
|
|
106
|
+
relevant_outdated_gems = if options[:groups]
|
|
107
|
+
without_groups, with_groups = outdated_gems.partition {|g| g[:groups].empty? }
|
|
108
|
+
with_groups.group_by {|g| g[:groups] }.sort.flat_map(&:last) + without_groups
|
|
109
|
+
elsif options_include_groups
|
|
110
|
+
outdated_gems.select {|g| g[:groups].split(", ").include?(options[:group]) }
|
|
111
111
|
else
|
|
112
112
|
outdated_gems
|
|
113
113
|
end
|
|
@@ -333,8 +333,6 @@ module Bundler
|
|
|
333
333
|
|
|
334
334
|
Bundler.ui.info justify(header, column_sizes)
|
|
335
335
|
|
|
336
|
-
data.sort_by! {|row| row[0] }
|
|
337
|
-
|
|
338
336
|
data.each do |row|
|
|
339
337
|
Bundler.ui.info justify(row, column_sizes)
|
|
340
338
|
end
|
data/lib/bundler/cli/platform.rb
CHANGED
|
@@ -25,7 +25,7 @@ module Bundler
|
|
|
25
25
|
else
|
|
26
26
|
platforms = Bundler.definition.platforms.map {|p| "* #{p}" }
|
|
27
27
|
|
|
28
|
-
output <<
|
|
28
|
+
output << platform_info
|
|
29
29
|
output << "Your app has gems that work on these platforms:\n#{platforms.join("\n")}"
|
|
30
30
|
|
|
31
31
|
if ruby_version
|
|
@@ -44,5 +44,19 @@ module Bundler
|
|
|
44
44
|
|
|
45
45
|
Bundler.ui.info output.join("\n\n")
|
|
46
46
|
end
|
|
47
|
+
|
|
48
|
+
private
|
|
49
|
+
|
|
50
|
+
def platform_info
|
|
51
|
+
info = "Your platform is: #{Gem::Platform.local}"
|
|
52
|
+
return info if Bundler.local_platform == Gem::Platform.local
|
|
53
|
+
|
|
54
|
+
info + "\nHowever, your effective platform is: #{Bundler.local_platform} " \
|
|
55
|
+
"(because force_ruby_platform is #{force_ruby_platform_origin})"
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def force_ruby_platform_origin
|
|
59
|
+
Bundler.settings.pretty_values_for(:force_ruby_platform).first.sub(/\ASet /, "set ")
|
|
60
|
+
end
|
|
47
61
|
end
|
|
48
62
|
end
|
data/lib/bundler/cli/show.rb
CHANGED
|
@@ -20,7 +20,7 @@ module Bundler
|
|
|
20
20
|
if gem_name == "bundler"
|
|
21
21
|
path = File.expand_path("../../..", __dir__)
|
|
22
22
|
else
|
|
23
|
-
spec =
|
|
23
|
+
spec = spec_for_gem(gem_name)
|
|
24
24
|
return unless spec
|
|
25
25
|
path = spec.full_gem_path
|
|
26
26
|
unless File.directory?(path)
|
|
@@ -55,6 +55,10 @@ module Bundler
|
|
|
55
55
|
|
|
56
56
|
private
|
|
57
57
|
|
|
58
|
+
def spec_for_gem(name)
|
|
59
|
+
Bundler::CLI::Common.select_spec_with_match_type(name, options)
|
|
60
|
+
end
|
|
61
|
+
|
|
58
62
|
def fetch_latest_specs
|
|
59
63
|
definition = Bundler.definition(true)
|
|
60
64
|
Bundler.ui.info "Fetching remote specs for outdated check...\n\n"
|
data/lib/bundler/cli/update.rb
CHANGED
|
@@ -13,7 +13,7 @@ module Bundler
|
|
|
13
13
|
|
|
14
14
|
update_bundler = options[:bundler]
|
|
15
15
|
|
|
16
|
-
Bundler.self_manager.update_bundler_and_restart_with_it_if_needed(update_bundler) if update_bundler
|
|
16
|
+
Bundler.self_manager.update_bundler_and_restart_with_it_if_needed(update_bundler, pre: options[:pre]) if update_bundler
|
|
17
17
|
|
|
18
18
|
sources = Array(options[:source])
|
|
19
19
|
groups = Array(options[:group]).map(&:to_sym)
|
data/lib/bundler/cli.rb
CHANGED
|
@@ -177,7 +177,7 @@ module Bundler
|
|
|
177
177
|
else
|
|
178
178
|
puts File.read("#{man_path}/#{File.basename(man_page)}.ronn")
|
|
179
179
|
end
|
|
180
|
-
elsif command_path =
|
|
180
|
+
elsif command_path = self.class.bundler_command_path(cli)
|
|
181
181
|
Kernel.exec(command_path, "--help")
|
|
182
182
|
else
|
|
183
183
|
super
|
|
@@ -189,11 +189,23 @@ module Bundler
|
|
|
189
189
|
return Bundler::Plugin.exec_command(command, ARGV[1..-1])
|
|
190
190
|
end
|
|
191
191
|
|
|
192
|
-
return super unless command_path =
|
|
192
|
+
return super unless command_path = bundler_command_path(command)
|
|
193
193
|
|
|
194
194
|
Kernel.exec(command_path, *ARGV[1..-1])
|
|
195
195
|
end
|
|
196
196
|
|
|
197
|
+
# Only PATH is searched, unlike Bundler.which, which also finds a file in
|
|
198
|
+
# the current directory and returns a bare name that Kernel.exec cannot run.
|
|
199
|
+
def self.bundler_command_path(command)
|
|
200
|
+
ENV.fetch("PATH", "").split(File::PATH_SEPARATOR).each do |path|
|
|
201
|
+
path = path[1..-2] if path.start_with?('"') && path.end_with?('"')
|
|
202
|
+
command_path = Bundler.find_executable(File.expand_path("bundler-#{command}", path))
|
|
203
|
+
return command_path if command_path
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
nil
|
|
207
|
+
end
|
|
208
|
+
|
|
197
209
|
desc "init [OPTIONS]", "Generates a Gemfile into the current working directory"
|
|
198
210
|
long_desc <<-D
|
|
199
211
|
Init generates a default Gemfile in the current working directory. When adding a
|
|
@@ -319,10 +331,10 @@ module Bundler
|
|
|
319
331
|
method_option "source", type: :array, banner: "Update a specific source (and all gems associated with it)"
|
|
320
332
|
method_option "force", type: :boolean, aliases: "--redownload", banner: "Force reinstalling every gem, even if already installed"
|
|
321
333
|
method_option "ruby", type: :boolean, banner: "Update ruby specified in Gemfile.lock"
|
|
322
|
-
method_option "bundler", type: :string, lazy_default: "
|
|
334
|
+
method_option "bundler", type: :string, lazy_default: ">= #{Bundler::VERSION}", banner: "Update the locked version of bundler"
|
|
323
335
|
method_option "patch", type: :boolean, banner: "Prefer updating only to next patch version"
|
|
324
336
|
method_option "minor", type: :boolean, banner: "Prefer updating only to next minor version"
|
|
325
|
-
method_option "major", type: :boolean, banner: "Prefer updating to
|
|
337
|
+
method_option "major", type: :boolean, banner: "Prefer updating to latest major version (default)"
|
|
326
338
|
method_option "pre", type: :boolean, banner: "Always choose the highest allowed version when updating gems, regardless of prerelease status"
|
|
327
339
|
method_option "strict", type: :boolean, banner: "Do not allow any gem to be updated past latest --patch | --minor | --major"
|
|
328
340
|
method_option "conservative", type: :boolean, banner: "Use bundle install conservative update behavior and do not allow shared dependencies to be updated."
|
|
@@ -342,6 +354,7 @@ module Bundler
|
|
|
342
354
|
D
|
|
343
355
|
method_option "paths", type: :boolean, banner: "List the paths of all gems that are required by your Gemfile."
|
|
344
356
|
method_option "outdated", type: :boolean, banner: "Show verbose output including whether gems are outdated (removed)."
|
|
357
|
+
method_option "exact-match", type: :boolean, banner: "Only match gems whose names exactly match the given name"
|
|
345
358
|
def show(gem_name = nil)
|
|
346
359
|
if ARGV.include?("--outdated")
|
|
347
360
|
removed_message = "the `--outdated` flag to `bundle show` has been removed in favor of `bundle show --verbose`"
|
|
@@ -367,6 +380,7 @@ module Bundler
|
|
|
367
380
|
desc "info GEM [OPTIONS]", "Show information for the given gem"
|
|
368
381
|
method_option "path", type: :boolean, banner: "Print full path to gem"
|
|
369
382
|
method_option "version", type: :boolean, banner: "Print gem version"
|
|
383
|
+
method_option "exact-match", type: :boolean, banner: "Only match gems whose names exactly match the given name"
|
|
370
384
|
def info(gem_name)
|
|
371
385
|
require_relative "cli/info"
|
|
372
386
|
Info.new(options, gem_name).run
|
|
@@ -434,7 +448,7 @@ module Bundler
|
|
|
434
448
|
method_option "filter-strict", type: :boolean, aliases: "--strict", banner: "Only list newer versions allowed by your Gemfile requirements"
|
|
435
449
|
method_option "update-strict", type: :boolean, banner: "Strict conservative resolution, do not allow any gem to be updated past latest --patch | --minor | --major"
|
|
436
450
|
method_option "minor", type: :boolean, banner: "Prefer updating only to next minor version"
|
|
437
|
-
method_option "major", type: :boolean, banner: "Prefer updating to
|
|
451
|
+
method_option "major", type: :boolean, banner: "Prefer updating to latest major version (default)"
|
|
438
452
|
method_option "patch", type: :boolean, banner: "Prefer updating only to next patch version"
|
|
439
453
|
method_option "filter-major", type: :boolean, banner: "Only list major newer versions"
|
|
440
454
|
method_option "filter-minor", type: :boolean, banner: "Only list minor newer versions"
|
|
@@ -530,6 +544,7 @@ module Bundler
|
|
|
530
544
|
|
|
531
545
|
desc "open GEM", "Opens the source directory of the given bundled gem"
|
|
532
546
|
method_option "path", type: :string, lazy_default: "", banner: "Open relative path of the gem source."
|
|
547
|
+
method_option "exact-match", type: :boolean, banner: "Only match gems whose names exactly match the given name"
|
|
533
548
|
def open(name)
|
|
534
549
|
require_relative "cli/open"
|
|
535
550
|
Open.new(options, name).run
|
|
@@ -640,11 +655,11 @@ module Bundler
|
|
|
640
655
|
method_option "normalize-platforms", type: :boolean, default: false, banner: "Normalize lockfile platforms"
|
|
641
656
|
method_option "patch", type: :boolean, banner: "If updating, prefer updating only to next patch version"
|
|
642
657
|
method_option "minor", type: :boolean, banner: "If updating, prefer updating only to next minor version"
|
|
643
|
-
method_option "major", type: :boolean, banner: "If updating, prefer updating to
|
|
658
|
+
method_option "major", type: :boolean, banner: "If updating, prefer updating to latest major version (default)"
|
|
644
659
|
method_option "pre", type: :boolean, banner: "If updating, always choose the highest allowed version, regardless of prerelease status"
|
|
645
660
|
method_option "strict", type: :boolean, banner: "If updating, do not allow any gem to be updated past latest --patch | --minor | --major"
|
|
646
661
|
method_option "conservative", type: :boolean, banner: "If updating, use bundle install conservative update behavior and do not allow shared dependencies to be updated"
|
|
647
|
-
method_option "bundler", type: :string, lazy_default: "
|
|
662
|
+
method_option "bundler", type: :string, lazy_default: ">= #{Bundler::VERSION}", banner: "Update the locked version of bundler"
|
|
648
663
|
method_option "cooldown", type: :numeric, banner: "Only consider gem versions published at least N days ago. Use 0 to disable."
|
|
649
664
|
def lock
|
|
650
665
|
require_relative "cli/lock"
|
data/lib/bundler/constants.rb
CHANGED
data/lib/bundler/definition.rb
CHANGED
|
@@ -167,6 +167,7 @@ module Bundler
|
|
|
167
167
|
|
|
168
168
|
@dependency_changes = converge_dependencies
|
|
169
169
|
@local_changes = converge_locals
|
|
170
|
+
@override_changes = converge_overrides
|
|
170
171
|
|
|
171
172
|
check_lockfile
|
|
172
173
|
end
|
|
@@ -198,7 +199,7 @@ module Bundler
|
|
|
198
199
|
|
|
199
200
|
sources.cached!
|
|
200
201
|
|
|
201
|
-
if options[:add_checksums] || (!options[:local] && (install_needed? || refetch_needed?(options)))
|
|
202
|
+
if options[:add_checksums] || (!options[:local] && (install_needed? || refetch_needed?(options) || @locked_spec_with_empty_checksums))
|
|
202
203
|
sources.remote!
|
|
203
204
|
true
|
|
204
205
|
else
|
|
@@ -346,7 +347,9 @@ module Bundler
|
|
|
346
347
|
#
|
|
347
348
|
# @return [SpecSet] resolved dependencies
|
|
348
349
|
def resolve
|
|
349
|
-
@resolve
|
|
350
|
+
return @resolve if @resolve
|
|
351
|
+
|
|
352
|
+
@resolve = if Bundler.frozen_bundle?
|
|
350
353
|
Bundler.ui.debug "Frozen, using resolution from the lockfile"
|
|
351
354
|
@locked_specs
|
|
352
355
|
elsif no_resolve_needed?
|
|
@@ -366,6 +369,8 @@ module Bundler
|
|
|
366
369
|
|
|
367
370
|
start_resolution
|
|
368
371
|
end
|
|
372
|
+
warn_inert_overrides(@resolve)
|
|
373
|
+
@resolve
|
|
369
374
|
end
|
|
370
375
|
|
|
371
376
|
def spec_git_paths
|
|
@@ -473,6 +478,11 @@ module Bundler
|
|
|
473
478
|
@resolved_bundler_version || Bundler.gem_version
|
|
474
479
|
end
|
|
475
480
|
|
|
481
|
+
# The lines for the OVERRIDES section of Gemfile.lock.
|
|
482
|
+
def overrides_to_lock
|
|
483
|
+
@overrides.map(&:to_lock).uniq
|
|
484
|
+
end
|
|
485
|
+
|
|
476
486
|
def to_lock
|
|
477
487
|
require_relative "lockfile_generator"
|
|
478
488
|
LockfileGenerator.generate(self)
|
|
@@ -595,6 +605,11 @@ module Bundler
|
|
|
595
605
|
added.concat new_deps.map {|d| "* #{pretty_dep(d)}" } if new_deps.any?
|
|
596
606
|
deleted.concat deleted_deps.map {|d| "* #{pretty_dep(d)}" } if deleted_deps.any?
|
|
597
607
|
|
|
608
|
+
if @override_changes
|
|
609
|
+
added.concat((overrides_to_lock - locked_overrides_to_lock).sort.map {|o| "* override #{o}" })
|
|
610
|
+
deleted.concat((locked_overrides_to_lock - overrides_to_lock).sort.map {|o| "* override #{o}" })
|
|
611
|
+
end
|
|
612
|
+
|
|
598
613
|
both_sources = Hash.new {|h, k| h[k] = [] }
|
|
599
614
|
current_dependencies.each {|d| both_sources[d.name][0] = d }
|
|
600
615
|
current_locked_dependencies.each {|d| both_sources[d.name][1] = d }
|
|
@@ -650,7 +665,7 @@ module Bundler
|
|
|
650
665
|
@missing_lockfile_dep ||
|
|
651
666
|
@unlocking_bundler ||
|
|
652
667
|
@locked_spec_with_missing_checksums ||
|
|
653
|
-
|
|
668
|
+
empty_checksums_actionable? ||
|
|
654
669
|
@locked_spec_with_missing_deps ||
|
|
655
670
|
@locked_spec_with_invalid_deps
|
|
656
671
|
end
|
|
@@ -659,6 +674,16 @@ module Bundler
|
|
|
659
674
|
unlocking? || something_changed?
|
|
660
675
|
end
|
|
661
676
|
|
|
677
|
+
# Only a remote fetch can fill an empty CHECKSUMS entry, so it justifies a
|
|
678
|
+
# resolution only when one is coming. Resolving locally for it would repeat
|
|
679
|
+
# on every `Bundler.setup` without changing the lockfile. Frozen mode still
|
|
680
|
+
# has to refuse the entry.
|
|
681
|
+
def empty_checksums_actionable?
|
|
682
|
+
return false unless @locked_spec_with_empty_checksums
|
|
683
|
+
|
|
684
|
+
Bundler.frozen_bundle? || !sources.local_mode?
|
|
685
|
+
end
|
|
686
|
+
|
|
662
687
|
def should_add_extra_platforms?
|
|
663
688
|
!lockfile_exists? && Bundler::MatchPlatform.generic_local_platform_is_ruby? && !Bundler.settings[:force_ruby_platform]
|
|
664
689
|
end
|
|
@@ -894,6 +919,8 @@ module Bundler
|
|
|
894
919
|
else
|
|
895
920
|
lockfile_changed_reason
|
|
896
921
|
end
|
|
922
|
+
elsif @override_changes
|
|
923
|
+
"the overrides in your gemfile changed"
|
|
897
924
|
else
|
|
898
925
|
"some dependencies were deleted from your gemfile"
|
|
899
926
|
end
|
|
@@ -929,6 +956,7 @@ module Bundler
|
|
|
929
956
|
[@locked_spec_with_empty_checksums, "your lockfile has an empty CHECKSUMS entry for \"#{@locked_spec_with_empty_checksums}\""],
|
|
930
957
|
[@locked_spec_with_missing_deps, "your lockfile includes \"#{@locked_spec_with_missing_deps}\" but not some of its dependencies"],
|
|
931
958
|
[@locked_spec_with_invalid_deps, "your lockfile does not satisfy dependencies of \"#{@locked_spec_with_invalid_deps}\""],
|
|
959
|
+
[@override_changes, "the overrides in your gemfile changed"],
|
|
932
960
|
].select(&:first).map(&:last).join(", ")
|
|
933
961
|
end
|
|
934
962
|
|
|
@@ -1095,25 +1123,77 @@ module Bundler
|
|
|
1095
1123
|
end
|
|
1096
1124
|
|
|
1097
1125
|
converge_overrides_outside_dependencies
|
|
1126
|
+
converge_rewritten_dependencies
|
|
1098
1127
|
|
|
1099
1128
|
@changed_dependencies.any?
|
|
1100
1129
|
end
|
|
1101
1130
|
|
|
1102
|
-
|
|
1131
|
+
# The lockfile keeps the upstream dependencies of every gem, so a gem that
|
|
1132
|
+
# a `with:`/`in:` override cut loose stays locked until a resolution drops
|
|
1133
|
+
# it.
|
|
1134
|
+
def converge_rewritten_dependencies
|
|
1103
1135
|
@overrides.each do |override|
|
|
1104
|
-
|
|
1105
|
-
# fresh resolution (no lockfile) or when the user runs `bundle update`.
|
|
1106
|
-
# Forcing a full re-resolve from a single :all directive would surprise
|
|
1107
|
-
# users with unrelated dependency churn.
|
|
1108
|
-
next unless override.target.is_a?(String)
|
|
1136
|
+
next unless override.from
|
|
1109
1137
|
|
|
1110
1138
|
name = override.target
|
|
1111
|
-
next if @changed_dependencies.include?(name)
|
|
1112
1139
|
next if @originally_locked_specs[name].empty?
|
|
1113
|
-
|
|
1140
|
+
next if @dependencies.any? {|d| d.name == name }
|
|
1141
|
+
|
|
1142
|
+
still_required = @originally_locked_specs.any? do |s|
|
|
1143
|
+
Override.rewrite_dependencies(@overrides, s.name, s.runtime_dependencies).any? {|d| d.name == name }
|
|
1144
|
+
end
|
|
1145
|
+
next if still_required
|
|
1146
|
+
|
|
1147
|
+
@gems_to_unlock << name
|
|
1148
|
+
@changed_dependencies << name
|
|
1149
|
+
end
|
|
1150
|
+
end
|
|
1151
|
+
|
|
1152
|
+
# A misspelled `in:` gem leaves the override with nothing to rewrite.
|
|
1153
|
+
def warn_inert_overrides(specs)
|
|
1154
|
+
@overrides.each do |override|
|
|
1155
|
+
next unless override.from
|
|
1156
|
+
next if specs[override.from].any? {|s| s.dependencies.any? {|d| d.name == override.target } }
|
|
1157
|
+
|
|
1158
|
+
Bundler.ui.warn "#{override} has no effect because the bundle has no #{override.from} that depends on #{override.target}"
|
|
1159
|
+
end
|
|
1160
|
+
end
|
|
1161
|
+
|
|
1162
|
+
# The lockfile records the Gemfile's overrides, so a change to them is a
|
|
1163
|
+
# change to the lockfile even when every locked version still satisfies
|
|
1164
|
+
# them. Rewriting the section needs no resolution, so this stays out of
|
|
1165
|
+
# #something_changed?. #write_lock rewrites it because the generated
|
|
1166
|
+
# contents differ, and the frozen check reports it.
|
|
1167
|
+
def converge_overrides
|
|
1168
|
+
return false unless @locked_gems
|
|
1169
|
+
|
|
1170
|
+
overrides_to_lock.sort != locked_overrides_to_lock.sort
|
|
1171
|
+
end
|
|
1172
|
+
|
|
1173
|
+
def locked_overrides_to_lock
|
|
1174
|
+
Array(@locked_gems&.overrides).map(&:to_lock).uniq
|
|
1175
|
+
end
|
|
1176
|
+
|
|
1177
|
+
def converge_overrides_outside_dependencies
|
|
1178
|
+
@overrides.each do |override|
|
|
1179
|
+
# :all and metadata overrides are intentionally not pre-unlocked.
|
|
1180
|
+
# Unlocking for them would re-resolve gems the user did not ask to
|
|
1181
|
+
# move. Install-time compatibility checks already honor them for locked
|
|
1182
|
+
# specs, and they affect resolution on a fresh lock or when the user
|
|
1183
|
+
# runs `bundle update`. Changing one still rewrites the OVERRIDES
|
|
1184
|
+
# section (see #converge_overrides).
|
|
1185
|
+
next unless override.target.is_a?(String) && override.field == :version
|
|
1186
|
+
|
|
1187
|
+
name = override.target
|
|
1188
|
+
# Overrides on direct deps are detected in the per-dep
|
|
1114
1189
|
# converge_dependencies loop via apply_override_to + matches_spec?.
|
|
1115
|
-
|
|
1116
|
-
|
|
1190
|
+
next if @dependencies.any? {|d| d.name == name }
|
|
1191
|
+
|
|
1192
|
+
locked_specs = @originally_locked_specs[name]
|
|
1193
|
+
next if locked_specs.empty?
|
|
1194
|
+
# Only a version string constrains on its own. :ignore_upper and nil
|
|
1195
|
+
# loosen requirements the lockfile already satisfies.
|
|
1196
|
+
next if override.apply_to(Gem::Requirement.default).satisfied_by?(locked_specs.first.version)
|
|
1117
1197
|
|
|
1118
1198
|
@gems_to_unlock << name
|
|
1119
1199
|
@changed_dependencies << name
|
|
@@ -1216,7 +1296,7 @@ module Bundler
|
|
|
1216
1296
|
def preload_git_source_worker
|
|
1217
1297
|
workers = Bundler.settings.installation_parallelization
|
|
1218
1298
|
|
|
1219
|
-
@preload_git_source_worker ||= Bundler::Worker.new(workers, "Git source preloading", ->(
|
|
1299
|
+
@preload_git_source_worker ||= Bundler::Worker.new(workers, "Git source preloading", ->(sources, _) { sources.each(&:specs) })
|
|
1220
1300
|
end
|
|
1221
1301
|
|
|
1222
1302
|
def preload_git_sources
|
|
@@ -1227,7 +1307,13 @@ module Bundler
|
|
|
1227
1307
|
end
|
|
1228
1308
|
|
|
1229
1309
|
begin
|
|
1230
|
-
|
|
1310
|
+
# Sources from the same repository share one cache directory, and
|
|
1311
|
+
# running git in that directory from two workers at once makes the
|
|
1312
|
+
# fetches collide. Preload sources that share a cache in one job, one
|
|
1313
|
+
# after the other, and run the separate caches in parallel.
|
|
1314
|
+
needed_git_sources.group_by(&:cache_path).each_value do |sources|
|
|
1315
|
+
preload_git_source_worker.enq(sources)
|
|
1316
|
+
end
|
|
1231
1317
|
ensure
|
|
1232
1318
|
preload_git_source_worker.stop
|
|
1233
1319
|
end
|
|
@@ -1342,7 +1428,7 @@ module Bundler
|
|
|
1342
1428
|
end
|
|
1343
1429
|
|
|
1344
1430
|
def source_map
|
|
1345
|
-
@source_map ||= SourceMap.new(sources, dependencies, @locked_specs)
|
|
1431
|
+
@source_map ||= SourceMap.new(sources, dependencies, @locked_specs, @overrides.filter_map {|o| o.operation if o.from })
|
|
1346
1432
|
end
|
|
1347
1433
|
|
|
1348
1434
|
def new_resolver_for_full_update
|