Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
18225b5
[DOC] Doc for File::absolute_path?
BurdetteLamar Aug 2, 2026
60c8296
[DOC] Improve docs for GC.start
peterzhu2118 Aug 2, 2026
dcf8847
[ruby/io-console] `IO#tty?` extension is unsupported on Cygwin
nobu Aug 3, 2026
6a9a387
[ruby/io-console] [DOC] Prevent RDoc from referencing internal modules
nobu Aug 3, 2026
f622e12
Bump github.com/microsoft/vcpkg from 2026.06.24 to 2026.07.29
dependabot[bot] Aug 3, 2026
e59558c
Fix operand in the update_global_event_hooks assertion
ko1 Jul 31, 2026
dca45c2
compile.c: pass the new operand ci to the write barrier, not the INSN
ko1 Aug 1, 2026
568dde7
Add NEWS entry for net-ftp and net-pop removal [Feature #21835]
hsbt Aug 3, 2026
bcddad7
Add NEWS entry for lazy loading of error decoration gems [Feature #21…
hsbt Aug 3, 2026
b5ae03c
Add NEWS entry for removed EOL platform support
hsbt Aug 3, 2026
bc5ce15
Add NEWS entry for experimental libfyaml backend of psych
hsbt Aug 3, 2026
f364e19
Link the psych libfyaml NEWS entry to ruby/psych#805
hsbt Aug 3, 2026
863175b
[ruby/rubygems] Split Gem::Security.write into write_private_key and …
junaruga Jul 17, 2026
f241c03
[ruby/rubygems] Replace OpenSSL::PKey::{RSA,DSA,EC}#to_pem
junaruga Jul 17, 2026
f274014
[ruby/rubygems] Recreated testing .pem files.
junaruga Jul 17, 2026
01a0597
[ruby/rubygems] Remove hardcoded key-dependent values from tests
junaruga Jul 17, 2026
53b7087
[ruby/rubygems] Remove #private? check from open_private_key and chec…
junaruga Jul 17, 2026
8d75aff
[ruby/rubygems] Guard RubyGems' YAML serializer against double loading
hsbt Aug 3, 2026
5f07e13
[ruby/rubygems] Ship RubyGems' YAML serializer in the Bundler gem
hsbt Aug 3, 2026
9f7e05c
[ruby/rubygems] Use RubyGems' YAML serializer in Bundler
hsbt Aug 3, 2026
f71a863
[ruby/rubygems] Port Bundler's YAML serializer specs to the RubyGems …
hsbt Aug 3, 2026
3ad19fa
[ruby/rubygems] Drop Bundler's stub YAML serializer
hsbt Aug 3, 2026
1f48cf8
[ruby/rubygems] Adapt the plugin index to Gem::YAMLSerializer semantics
Aug 3, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,13 @@ Note: We're only listing outstanding class updates.

## Stdlib updates

* Psych

* An experimental libfyaml backend has been added. It is only
enabled when psych is built with `--enable-libfyaml`, and the
default libyaml backend remains unchanged otherwise. It is not
supported on Windows. [[GH-psych #805]]

### The following bundled gems are added.


Expand All @@ -117,6 +124,14 @@ releases.
* tsort 0.2.0
* win32-registry 0.1.2

### The following bundled gems are removed.

* net-ftp 0.3.9
* net-pop 0.1.2

They are still available on rubygems.org and can be installed with
`gem install`. [[Feature #21835]]

### The following default gem is added.

### The following default gems are updated.
Expand Down Expand Up @@ -193,6 +208,14 @@ Ruby 4.0 bundled RubyGems and Bundler version 4. see the following links for det

## Supported platforms

* Support code for the following platforms has been removed. Note
that all of them reached end of life many years ago and Ruby has
long been unbuildable on them.

* Interix (Windows Services for UNIX)
* SunOS 4 (Solaris, i.e. SunOS 5, is unaffected)
* BSD/OS (BSDi)

## Compatibility issues

* `Kernel#at_exit` and `END {}` now raise `Ractor::IsolationError` when called
Expand Down Expand Up @@ -240,6 +263,12 @@ The following APIs, which have been deprecated for many years, are removed.

- The default garbage collector has been switched from a freelist allocator to a bump pointer allocator. [[PR #17201]]

- The error_highlight, did_you_mean, and syntax_suggest gems are now
loaded lazily on the first error display instead of at interpreter
boot, which reduces startup time. `Process.warmup` loads them
eagerly so that pre-forking servers keep their code in
copy-on-write shared memory. [[Feature #21951]]

### Ractor

A lot of work has gone into making Ractors more stable, performant, and usable. These improvements bring Ractor implementation closer to leaving experimental status.
Expand All @@ -254,9 +283,11 @@ A lot of work has gone into making Ractors more stable, performant, and usable.
[Feature #21781]: https://bugs.ruby-lang.org/issues/21781
[Feature #21785]: https://bugs.ruby-lang.org/issues/21785
[Feature #21796]: https://bugs.ruby-lang.org/issues/21796
[Feature #21835]: https://bugs.ruby-lang.org/issues/21835
[Feature #21853]: https://bugs.ruby-lang.org/issues/21853
[Feature #21861]: https://bugs.ruby-lang.org/issues/21861
[Feature #21932]: https://bugs.ruby-lang.org/issues/21932
[Feature #21951]: https://bugs.ruby-lang.org/issues/21951
[Feature #21981]: https://bugs.ruby-lang.org/issues/21981
[Feature #22097]: https://bugs.ruby-lang.org/issues/22097
[Feature #22135]: https://bugs.ruby-lang.org/issues/22135
Expand All @@ -265,6 +296,7 @@ A lot of work has gone into making Ractors more stable, performant, and usable.
[Feature #22175]: https://bugs.ruby-lang.org/issues/22175
[Feature #22185]: https://bugs.ruby-lang.org/issues/22185
[PR #17201]: https://github.com/ruby/ruby/pull/17201
[GH-psych #805]: https://github.com/ruby/psych/pull/805
[RubyGems-v4.0.4]: https://github.com/rubygems/rubygems/releases/tag/v4.0.4
[RubyGems-v4.0.5]: https://github.com/rubygems/rubygems/releases/tag/v4.0.5
[RubyGems-v4.0.6]: https://github.com/rubygems/rubygems/releases/tag/v4.0.6
Expand Down
2 changes: 1 addition & 1 deletion compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -5857,7 +5857,7 @@ compile_massign_lhs(rb_iseq_t *iseq, LINK_ANCHOR *const pre, LINK_ANCHOR *const
ci = ci_flag_set(iseq, ci, VM_CALL_ARGS_SPLAT_MUT);
}
OPERAND_AT(iobj, 0) = (VALUE)ci;
RB_OBJ_WRITTEN(iseq, Qundef, iobj);
RB_OBJ_WRITTEN(iseq, Qundef, ci);

/* Given: h[*a], h[*b, 1] = ary
* h[*a] uses splatarray false and does not set VM_CALL_ARGS_SPLAT_MUT,
Expand Down
11 changes: 5 additions & 6 deletions ext/io/console/console.c
Original file line number Diff line number Diff line change
Expand Up @@ -1916,14 +1916,14 @@ console_ttyname(VALUE io)

typedef enum {
platform_default,
#if defined _WIN32 || defined __CYGWIN__
#if defined _WIN32
platform_cygwin,
platform_msys,
#endif
platform_any,

platform_default_bit = 1U << platform_default,
#if defined _WIN32 || defined __CYGWIN__
#if defined _WIN32
platform_cygwin_bit = 1U << platform_cygwin,
platform_msys_bit = 1U << platform_msys,
#endif
Expand Down Expand Up @@ -1965,7 +1965,7 @@ console_platform_tty_p(int argc, VALUE *argv, VALUE io)
if (m == ID2SYM(rb_intern("any"))) {
mode |= platform_any_bit;
}
#if defined _WIN32 || defined __CYGWIN__
#if defined _WIN32
else if (m == ID2SYM(rb_intern("cygwin"))) {
mode |= platform_cygwin_bit;
}
Expand All @@ -1982,7 +1982,7 @@ console_platform_tty_p(int argc, VALUE *argv, VALUE io)
ret = rb_call_super(0, 0);
}
if ((mode & ~platform_default_bit) && !RTEST(ret)) {
#if defined _WIN32 || defined __CYGWIN__
#if defined _WIN32
if (mode & (platform_cygwin_bit | platform_msys_bit)) {
struct {
FILE_NAME_INFO info;
Expand Down Expand Up @@ -2080,9 +2080,8 @@ InitVM_console(void)
rb_define_method(rb_cIO, "getpass", console_getpass, -1);
rb_define_method(rb_cIO, "ttyname", console_ttyname, 0);
{
/* :stopdoc: */
/* :nodoc: */
VALUE platform = rb_define_module_under(rb_cIO, "platform_tty");
/* :startdoc: */
{
VALUE rb_cIO = platform;
rb_define_method(rb_cIO, "tty?", console_platform_tty_p, -1);
Expand Down
20 changes: 16 additions & 4 deletions file.c
Original file line number Diff line number Diff line change
Expand Up @@ -4762,13 +4762,25 @@ s_absolute_path(int c, const VALUE * v, VALUE _)
}

/*
* :markup: markdown
*
* call-seq:
* File.absolute_path?(file_name) -> true or false
* File.absolute_path?(path) -> true or false
*
* Returns <code>true</code> if +file_name+ is an absolute path, and
* <code>false</code> otherwise.
* Returns whether the given `path` is an absolute path:
*
* ```ruby
* File.absolute_path?('/home') # => true
* File.absolute_path?('lib') # => false
* ```
*
* The result is OS-dependent for some paths:
*
* ```ruby
* File.absolute_path?('C:/') # => true # On Windows.
* File.absolute_path?('C:/') # => false # Elsewhere.
* ```
*
* File.absolute_path?("c:/foo") #=> false (on Linux), true (on Windows)
*/

static VALUE
Expand Down
12 changes: 6 additions & 6 deletions gc.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,28 +12,28 @@ module GC
# Keyword arguments:
#
# - +full_mark+:
# its boolean value determines whether to perform a major garbage collection cycle:
# a boolean value specifying whether to perform a major garbage collection cycle:
#
# - +true+: initiates a major garbage collection cycle,
# meaning all objects (old and new) are marked.
# - +false+: initiates a minor garbage collection cycle,
# meaning only young objects are marked.
#
# - +immediate_mark+:
# its boolean value determines whether to perform incremental marking:
# a boolean value specifying whether marking is performed incrementally:
#
# - +true+: marking is completed before the method returns.
# - +false+: marking is performed by parts,
# - +false+: marking is performed in parts,
# interleaved with program execution both before the method returns and afterward;
# therefore marking may not be completed before the return.
# Note that if +full_mark+ is +false+, marking will always be immediate,
# Note that if +full_mark+ is +false+, marking is always immediate,
# regardless of the value of +immediate_mark+.
#
# - +immediate_sweep+:
# its boolean value determines whether to defer sweeping (using lazy sweep):
# a boolean value specifying whether sweeping is deferred (lazy sweep):
#
# - +true+: sweeping is completed before the method returns.
# - +false+: sweeping is performed by parts,
# - +false+: sweeping is performed in parts,
# interleaved with program execution both before the method returns and afterward;
# therefore sweeping may not be completed before the return.
#
Expand Down
7 changes: 4 additions & 3 deletions lib/bundler/bundler.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,12 @@ Gem::Specification.new do |s|

s.files = Dir.glob("lib/bundler{.rb,/**/*}", File::FNM_DOTMATCH).reject {|f| File.directory?(f) }

# Bundler reuses RubyGems' vendored URI and SecureRandom. Ship a copy under
# lib/rubygems so Bundler stays self-contained on RubyGems versions that
# predate them.
# Bundler reuses RubyGems' vendored URI and SecureRandom and its pure-Ruby
# YAML serializer. Ship a copy under lib/rubygems so Bundler stays
# self-contained on RubyGems versions that predate them.
s.files += Dir.glob("lib/rubygems/vendor/uri/**/*", File::FNM_DOTMATCH).reject {|f| File.directory?(f) }
s.files += Dir.glob("lib/rubygems/vendor/securerandom/**/*", File::FNM_DOTMATCH).reject {|f| File.directory?(f) }
s.files += Dir.glob("lib/rubygems/yaml_serializer.rb")

# include the gemspec itself because warbler breaks w/o it
s.files += %w[lib/bundler/bundler.gemspec]
Expand Down
16 changes: 9 additions & 7 deletions lib/bundler/plugin/index.rb
Original file line number Diff line number Diff line change
Expand Up @@ -171,14 +171,16 @@ def load_index(index_file, global = false)

data = index_f.read

require_relative "../yaml_serializer"
index = YAMLSerializer.load(data)
require "rubygems/yaml_serializer"
# Empty sections load as nil, e.g. from index files written by
# older Bundler versions, which dumped empty hashes as a bare key.
index = Gem::YAMLSerializer.load(data) || {}

@commands.merge!(index["commands"])
@hooks.merge!(index["hooks"])
@commands.merge!(index["commands"] || {})
@hooks.merge!(index["hooks"] || {})
@load_paths.merge!(transform_index_paths(index["load_paths"]) {|p| absolutize_path(p, base) })
@plugin_paths.merge!(transform_index_paths(index["plugin_paths"]) {|p| absolutize_path(p, base) })
@sources.merge!(index["sources"]) unless global
@sources.merge!(index["sources"] || {}) unless global
end
end

Expand All @@ -196,10 +198,10 @@ def save_index
"sources" => @sources,
}

require_relative "../yaml_serializer"
require "rubygems/yaml_serializer"
SharedHelpers.filesystem_access(index_file) do |index_f|
FileUtils.mkdir_p(index_f.dirname)
File.open(index_f, "w") {|f| f.puts YAMLSerializer.dump(index) }
File.open(index_f, "w") {|f| f.puts Gem::YAMLSerializer.dump(index) }
end
end

Expand Down
6 changes: 2 additions & 4 deletions lib/bundler/settings.rb
Original file line number Diff line number Diff line change
Expand Up @@ -504,12 +504,10 @@ def load_config(config_file)
end

def serializer_class
# The Bundler gem ships its own copy of Gem::YAMLSerializer, so this
# resolves even on RubyGems versions that predate it.
require "rubygems/yaml_serializer"
Gem::YAMLSerializer
rescue LoadError
# TODO: Remove this when RubyGems 3.4 is EOL
require_relative "yaml_serializer"
YAMLSerializer
end

FALLBACK_TIMEOUT_URI_OPTION = "fallback_timeout"
Expand Down
98 changes: 0 additions & 98 deletions lib/bundler/yaml_serializer.rb

This file was deleted.

8 changes: 3 additions & 5 deletions lib/rubygems/commands/cert_command.rb
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,6 @@ def open_private_key(key_file)
check_openssl
passphrase = ENV["GEM_PRIVATE_KEY_PASSPHRASE"]
key = OpenSSL::PKey.read File.read(key_file), passphrase
raise Gem::OptionParser::InvalidArgument,
"#{key_file}: private key not found" unless key.private?
key
rescue Errno::ENOENT
raise Gem::OptionParser::InvalidArgument, "#{key_file}: does not exist"
Expand Down Expand Up @@ -161,7 +159,7 @@ def build_cert(email, key) # :nodoc:
Gem::Security::ONE_DAY * expiration_length_days
)

Gem::Security.write cert, "gem-public_cert.pem"
Gem::Security.write_certificate cert, "gem-public_cert.pem"
end

def build_key # :nodoc:
Expand All @@ -178,7 +176,7 @@ def build_key # :nodoc:

algorithm = options[:key_algorithm] || Gem::Security::DEFAULT_KEY_ALGORITHM
key = Gem::Security.create_key(algorithm)
key_path = Gem::Security.write key, "gem-private_key.pem", 0o600, passphrase
key_path = Gem::Security.write_private_key key, "gem-private_key.pem", 0o600, passphrase

[key, key_path]
end
Expand Down Expand Up @@ -298,7 +296,7 @@ def sign(cert_file)

cert = Gem::Security.sign cert, issuer_key, issuer_cert

Gem::Security.write cert, cert_file, permissions
Gem::Security.write_certificate cert, cert_file, permissions
end

def sign_certificates # :nodoc:
Expand Down
Loading