diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 22c9d0bda3..3fcde80117 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -294,6 +294,12 @@ jobs: - name: tests (macOS 13) test-flags: --coverage runs-on: macos-13 + - name: tests (Ubuntu 22.04; Ruby 3.1) + runs-on: ubuntu-22.04 + ruby: '3.1' + - name: tests (macOS 13; Ruby 3.1) + runs-on: macos-13 + ruby: '3.1' steps: - name: Set up Homebrew id: set-up-homebrew @@ -307,8 +313,23 @@ jobs: uses: actions/cache@v3 with: path: ${{ steps.set-up-homebrew.outputs.gems-path }} - key: ${{ runner.os }}-rubygems-${{ steps.set-up-homebrew.outputs.gems-hash }} - restore-keys: ${{ runner.os }}-rubygems- + key: ${{ runner.os }}-rubygems${{ matrix.ruby }}-${{ steps.set-up-homebrew.outputs.gems-hash }} + restore-keys: ${{ runner.os }}-rubygems${{ matrix.ruby }}- + + - name: Setup Ruby + if: matrix.ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ matrix.ruby }} + + - name: Setup Ruby environment + if: matrix.ruby + run: | + echo "HOMEBREW_USE_RUBY_FROM_PATH=1" >> "${GITHUB_ENV}" + echo "HOMEBREW_BOOTSNAP=" >> "${GITHUB_ENV}" # Unsupported, for now + rm -rf "${{ steps.set-up-homebrew.outputs.repository-path }}/Library/Homebrew/vendor/portable-ruby" + + - run: brew config - name: Install Bundler RubyGems run: brew install-bundler-gems --groups=all @@ -320,8 +341,8 @@ jobs: uses: actions/cache@v3 with: path: tests - key: ${{ runner.os }}-${{ matrix.test-flags }}-parallel_runtime_rspec-${{ github.sha }} - restore-keys: ${{ runner.os }}-${{ matrix.test-flags }}-parallel_runtime_rspec- + key: ${{ runner.os }}-${{ matrix.test-flags }}-parallel_runtime_rspec${{ matrix.ruby }}-${{ github.sha }} + restore-keys: ${{ runner.os }}-${{ matrix.test-flags }}-parallel_runtime_rspec${{ matrix.ruby }}- - name: Install brew tests dependencies if: matrix.name != 'tests (generic OS)' diff --git a/.gitignore b/.gitignore index 31b47cb161..806bde19fc 100644 --- a/.gitignore +++ b/.gitignore @@ -37,6 +37,10 @@ **/vendor/bundle/ruby/*/plugins **/vendor/bundle/ruby/*/specifications +# Ignore Ruby gems for versions other than we explicitly vendor +**/vendor/bundle/ruby/*/ +!**/vendor/bundle/ruby/2.6.0/ + # Ignore Bundler binary files **/vendor/bundle/ruby/*/gems/**/*.bundle diff --git a/Library/Homebrew/Gemfile b/Library/Homebrew/Gemfile index 191d22a639..2c494287fc 100644 --- a/Library/Homebrew/Gemfile +++ b/Library/Homebrew/Gemfile @@ -4,7 +4,7 @@ source "https://rubygems.org" # The default case (no envs), should always be a restrictive bound on the lowest supported minor version. # This is the branch that Dependabot will use. -if ENV.fetch("HOMEBREW_DEVELOPER", "").empty? || ENV.fetch("HOMEBREW_USE_RUBY_FROM_PATH", "").empty? +if ENV.fetch("HOMEBREW_USE_RUBY_FROM_PATH", "").empty? ruby "~> 2.6.0" else ruby ">= 2.6.0" diff --git a/Library/Homebrew/cask/artifact/abstract_uninstall.rb b/Library/Homebrew/cask/artifact/abstract_uninstall.rb index c36f371c17..234a7a5d8b 100644 --- a/Library/Homebrew/cask/artifact/abstract_uninstall.rb +++ b/Library/Homebrew/cask/artifact/abstract_uninstall.rb @@ -28,12 +28,12 @@ module Cask ].freeze def self.from_args(cask, **directives) - new(cask, directives) + new(cask, **directives) end attr_reader :directives - def initialize(cask, directives) + def initialize(cask, **directives) directives.assert_valid_keys(*ORDERED_DIRECTIVES) super(cask, **directives) diff --git a/Library/Homebrew/cask/cask_loader.rb b/Library/Homebrew/cask/cask_loader.rb index 379b8b6e8c..22b7efe25e 100644 --- a/Library/Homebrew/cask/cask_loader.rb +++ b/Library/Homebrew/cask/cask_loader.rb @@ -333,7 +333,13 @@ module Cask # for artifacts with blocks that can't be loaded from the API send(key) {} # empty on purpose else - send(key, *artifact[key]) + args = artifact[key] + kwargs = if args.last.is_a?(Hash) + args.pop + else + {} + end + send(key, *args, **kwargs) end end diff --git a/Library/Homebrew/cmd/readall.rb b/Library/Homebrew/cmd/readall.rb index 2e2ffe6bea..a352ca0cf3 100644 --- a/Library/Homebrew/cmd/readall.rb +++ b/Library/Homebrew/cmd/readall.rb @@ -62,7 +62,7 @@ module Homebrew end taps.each do |tap| - Homebrew.failed = true unless Readall.valid_tap?(tap, options) + Homebrew.failed = true unless Readall.valid_tap?(tap, **options) end end end diff --git a/Library/Homebrew/dev-cmd/tests.rb b/Library/Homebrew/dev-cmd/tests.rb index c4ab2ff194..d170366784 100644 --- a/Library/Homebrew/dev-cmd/tests.rb +++ b/Library/Homebrew/dev-cmd/tests.rb @@ -208,8 +208,8 @@ module Homebrew HOMEBREW_CACHE HOMEBREW_LOGS HOMEBREW_TEMP - HOMEBREW_USE_RUBY_FROM_PATH ] + allowed_test_env << "HOMEBREW_USE_RUBY_FROM_PATH" if Homebrew::EnvConfig.developer? Homebrew::EnvConfig::ENVS.keys.map(&:to_s).each do |env| next if allowed_test_env.include?(env) diff --git a/Library/Homebrew/test/cli/named_args_spec.rb b/Library/Homebrew/test/cli/named_args_spec.rb index 6328379e36..ecbfbd34db 100644 --- a/Library/Homebrew/test/cli/named_args_spec.rb +++ b/Library/Homebrew/test/cli/named_args_spec.rb @@ -4,17 +4,15 @@ require "cli/named_args" def setup_unredable_formula(name) error = FormulaUnreadableError.new(name, RuntimeError.new("testing")) - allow(Formulary).to receive(:factory).with(name, {}).and_raise(error) + allow(Formulary).to receive(:factory).with(name, any_args).and_raise(error) end def setup_unredable_cask(name) error = Cask::CaskUnreadableError.new(name, "testing") - allow(Cask::CaskLoader).to receive(:load).with(name).and_raise(error) - allow(Cask::CaskLoader).to receive(:load).with(name, config: nil).and_raise(error) + allow(Cask::CaskLoader).to receive(:load).with(name, any_args).and_raise(error) config = instance_double(Cask::Config) allow(Cask::Config).to receive(:from_args).and_return(config) - allow(Cask::CaskLoader).to receive(:load).with(name, config: config).and_raise(error) end describe Homebrew::CLI::NamedArgs do diff --git a/Library/Homebrew/test/dev-cmd/irb_spec.rb b/Library/Homebrew/test/dev-cmd/irb_spec.rb index 24478f5b13..97696fbc44 100644 --- a/Library/Homebrew/test/dev-cmd/irb_spec.rb +++ b/Library/Homebrew/test/dev-cmd/irb_spec.rb @@ -27,7 +27,10 @@ describe "brew irb" do .and not_to_output.to_stderr .and be_a_success - expect(history_file).to exist + # TODO: newer Ruby only supports history saving in interactive sessions + # and not if you feed in data from a file or stdin like we are doing here. + # The test will need to be adjusted for this to work. + expect(history_file).to exist if RUBY_VERSION < "2.7" end end end diff --git a/Library/Homebrew/test/rubocop_spec.rb b/Library/Homebrew/test/rubocop_spec.rb index 39892b7e70..ce163c2d98 100644 --- a/Library/Homebrew/test/rubocop_spec.rb +++ b/Library/Homebrew/test/rubocop_spec.rb @@ -6,7 +6,11 @@ describe "RuboCop" do context "when calling `rubocop` outside of the Homebrew environment" do before do ENV.each_key do |key| - ENV.delete(key) if key.start_with?("HOMEBREW_") && key != "HOMEBREW_USE_RUBY_FROM_PATH" + allowlist = %w[ + HOMEBREW_TESTS + HOMEBREW_USE_RUBY_FROM_PATH + ] + ENV.delete(key) if key.start_with?("HOMEBREW_") && allowlist.exclude?(key) end ENV["XDG_CACHE_HOME"] = (HOMEBREW_CACHE.realpath/"style").to_s diff --git a/Library/Homebrew/test/support/helper/formula.rb b/Library/Homebrew/test/support/helper/formula.rb index b919f77831..0c17ef4e04 100644 --- a/Library/Homebrew/test/support/helper/formula.rb +++ b/Library/Homebrew/test/support/helper/formula.rb @@ -15,8 +15,7 @@ module Test allow(Formulary).to receive(:loader_for).and_call_original if call_original loader = double(get_formula: formula) - allow(Formulary).to receive(:loader_for).with(ref, from: :keg, warn: false).and_return(loader) - allow(Formulary).to receive(:loader_for).with(ref, {}).and_return(loader) + allow(Formulary).to receive(:loader_for).with(ref, any_args).and_return(loader) end end end diff --git a/Library/Homebrew/test/test_runner_formula_spec.rb b/Library/Homebrew/test/test_runner_formula_spec.rb index df7c0b32ab..ceb1debd1f 100644 --- a/Library/Homebrew/test/test_runner_formula_spec.rb +++ b/Library/Homebrew/test/test_runner_formula_spec.rb @@ -296,12 +296,12 @@ describe TestRunnerFormula do context "when a formula has no dependents" do it "returns an empty array" do - expect(described_class.new(testball).dependents(current_system)).to eq([]) - expect(described_class.new(xcode_helper).dependents(current_system)).to eq([]) - expect(described_class.new(linux_kernel_requirer).dependents(current_system)).to eq([]) - expect(described_class.new(old_non_portable_software).dependents(current_system)).to eq([]) - expect(described_class.new(fancy_new_software).dependents(current_system)).to eq([]) - expect(described_class.new(needs_modern_compiler).dependents(current_system)).to eq([]) + expect(described_class.new(testball).dependents(**current_system)).to eq([]) + expect(described_class.new(xcode_helper).dependents(**current_system)).to eq([]) + expect(described_class.new(linux_kernel_requirer).dependents(**current_system)).to eq([]) + expect(described_class.new(old_non_portable_software).dependents(**current_system)).to eq([]) + expect(described_class.new(fancy_new_software).dependents(**current_system)).to eq([]) + expect(described_class.new(needs_modern_compiler).dependents(**current_system)).to eq([]) end end @@ -313,11 +313,11 @@ describe TestRunnerFormula do allow(Formula).to receive(:all).and_return([testball_user, recursive_testball_dependent]) expect( - described_class.new(testball, eval_all: true).dependents(current_system).map(&:name), + described_class.new(testball, eval_all: true).dependents(**current_system).map(&:name), ).to eq(["testball_user"]) expect( - described_class.new(testball_user, eval_all: true).dependents(current_system).map(&:name), + described_class.new(testball_user, eval_all: true).dependents(**current_system).map(&:name), ).to eq(["recursive_testball_dependent"]) end diff --git a/Library/Homebrew/test/utils/ruby_check_version_script_spec.rb b/Library/Homebrew/test/utils/ruby_check_version_script_spec.rb index 6141fbe634..86e88af7a6 100644 --- a/Library/Homebrew/test/utils/ruby_check_version_script_spec.rb +++ b/Library/Homebrew/test/utils/ruby_check_version_script_spec.rb @@ -5,6 +5,7 @@ describe Utils do subject do homebrew_env = ENV.select { |key, _| key.start_with?("HOMEBREW_") } Bundler.with_unbundled_env do + ENV.delete_if { |key,| key.start_with?("HOMEBREW_") } ENV.update(homebrew_env) quiet_system "#{HOMEBREW_LIBRARY_PATH}/utils/ruby_check_version_script.rb", required_ruby_version end diff --git a/Library/Homebrew/utils/gems.rb b/Library/Homebrew/utils/gems.rb index 2d594c5491..157db7bec2 100644 --- a/Library/Homebrew/utils/gems.rb +++ b/Library/Homebrew/utils/gems.rb @@ -177,13 +177,16 @@ module Homebrew def user_gem_groups @user_gem_groups ||= if GEM_GROUPS_FILE.exist? GEM_GROUPS_FILE.readlines(chomp: true) - else - # Backwards compatibility. This else block can be replaced by `[]` by the end of 2023. + elsif RUBY_VERSION < "2.7" + # Backwards compatibility. This elsif block removed by the end of 2023. + # We will not support this in Ruby >=2.7. require "settings" groups = Homebrew::Settings.read(:gemgroups)&.split(";") || [] write_user_gem_groups(groups) Homebrew::Settings.delete(:gemgroups) groups + else + [] end end @@ -194,8 +197,9 @@ module Homebrew def forget_user_gem_groups! if GEM_GROUPS_FILE.exist? GEM_GROUPS_FILE.truncate(0) - else + elsif RUBY_VERSION < "2.7" # Backwards compatibility. This else block can be removed by the end of 2023. + # We will not support this in Ruby >=2.7. require "settings" Homebrew::Settings.delete(:gemgroups) end diff --git a/Library/Homebrew/utils/ruby.sh b/Library/Homebrew/utils/ruby.sh index 087e28dc5d..b8573b1705 100644 --- a/Library/Homebrew/utils/ruby.sh +++ b/Library/Homebrew/utils/ruby.sh @@ -16,7 +16,7 @@ test_ruby() { } can_use_ruby_from_path() { - if [[ -n "${HOMEBREW_DEVELOPER}" && -n "${HOMEBREW_USE_RUBY_FROM_PATH}" ]] + if [[ -n "${HOMEBREW_DEVELOPER}" || -n "${HOMEBREW_TESTS}" ]] && [[ -n "${HOMEBREW_USE_RUBY_FROM_PATH}" ]] then return 0 fi diff --git a/Library/Homebrew/utils/ruby_check_version_script.rb b/Library/Homebrew/utils/ruby_check_version_script.rb index 2d2ffbd26d..40bd14aa90 100755 --- a/Library/Homebrew/utils/ruby_check_version_script.rb +++ b/Library/Homebrew/utils/ruby_check_version_script.rb @@ -17,7 +17,7 @@ ruby_version_major, ruby_version_minor, = ruby_version.canonical_segments homebrew_required_ruby_version_major, homebrew_required_ruby_version_minor, = homebrew_required_ruby_version.canonical_segments -if !ENV.fetch("HOMEBREW_DEVELOPER", "").empty? && +if (!ENV.fetch("HOMEBREW_DEVELOPER", "").empty? || !ENV.fetch("HOMEBREW_TESTS", "").empty?) && !ENV.fetch("HOMEBREW_USE_RUBY_FROM_PATH", "").empty? && ruby_version >= homebrew_required_ruby_version return