summaryrefslogtreecommitdiff
path: root/lib
AgeCommit message (Collapse)Author
2025-12-05[ruby/timeout] Only the timeout method should be public on the Timeout moduleBenoit Daloze
https://github.com/ruby/timeout/commit/cd51eac3ca
2025-12-04[ruby/rubygems] Increase connection pool to allow for up to 70% speed increase:Edouard CHIN
- ### TL;DR Bundler is heavily limited by the connection pool which manages a single connection. By increasing the number of connection, we can drastiscally speed up the installation process when many gems need to be downloaded and installed. ### Benchmark There are various factors that are hard to control such as compilation time and network speed but after dozens of tests I can consistently get aroud 70% speed increase when downloading and installing 472 gems, most having no native extensions (on purpose). ``` # Before bundle install 28.60s user 12.70s system 179% cpu 23.014 total # After bundle install 30.09s user 15.90s system 281% cpu 16.317 total ``` You can find on this gist how this was benchmarked and the Gemfile used https://gist.github.com/Edouard-chin/c8e39148c0cdf324dae827716fbe24a0 ### Context A while ago in #869, Aaron introduced a connection pool which greatly improved Bundler speed. It was noted in the PR description that managing one connection was already good enough and it wasn't clear whether we needed more connections. Aaron also had the intuition that we may need to increase the pool for downloading gems and he was right. > We need to study how RubyGems uses connections and make a decision > based on request usage (e.g. only use one connection for many small > requests like bundler API, and maybe many connections for > downloading gems) When bundler downloads and installs gem in parallel https://github.com/ruby/rubygems/blob/4f85e02fdd89ee28852722dfed42a13c9f5c9193/bundler/lib/bundler/installer/parallel_installer.rb#L128 most threads have to wait for the only connection in the pool to be available which is not efficient. ### Solution This commit modifies the pool size for the fetcher that Bundler uses. RubyGems fetcher will continue to use a single connection. The bundler fetcher is used in 2 places. 1. When downloading gems https://github.com/ruby/rubygems/blob/4f85e02fdd89ee28852722dfed42a13c9f5c9193/bundler/lib/bundler/source/rubygems.rb#L481-L484 2. When grabing the index (not the compact index) using the `bundle install --full-index` flag. https://github.com/ruby/rubygems/blob/4f85e02fdd89ee28852722dfed42a13c9f5c9193/bundler/lib/bundler/fetcher/index.rb#L9 Having more connections in 2) is not any useful but tweaking the size based on where the fetcher is used is a bit tricky so I opted to modify it at the class level. I fiddle with the pool size and found that 5 seems to be the sweet spot at least for my environment. https://github.com/ruby/rubygems/commit/6063fd9963
2025-12-03[ruby/rubygems] Bump Rubygems version to 4.0.0Hiroshi SHIBATA
https://github.com/ruby/rubygems/commit/9d744beb56
2025-12-03[ruby/rubygems] Bump Bundler version to 4.0.0Hiroshi SHIBATA
https://github.com/ruby/rubygems/commit/a55c485226
2025-12-02[ruby/prism] Fix the ripper translator to parse as the current rubyEarlopain
Otherwise, it uses the latest prism version https://github.com/ruby/prism/commit/86406f63aa
2025-12-02[ruby/rubygems] Make BUNDLE_LOCKFILE environment variable have precedence ↵Jeremy Evans
over lockfile method in Gemfile It would be simpler to do `options[:lockfile] ||= ENV["BUNDLE_LOCKFILE"]`, but that doesn't work as `options` is frozen. Fixes https://github.com/ruby/rubygems/pull/9117 https://github.com/ruby/rubygems/commit/6e3603a0e9
2025-12-02[ruby/optparse] Remove `const_set` and instead use explicit assignmentsSam Westerman
https://github.com/ruby/optparse/commit/6e2709a5fd
2025-12-02[ruby/rubygems] Improve banner message for the default command.Hiroshi SHIBATA
Co-authored-by: Benoit Daloze <eregontp@gmail.com> https://github.com/ruby/rubygems/commit/463488b439 Co-authored-by: Patrik Ragnarsson <patrik@starkast.net>
2025-11-29[ruby/prism] Optimize `Prism::Source#find_line`Earlopain
This is more concise and ruby does a better job performance-wise. This used to be `bsearch_index` already but https://github.com/ruby/prism/commit/6d8358c08395438d5924777c1fc3001a5ebf0aa3 changed it. https://github.com/ruby/prism/pull/1733#discussion_r1373702087 said: > Yeah the edge case was that the value matched an element exactly But surely there would be a test to show this behaviour? Gets called as part of pretty-printing nodes. Further reduces the time for `SnapshotsTest` by ~16% for me. https://github.com/ruby/prism/commit/f448e2b995
2025-11-29[ruby/tempfile] [DOC] Monofont some text in Tempfile.createPeter Zhu
https://github.com/ruby/tempfile/commit/7fa7436baa
2025-11-29[ruby/tempfile] [DOC] Fix monofont for Tempfile.createPeter Zhu
https://github.com/ruby/tempfile/commit/96361e9e42
2025-11-29[ruby/rubygems] Also use String#include? for RUBY_PLATFORMHiroshi SHIBATA
https://github.com/ruby/rubygems/commit/5fd95f38d3
2025-11-29Fixup with mswin and nmake build for -j flagHiroshi SHIBATA
2025-11-28[ruby/rubygems] Add informational message when default_cli_command is unset.Hiroshi SHIBATA
https://github.com/ruby/rubygems/commit/9e44b5ebc4
2025-11-28[ruby/rubygems] Print help summary when the default command failJean Boussier
As mentioned in https://github.com/ruby/rubygems/issues/9124, the intent for changing the default command was to be more welcoming. I think we can acheive that by attempting to install, but to print that same help message if there is no Gemfile. That should address both concerns. https://github.com/ruby/rubygems/commit/f3f505c02a
2025-11-28[ruby/rubygems] Restore `install` as default commandJean Boussier
Fix: https://github.com/ruby/rubygems/issues/9124 This behavior is a deeply entrenched convention and changing it will annoy lots of developers with unclear gains. https://github.com/ruby/rubygems/commit/628e0ede46
2025-11-28[ruby/rubygems] Use String#include? with suggested by ↵Hiroshi SHIBATA
Performance/StringInclude cop https://github.com/ruby/rubygems/commit/fdd3419144
2025-11-28[ruby/rubygems] Fixed checksums generation issue when no source is specifiedHiroshi SHIBATA
https://github.com/ruby/rubygems/commit/bb4d791cb4
2025-11-29nmake didn't support -j flagHiroshi SHIBATA
2025-11-28[ruby/rubygems] Add `MAKEFLAGS=-j` by default before compiling:Edouard CHIN
- Depending on the native extension, it can greatly reduce compilation time when executing recipes simultaneously. For example on Prism: ``` # Before time gem install prism Building native extensions. This could take a while... Successfully installed prism-1.6.0 1 gem installed gem install prism 3.61s user 0.80s system 95% cpu 4.595 total ``` ``` # After time MAKEFLAGS="-j" gem install prism Building native extensions. This could take a while... Successfully installed prism-1.6.0 1 gem installed MAKEFLAGS="-j" gem install prism 4.47s user 1.27s system 246% cpu 2.330 total ``` I don't think adding `-j` as a default is harmful, but I'm admitedly not very knowledgable when it comes to compiler. https://github.com/ruby/rubygems/commit/61340081c6 Co-authored-by: Aaron Patterson <tenderlove@ruby-lang.org>
2025-11-26[ruby/optparse] Remove unneeded `public`Sam Westerman
Removed public visibility from the candidate method. https://github.com/ruby/optparse/commit/9a784a89a2
2025-11-26[ruby/optparse] Put `private` before method declarationsSam Westerman
https://github.com/ruby/optparse/commit/5478354d4f
2025-11-26[ruby/rubygems] Bump up to 4.0.0.beta2Hiroshi SHIBATA
https://github.com/ruby/rubygems/commit/b8529f48bf
2025-11-25[ruby/rubygems] Support bundle install --lockfile optionJeremy Evans
This allows for specifying the lockfile to read and write. It mirrors the --gemfile option, and has higher priority than the lockfile method in the Gemfile. It also mirrors the bundle lock --lockfile option. When the --lockfile option is used, it is applied twice. First, before the Gemfile is read, to specify the lockfile to operate on, and again after the Gemfile is read, so that if the Gemfile has a lockfile method that overrides the defintion's lockfile, the --lockfile option still has higher precedence. https://github.com/ruby/rubygems/commit/17acdd4a89
2025-11-25[ruby/uri] [DOC] Fix result of sample code in `#user=`Yuji Yaginuma
A `password` is cleared when change a user now. https://github.com/ruby/uri/commit/af6714473c
2025-11-24[ruby/forwardable] Use generic argument forwarding (...) instead of ↵Jeremy Evans
ruby2_keywords on Ruby 2.7+ On Ruby 3.4+, generic argument forwarding is significantly faster as it does not allocate. https://github.com/ruby/forwardable/commit/b606c3bf0a
2025-11-21[ruby/rubygems] Undeprecate Gem::Version#<=> against stringsJean Boussier
This pattern is extremely common across the ecosystem, I don't think it's reasonable to deprecate it. I understand the performance argument, but perhaps the dependency resolution algorithm can use another method that is private API and only works with two `Version` instance. https://github.com/ruby/rubygems/commit/024b4b547a
2025-11-21Fixed warning for String comparison of Gem::VersionHiroshi SHIBATA
2025-11-21[ruby/rubygems] Check for file existence before deletion from cachePhilip Arndt
(https://github.com/ruby/rubygems/pull/9095) * Rescue when deleting a non-existent cached gem file When a gem was in the cache, but another process deletes it first, this delete command fails. To work around this, I'm rescuing from Errno::ENOENT and swalling the error. The file is gone, and we can move on. * Apply suggestion from @kou Co-authored-by: Sutou Kouhei <kou@cozmixng.org> --------- https://github.com/ruby/rubygems/commit/b30bcbc648 Co-authored-by: Hiroshi SHIBATA <hsbt@ruby-lang.org> Co-authored-by: Sutou Kouhei <kou@cozmixng.org>
2025-11-21[ruby/rubygems] Respect `BUNDLE_VERSION` config at Gem::BundlerVersionFinderHiroshi SHIBATA
If we use "system" variable in BUNDLE_VERSION on Bundler configuration, we can use bundler version provided by system installation. But the current logic returns the first activated version of bundler like 2.7.2. It makes to confuse users. https://github.com/ruby/rubygems/commit/4eb66d9549
2025-11-21[ruby/rubygems] Deprecate comparing Gem::Version objects with stringsAaron Patterson
Comparing version objects is a huge bottleneck in dependency solvers (like inside Bundler). I would like to make comparing version objects cheaper. Right now we support comparing version objects with strings by trying to coerce the string to a version. So for example: ```ruby Gem::Version.new("1") <=> "12" ``` I would like to deprecate and remove support for this feature so that we can reduce the overhead of `def <=>`. I'm not sure what version of RubyGems we could remove this from though. https://github.com/ruby/rubygems/commit/81b7602183
2025-11-21[ruby/rubygems] create a gem version instead of comparing with a stringAaron Patterson
https://github.com/ruby/rubygems/commit/c1e3d4d63b
2025-11-21[ruby/rubygems] Fixed RuboCop offense in Rakefile generated by `bundle gem`sue445
``` Offenses: Rakefile:18:1: C: [Correctable] Layout/EmptyLines: Extra blank line detected. Diff: @@ -11,4 +11,5 @@ ext.lib_dir = "lib/test_gem" end + task default: :compile https://github.com/ruby/rubygems/commit/8c414729df
2025-11-21[ruby/rubygems] Add go_gem/rake_task for Go native extention gem skeletonsue445
https://github.com/ruby/rubygems/commit/64f92d2da0
2025-11-20[ruby/rubygems] Keep legacy windows platform, not removed themHiroshi SHIBATA
https://github.com/ruby/rubygems/commit/f360af8e3b
2025-11-20[ruby/rubygems] Add support for BUNDLE_LOCKFILE environment variableJeremy Evans
This specifies the lockfile location. This allows for easy support of different lockfiles per Ruby version or platform. https://github.com/ruby/rubygems/commit/b54d65bc0a Co-authored-by: Sutou Kouhei <kou@cozmixng.org> Co-authored-by: Colby Swandale <996377+colby-swandale@users.noreply.github.com>
2025-11-20[ruby/rubygems] Add support for bundle install --no-lockJeremy Evans
This allows for the same behavior as including `lockfile false` in the Gemfile. This allows you to get the behavior without modifying the Gemfile, which is useful if you do not control the Gemfile. This is similar to the --no-lock option already supported by `gem install -g Gemfile`. https://github.com/ruby/rubygems/commit/6c94623881 Co-authored-by: Colby Swandale <996377+colby-swandale@users.noreply.github.com>
2025-11-20[ruby/rubygems] Add support for lockfile in GemfileJeremy Evans
This allows you to specify the lockfile to use. This is useful if you want to use different lockfiles for different ruby versions or platforms. You can also skip writing the lockfile by using a false value. https://github.com/ruby/rubygems/commit/2896aa3fc2 Co-authored-by: Colby Swandale <996377+colby-swandale@users.noreply.github.com>
2025-11-20[ruby/rubygems] Make the Bundler logger thread safe:Edouard CHIN
- The Logger is not thread safe when calling `with_level`. This now becomes problematic because we are using multiple threads during the resolution phase in order to fetch git gems. https://github.com/ruby/rubygems/commit/380653ae74
2025-11-20[ruby/rubygems] Run git operations in parallel to speed things up:Edouard CHIN
- ### Problem When you have a Gemfile that contains git gems, each repository will be fetched one by one. This is extremelly slow. A simple Gemfile with 5 git gems (small repositories) can take up to 10 seconds just to fetch the repos. We can speed this up by running multiple git process and fetching repositories silmutaneously. ### Solution The repositories are fetched in Bundler when `Source::Git#specs` is called. The problem is that `source.specs` is called in various places depending on Gemfile. I think the issue is that calling `source.specs` feels like that as a "side effect" we are going to clone repositories. I believe that fetching repositories should be an explicit call. For instance: ```ruby source "https://rubygems.org" gem "foo", github: "foo/foo" # The repository foo will be fetched as a side effect to the call to `source.spec_names` # https://github.com/ruby/rubygems/blob/6cc7d71dac3d0275c9727cf200c7acfbf6c78d37/bundler/lib/bundler/source_map.rb#L21 ``` ```ruby source "https://rubygems.org" gem "bar", source: "https://example.org" gem "foo", github: "foo/foo" # The repository foo will be fetched on a different codepath # https://github.com/ruby/rubygems/blob/6cc7d71dac3d0275c9727cf200c7acfbf6c78d37/bundler/lib/bundler/source/rubygems_aggregate.rb#L35 # That is because the gem "bar" has a source that doesn't have the `/dependencies` API # endpoint and therefore Bundler enters a different branch condition. ``` I opted to add a self explanatory call to fetch the git source repositories just before we start the resolution, and *just* before any other calls to `source.specs` is performed. https://github.com/ruby/rubygems/commit/f0ef526f23
2025-11-20Support backwards compatibility for Set subclassesJeremy Evans
For subclasses from Set, require `set/subclass_compatible`, and extend the subclass and include a module in it that makes it more backwards compatible with the pure Ruby Set implementation used before Ruby 4. The module included in the subclass contains a near-copy of the previous Set implementation, with the following changes: * Accesses to `@hash` are generally replaced with `super` calls. In some cases, they are replaced with a call to another instance method. * Some methods that only accessed `@hash` and nothing else are not defined, so they inherit behavior from core Set. * The previous `Set#divide` implementation is not used, to avoid depending on tsort. This fixes the following two issues: * [Bug #21375] Set[] does not call #initialize * [Bug #21396] Set#initialize should call Set#add on items passed in It should also fix the vast majority of backwards compatibility issues in other cases where code subclassed Set and depended on implementation details (such as which methods call which other methods). This does not affect Set internals, so Set itself remains fast. For users who want to subclass Set but do not need to worry about backwards compatibility, they can subclass from Set::CoreSet, a Set subclass that does not have the backward compatibility layer included.
2025-11-20[ruby/rubygems] Bump up to 4.0.0.beta1Hiroshi SHIBATA
https://github.com/ruby/rubygems/commit/9be811c01a
2025-11-19[ruby/error_highlight] Fix prism_spot_def_for_name for singletonsJohn Hawthorn
Previously calling a singleton method with invalid arguments would give: RuntimeError: Incompatible locations This is because `join` wants the operator to come before the location https://github.com/ruby/error_highlight/commit/44920551dd
2025-11-19[ruby/rubygems] Use method_defined?(:method, false)Hiroshi SHIBATA
https://github.com/ruby/rubygems/commit/6cc7d71dac
2025-11-19[ruby/rubygems] Warn users that `bundle` now display the help:Edouard CHIN
- In https://github.com/ruby/rubygems/commit/31d67ecc056fb5a9193bc66a6e69e21576a87702 we enforced the new behaviour where running `bundle` no longer installs gems but displays the help. Users now have a way to configure their preferred default command using the `BUNDLE_DEFAULT_CLI_COMMAND` flag. With the preview of Ruby 4.0 now being released, some people will start to see this new change. The problem is that the previous behaviour had existed for like an eternity and we didn't warn users about this change in advance. I'd like to provide a deprecation/warning cycle because this is confusing users already and this breaks various CI setup that now needs to be changed immediately. https://github.com/ruby/rubygems/commit/e415480ac5
2025-11-19[ruby/rubygems] Handle BUNDLER_VERSION being set to an empty stringCody Cutrer
This is useful, in case you're using Docker, and an upstream Dockerfile sets BUNDLER_VERSION to something you don't want. It's impossible to unset it... only override to be the empty string. https://github.com/ruby/rubygems/commit/ffa3eb9ac6
2025-11-19[ruby/rubygems] Add `--ext=go` to `bundle gem`Go Sueyoshi
(https://github.com/ruby/rubygems/pull/8183) * Add new gem templates * Add `--ext=go` in `bundle gem` * Add setup-go to .github/workflows/main.yml * Embed go version in go.mod * Use go in bundler CI * Add example method to template * Install Go in .circleci/config.yml * Install Go in .gitlab-ci.yml * Allow hard tabs in go template * Run `rake update_manifest` * Fix test * Move go_gem to gemspec Respect to 9b0ec80 * nits: :golf: * includes valid module name in go.mod * generate header file * Run `go mod tidy` to create `go.sum` * Check if `go.sum` is generated only when Go is installed To avoid test failure in environments where Go is not installed * Run CI * Workaround for hung up c.f. https://github.com/rubygems/rubygems/actions/runs/11639408044/job/32415545422 * Write man for --ext=go * Re-generate man with `./bin/rake man:build` * pinning :pushpin: * Update with `./bin/rake man:build` * nits: Extract to method * nits: Use `sys_exec` instead of `system` * Clean go module cache after test Workaround following error ``` 1) bundle gem gem naming with underscore --ext parameter set with go includes go_gem extension in extconf.rb Failure/Error: FileUtils.rm_r(dir) Errno::EACCES: Permission denied @ apply2files - /home/runner/work/rubygems/rubygems/bundler/tmp/2.2/home/go/pkg/mod/gopkg.in/yaml.v3@v3.0.1/decode_test.go # ./spec/support/helpers.rb:37:in `block in reset!' # ./spec/support/helpers.rb:21:in `each' # ./spec/support/helpers.rb:21:in `reset!' # ./spec/spec_helper.rb:130:in `block (2 levels) in <top (required)>' # /home/runner/work/rubygems/rubygems/lib/rubygems.rb:303:in `load' # /home/runner/work/rubygems/rubygems/lib/rubygems.rb:303:in `activate_and_load_bin_path' ``` Files installed with `go get` have permissions set to 444 ref. https://github.com/golang/go/issues/35615 ``` $ ls -l /home/runner/work/rubygems/rubygems/bundler/tmp/2.2/home/go/pkg/mod/gopkg.in/yaml.v3@v3.0.1/decode_test.go -r--r--r-- 1 runner runner 42320 Nov 15 06:38 /home/runner/work/rubygems/rubygems/bundler/tmp/2.2/home/go/pkg/mod/gopkg.in/yaml.v3@v3.0.1/decode_test.go ``` So they cannot be deleted by `FileUtils.rm_r`. Therefore, this is necessary to execute `go clean -modcache` separately from `FileUtils.rm_r` to circumvent it. * Remove needless changes ref. https://github.com/ruby/rubygems/pull/8183#discussion_r2532902051 * ci: setup-go is needless * Don't run go command in `bundle gem` ref. https://github.com/ruby/rubygems/pull/8183#discussion_r2532765470 * Revert unrelated date changes --------- https://github.com/ruby/rubygems/commit/260d7d60b3 Co-authored-by: Hiroshi SHIBATA <hsbt@ruby-lang.org>
2025-11-19[ruby/rubygems] Replace instance method look up in plugin installereileencodes
`Gem::Installer.instance_methods(false).include?(:generate_plugins)` is 63x slower than `Gem::Installer.method_defined?(:generate_plugins)` in a microbenchmark. The latter is a direct lookup, whereas the former will create an array, which will be slower. ```ruby require "benchmark/ips" Benchmark.ips do |x| x.report "instance_methods" do Gem::Installer.instance_methods(false).include?(:generate_plugins) end x.report "method_defined" do Gem::Installer.method_defined?(:generate_plugins) end x.compare! end ``` ``` $ ruby -I lib/ benchmark_methods.rb ruby 3.4.4 (2025-05-14 revision https://github.com/ruby/rubygems/commit/a38531fd3f) +PRISM [arm64-darwin23] Warming up -------------------------------------- instance_methods 58.449k i/100ms method_defined 3.375M i/100ms Calculating ------------------------------------- instance_methods 541.874k (± 5.7%) i/s (1.85 μs/i) - 2.747M in 5.087825s method_defined 34.263M (± 1.1%) i/s (29.19 ns/i) - 172.135M in 5.024524s Comparison: method_defined: 34263189.1 i/s instance_methods: 541874.3 i/s - 63.23x slower ``` This does not make much difference in an overall benchmark or profile, but this is more idiomatic Ruby than the prior code. https://github.com/ruby/rubygems/commit/49dec52cb2
2025-11-18[ruby/rubygems] bin/rubocop -aHiroshi SHIBATA
https://github.com/ruby/rubygems/commit/fee8dd2f08
2025-11-18[ruby/rubygems] Removed unused SimilarityDetectorHiroshi SHIBATA
https://github.com/ruby/rubygems/commit/40ace48651