diff --git a/.github/actions/setup/directories/action.yml b/.github/actions/setup/directories/action.yml index f1b09944607785..7b955d4ff0dab2 100644 --- a/.github/actions/setup/directories/action.yml +++ b/.github/actions/setup/directories/action.yml @@ -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 @@ -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)) }} diff --git a/.github/workflows/modgc.yml b/.github/workflows/modgc.yml index ff43bfb21e2575..8349cf38aa96df 100644 --- a/.github/workflows/modgc.yml +++ b/.github/workflows/modgc.yml @@ -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 diff --git a/.github/workflows/tarball-windows.yml b/.github/workflows/tarball-windows.yml index 34b3187d7180ce..a472af6e9e0fbe 100644 --- a/.github/workflows/tarball-windows.yml +++ b/.github/workflows/tarball-windows.yml @@ -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 }} @@ -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 diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 4aa55366d3030b..2059285e07fa0d 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -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') }} @@ -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') }} diff --git a/.github/workflows/zjit-macos.yml b/.github/workflows/zjit-macos.yml index 8cd40023ee790c..be9bbec4098472 100644 --- a/.github/workflows/zjit-macos.yml +++ b/.github/workflows/zjit-macos.yml @@ -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' }} diff --git a/.github/workflows/zjit-ubuntu.yml b/.github/workflows/zjit-ubuntu.yml index 729e1eb542de62..25e89d21bb4ac8 100644 --- a/.github/workflows/zjit-ubuntu.yml +++ b/.github/workflows/zjit-ubuntu.yml @@ -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' }} diff --git a/lib/rubygems/util/atomic_file_writer.rb b/lib/rubygems/util/atomic_file_writer.rb index c21b8e67193e64..9af6d54b549843 100644 --- a/lib/rubygems/util/atomic_file_writer.rb +++ b/lib/rubygems/util/atomic_file_writer.rb @@ -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 diff --git a/set.c b/set.c index 134770e70ab0ae..203a0abfd1bb82 100644 --- a/set.c +++ b/set.c @@ -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 $,): * - * $, # => 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) @@ -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 include? and member? do not test member - * equality using == 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) @@ -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) diff --git a/spec/bundler/bundler/cli_spec.rb b/spec/bundler/bundler/cli_spec.rb index 56caf9937e29f6..1e8ffa7e37c883 100644 --- a/spec/bundler/bundler/cli_spec.rb +++ b/spec/bundler/bundler/cli_spec.rb @@ -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}. @@ -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}. diff --git a/spec/bundler/bundler/env_spec.rb b/spec/bundler/bundler/env_spec.rb index 2b7dbde217d8e2..1501bb9eb9b8fa 100644 --- a/spec/bundler/bundler/env_spec.rb +++ b/spec/bundler/bundler/env_spec.rb @@ -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") @@ -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") diff --git a/spec/bundler/bundler/installer/parallel_installer_spec.rb b/spec/bundler/bundler/installer/parallel_installer_spec.rb index 6a91f05bf8b48b..528dc1ae93e525 100644 --- a/spec/bundler/bundler/installer/parallel_installer_spec.rb +++ b/spec/bundler/bundler/installer/parallel_installer_spec.rb @@ -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 diff --git a/spec/bundler/bundler/lockfile_parser_spec.rb b/spec/bundler/bundler/lockfile_parser_spec.rb index cec77b0cb4cde0..c92d8909d29e56 100644 --- a/spec/bundler/bundler/lockfile_parser_spec.rb +++ b/spec/bundler/bundler/lockfile_parser_spec.rb @@ -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", diff --git a/spec/bundler/bundler/shared_helpers_spec.rb b/spec/bundler/bundler/shared_helpers_spec.rb index 41115aa667312b..ab89d280a22416 100644 --- a/spec/bundler/bundler/shared_helpers_spec.rb +++ b/spec/bundler/bundler/shared_helpers_spec.rb @@ -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 diff --git a/spec/bundler/commands/cache_spec.rb b/spec/bundler/commands/cache_spec.rb index e223d07f7fc1e7..b33a5a386c7449 100644 --- a/spec/bundler/commands/cache_spec.rb +++ b/spec/bundler/commands/cache_spec.rb @@ -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] diff --git a/spec/bundler/commands/exec_spec.rb b/spec/bundler/commands/exec_spec.rb index aa35685be8ff50..d744fc616bf238 100644 --- a/spec/bundler/commands/exec_spec.rb +++ b/spec/bundler/commands/exec_spec.rb @@ -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) @@ -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) @@ -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 @@ -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 @@ -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 diff --git a/spec/bundler/commands/install_spec.rb b/spec/bundler/commands/install_spec.rb index 18c3fd65038c16..f8a134f231089e 100644 --- a/spec/bundler/commands/install_spec.rb +++ b/spec/bundler/commands/install_spec.rb @@ -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 diff --git a/spec/bundler/commands/lock_spec.rb b/spec/bundler/commands/lock_spec.rb index 1a434009232e2b..0a1f1f8902ba9e 100644 --- a/spec/bundler/commands/lock_spec.rb +++ b/spec/bundler/commands/lock_spec.rb @@ -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 diff --git a/spec/bundler/commands/pristine_spec.rb b/spec/bundler/commands/pristine_spec.rb index 5f80b9e5348b21..842001f6b09fc9 100644 --- a/spec/bundler/commands/pristine_spec.rb +++ b/spec/bundler/commands/pristine_spec.rb @@ -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) @@ -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) diff --git a/spec/bundler/install/global_cache_spec.rb b/spec/bundler/install/global_cache_spec.rb index 4cffa65b2a9d97..259e8d57ba2ebc 100644 --- a/spec/bundler/install/global_cache_spec.rb +++ b/spec/bundler/install/global_cache_spec.rb @@ -63,6 +63,7 @@ def source2_global_cache(*segments) end it "uses a shorter path for the cache to not hit filesystem limits" do + skip "Windows without long path support cannot create the long cache path" if Gem.win_platform? install_gemfile <<-G, artifice: "compact_index", verbose: true source "http://#{"a" * 255}.test" gem "myrack" @@ -82,17 +83,19 @@ def source2_global_cache(*segments) # the more verbose and explicit approach. This whole ensure block can be # removed once/if https://bugs.ruby-lang.org/issues/21177 is fixed, and # once the fix propagates to all supported rubies. - File.delete cached_gem - Dir.rmdir source_cache - - File.delete compact_index_cache_path.join(source_segment, "info", "myrack") - Dir.rmdir compact_index_cache_path.join(source_segment, "info") - File.delete compact_index_cache_path.join(source_segment, "info-etags", "myrack-92f3313ce5721296f14445c3a6b9c073") - Dir.rmdir compact_index_cache_path.join(source_segment, "info-etags") - Dir.rmdir compact_index_cache_path.join(source_segment, "info-special-characters") - File.delete compact_index_cache_path.join(source_segment, "versions") - File.delete compact_index_cache_path.join(source_segment, "versions.etag") - Dir.rmdir compact_index_cache_path.join(source_segment) + if cached_gem + File.delete cached_gem + Dir.rmdir source_cache + + File.delete compact_index_cache_path.join(source_segment, "info", "myrack") + Dir.rmdir compact_index_cache_path.join(source_segment, "info") + File.delete compact_index_cache_path.join(source_segment, "info-etags", "myrack-92f3313ce5721296f14445c3a6b9c073") + Dir.rmdir compact_index_cache_path.join(source_segment, "info-etags") + Dir.rmdir compact_index_cache_path.join(source_segment, "info-special-characters") + File.delete compact_index_cache_path.join(source_segment, "versions") + File.delete compact_index_cache_path.join(source_segment, "versions.etag") + Dir.rmdir compact_index_cache_path.join(source_segment) + end end describe "when the same gem from different sources is installed" do diff --git a/spec/bundler/realworld/fixtures/tapioca/Gemfile.lock b/spec/bundler/realworld/fixtures/tapioca/Gemfile.lock index c2df2f92299ad2..a08089a6f7b33b 100644 --- a/spec/bundler/realworld/fixtures/tapioca/Gemfile.lock +++ b/spec/bundler/realworld/fixtures/tapioca/Gemfile.lock @@ -32,7 +32,7 @@ GEM thor (>= 1.2.0) yard-sorbet thor (1.4.0) - yard (0.9.42) + yard (0.9.44) yard-sorbet (0.9.0) sorbet-runtime yard diff --git a/spec/bundler/support/path.rb b/spec/bundler/support/path.rb index 7a482912cf3760..17dafb91b70ffb 100644 --- a/spec/bundler/support/path.rb +++ b/spec/bundler/support/path.rb @@ -127,6 +127,16 @@ def tmp_root end end + # On Windows there is no relative path between different drives, and much of + # the spec setup (temp home, bundled app, caches) lives under the temp dir. + # When the temp dir is on a different drive than the source tree, examples + # that compare or look up paths across the two cannot be set up correctly. + def tmp_and_source_on_different_drives? + return false unless Gem.win_platform? + drive = ->(path) { path.to_s[/\A[a-zA-Z]:/]&.upcase } + drive[tmp_root] != drive[source_root] + end + # Bump this version whenever you make a breaking change to the spec setup # that requires regenerating tmp/. diff --git a/spec/bundler/support/platforms.rb b/spec/bundler/support/platforms.rb index 56a08430056b98..28ba84634860c9 100644 --- a/spec/bundler/support/platforms.rb +++ b/spec/bundler/support/platforms.rb @@ -28,6 +28,13 @@ def not_local_tag [:jruby, :windows, :ruby].find {|tag| tag != local_tag } end + # The mswin build uses nmake and MSVC, which differ from the mingw build in + # ways several specs need to skip (no make jobserver, MSVC Makefile syntax, + # extensionless executables, mswin-only fixtures). + def mswin? + RUBY_PLATFORM.include?("mswin") + end + def local_ruby_engine RUBY_ENGINE end diff --git a/spec/bundler/support/subprocess.rb b/spec/bundler/support/subprocess.rb index 91db80da488c6a..b03ba839dd8623 100644 --- a/spec/bundler/support/subprocess.rb +++ b/spec/bundler/support/subprocess.rb @@ -38,7 +38,7 @@ def sh(cmd, options = {}) dir = options[:dir] env = options[:env] || {} - command_execution = CommandExecution.new(cmd.to_s, timeout: options[:timeout] || 60) + command_execution = CommandExecution.new(cmd.to_s, timeout: options[:timeout] || (Gem.win_platform? ? 120 : 60)) open3_opts = {} open3_opts[:chdir] = dir if dir diff --git a/tool/fake.rb b/tool/fake.rb index 2c458985d8e1d3..a8d727db2150ee 100644 --- a/tool/fake.rb +++ b/tool/fake.rb @@ -27,7 +27,15 @@ class File if $extmk $ruby = "$(topdir)/miniruby -I'$(topdir)' -I'$(top_srcdir)/lib' -I'$(extout)/$(arch)' -I'$(extout)/common'" else - $ruby = baseruby + # `CROSS_COMPILING` holds the platform of the ruby that loaded this fake. + # When it matches the built ruby's platform we are not really cross + # compiling, so the just-built ruby runs on this host and matches the build + # tree. Prefer it over baseruby, which may be an older release whose version + # check rejects the freshly built standard library when building gems with + # native extensions (e.g. the bundler spec's test gems run via + # `make test-bundler[-parallel]`). + native = defined?(CROSS_COMPILING) && CROSS_COMPILING == RUBY_PLATFORM + $ruby = native && File.exist?($builtruby) ? $builtruby : baseruby end $static = static untrace_var(:$ruby, posthook) diff --git a/tool/lib/_tmpdir.rb b/tool/lib/_tmpdir.rb index ac5b9be792ec63..f4ac29ffb64fd9 100644 --- a/tool/lib/_tmpdir.rb +++ b/tool/lib/_tmpdir.rb @@ -21,10 +21,18 @@ end # warn "tmpdir(#{tmpdir.size}) = #{tmpdir}" +# Bundler's spec helpers walk up the directory tree looking for `.bundle`, +# stopping once they see a `tmp` directory (Bundler::SharedHelpers#search_up). +# On Windows the temp dir lives under the user home (%LOCALAPPDATA%\Temp), so +# without a `tmp` marker the search escapes the sandbox and picks up the real +# ~/.bundle. Create one so the search stops at the temp root. +Dir.mkdir(File.join(tmpdir, "tmp")) + pid = $$ END { if pid == $$ begin + Dir.rmdir(File.join(tmpdir, "tmp")) Dir.rmdir(tmpdir) rescue Errno::ENOENT rescue Errno::ENOTEMPTY diff --git a/tool/runruby.rb b/tool/runruby.rb index ec63d1008a2348..1f7268bd4114b7 100755 --- a/tool/runruby.rb +++ b/tool/runruby.rb @@ -140,6 +140,24 @@ def File.realpath(*args) # See: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=271490 env['LD_BIND_NOW'] = 'yes' if /freebsd/ =~ RUBY_PLATFORM +# On Windows the freshly built ruby often has no usable default CA bundle (its +# OpenSSL's OPENSSLDIR does not exist), which breaks HTTPS in tests such as +# test-bundler. Fall back to the CA bundle of baseruby (the installed ruby the +# build was bootstrapped with, recorded in the fake script), unless the caller +# already configured one. +if /mswin|mingw/ =~ RUBY_PLATFORM and !ENV["SSL_CERT_FILE"] and !ENV["SSL_CERT_DIR"] + fake = File.join(abs_archdir, "#{config['arch']}-fake.rb") + if File.exist?(fake) and /^baseruby\s*=\s*"([^"\n]+)"/ =~ File.read(fake) + baseruby = $1 + script = "f = OpenSSL::X509::DEFAULT_CERT_FILE; print f if File.exist?(f)" + begin + cert = IO.popen([baseruby, "-ropenssl", "-e", script], err: File::NULL, &:read) + env["SSL_CERT_FILE"] = cert if $?.success? and !cert.empty? + rescue SystemCallError + end + end +end + ENV.update env if debugger diff --git a/vcpkg.json b/vcpkg.json index c2caad14cddf8a..2c30ac0fdd3713 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -7,5 +7,5 @@ "openssl", "zlib" ], - "builtin-baseline": "f3e10653cc27d62a37a3763cd84b38bca07c6075" + "builtin-baseline": "cd61e1e26a038e82d6550a3ebbe0fbbfe7da78e3" } \ No newline at end of file