Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
b5e6850
fake.rb: Use the just-built ruby for native gems when not cross compi…
hsbt Jun 27, 2026
f00181b
runruby.rb: Provide a CA bundle for the built ruby on Windows
hsbt Jun 27, 2026
2171753
[ruby/bundler] Skip make jobserver specs on Windows
hsbt Jun 27, 2026
d701adf
[ruby/bundler] Compute lockfile_path like the parser does in lockfile…
hsbt Jun 27, 2026
2343866
[ruby/bundler] Skip specs needing a same-drive temp dir on Windows
hsbt Jun 27, 2026
c27a4a3
[ruby/bundler] Only check drive mismatch on Windows
hsbt Jun 27, 2026
89af98c
[ruby/bundler] Skip parallel make specs on Windows
hsbt Jun 27, 2026
dc74fb4
[ruby/bundler] Skip more bundle exec specs on Windows
hsbt Jun 27, 2026
52ccfc1
[ruby/bundler] Skip the long cache path spec on Windows
hsbt Jun 27, 2026
5c5f846
[ruby/bundler] Skip the legacy windows cache spec on Windows
hsbt Jun 27, 2026
663c940
[ruby/bundler] Skip the add-platform lock spec on Windows
hsbt Jun 27, 2026
361e0a9
[ruby/bundler] Skip the build config Makefile specs on Windows
hsbt Jun 27, 2026
888f6e0
Keep bundler specs in their sandbox when temp is under the user home
hsbt Jun 27, 2026
90ac868
[ruby/bundler] Allow more time for spec commands on Windows
hsbt Jun 27, 2026
1bcc15d
Remove the tmp marker before removing the temp root
hsbt Jun 28, 2026
e66791a
[ruby/bundler] Skip the mswin-specific specs only on mswin, not mingw
hsbt Jun 28, 2026
89732c6
[ruby/rubygems] Bump yard from 0.9.42 to 0.9.44 in /spec/realworld/fi…
dependabot[bot] Jun 29, 2026
7eab0be
[ruby/rubygems] Satisfy rubocop on the forward-ported Windows specs
hsbt Jun 29, 2026
bf9ea8d
[ruby/rubygems] Add an mswin? spec helper for the Windows skips
hsbt Jun 29, 2026
dc3aae7
[ruby/rubygems] Build the raygun-apm mswin variant instead of skipping
hsbt Jun 29, 2026
c050a73
[ruby/rubygems] Trim the basename so the MAX_PATH guard actually shor…
hsbt Jun 29, 2026
0c432b6
Bump github.com/microsoft/vcpkg from master to 2026.06.24
dependabot[bot] Jun 29, 2026
af5128d
Bump the github-actions group across 2 directories with 5 updates
dependabot[bot] Jun 29, 2026
f2e09df
[DOC] Update Set#each documentation
BurdetteLamar Jun 29, 2026
d945702
[DOC] Update Set#include? documentation
BurdetteLamar Jun 29, 2026
a291454
[DOC] Update Set#join documentation
BurdetteLamar Jun 29, 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
4 changes: 2 additions & 2 deletions .github/actions/setup/directories/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ runs:
fetch-depth: ${{ inputs.fetch-depth }}
persist-credentials: false

- uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
- uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: ${{ inputs.srcdir }}/.downloaded-cache
key: ${{ runner.os }}-${{ runner.arch }}-downloaded-cache
Expand All @@ -127,7 +127,7 @@ runs:
# because they are the ones that clone the complete set into gems/src; other
# jobs would otherwise save a partial gems/src and poison the shared key.
- if: inputs.bundled-gems-src-cache == 'true'
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: ${{ inputs.srcdir }}/gems/src
key: ${{ runner.os }}-${{ runner.arch }}-bundled-gems-src-${{ hashFiles(format('{0}/gems/bundled_gems', inputs.srcdir)) }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/modgc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ jobs:
${SETARCH} ../src/configure -C --disable-install-doc --with-modular-gc="${MODULAR_GC_DIR}" \
${arch:+--target=$arch-$OSTYPE --host=$arch-$OSTYPE}
- uses: actions-rust-lang/setup-rust-toolchain@46268bd060767258de96ed93c1251119784f2ab6 # v1.16.1
- uses: actions-rust-lang/setup-rust-toolchain@166cdcfd11aee3cb47222f9ddb555ce30ddb9659 # v1.17.0
with:
cache-bin: false
- name: Set MMTk environment variables
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/tarball-windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ jobs:
shell: msys2 {0}
run: echo PATCH=$(cygpath -wa $(command -v patch)) >> $GITHUB_ENV
if: ${{ steps.setup-msys2.outcome == 'success' }}
- uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
- uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: C:\vcpkg\installed
key: ${{ runner.os }}-vcpkg-installed-${{ env.OS_VER }}-${{ github.sha }}
Expand All @@ -82,7 +82,7 @@ jobs:
run: 7z x pkg/*.zip
working-directory:

- uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
- uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: snapshot-*/.downloaded-cache
key: downloaded-cache
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ jobs:

- name: Restore vcpkg artifact
id: restore-vcpkg
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: src\vcpkg_installed
key: windows-${{ matrix.os }}-vcpkg-${{ hashFiles('src/vcpkg.json') }}
Expand All @@ -104,7 +104,7 @@ jobs:
if: ${{ ! steps.restore-vcpkg.outputs.cache-hit }}

- name: Save vcpkg artifact
uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: src\vcpkg_installed
key: windows-${{ matrix.os }}-vcpkg-${{ hashFiles('src/vcpkg.json') }}
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@9e1e5806d4a4822de933115878265be9aaa786d9 # v2.82.2
- uses: taiki-e/install-action@9bcaee1dcae34154180f412e2fa69355a7cda9f6 # v2.82.6
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 @@ -130,7 +130,7 @@ jobs:
ruby-version: '3.1'
bundler: none

- uses: taiki-e/install-action@9e1e5806d4a4822de933115878265be9aaa786d9 # v2.82.2
- uses: taiki-e/install-action@9bcaee1dcae34154180f412e2fa69355a7cda9f6 # v2.82.6
with:
tool: nextest@0.9
if: ${{ matrix.test_task == 'zjit-check' }}
Expand Down
18 changes: 12 additions & 6 deletions lib/rubygems/util/atomic_file_writer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,22 @@ def self.open(file_name)
tmp_suffix = ".tmp.#{SecureRandom.hex}"
dirname = File.dirname(file_name)
basename = File.basename(file_name)
tmp_path = File.join(dirname, ".#{basename.byteslice(0, 254 - tmp_suffix.bytesize)}#{tmp_suffix}")
base_slice = basename.byteslice(0, 254 - tmp_suffix.bytesize)
tmp_path = File.join(dirname, ".#{base_slice}#{tmp_suffix}")

# The temporary name is longer than the final one, so on Windows a
# writable destination can still map to a path beyond the 260-character
# MAX_PATH limit. Only in that case, trim the random suffix just enough to
# fit, keeping at least 8 hex characters to avoid collisions.
# MAX_PATH limit. Trim the random suffix first, keeping at least 8 hex
# characters to avoid collisions, then shorten the basename if that is not
# enough. Recomputing the basename from the trimmed suffix would just let
# it grow back, so trim the already-sliced basename instead.
if tmp_path.length >= 260 && Gem.win_platform?
keep = [tmp_suffix.bytesize - (tmp_path.length - 259), ".tmp.".bytesize + 8].max
tmp_suffix = tmp_suffix.byteslice(0, keep)
tmp_path = File.join(dirname, ".#{basename.byteslice(0, 254 - tmp_suffix.bytesize)}#{tmp_suffix}")
overflow = tmp_path.length - 259
trim = [tmp_suffix.bytesize - (".tmp.".bytesize + 8), overflow].min
tmp_suffix = tmp_suffix.byteslice(0, tmp_suffix.bytesize - trim)
overflow -= trim
base_slice = base_slice.byteslice(0, [base_slice.bytesize - overflow, 0].max) if overflow > 0
tmp_path = File.join(dirname, ".#{base_slice}#{tmp_suffix}")
end

flags = File::RDWR | File::CREAT | File::EXCL | File::BINARY
Expand Down
63 changes: 38 additions & 25 deletions set.c
Original file line number Diff line number Diff line change
Expand Up @@ -692,23 +692,28 @@ set_i_to_set(VALUE set)

/*
* call-seq:
* join(separator = $,) -> new_string
* join(separator = $,) -> string
*
* Returns the new string formed by joining the string-converted elements of +self+
* Returns the string formed by joining the string-converted elements of +self+
* with the given +separator+ (defaults to <tt>$,</tt>):
*
* $, # => nil
* Set[].join # => ""
* Set[%w[foo]].join # => "foo"
* s = Set[%w[foo bar baz]] # => Set[["foo", "bar", "baz"]]
* s.join # => "foobarbaz"
* s.join('|') # => "foo|bar|baz"
* s.join(' :|: ') # => "foo :|: bar :|: baz"
* $, # => nil
* Set[*%w[foo bar baz]].join
* # => "foobarbaz"
* Set[*%w[foo bar baz]].join(', ')
* # => "foo, bar, baz"
*
* Flattens and joins nested arrays:
* Flattens nested arrays:
*
* Set[[:foo, [:bar, [:baz, :bat]]]].join0 # => "foobarbazbat"
* Set[[:foo, [:bar, [:baz, :bat]]]].join
* # => "foobarbazbat"
*
* Does not flatten nested sets:
*
* Set[Set[:foo, Set[:bar, Set[:baz, :bat]]]].join
* # => "Set[:foo, Set[:bar, Set[:baz, :bat]]]"
*
* Related: see {Methods for Converting}[rdoc-ref:Set@Methods+for+Converting].
*/
static VALUE
set_i_join(int argc, VALUE *argv, VALUE set)
Expand Down Expand Up @@ -1136,27 +1141,29 @@ set_i_intersection(VALUE set, VALUE other)

/*
* call-seq:
* include?(item) -> true or false
* include?(object) -> true or false
*
* Returns true if the set contains the given object:
* Returns whether the given +object+ is an element of +self+:
*
* Set[1, 2, 3].include? 2 #=> true
* Set[1, 2, 3].include? 4 #=> false
* set = [0, :zero, '0']
* set.include?('0') # => true
* set.include?('zero') # => false
*
* Note that <code>include?</code> and <code>member?</code> do not test member
* equality using <code>==</code> as do other Enumerables.
* Tests equality using `hash` and `eql?`.
*
* This is aliased to #===, so it is usable in +case+ expressions:
* Aliased as #===, which means that sets may be used in +case+ expressions:
*
* case :apple
* when Set[:potato, :carrot]
* "vegetable"
* 'vegetable'
* when Set[:apple, :banana]
* "fruit"
* 'fruit'
* else
* 'unknown'
* end
* # => "fruit"
*
* See also Enumerable#include?
* Related: see {Methods for Querying}[rdoc-ref:Set@Methods+for+Querying].
*/
static VALUE
set_i_include(VALUE set, VALUE item)
Expand Down Expand Up @@ -1471,12 +1478,18 @@ set_each_i(st_data_t key, st_data_t dummy)

/*
* call-seq:
* each { |o| ... } -> self
* each {|element| ... } -> self
* each -> enumerator
*
* Calls the given block once for each element in the set, passing
* the element as parameter. Returns an enumerator if no block is
* given.
* With a block given, calls the block once for each element in the set,
* passing the element as a parameter;
* returns +self+:
*
* sum = 0
* Set[1, 2, 3].each {|i| sum += i }
* sum => 6
*
* With no block given, returns an Enumerator.
*/
static VALUE
set_i_each(VALUE set)
Expand Down
2 changes: 2 additions & 0 deletions spec/bundler/bundler/cli_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ def out_with_macos_man_workaround
context "when the latest version is greater than the current version" do
let(:latest_version) { "222.0" }
it "prints the version warning" do
skip "temp dir is on a different drive than the source tree" if tmp_and_source_on_different_drives?
bundle "fail", env: { "BUNDLER_VERSION" => bundler_version }, raise_on_error: false
expect(err).to start_with(<<-EOS.strip)
The latest bundler is #{latest_version}, but you are currently running #{bundler_version}.
Expand Down Expand Up @@ -264,6 +265,7 @@ def out_with_macos_man_workaround
context "and is a pre-release" do
let(:latest_version) { "222.0.0.pre.4" }
it "prints the version warning" do
skip "temp dir is on a different drive than the source tree" if tmp_and_source_on_different_drives?
bundle "fail", env: { "BUNDLER_VERSION" => bundler_version }, raise_on_error: false
expect(err).to start_with(<<-EOS.strip)
The latest bundler is #{latest_version}, but you are currently running #{bundler_version}.
Expand Down
2 changes: 2 additions & 0 deletions spec/bundler/bundler/env_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ def with_clear_paths(env_var, env_value)
let(:output) { described_class.report(print_gemfile: true) }

it "prints the config with redacted values" do
skip "temp dir is on a different drive than the source tree" if tmp_and_source_on_different_drives?
expect(output).to include("https://localgemserver.test")
expect(output).to include("user:[REDACTED]")
expect(output).to_not include("user:pass")
Expand All @@ -131,6 +132,7 @@ def with_clear_paths(env_var, env_value)
let(:output) { described_class.report(print_gemfile: true) }

it "prints the config with redacted values" do
skip "temp dir is on a different drive than the source tree" if tmp_and_source_on_different_drives?
expect(output).to include("https://localgemserver.test")
expect(output).to include("[REDACTED]:x-oauth-basic")
expect(output).to_not include("api_token:x-oauth-basic")
Expand Down
5 changes: 5 additions & 0 deletions spec/bundler/bundler/installer/parallel_installer_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,11 @@
skip "This example is runnable when RubyGems::Installer implements `build_jobs`"
end

# The make jobserver is a GNU make feature. On Windows extensions are built
# with nmake, which has no `-j` jobserver, so the per-gem slot count never
# appears in the build output.
skip "The make jobserver is not available on Windows (nmake)" if mswin?

# When run under a parent make that already passes `-j` (e.g. ruby/ruby's
# `make test-bundler-parallel`), RubyGems' extension builder sees the
# inherited MAKEFLAGS as "jobs already requested" and skips appending its
Expand Down
2 changes: 1 addition & 1 deletion spec/bundler/bundler/lockfile_parser_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@
let(:platforms) { [Gem::Platform::RUBY] }
let(:bundler_version) { Gem::Version.new("1.12.0.rc.2") }
let(:ruby_version) { "ruby 2.1.3p242" }
let(:lockfile_path) { Bundler.default_lockfile.relative_path_from(Dir.pwd) }
let(:lockfile_path) { Bundler::SharedHelpers.relative_lockfile_path }
let(:rake_sha256_checksum) do
Bundler::Checksum.from_lock(
"sha256=814828c34f1315d7e7b7e8295184577cc4e969bad6156ac069d02d63f58d82e8",
Expand Down
1 change: 1 addition & 0 deletions spec/bundler/bundler/shared_helpers_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
describe "#default_bundle_dir" do
context ".bundle does not exist" do
it "returns nil" do
skip "temp dir is on a different drive than the source tree" if tmp_and_source_on_different_drives?
expect(subject.default_bundle_dir).to be_nil
end
end
Expand Down
1 change: 1 addition & 0 deletions spec/bundler/commands/cache_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@
end

it "prints a warn when using legacy windows rubies" do
skip "the legacy windows platform gem is not cached for the current mswin platform" if mswin?
gemfile <<-D
source "https://gem.repo1"
gem 'myrack', :platforms => [:ruby_20, :x64_mingw_20]
Expand Down
5 changes: 5 additions & 0 deletions spec/bundler/commands/exec_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
end

it "works when exec'ing to rubygems" do
skip "https://github.com/ruby/rubygems/issues/3351" if mswin?
install_gemfile "source \"https://gem.repo1\"; gem \"myrack\""
bundle "exec #{gem_cmd} --version"
expect(out).to eq(Gem::VERSION)
Expand Down Expand Up @@ -204,6 +205,7 @@
end

it "uses version provided by ruby" do
skip "https://github.com/ruby/rubygems/issues/3351" if mswin?
bundle "exec erb --version"

expect(stdboth).to eq(default_erb_version)
Expand Down Expand Up @@ -632,6 +634,7 @@

describe "with gems bundled via :path with invalid gemspecs" do
it "outputs the gemspec validation errors" do
skip "https://github.com/ruby/rubygems/issues/3351" if mswin?
build_lib "foo"

gemspec = lib_path("foo-1.0").join("foo.gemspec").to_s
Expand Down Expand Up @@ -692,6 +695,7 @@ def bin_path(a,b,c)
end

it "works" do
skip "https://github.com/ruby/rubygems/issues/3351" if mswin?
bundle "exec #{gem_cmd} uninstall foo"
expect(out).to eq("Successfully uninstalled foo-1.0")
end
Expand All @@ -713,6 +717,7 @@ def bin_path(a,b,c)
end

it "does not load plugins outside of the bundle" do
skip "https://github.com/ruby/rubygems/issues/3351" if mswin?
bundle "exec #{gem_cmd} -v"
expect(out).not_to include("FAIL")
end
Expand Down
5 changes: 5 additions & 0 deletions spec/bundler/commands/install_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1349,6 +1349,11 @@ def run
skip "This example is runnable when RubyGems::Installer implements `build_jobs`"
end

# The make jobserver is a GNU make feature. On Windows extensions are built
# with nmake, which has no `-j` jobserver (and an inherited `-j` MAKEFLAGS
# even breaks nmake), so the slot count these examples assert never appears.
skip "The make jobserver is not available on Windows (nmake)" if mswin?

@old_makeflags = ENV["MAKEFLAGS"]
@gemspec = nil

Expand Down
5 changes: 5 additions & 0 deletions spec/bundler/commands/lock_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1301,6 +1301,11 @@
s.platform = "x64-mingw-ucrt"
s.required_ruby_version = "< #{next_ruby_minor}.dev"
end

build_gem "raygun-apm", "1.0.78" do |s|
s.platform = "x64-mswin64"
s.required_ruby_version = "< #{next_ruby_minor}.dev"
end
end

gemfile <<-G
Expand Down
2 changes: 2 additions & 0 deletions spec/bundler/commands/pristine_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,7 @@
# This just verifies that the generated Makefile from the c_ext gem makes
# use of the build_args from the bundle config
it "applies the config when installing the gem" do
skip "the generated Makefile uses MSVC `-libpath:` syntax instead of `-L` on Windows" if mswin?
bundle "pristine"

makefile_contents = File.read(c_ext_dir.join("Makefile").to_s)
Expand All @@ -249,6 +250,7 @@
# This just verifies that the generated Makefile from the c_ext gem makes
# use of the build_args from the bundle config
it "applies the config when installing the gem" do
skip "the generated Makefile uses MSVC `-libpath:` syntax instead of `-L` on Windows" if mswin?
bundle "pristine"

makefile_contents = File.read(c_ext_dir.join("Makefile").to_s)
Expand Down
Loading