103359 Commits
Author SHA1 Message Date
Takashi Kokubun 1de408bb4d ZJIT: Don't profile singleton classes of non-module objects (#19540) 2026-10-27 17:02:34 -07:00
Hiroshi SHIBATAandClaude Opus 5.5 997e41e85f [ruby/rubygems] Hash Bundler::Source::Rubygems from its remotes without credentials
eql? ignores credentials, so two sources that differ only in them were equal but hashed differently, and the uniq! in SourceList kept both. The lockfile then got a duplicate GEM section for the same remote.

https://github.com/ruby/rubygems/issues/8472

https://github.com/ruby/rubygems/commit/c8f328ab49

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 00:01:00 +00:00
Hiroshi SHIBATAandClaude Opus 5.5 021446fa21 Fix the timeout of getaddrinfo with a nil host or service
Building the error message from a NULL pointer raised ArgumentError instead of IO::TimeoutError.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 08:42:54 +09:00
Hiroshi SHIBATAandClaude Opus 5.5 47d566434f mswin: Resolve hostnames in a dedicated thread
Without pthread, mswin fell back to GETADDRINFO_IMPL 1, which ignores the timeout of Addrinfo.getaddrinfo and lets neither Timeout, Thread#kill nor Thread#raise stop the caller until getaddrinfo(3) returns. Start the resolver thread with _beginthreadex(3) so mswin takes GETADDRINFO_IMPL 2 as the pthread platforms do. MinGW stays on GETADDRINFO_IMPL 1.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 08:42:54 +09:00
Hiroshi SHIBATAandClaude Opus 5.5 a98386e422 Drop the unused thread handle from the resolver thread creation
No caller reads the pthread_t, so raddrinfo_thread_create() no longer takes one, and a non-pthread implementation can sit behind it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 08:42:54 +09:00
Benoit DalozeandClaude Opus 5.5 db563a3578 Add a signal fence in rb_ec_clear_vm_stack()
Since the fix for Bug #21441, ec->cfp is set to NULL before clearing
the VM stack so that thread_profile_frames() called from a signal
handler returns early instead of walking a stack that is no longer set
on the ec. But these are plain stores to distinct fields of the same
struct, so the compiler is free to reorder them.

With Apple clang 21 and GCC 16 on macOS arm64, and with clang 18 and
GCC 13 on Linux aarch64, both stores of rb_ec_set_vm_stack() were
combined into a single stp emitted before the store to ec->cfp
(vm_stack is at offset 0, vm_stack_size at 0x8 and cfp at 0x10):

    stp xzr, xzr, [x0]        ; ec->vm_stack = NULL, vm_stack_size = 0
    str xzr, [x0, #0x10]      ; ec->cfp = NULL
    ret

So a signal in between would see a non-NULL ec->cfp with a NULL
ec->vm_stack. Stopping there in lldb when a thread terminates and
calling rb_profile_frames() segfaults in thread_profile_frames(), as
end_cfp is computed from the NULL ec->vm_stack and the loop walks past
the control frames. With this change, ec->cfp is already NULL at that
point and rb_profile_frames() returns 0.

Like in vm_push_frame(), use atomic_signal_fence() to keep the store to
ec->cfp first. With it, all these compilers emit the store to ec->cfp no
later than the stores clearing the stack. The rest of vm.o is unchanged
with Apple clang 21, GCC 16 and GCC 13 on aarch64. Clang 21 and 18:

    stp xzr, xzr, [x0, #0x8]  ; ec->vm_stack_size = 0, cfp = NULL
    str xzr, [x0]             ; ec->vm_stack = NULL
    ret

GCC 16 and 13:

    str xzr, [x0, #0x10]      ; ec->cfp = NULL
    stp xzr, xzr, [x0]        ; ec->vm_stack = NULL, vm_stack_size = 0
    ret

With GCC 13 on x86_64, the store to ec->cfp is already emitted first
without the fence, and vm.o is identical with and without it:

    endbr64
    movq $0x0, 0x10(%rdi)     ; ec->cfp = NULL
    movq $0x0, (%rdi)         ; ec->vm_stack = NULL
    movq $0x0, 0x8(%rdi)      ; ec->vm_stack_size = 0
    ret

[Bug #22477]

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 19:41:17 +01:00
95f21cd82c Fix fill_cbuf putting back more bytes than the current rbuf fill holds
The converter can still hold readagain bytes from an earlier rbuf fill,
so fill_cbuf must not put all of them back into the current rbuf. Clamp
the putback to the bytes taken from the current fill; the rest stay in
the converter and are re-read first on the next conversion.

Co-authored-by: Percze Dániel <162882837+Flashmyname@users.noreply.github.com>
Co-Authored-By: Claude Mythos 5.1 <noreply@anthropic.com>
2026-10-28 03:18:36 +09:00
Yusuke EndohandClaude Mythos 5.1 93c45a96b5 Check remaining pattern length in str_lower_case_match
A text character can case-fold to more bytes than remain in the
pattern, e.g. U+00DF folds to "ss" against /s/i.  Such a character
cannot match, so stop there instead of comparing beyond the pattern.

Reported-by: Paul Ryan (https://hackerone.com/secpaul)
Co-Authored-By: Claude Mythos 5.1 <noreply@anthropic.com>
2026-10-28 01:48:57 +09:00
femto 33ac6afea7 ZJIT: Mark String#% as returning StringExact (#19479)
rb_str_format always allocates its result with rb_str_buf_new, so the
result is a plain String even when the receiver is a subclass.

Fixes https://github.com/Shopify/ruby/issues/1085
2026-10-27 11:28:18 -04:00
dak2 93d313551b ZJIT: Test that NoEPEscape resumes after the call
Existing tests only read a local that eval wrote, which passes even if
the side exit resumed before the call. Pin the snapshot pc in an HIR
test and count how many times eval runs when the patch point fires.
2026-10-27 11:16:38 -04:00
Kevin Newton caf4f279d1 [ruby/prism] Test embedded in CI
Make sure we do not accidentally break newlib/ARM embedded consumers.

https://github.com/ruby/prism/commit/19762c99ce
2026-10-27 14:17:54 +00:00
Luke Gruber 25eb737f03 eliminate cross-TU calls to rb_vm_empty_cc()
rb_vm_empty_cc(), rb_vm_empty_cc_for_super() and rb_vm_uncached_cc()
shouldn't be real function calls. rb_iseq_mark_and_move was calling
these as real functions in a loop.
2026-10-27 09:49:20 -04:00
Luke Gruber ae2c6841c4 Don't create CCs for methods we assume are cold
The assumption is that we're usually calling these methods on boot, and they don't
need CCs. CCs scale with the number of classes that use these methods in the app, so
if you have 10k classes and these classes use 3 of these methods on average, then that
saves 30k CC objects.

Methods on Module that are marked cold are:

public, protected, private, module_function, ruby2_keywords, alias_method, undef_method,
remove_method, attr_reader, attr_writer, attr_accessor, include, prepend.

If these methods ever get redefined, they get new method definitions that are not
marked uncacheable (CCs will get created).

In one of our apps (not the largest), we observed this difference after boot:

| method            | before | after | delta       |
|-------------------|-------:|------:|------------:|
| `include`         |   4518 |     2 |       -4516 |
| `alias_method`    |   3921 |     0 |       -3921 |
| `ruby2_keywords`  |   3784 |     0 |       -3784 |
| `private`         |   3519 |     3 |       -3516 |
| `attr_reader`     |   2738 |     0 |       -2738 |
| `attr_accessor`   |   2288 |     0 |       -2288 |
| `prepend`         |    354 |     1 |        -353 |
| `protected`       |    303 |     0 |        -303 |
| `public`          |    302 |     0 |        -302 |
| `undef_method`    |    178 |     0 |        -178 |
| `attr_writer`     |    124 |     0 |        -124 |
| `module_function` |     42 |     0 |         -42 |
| `remove_method`   |     24 |     0 |         -24 |
| **total**         |        |       | **-22,089** |

NOTE: CC tables and ccs (the malloced struct) are still being created, so this only reduces
the CC objects themselves. I will tackle that in a follow-up.
2026-10-27 09:49:20 -04:00
Sutou KouheiandClaude Opus 4.8 32f06ce98c Don't retag the shared fstring via TYPE_UCLASS in Marshal.load
This is not a real-world problem. Marshal.dump never emits this payload.
It can only be hand-crafted. Loading untrusted Marshal data is already
unsafe. This fix only avoids false positives from security scanners.

TYPE_UCLASS ('C') relabels the wrapped object's class with RBASIC_SET_CLASS.
It assumes the object was freshly allocated during load. But with
freeze: true, r_leave() interns a wrapped bare String first, and
interning a bare String returns the shared global fstring. So the relabel
hits that global object instead, corrupting every other reference to the
same interned string.

Load the wrapped object as a partial so r_leave() is deferred, and
finalize it only after the class has been set. The String is then
interned as a non-bare String, which keeps the result a distinct object
instead of the shared fstring.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-27 20:50:14 +09:00
Nobuyoshi Nakada cda3527671 CI: Windows: Refactor setup/directories cleanup
Use the input values via environment variables directory, without a
separated step.  Retry to remove build directory for Windows.
2026-10-27 16:37:34 +09:00
Nobuyoshi Nakada 60ba00dfb7 CI: Windows: Remove WindowsApps from PATH to prevent post-run error 2026-10-27 13:39:03 +09:00
dependabot[bot] 9647794c89 Bump ruby/setup-ruby
Bumps the github-actions group with 1 update in the / directory: [ruby/setup-ruby](https://github.com/ruby/setup-ruby).


Updates `ruby/setup-ruby` from 1.334.0 to 1.335.0
- [Release notes](https://github.com/ruby/setup-ruby/releases)
- [Changelog](https://github.com/ruby/setup-ruby/blob/master/release.rb)
- [Commits](https://github.com/ruby/setup-ruby/compare/26e5b7d197ebf60545ee9667bcbace0be11ccaec...7f797815d8adceb1c412e7abefdd1ab4abc47a5f)

---
updated-dependencies:
- dependency-name: ruby/setup-ruby
  dependency-version: 1.335.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-10-27 11:47:35 +09:00
Hiroshi SHIBATAandClaude Opus 5.5 ee55edef0d Walk a fixed directory in the Ruby::Box Pathname#find test
Pathname.new('.').find walked the whole working directory twice, so the run time depended on where the tests were started. With an in-source build that is the entire checkout, which exceeded the 60 second timeout on rubyci's macOS machine. Only the lazy require of find matters here, so walking test/ruby is enough.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 09:58:14 +09:00
BurdetteLamar 892b5d7cbd [DOC] Doc for class MatchData 2026-10-27 09:54:05 +09:00
Hiroshi SHIBATAandClaude Opus 5.5 aed528a95c [ruby/rubygems] Rewrite the OVERRIDES section without resolving again
An override change made the lockfile count as needing resolution, so `bundle install` fetched the remote index and failed offline when the compact index cache was absent, and `Bundler.setup` re-resolved on boot. The section only needs to be regenerated, which #write_lock already does when the contents differ, and the frozen check still reports the change.

https://github.com/ruby/rubygems/commit/a616f3d1bb

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 00:42:50 +00:00
Hiroshi SHIBATAandClaude Mythos 5.1 12ebde9bf1 [ruby/rubygems] Limit the gemfile(5) promise that override changes keep locked versions
A locked gem that is not installed and whose metadata rejects the current Ruby is re-resolved during materialization whether or not an override changed, so the man page cannot promise that adding or removing a metadata override never moves a locked version.

https://github.com/ruby/rubygems/commit/c3e0897ff1

Co-Authored-By: Claude Mythos 5.1 <noreply@anthropic.com>
2026-10-27 00:42:49 +00:00
William T. NelsonandClaude Opus 5.5 b77c9f32dc [ruby/test-unit-ruby-core] Close stdin before terminating a
timed-out memory leak child
(https://github.com/ruby/test-unit-ruby-core/pull/37)

* Close stdin before terminating a timed-out memory leak child

With a sample range, assert_no_memory_leak keeps the child's stdin open,
and the child's ensure clause reads a "continue" line from it after each
sample. When the timeout fires while the child is running the sampled
code, EnvUtil.terminate sends SIGTERM, and the child's ensure clause
then blocks reading stdin, which was closed only after terminate
returned. SIGTERM cannot end the child, so terminate escalates to
SIGABRT and then waits for the aborted child without a time limit. On
ruby/ruby's YJIT macOS CI jobs the child sometimes did not exit after
the RUBY_ON_BUG core dump, and the test worker hung until the runner
killed it 20 minutes later. In other runs the test passed but left a
crash report for the child.

Close stdin first. The child's read then returns nil, and its ensure
clause breaks out of the sample loop. The break discards the
SignalException raised by SIGTERM, so the child exits with status 0. If
SIGTERM arrives before the child reaches the sample loop, the child
still dies from SIGTERM.

The existing timeout test now also checks that the child exited
normally or by SIGTERM.

https://github.com/ruby/test-unit-ruby-core/commit/ce7a92e724

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 00:23:25 +00:00
Takashi Kokubun 5167808893 Generate revision.h by configure in the build directory (#19545)
configure created revision.h in $srcdir when it was missing.  Since
version.h includes "revision.h", the copy in $srcdir is found before
the one in the build directory.

This used to be harmless because file2lastrev.rb, run with --srcdir,
overwrote that copy in $srcdir on every build.  Since 4361d8e48f
(GH-19367), make writes only ./revision.h via lastrev and ifchange, so
the copy in $srcdir was left stale, and every out-of-place build
sharing that $srcdir kept embedding the revision at the time of that
configure run.
2026-10-26 17:09:17 -07:00
Hiroshi SHIBATAandClaude Opus 5.5 c6c27d0320 Promote the Windows binary package when publishing a release
draft-release in ruby/actions stages an mswin binary zip next to the draft tarballs, but nothing promotes it to pub/ruby/binaries, so each release has needed a manual publish-binaries run. Dispatch it alongside the other post-release hooks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 08:33:16 +09:00
Takashi Kokubun db1bde0969 Skip rbs DirSingletonTest#test_for_fd to stop flaky EBADF (#19542)
test_for_fd in rbs 4.2.0 calls Dir.for_fd twice with the fd of a Dir it
then closes, and never closes the two Dirs Dir.for_fd returned. Both
still own that fd number. When GC later finalizes them, closedir()
closes whatever file has since been given the same number, and the
owner of that file fails on close with:

    Errno::EBADF: Bad file descriptor @ fptr_finalize_flush

In test-bundled-gems this usually hits FileTestSingletonTest, which
runs right after Dir_test.rb and opens files in every test. Whether it
fails depends on GC timing, so it shows up as a flake.

https://github.com/ruby/rbs/pull/3191 fixes the test upstream, but no released rbs has it yet.
Skip the test until the bundled rbs includes that fix.
2026-10-26 16:30:08 -07:00
Matt Valentine-House e14d739e26 Promote the ring before measuring oldmalloc major intervals
test_major_sweep_does_not_create_oldmalloc_debt assumed the ring was
already old when the loop started. When Ruby is running with parse.y
this isn't always the case. That only held when GCs ran while
the ring was built. Under parse.y often none did, so the ring was
still young after GC.start.

This means that Minor GCs freed the buffers before they got promoted and
so there isn't any old garbage to sweep.

This commit runs GC.start RVALUE_OLD_AGE times before the loop, so every
buffer in the ring is old and each replacement leaves old garbage for
the next major to sweep, regardless of startup GC history.
2026-10-26 22:01:25 +00:00
Luke Gruber 29264f878a Fix rb_gc_ever_multi_ractor_p to simply read the latch variable
In single-ractor mode, we don't want foreign_object_p checks to actually
run (there can be no foreign objspaces). This foreign_object_p check return
false if there was never a (non-main) Ractor created. Previously,
rb_gc_ever_multi_ractor_p() was needlessly complex. This change should
speed up marking and WB implementations in single-ractor mode.
2026-10-26 14:29:57 -04:00
Nobuyoshi Nakada 6b15825df0 Use digit scanner in the universal parser
Parser configuration no longer needs base-specific scanner callbacks.
2026-10-27 01:32:35 +09:00
HASUMI Hitoshi f2f9b55680 [ruby/prism] Let an embedder set PM_CONSTANT_POOL_MIN_CAPACITY
The constant pool starts at source size / 120 entries, 4 at the least,
and doubles at a load of 3/4; each outgrown pair of arrays stays in the
metadata arena. An embedder that interns a fixed set of names into the
pool at every parse (mruby's compiler puts its 58 presyms there, as its
symbol table) grows a short program's pool from 4 to 128 and leaves
about 3 KB behind, as much as the pool itself. With the minimum under
#ifndef it can build with -DPM_CONSTANT_POOL_MIN_CAPACITY=128: measured
on a 32-bit build with 2 KB arena blocks, parsing one REPL line then
holds 6 KB instead of 10 KB. The default stays 4.

https://github.com/ruby/prism/commit/7ed8c71c59
2026-10-26 15:44:00 +00:00
HASUMI Hitoshi ab52c6ab86 [ruby/prism] Include sys/types.h before inttypes.h again, for newlib
61ebe5123 made defines.h include <sys/types.h> ahead of <inttypes.h>:
with an arm-none-eabi toolchain whose <stdint.h> is GCC's own, newlib's
<inttypes.h> never sees the marker it tests before defining the 64-bit
PRI macros, and PRIu64 goes undefined while PRIu32 does not. 400b21739
("Remove defines") took the header out and the workaround with it, so
a cross build of integer.c and errors_format.c, the two files that
include <inttypes.h> now, fails on such a toolchain (Debian's
gcc-arm-none-eabi 13.2.1 with newlib). Put the include back in those
two files, with the note.

https://github.com/ruby/prism/commit/ff42521e49
2026-10-26 15:43:58 +00:00
HASUMI Hitoshi 10c945beab [ruby/prism] Let an embedder set PM_ARENA_INITIAL_SIZE
The arena's first block is 8 KB, sized for a host. An embedder on a
small heap parses short programs (a REPL line uses about 6 KB in two
arenas) and pays two 8 KB blocks for each; with the constant under
#ifndef it can build with -DPM_ARENA_INITIAL_SIZE=2048 instead.

https://github.com/ruby/prism/commit/f7a062efd4
2026-10-26 15:43:57 +00:00
Kevin Newton 51f2767aa0 [ruby/prism] Avoid vsnprintf when possible
When formatting error messages, first try to format into a fixed
buffer instead of formatting once to get the length then a second
time to get the actual format.

https://github.com/ruby/prism/commit/557cffe23e
2026-10-26 15:38:14 +00:00
Peter Zhu 3e63685771 Use delta zigzag encoding for iseq node_id
Node ids are assigned sequentially by the parser and compilation emits
instructions in an order correlated with the tree, so the delta between
consecutive instructions are likely to be small. We can store the delta
between consecutive instructions using zigzag encoding.

On Shopify's monolith, this reduces the boot heap memsize by 20MB.
2026-10-26 20:21:04 +09:00
Yusuke EndohandClaude Opus 5.5 b861e2ba10 Skip Addrinfo specs unsupported by musl as on Android
musl getaddrinfo does not support SOCK_SEQPACKET and getnameinfo does
not support AF_UNIX.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 17:21:03 +09:00
Yusuke EndohandClaude Opus 5.5 21e6dea114 Fix Time specs that depend on the TZ parsing of glibc
* Time#utc_offset: use America/New_York, as musl parses "EST5EDT" as
  a POSIX TZ string instead of loading the zoneinfo file.
* Time#zone: musl accepts "hello-foo" as a POSIX TZ string.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 17:21:03 +09:00
Yusuke EndohandClaude Opus 5.5 e7f03c8f28 Skip the Encoding.locale_charmap spec for the C locale on musl
musl does not return "ANSI_X3.4-1968" for the C locale.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 17:21:03 +09:00
Yusuke EndohandClaude Opus 5.5 1749dbbebe Read /proc/<pid>/cmdline to check the process title if available
Process.setproctitle and $0 specs used `ps -ocommand= -p`, but busybox
ps does not support -o/-p.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 17:21:03 +09:00
Yusuke EndohandClaude Opus 5.5 3d973f2b5a Skip argv[0] specs of Process.spawn and Process.exec on busybox /bin/sh
busybox is a multi-call binary which dispatches on argv[0], so it
cannot run as /bin/sh with an arbitrary argv[0] such as "argv_zero".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 17:21:03 +09:00
Hiroshi SHIBATAandClaude Opus 5.5 5d1d072289 [ruby/zlib] Fix the rdoc of Zlib::Inflate#sync
It described the return values the other way around, and did not mention Zlib::InProgressError.

https://github.com/ruby/zlib/commit/bbff886734

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 07:29:52 +00:00
Hiroshi SHIBATAandClaude Opus 5.5 20a9f1a53d [ruby/zlib] Raise InProgressError from Zlib::Inflate#sync during inflate
Called from the block of Zlib::Inflate#inflate, #sync pointed next_in at its argument, and the inflate loop kept reading from there after the block returned.

https://github.com/ruby/zlib/commit/f7822c93e7

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 07:29:52 +00:00
Farid Zakaria 0b5272459c [ruby/rubygems] Add checksums after platform changes in bundle lock
`bundle lock --add-checksums --add-platform arm64-darwin` wrote a
lockfile that listed arm64-darwin under PLATFORMS but carried none of
its platform-specific gems. `Definition#add_checksums` resolves the
bundle to fetch the checksums, and it ran before the platform options
were applied, so the resolution never saw the new platform.

This usually went unnoticed. `SpecSet#add_extra_platforms!` tries to
complete every platform the sources know about, and for most bundles
that added the darwin gems anyway. It stops working as soon as one gem
has a precompiled darwin build whose `required_ruby_version` excludes
the current Ruby (bcrypt_pbkdf 1.1.2 on Ruby 3.4): `complete_platform`
then gives up on darwin for every gem, and the lockfile ends up listing
a platform it has no gems for. Running `bundle lock` again does not
repair it, because the platform is already listed.

Apply `--add-checksums` after the platform changes have been recorded.

https://github.com/ruby/rubygems/commit/2f1d325fc2
2026-10-26 06:39:10 +00:00
Islam Elsayed eeb0e37a3e [ruby/rubygems] Drop the comment on the retry
https://github.com/ruby/rubygems/commit/12dc1f7743
2026-10-26 06:23:37 +00:00
Islam Elsayed a36b26e06b [ruby/rubygems] Apply BUNDLE_RETRY to lazy gemspec downloads
Resolving through the full-index API lazily downloads individual
gemspecs from /quick/Marshal.4.8/*.gemspec.rz. `Fetcher#fetch_spec` made
that request bare:

    Bundler.safe_load_marshal Bundler.rubygems.inflate(downloader.fetch(uri).body)

while `specs_with_retry`, in the same class, wraps its network call in
`Bundler::Retry`. So a single transient failure — a read timeout, say —
aborted the whole resolution, no matter what BUNDLE_RETRY was set to.
That is most painful without a lockfile, where a resolve can fetch a
great many gemspecs one at a time and any one of them can end it.

Wrap the download in the same `Bundler::Retry.new("fetcher", FAIL_ERRORS)`
the index path already uses. FAIL_ERRORS is what keeps this from retrying
things that will not change, such as authentication failures.

Only the download branch is wrapped. The file:// and cached-gemspec
branches do no network I/O, so retrying them would just repeat a local
failure.

Closes https://github.com/ruby/rubygems/pull/9817

https://github.com/ruby/rubygems/commit/9578cf9e93
2026-10-26 06:23:37 +00:00
Hiroshi SHIBATAandClaude Opus 5.5 5223de67e8 mkmf: Skip debug info in link checks on macOS
A link check compiles and links conftest.c in one clang invocation, and with -g clang then runs dsymutil, which reads the DWARF of every object pulled in from libruby-static.a. Each check took about 2.2 s instead of 0.17 s on a static build.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 15:00:55 +09:00
Hiroshi SHIBATAandClaude Opus 5.5 329d9a513f [ruby/rubygems] Skip only a missing bin directory, before asking about executables
The check ran after the prompt, so the user was still asked about executables that could not exist. File.directory? also returned false when a parent directory was not searchable, which skipped the executables and removed the gem anyway. Only ENOENT skips now, and other errors still reach the writable check.

https://github.com/ruby/rubygems/commit/ed96042879

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 05:41:20 +00:00
Nacl-HCl 1a39db7084 [ruby/rubygems] Skip executable removal gracefully when the bin directory is missing
Fixes ruby/rubygems#9959

remove_executables raised Gem::FilePermissionError when the gem's bin
directory did not exist at all, since File.writable? is false for a
missing directory and aborting uninstall entirely was never intended.
Now the missing directory case returns early: there is nothing to
remove.

https://github.com/ruby/rubygems/commit/03d22cfba8
2026-10-26 05:41:19 +00:00
Hiroshi SHIBATAandClaude Opus 5.5 542d4e2ade [ruby/rubygems] Omit the lock handover test on JRuby on Windows
The waiting thread's flock fails with Errno::EINVAL there when another thread of the same JVM already locks the file. Separate processes, which are what the lock guards against, are not affected.

https://github.com/ruby/rubygems/commit/ddc674293b

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 05:29:46 +00:00
Richard Janita 3541b9e034 [ruby/rubygems] Fix file locks letting multiple processes in when lock files are removed
Gem.open_file_with_lock removed its lock file after releasing the lock.
Since flock locks the file itself rather than its path, a process that
was waiting on the old file could acquire it after it had been removed,
while a newly arriving process created a fresh lock file and locked it
immediately, so both ran at the same time.

Remove the lock file while still holding the lock, and after acquiring
it, check that the locked file is still the one at the lock path,
retrying otherwise.

https://github.com/ruby/rubygems/commit/9a93c235e7
2026-10-26 05:29:46 +00:00
Shaisolaris 05fc71fb34 [ruby/rubygems] Preload git sources that share a cache one after another
Gems sourced from the same git repository share one cache directory.
Since git sources are preloaded in parallel, two workers could run git
fetch in that directory at the same time, and the fetches collided on
the shallow file and its lock, failing bundle install.

Group the sources by cache path and preload each group in a single job,
so sources sharing a cache run one after another while separate
repositories still run in parallel.

Fixes https://github.com/ruby/rubygems/pull/9946

https://github.com/ruby/rubygems/commit/c20901e6a1
2026-10-26 05:29:30 +00:00
Yusuke EndohandClaude Opus 5.5 fd77a0a2a0 leakchecker.rb: Ignore lsof that does not print the expected header
busybox lsof ignores the options and prints no header line, so the
FD/TYPE/NODE columns cannot be found and check_fd_leak crashed with
NoMethodError, which killed the test worker. Treat such lsof as
unavailable; leaked fds are still reported.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 14:05:30 +09:00