Skip to content

Commit f85c7de

Browse files
authored
Update RubyGems 3.5.16 and Bundler 2.5.16 for Ruby 3.3 (ruby#11252)
* Merge RubyGems-3.5.12 and Bundler-2.5.12 * Merge RubyGems-3.5.13 and Bundler-2.5.13 * Merge RubyGems-3.5.14 and Bundler-2.5.14 * Merge RubyGems-3.5.15 and Bundler-2.5.15 * Merge RubyGems-3.5.16 and Bundler-2.5.16
1 parent 0922afa commit f85c7de

File tree

245 files changed

+7592
-5857
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

245 files changed

+7592
-5857
lines changed

lib/bundler.rb

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ module Bundler
4242
autoload :Checksum, File.expand_path("bundler/checksum", __dir__)
4343
autoload :CLI, File.expand_path("bundler/cli", __dir__)
4444
autoload :CIDetector, File.expand_path("bundler/ci_detector", __dir__)
45+
autoload :CompactIndexClient, File.expand_path("bundler/compact_index_client", __dir__)
4546
autoload :Definition, File.expand_path("bundler/definition", __dir__)
4647
autoload :Dependency, File.expand_path("bundler/dependency", __dir__)
4748
autoload :Deprecate, File.expand_path("bundler/deprecate", __dir__)
@@ -166,6 +167,10 @@ def setup(*groups)
166167
end
167168
end
168169

170+
def auto_switch
171+
self_manager.restart_with_locked_bundler_if_needed
172+
end
173+
169174
# Automatically install dependencies if Bundler.settings[:auto_install] exists.
170175
# This is set through config cmd `bundle config set --global auto_install 1`.
171176
#
@@ -356,7 +361,7 @@ def rm_rf(path)
356361
def settings
357362
@settings ||= Settings.new(app_config_path)
358363
rescue GemfileNotFound
359-
@settings = Settings.new(Pathname.new(".bundle").expand_path)
364+
@settings = Settings.new
360365
end
361366

362367
# @return [Hash] Environment present before Bundler was activated

lib/bundler/cli.rb

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ def initialize(*args)
6565
Bundler.reset_settings_and_root!
6666
end
6767

68-
Bundler.self_manager.restart_with_locked_bundler_if_needed
68+
Bundler.auto_switch
6969

7070
Bundler.settings.set_command_option_if_given :retry, options[:retry]
7171

@@ -550,10 +550,13 @@ def viz
550550
method_option :rubocop, type: :boolean, desc: "Add rubocop to the generated Rakefile and gemspec. Set a default with `bundle config set --global gem.rubocop true`."
551551
method_option :changelog, type: :boolean, desc: "Generate changelog file. Set a default with `bundle config set --global gem.changelog true`."
552552
method_option :test, type: :string, lazy_default: Bundler.settings["gem.test"] || "", aliases: "-t", banner: "Use the specified test framework for your library",
553+
enum: %w[rspec minitest test-unit],
553554
desc: "Generate a test directory for your library, either rspec, minitest or test-unit. Set a default with `bundle config set --global gem.test (rspec|minitest|test-unit)`."
554555
method_option :ci, type: :string, lazy_default: Bundler.settings["gem.ci"] || "",
556+
enum: %w[github gitlab circle],
555557
desc: "Generate CI configuration, either GitHub Actions, GitLab CI or CircleCI. Set a default with `bundle config set --global gem.ci (github|gitlab|circle)`"
556558
method_option :linter, type: :string, lazy_default: Bundler.settings["gem.linter"] || "",
559+
enum: %w[rubocop standard],
557560
desc: "Add a linter and code formatter, either RuboCop or Standard. Set a default with `bundle config set --global gem.linter (rubocop|standard)`"
558561
method_option :github_username, type: :string, default: Bundler.settings["gem.github_username"], banner: "Set your username on GitHub", desc: "Fill in GitHub username on README so that you don't have to do it manually. Set a default with `bundle config set --global gem.github_username <your_username>`."
559562

@@ -767,13 +770,10 @@ def warn_on_outdated_bundler
767770

768771
return unless SharedHelpers.md5_available?
769772

770-
latest = Fetcher::CompactIndex.
771-
new(nil, Source::Rubygems::Remote.new(Gem::URI("https://rubygems.org")), nil, nil).
772-
send(:compact_index_client).
773-
instance_variable_get(:@cache).
774-
dependencies("bundler").
775-
map {|d| Gem::Version.new(d.first) }.
776-
max
773+
require_relative "vendored_uri"
774+
remote = Source::Rubygems::Remote.new(Gem::URI("https://rubygems.org"))
775+
cache_path = Bundler.user_cache.join("compact_index", remote.cache_slug)
776+
latest = Bundler::CompactIndexClient.new(cache_path).latest_version("bundler")
777777
return unless latest
778778

779779
current = Gem::Version.new(VERSION)

lib/bundler/cli/fund.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ def run
1616
deps = if groups.any?
1717
Bundler.definition.dependencies_for(groups)
1818
else
19-
Bundler.definition.current_dependencies
19+
Bundler.definition.requested_dependencies
2020
end
2121

2222
fund_info = deps.each_with_object([]) do |dep, arr|

lib/bundler/cli/gem.rb

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ def initialize(options, gem_name, thor)
3232

3333
validate_ext_name if @extension
3434
validate_rust_builder_rubygems_version if @extension == "rust"
35-
travis_removal_info
3635
end
3736

3837
def run
@@ -276,6 +275,7 @@ def validate_ext_name
276275
end
277276

278277
def ask_and_set_test_framework
278+
return if skip?(:test)
279279
test_framework = options[:test] || Bundler.settings["gem.test"]
280280

281281
if test_framework.to_s.empty?
@@ -301,6 +301,10 @@ def ask_and_set_test_framework
301301
test_framework
302302
end
303303

304+
def skip?(option)
305+
options.key?(option) && options[option].nil?
306+
end
307+
304308
def hint_text(setting)
305309
if Bundler.settings["gem.#{setting}"] == false
306310
"Your choice will only be applied to this gem."
@@ -311,6 +315,7 @@ def hint_text(setting)
311315
end
312316

313317
def ask_and_set_ci
318+
return if skip?(:ci)
314319
ci_template = options[:ci] || Bundler.settings["gem.ci"]
315320

316321
if ci_template.to_s.empty?
@@ -342,6 +347,7 @@ def ask_and_set_ci
342347
end
343348

344349
def ask_and_set_linter
350+
return if skip?(:linter)
345351
linter_template = options[:linter] || Bundler.settings["gem.linter"]
346352
linter_template = deprecated_rubocop_option if linter_template.nil?
347353

@@ -448,19 +454,6 @@ def standard_version
448454
"1.3"
449455
end
450456

451-
# TODO: remove at next minor release
452-
def travis_removal_info
453-
if options[:ci] == "travis"
454-
Bundler.ui.error "Support for Travis CI was removed from gem skeleton generator."
455-
exit 1
456-
end
457-
458-
if Bundler.settings["gem.ci"] == "travis"
459-
Bundler.ui.error "Support for Travis CI was removed from gem skeleton generator, but it is present in bundle config. Please configure another provider using `bundle config set gem.ci SERVICE` (where SERVICE is one of github/gitlab/circle) or unset configuration using `bundle config unset gem.ci`."
460-
exit 1
461-
end
462-
end
463-
464457
def validate_rust_builder_rubygems_version
465458
if Gem::Version.new(rust_builder_required_rubygems_version) > Gem.rubygems_version
466459
Bundler.ui.error "Your RubyGems version (#{Gem.rubygems_version}) is too old to build Rust extension. Please update your RubyGems using `gem update --system` or any other way and try again."

lib/bundler/compact_index_client.rb

Lines changed: 51 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,29 @@
44
require "set"
55

66
module Bundler
7+
# The CompactIndexClient is responsible for fetching and parsing the compact index.
8+
#
9+
# The compact index is a set of caching optimized files that are used to fetch gem information.
10+
# The files are:
11+
# - names: a list of all gem names
12+
# - versions: a list of all gem versions
13+
# - info/[gem]: a list of all versions of a gem
14+
#
15+
# The client is instantiated with:
16+
# - `directory`: the root directory where the cache files are stored.
17+
# - `fetcher`: (optional) an object that responds to #call(uri_path, headers) and returns an http response.
18+
# If the `fetcher` is not provided, the client will only read cached files from disk.
19+
#
20+
# The client is organized into:
21+
# - `Updater`: updates the cached files on disk using the fetcher.
22+
# - `Cache`: calls the updater, caches files, read and return them from disk
23+
# - `Parser`: parses the compact index file data
24+
# - `CacheFile`: a concurrency safe file reader/writer that verifies checksums
25+
#
26+
# The client is intended to optimize memory usage and performance.
27+
# It is called 100s or 1000s of times, parsing files with hundreds of thousands of lines.
28+
# It may be called concurrently without global interpreter lock in some Rubies.
29+
# As a result, some methods may look more complex than necessary to save memory or time.
730
class CompactIndexClient
831
# NOTE: MD5 is here not because we expect a server to respond with it, but
932
# because we use it to generate the etag on first request during the upgrade
@@ -12,6 +35,13 @@ class CompactIndexClient
1235
SUPPORTED_DIGESTS = { "sha-256" => :SHA256, "md5" => :MD5 }.freeze
1336
DEBUG_MUTEX = Thread::Mutex.new
1437

38+
# info returns an Array of INFO Arrays. Each INFO Array has the following indices:
39+
INFO_NAME = 0
40+
INFO_VERSION = 1
41+
INFO_PLATFORM = 2
42+
INFO_DEPS = 3
43+
INFO_REQS = 4
44+
1545
def self.debug
1646
return unless ENV["DEBUG_COMPACT_INDEX"]
1747
DEBUG_MUTEX.synchronize { warn("[#{self}] #{yield}") }
@@ -21,106 +51,47 @@ class Error < StandardError; end
2151

2252
require_relative "compact_index_client/cache"
2353
require_relative "compact_index_client/cache_file"
54+
require_relative "compact_index_client/parser"
2455
require_relative "compact_index_client/updater"
2556

26-
attr_reader :directory
27-
28-
def initialize(directory, fetcher)
29-
@directory = Pathname.new(directory)
30-
@updater = Updater.new(fetcher)
31-
@cache = Cache.new(@directory)
32-
@endpoints = Set.new
33-
@info_checksums_by_name = {}
34-
@parsed_checksums = false
35-
@mutex = Thread::Mutex.new
36-
end
37-
38-
def execution_mode=(block)
39-
Bundler::CompactIndexClient.debug { "execution_mode=" }
40-
@endpoints = Set.new
41-
42-
@execution_mode = block
43-
end
44-
45-
# @return [Lambda] A lambda that takes an array of inputs and a block, and
46-
# maps the inputs with the block in parallel.
47-
#
48-
def execution_mode
49-
@execution_mode || sequentially
50-
end
51-
52-
def sequential_execution_mode!
53-
self.execution_mode = sequentially
54-
end
55-
56-
def sequentially
57-
@sequentially ||= lambda do |inputs, &blk|
58-
inputs.map(&blk)
59-
end
57+
def initialize(directory, fetcher = nil)
58+
@cache = Cache.new(directory, fetcher)
59+
@parser = Parser.new(@cache)
6060
end
6161

6262
def names
63-
Bundler::CompactIndexClient.debug { "/names" }
64-
update("names", @cache.names_path, @cache.names_etag_path)
65-
@cache.names
63+
Bundler::CompactIndexClient.debug { "names" }
64+
@parser.names
6665
end
6766

6867
def versions
69-
Bundler::CompactIndexClient.debug { "/versions" }
70-
update("versions", @cache.versions_path, @cache.versions_etag_path)
71-
versions, @info_checksums_by_name = @cache.versions
72-
versions
68+
Bundler::CompactIndexClient.debug { "versions" }
69+
@parser.versions
7370
end
7471

7572
def dependencies(names)
7673
Bundler::CompactIndexClient.debug { "dependencies(#{names})" }
77-
execution_mode.call(names) do |name|
78-
update_info(name)
79-
@cache.dependencies(name).map {|d| d.unshift(name) }
80-
end.flatten(1)
74+
names.map {|name| info(name) }
8175
end
8276

83-
def update_and_parse_checksums!
84-
Bundler::CompactIndexClient.debug { "update_and_parse_checksums!" }
85-
return @info_checksums_by_name if @parsed_checksums
86-
update("versions", @cache.versions_path, @cache.versions_etag_path)
87-
@info_checksums_by_name = @cache.checksums
88-
@parsed_checksums = true
89-
end
90-
91-
private
92-
93-
def update(remote_path, local_path, local_etag_path)
94-
Bundler::CompactIndexClient.debug { "update(#{local_path}, #{remote_path})" }
95-
unless synchronize { @endpoints.add?(remote_path) }
96-
Bundler::CompactIndexClient.debug { "already fetched #{remote_path}" }
97-
return
98-
end
99-
@updater.update(url(remote_path), local_path, local_etag_path)
77+
def info(name)
78+
Bundler::CompactIndexClient.debug { "info(#{name})" }
79+
@parser.info(name)
10080
end
10181

102-
def update_info(name)
103-
Bundler::CompactIndexClient.debug { "update_info(#{name})" }
104-
path = @cache.info_path(name)
105-
unless existing = @info_checksums_by_name[name]
106-
Bundler::CompactIndexClient.debug { "skipping updating info for #{name} since it is missing from versions" }
107-
return
108-
end
109-
checksum = SharedHelpers.checksum_for_file(path, :MD5)
110-
if checksum == existing
111-
Bundler::CompactIndexClient.debug { "skipping updating info for #{name} since the versions checksum matches the local checksum" }
112-
return
113-
end
114-
Bundler::CompactIndexClient.debug { "updating info for #{name} since the versions checksum #{existing} != the local checksum #{checksum}" }
115-
update("info/#{name}", path, @cache.info_etag_path(name))
82+
def latest_version(name)
83+
Bundler::CompactIndexClient.debug { "latest_version(#{name})" }
84+
@parser.info(name).map {|d| Gem::Version.new(d[INFO_VERSION]) }.max
11685
end
11786

118-
def url(path)
119-
path
87+
def available?
88+
Bundler::CompactIndexClient.debug { "available?" }
89+
@parser.available?
12090
end
12191

122-
def synchronize
123-
@mutex.synchronize { yield }
92+
def reset!
93+
Bundler::CompactIndexClient.debug { "reset!" }
94+
@cache.reset!
12495
end
12596
end
12697
end

0 commit comments

Comments
 (0)