Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
53a0811
win32: Run mkdepend with baseruby, not with the just built ruby
hsbt Sep 4, 2026
6af323a
win32: Record --without-ext in configure_args just once
hsbt Sep 4, 2026
9adbd81
[ruby/rubygems] Read Bundler's settings from RubyGems through one helper
hsbt Sep 4, 2026
7a6d50a
[ruby/rubygems] Wire the --cooldown flag through one method
hsbt Sep 4, 2026
c709569
[ruby/rubygems] Let the gem and bundle cooldown settings cover each o…
hsbt Sep 4, 2026
8c22dc4
[ruby/rubygems] Report the gemrc cooldown from bundle config
hsbt Sep 4, 2026
2b3a89a
[ruby/rubygems] Clear BUNDLE_COOLDOWN for the RubyGems test suite
hsbt Sep 4, 2026
232354d
Bump the github-actions group across 2 directories with 2 updates
dependabot[bot] Sep 4, 2026
5c54382
Pass XLDFLAGS when linking exe/ruby
hsbt Sep 3, 2026
f1065ae
Restore ldflags from a reused extension Makefile
hsbt Sep 3, 2026
cf96433
Name the missing directories when LDFLAGS is rejected
hsbt Sep 3, 2026
ef21bf4
Document --with-static-linked-ext
hsbt Sep 3, 2026
3c3a34a
Handle a -L option separated from its path
hsbt Sep 3, 2026
5efd4ad
Drop the GNU make note from --with-static-linked-ext
hsbt Sep 3, 2026
b0a25ca
Split the Etc.getlogin spec per platform
hsbt Sep 4, 2026
f100344
Compare Etc.getlogin with ENV['USER'] on Windows
hsbt Sep 4, 2026
bfaf35d
Note the Windows Etc.getlogin change in NEWS
hsbt Sep 4, 2026
2d663d5
runruby.rb: Ask baseruby for its effective CA bundle on Windows
hsbt Sep 4, 2026
eb2dc8c
Make rb_f_require_relative static
peterzhu2118 Sep 2, 2026
6a91edf
[ruby/rubygems] Stamp built_at from the changelog header template
hsbt Sep 4, 2026
f9da0fe
[ruby/rubygems] Cut one changelog for RubyGems and Bundler
hsbt Sep 4, 2026
4286a1e
[ruby/rubygems] Fold the Bundler changelog into CHANGELOG.md
hsbt Sep 4, 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
2 changes: 1 addition & 1 deletion .github/actions/setup/directories/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ runs:
INPUT_MAKE_COMMAND: ${{ inputs.make-command }}

- name: clean
uses: gacts/run-and-post-run@598d7a875d5620e0457490555b5e18e46082aa47 # v1.4.4
uses: gacts/run-and-post-run@fc6503862aba998e2f2123225ad63c09a92ed46e # v1.4.5
with:
working-directory:
post: |
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/zjit-macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ jobs:
rustup install ${{ matrix.rust_version }} --profile minimal
rustup default ${{ matrix.rust_version }}

- uses: taiki-e/install-action@1ed6d7be6168f6c9046541087ff549b6bc581fdf # v2.87.2
- uses: taiki-e/install-action@0758d235715de2f3551eacc980d9ae8fce9342c3 # v2.87.3
with:
tool: nextest@0.9
if: ${{ matrix.test_task == 'zjit-check' }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/zjit-ubuntu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ jobs:
ruby-version: '3.1'
bundler: none

- uses: taiki-e/install-action@1ed6d7be6168f6c9046541087ff549b6bc581fdf # v2.87.2
- uses: taiki-e/install-action@0758d235715de2f3551eacc980d9ae8fce9342c3 # v2.87.3
with:
tool: nextest@0.9
if: ${{ matrix.test_task == 'zjit-check' }}
Expand Down
4 changes: 4 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,10 @@ Ruby 4.0 bundled RubyGems and Bundler version 4. see the following links for det

## Stdlib compatibility issues

* `Etc.getlogin` on Windows now returns the login name determined when the
process starts, from the `USER` or `USERNAME` environment variable or
`GetUserName()`. It used to follow later changes to `ENV['USER']`.

## C API updates

### Embedded TypedData
Expand Down
2 changes: 1 addition & 1 deletion common.mk
Original file line number Diff line number Diff line change
Expand Up @@ -1065,7 +1065,7 @@ $(PLATFORM_D):
exe/$(PROGRAM): $(TIMESTAMPDIR)/$(arch)/.time
exe/$(PROGRAM): ruby-runner.c ruby-runner.h exe/.time $(PREP) {$(VPATH)}config.h
$(Q) $(CC) $(CFLAGS) $(INCFLAGS) $(CPPFLAGS) -DRUBY_INSTALL_NAME=$(@F) $(COUTFLAG)ruby-runner.$(OBJEXT) -c $(CSRCFLAG)$(srcdir)/ruby-runner.c
$(Q) $(PURIFY) $(CC) $(CFLAGS) $(LDFLAGS) $(OUTFLAG)$@ ruby-runner.$(OBJEXT) $(LIBS)
$(Q) $(PURIFY) $(CC) $(CFLAGS) $(LDFLAGS) $(XLDFLAGS) $(OUTFLAG)$@ ruby-runner.$(OBJEXT) $(LIBS)
$(Q) $(POSTLINK)
$(Q) $(BOOTSTRAPRUBY) \
-e 'prog, dest, inst = ARGV; dest += "/ruby"' \
Expand Down
13 changes: 12 additions & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -698,7 +698,18 @@ RUBY_WERROR_FLAG([
[
cd .. && rm -fr tmp.$$.try_link
AC_MSG_RESULT(no)
AC_MSG_ERROR([something wrong with LDFLAGS="$LDFLAGS"])
rb_ldflags_nodir= rb_ldflags_Lopt=
for rb_ldflags_arg in $LDFLAGS; do
AS_IF([test "$rb_ldflags_Lopt"], [rb_ldflags_Lopt=],
[AS_CASE(["$rb_ldflags_arg"],
[-L?*], [rb_ldflags_arg="${rb_ldflags_arg@%:@-L}" rb_ldflags_Lopt=],
[-L], [rb_ldflags_Lopt=yes; continue],
[continue])])
AS_IF([test -d "${rb_ldflags_arg}"], [],
[rb_ldflags_nodir="$rb_ldflags_nodir ${rb_ldflags_arg}"])
done
AC_MSG_ERROR([something wrong with LDFLAGS="$LDFLAGS"]dnl
[${rb_ldflags_nodir:+; no such directory:$rb_ldflags_nodir}])
]
)
cd .. && rm -fr tmp.$$.try_link
Expand Down
21 changes: 21 additions & 0 deletions doc/contributing/building_ruby.md
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,27 @@ required to build Ruby. To build Miniruby:
make miniruby
```

### Statically linking extensions

`configure --with-static-linked-ext` links the extension libraries under `ext/`
into the `ruby` binary instead of building them as separate `.so`/`.bundle`
files, and makes `RbConfig::CONFIG["EXTSTATIC"]` `"static"`. Bundled gems that
have C extensions, such as `bigdecimal` and `fiddle`, are unaffected and are
still built as loadable objects.

The external libraries the extensions need are then linked into `ruby` itself,
so pass `--with-EXTLIB-dir` to `configure` rather than putting the paths in
`LDFLAGS` by hand. On macOS with Homebrew:

```sh
./configure --with-static-linked-ext --with-openssl-dir=$(brew --prefix openssl@3)
```

`brew --prefix LIB` prints a path even for a formula that is not installed, so
generating `LDFLAGS` from it can yield `-L` options for directories that do not
exist, which `configure` rejects. Use `brew --prefix --installed LIB`, which
fails instead of printing a path for an uninstalled formula.

## Debugging

You can use either lldb or gdb for debugging. Before debugging, you need to
Expand Down
4 changes: 4 additions & 0 deletions ext/extmk.rb
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,10 @@ def extract_makefile(makefile, keep = true)
/^STATIC_LIB[ \t]*=[ \t]*\S+/ =~ m or $static = false
end
$preload = Shellwords.shellwords(m[/^preload[ \t]*=[ \t]*(.*)/, 1] || "")
if ldflags = m[/^ldflags[ \t]*=[ \t]*(.*)/, 1] and !$LDFLAGS.include?(ldflags)
# extconf.rb may have added library paths here, e.g. via pkg_config.
$LDFLAGS += " " + ldflags
end
if dldflags = m[/^dldflags[ \t]*=[ \t]*(.*)/, 1] and !$DLDFLAGS.include?(dldflags)
$DLDFLAGS += " " + dldflags
end
Expand Down
11 changes: 6 additions & 5 deletions lib/bundler/bundler.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Gem::Specification.new do |s|

s.metadata = {
"bug_tracker_uri" => "https://github.com/ruby/rubygems/issues?q=is%3Aopen+is%3Aissue+label%3ABundler",
"changelog_uri" => "https://github.com/ruby/rubygems/blob/master/CHANGELOG-bundler.md",
"changelog_uri" => "https://github.com/ruby/rubygems/blob/master/CHANGELOG.md",
"homepage_uri" => "https://bundler.io/",
"source_code_uri" => "https://github.com/ruby/rubygems",
}
Expand All @@ -40,13 +40,14 @@ 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, SecureRandom and PubGrub, its
# pure-Ruby YAML serializer, its compact index client and its credential
# store. Ship a copy under lib/rubygems so Bundler stays self-contained on
# RubyGems versions that predate them.
# pure-Ruby YAML serializer, its shared cooldown setting rules, its compact
# index client and its credential store. 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/vendor/pub_grub/**/*", File::FNM_DOTMATCH).reject {|f| File.directory?(f) }
s.files += Dir.glob("lib/rubygems/yaml_serializer.rb")
s.files += Dir.glob("lib/rubygems/cooldown_settings.rb")
s.files += Dir.glob("lib/rubygems/compact_index_client{.rb,/**/*}", File::FNM_DOTMATCH).reject {|f| File.directory?(f) }
s.files += Dir.glob("lib/rubygems/credential_store{.rb,/**/*}", File::FNM_DOTMATCH).reject {|f| File.directory?(f) }

Expand All @@ -55,7 +56,7 @@ Gem::Specification.new do |s|

# These live next to the gemspec when Bundler ships as a gem, but not when
# it is synced into Ruby core, where the gemspec moves under lib/bundler.
s.files += %w[CHANGELOG-bundler.md MIT.txt].select {|f| File.file?(f) }
s.files += %w[MIT.txt].select {|f| File.file?(f) }
s.bindir = "exe"
s.executables = %w[bundle bundler]
s.require_paths = ["lib"]
Expand Down
3 changes: 1 addition & 2 deletions lib/bundler/cli/add.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ def initialize(options, gems)
def run
Bundler.ui.level = "warn" if options[:quiet]

Bundler::CLI::Common.validate_cooldown!(options[:cooldown])
Bundler.settings.set_command_option_if_given :cooldown, options[:cooldown]
Bundler::CLI::Common.configure_cooldown(options)

validate_options!
inject_dependencies
Expand Down
33 changes: 22 additions & 11 deletions lib/bundler/cli/common.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,37 @@

module Bundler
module CLI::Common
# Validates the `--cooldown` flag and makes it the setting for this
# command. Every command that takes the flag goes through here, so they
# share one reading of the value.
def self.configure_cooldown(options)
value = options[:cooldown]

validate_cooldown!(value)
Bundler.settings.set_command_option_if_given :cooldown, value
end

def self.validate_cooldown!(value)
# Without the flag the config file and BUNDLE_COOLDOWN decide, and those
# only warn, so a typo left in a config file keeps the command usable.
# Without the flag the config files, BUNDLE_COOLDOWN and the gemrc
# setting decide, and those only warn, so a typo left in a config file
# keeps the command usable.
return warn_invalid_cooldown_setting if value.nil?
return if value.is_a?(Integer) && value >= 0
raise InvalidOption, "Expected `--cooldown` to be a non-negative integer, got #{value.inspect}"
end

# A cooldown value that cannot be read as a non-negative integer disables
# the cooldown for every source, overriding any per-source `cooldown:` in
# the Gemfile, so say so rather than letting the protection lapse quietly.
# A cooldown value that cannot be read as a non-negative integer takes no
# part in the resolution, so say so rather than letting the protection
# lapse quietly. The RubyGems `:cooldown:` setting feeds the same
# resolution and is checked in Bundler::Settings#rubygems_cooldown, where
# reading it is already being paid for.
def self.warn_invalid_cooldown_setting
value = Bundler.settings.locations(:cooldown).values.first
return if value.nil?
require "rubygems/cooldown_settings"

days = Integer(value.to_s, exception: false)
return if days && !days.negative?
value = Bundler.settings.locations(:cooldown).values.first
return unless Gem::CooldownSettings.invalid?(value)

Bundler.ui.warn "Invalid cooldown value #{value.inspect}, so the cooldown is disabled for all sources. " \
"Expected a non-negative integer number of days."
Bundler.ui.warn Gem::CooldownSettings.invalid_message(value, "Bundler's configuration")
end

def self.output_post_install_messages(messages)
Expand Down
2 changes: 1 addition & 1 deletion lib/bundler/cli/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ def run
confirm(name)
end

if current_value.nil? && !Bundler.settings.credential_stored?(name)
if current_value.nil? && !Bundler.settings.stored_outside_config_files?(name)
exit 1
else
return
Expand Down
3 changes: 1 addition & 2 deletions lib/bundler/cli/install.rb
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,7 @@ def normalize_settings

Bundler.settings.set_command_option_if_given :jobs, options["jobs"]

Bundler::CLI::Common.validate_cooldown!(options["cooldown"])
Bundler.settings.set_command_option_if_given :cooldown, options["cooldown"]
Bundler::CLI::Common.configure_cooldown(options)

Bundler.settings.set_command_option_if_given :no_install, options["no-install"]

Expand Down
3 changes: 1 addition & 2 deletions lib/bundler/cli/lock.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ def run

check_for_conflicting_options

Bundler::CLI::Common.validate_cooldown!(options[:cooldown])
Bundler.settings.set_command_option_if_given :cooldown, options[:cooldown]
Bundler::CLI::Common.configure_cooldown(options)

print = options[:print]
previous_output_stream = Bundler.ui.output_stream
Expand Down
3 changes: 1 addition & 2 deletions lib/bundler/cli/outdated.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,7 @@ def initialize(options, gems)
def run
check_for_deployment_mode!

Bundler::CLI::Common.validate_cooldown!(options[:cooldown])
Bundler.settings.set_command_option_if_given :cooldown, options[:cooldown]
Bundler::CLI::Common.configure_cooldown(options)

Bundler.definition.validate_runtime!
current_specs = Bundler.ui.silence { Bundler.definition.resolve }
Expand Down
3 changes: 1 addition & 2 deletions lib/bundler/cli/update.rb
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,7 @@ def run
opts["force"] = options[:redownload] if options[:redownload]

Bundler.settings.set_command_option_if_given :jobs, opts["jobs"]
Bundler::CLI::Common.validate_cooldown!(options[:cooldown])
Bundler.settings.set_command_option_if_given :cooldown, options[:cooldown]
Bundler::CLI::Common.configure_cooldown(options)

Bundler.definition.validate_runtime!

Expand Down
2 changes: 1 addition & 1 deletion lib/bundler/man/bundle-add.1
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ Adds pessimistic declaration of version\.
Adds strict declaration of version\.
.TP
\fB\-\-cooldown=<number>\fR
Only consider gem versions published at least \fInumber\fR days ago when resolving\. Pass \fB0\fR to disable cooldown for this run\. See \fBcooldown\fR in bundle\-config(1) for precedence rules\.
Only consider gem versions published at least \fInumber\fR days ago when resolving\. Pass \fB0\fR to disable cooldown for this run, overriding every other cooldown setting, RubyGems' own included\. See \fBcooldown\fR in bundle\-config(1) for precedence rules\.
.SH "EXAMPLES"
.IP "1." 4
You can add the \fBrails\fR gem to the Gemfile without any version restriction\. The source of the gem will be the global source\.
Expand Down
5 changes: 3 additions & 2 deletions lib/bundler/man/bundle-add.1.ronn
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,9 @@ Adds the named gem to the [`Gemfile(5)`][Gemfile(5)] and run `bundle install`.

* `--cooldown=<number>`:
Only consider gem versions published at least <number> days ago when
resolving. Pass `0` to disable cooldown for this run. See `cooldown`
in bundle-config(1) for precedence rules.
resolving. Pass `0` to disable cooldown for this run, overriding every
other cooldown setting, RubyGems' own included. See `cooldown` in
bundle-config(1) for precedence rules.

## EXAMPLES

Expand Down
2 changes: 1 addition & 1 deletion lib/bundler/man/bundle-cache.1
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Include gems for all platforms present in the lockfile, not only the current one
Specify a different cache path than the default (vendor/cache)\.
.TP
\fB\-\-cooldown=<number>\fR
Only consider gem versions published at least \fInumber\fR days ago when resolving before caching\. Pass \fB0\fR to disable cooldown for this run, overriding any per\-source or global configuration\. See \fBcooldown\fR in bundle\-config(1)\.
Only consider gem versions published at least \fInumber\fR days ago when resolving before caching\. Pass \fB0\fR to disable cooldown for this run, overriding every other cooldown setting, RubyGems' own included\. See \fBcooldown\fR in bundle\-config(1)\.
.TP
\fB\-\-gemfile=GEMFILE\fR
Use the specified gemfile instead of Gemfile\.
Expand Down
4 changes: 2 additions & 2 deletions lib/bundler/man/bundle-cache.1.ronn
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ use the gems in the cache in preference to the ones on `rubygems.org`.
* `--cooldown=<number>`:
Only consider gem versions published at least <number> days ago when
resolving before caching. Pass `0` to disable cooldown for this run,
overriding any per-source or global configuration. See `cooldown` in
bundle-config(1).
overriding every other cooldown setting, RubyGems' own included. See
`cooldown` in bundle-config(1).

* `--gemfile=GEMFILE`:
Use the specified gemfile instead of Gemfile.
Expand Down
8 changes: 5 additions & 3 deletions lib/bundler/man/bundle-config.1
Original file line number Diff line number Diff line change
Expand Up @@ -90,16 +90,18 @@ The following is a list of all configuration keys and their purpose\. You can le
.IP
The effective cooldown for any given gem is resolved from three layers, highest precedence first:
.IP "1." 4
CLI flag \fB\-\-cooldown N\fR on \fBinstall\fR, \fBupdate\fR, \fBadd\fR, and \fBoutdated\fR\.
CLI flag \fB\-\-cooldown N\fR on \fBinstall\fR, \fBupdate\fR, \fBadd\fR, \fBcache\fR, \fBlock\fR, and \fBoutdated\fR\.
.IP "2." 4
This setting (\fBbundle config set cooldown N\fR or \fBBUNDLE_COOLDOWN=N\fR)\.
.IP "3." 4
The per\-source \fBcooldown:\fR keyword in the Gemfile, such as \fBsource "https://rubygems\.org", cooldown: 7\fR\.
.IP "" 0
.IP
The CLI flag and this setting apply uniformly to every source, including ones declared with their own \fBcooldown:\fR value\. To keep a private registry permanently exempt while still cooling down public gems, declare \fBsource "https://internal", cooldown: 0\fR in the Gemfile; remember that \fB\-\-cooldown N\fR on the command line will still override it for that single run\.
The CLI flag and this setting apply uniformly to every source, including ones declared with their own \fBcooldown:\fR value\. To exempt a private registry while still cooling down public gems, declare \fBsource "https://internal", cooldown: 0\fR in the Gemfile\. That exemption is not absolute\. \fB\-\-cooldown N\fR on the command line overrides it for a single run, and a gemrc cooldown raises it the same way it raises any other layer, as described below\. Where a gemrc cooldown is configured, \fB\-\-cooldown 0\fR is the only way to get the exemption back\.
.IP
The value must be a non\-negative integer\. \fB\-\-cooldown\fR rejects anything else outright, while a value coming from this setting or from \fBBUNDLE_COOLDOWN\fR only warns, because a typo left in a config file should not make every command fail\. Such a value disables the cooldown for every source, including sources that declare their own \fBcooldown:\fR in the Gemfile\.
RubyGems has a cooldown of its own, set with \fBgem\fR's \fB\-\-cooldown\fR flag or the \fB:cooldown:\fR key in the gemrc file, and the two are read together\. Whatever the three layers above resolve to is raised to the gemrc value, and the longer of the two wins\. It carries the other way round as well\. \fBgem install\fR, \fBgem update\fR and \fBgem outdated\fR read this setting and \fBBUNDLE_COOLDOWN\fR, so a cooldown configured for either tool covers both\. The Gemfile per\-source \fBcooldown:\fR is the exception, since \fBgem\fR never reads a Gemfile\. A configured \fB0\fR takes part like any other value rather than switching the cooldown off, so \fBbundle config set cooldown 0\fR does not cancel a gemrc cooldown\. The \fB\-\-cooldown\fR flag is what bypasses the other tool's setting\. It wins outright, which is why \fB\-\-cooldown 0\fR remains the escape hatch for an urgent update\.
.IP
The value must be a non\-negative integer\. \fB\-\-cooldown\fR rejects anything else outright, while a value coming from this setting, from \fBBUNDLE_COOLDOWN\fR or from the gemrc file only warns, because a typo left in a config file should not make every command fail\. Such a value takes no part in the resolution above, so a per\-source \fBcooldown:\fR in the Gemfile, or a usable value configured for the other tool, still applies\. The warning names where the value came from, since either tool reports the other's setting as well as its own\.
.IP
Cooldown filtering depends on the gem server providing a per\-version \fBcreated_at\fR timestamp in the v2 compact\-index format\. Versions without that metadata \- older gem servers, historical entries that predate the v2 cutover on \fBrubygems\.org\fR, or private registries that still emit the v1 format \- are treated as outside the cooldown window and remain resolvable\. If you rely on cooldown for supply\-chain protection, confirm that the gem server emits \fBcreated_at\fR in its \fB/info/<gem>\fR responses\.
.IP
Expand Down
Loading