From 89e640c567eddbaf1c682df01e1ecd624574aa5b Mon Sep 17 00:00:00 2001 From: Douglas Eichelberger Date: Fri, 22 Nov 2024 18:06:49 -0800 Subject: [PATCH 1/2] Remove OpenStruct from Uses cmd --- Library/Homebrew/cli/named_args.rb | 8 ++++---- Library/Homebrew/cmd/uses.rb | 11 ++++++----- Library/Homebrew/formula.rb | 8 +------- Library/Homebrew/formula.rbi | 3 --- Library/Homebrew/test/cmd/uses_spec.rb | 19 +++++++++++++++++++ 5 files changed, 30 insertions(+), 19 deletions(-) diff --git a/Library/Homebrew/cli/named_args.rb b/Library/Homebrew/cli/named_args.rb index 7d46b75450182..5990e875f3d54 100644 --- a/Library/Homebrew/cli/named_args.rb +++ b/Library/Homebrew/cli/named_args.rb @@ -55,7 +55,7 @@ def to_formulae sig { params( only: T.nilable(Symbol), - ignore_unavailable: T.nilable(T::Boolean), + ignore_unavailable: T::Boolean, method: T.nilable(Symbol), uniq: T::Boolean, warn: T::Boolean, @@ -63,7 +63,7 @@ def to_formulae } def to_formulae_and_casks( only: parent&.only_formula_or_cask, - ignore_unavailable: nil, + ignore_unavailable: false, method: T.unsafe(nil), uniq: true, warn: T.unsafe(nil) @@ -367,10 +367,10 @@ def to_kegs end sig { - params(only: T.nilable(Symbol), ignore_unavailable: T.nilable(T::Boolean), all_kegs: T.nilable(T::Boolean)) + params(only: T.nilable(Symbol), ignore_unavailable: T::Boolean, all_kegs: T.nilable(T::Boolean)) .returns([T::Array[Keg], T::Array[Cask::Cask]]) } - def to_kegs_to_casks(only: parent&.only_formula_or_cask, ignore_unavailable: nil, all_kegs: nil) + def to_kegs_to_casks(only: parent&.only_formula_or_cask, ignore_unavailable: false, all_kegs: nil) method = all_kegs ? :kegs : :default_kegs @to_kegs_to_casks ||= {} @to_kegs_to_casks[method] ||= diff --git a/Library/Homebrew/cmd/uses.rb b/Library/Homebrew/cmd/uses.rb index 3bcb86a2e6de7..6bba12442667c 100644 --- a/Library/Homebrew/cmd/uses.rb +++ b/Library/Homebrew/cmd/uses.rb @@ -5,7 +5,6 @@ require "formula" require "cask/caskroom" require "dependencies_helpers" -require "ostruct" module Homebrew module Cmd @@ -15,6 +14,11 @@ module Cmd class Uses < AbstractCommand include DependenciesHelpers + class UnavailableFormula < T::Struct + const :name, String + const :full_name, String + end + cmd_args do description <<~EOS Show formulae and casks that specify as a dependency; that is, show dependents @@ -64,10 +68,7 @@ def run opoo e used_formulae_missing = true # If the formula doesn't exist: fake the needed formula object name. - # This is a legacy use of OpenStruct that should be refactored. - # rubocop:disable Style/OpenStructUse - args.named.map { |name| OpenStruct.new name:, full_name: name } - # rubocop:enable Style/OpenStructUse + args.named.map { |name| UnavailableFormula.new name:, full_name: name } end use_runtime_dependents = args.installed? && diff --git a/Library/Homebrew/formula.rb b/Library/Homebrew/formula.rb index 4416b826f5757..0b3c00e51ccb1 100644 --- a/Library/Homebrew/formula.rb +++ b/Library/Homebrew/formula.rb @@ -2886,7 +2886,7 @@ def run_test(keep_tmp: false) sig { returns(T::Boolean) } def test_defined? - false + method(:test).owner != Formula end def test; end @@ -3348,12 +3348,6 @@ def inherited(child) end end - def method_added(method) - super - - define_method(:test_defined?) { true } if method == :test - end - def freeze specs.each(&:freeze) @livecheck.freeze diff --git a/Library/Homebrew/formula.rbi b/Library/Homebrew/formula.rbi index 85be1bf27e4fb..2beea9c311563 100644 --- a/Library/Homebrew/formula.rbi +++ b/Library/Homebrew/formula.rbi @@ -1,9 +1,6 @@ # typed: strict -# This file provides definitions for Forwardable#delegate, which is currently not supported by Sorbet. - class Formula - def self.on_system_blocks_exist?; end # This method is included by `OnSystem` def self.on_macos(&block); end end diff --git a/Library/Homebrew/test/cmd/uses_spec.rb b/Library/Homebrew/test/cmd/uses_spec.rb index 92d27df77812b..9cea6ade8c461 100644 --- a/Library/Homebrew/test/cmd/uses_spec.rb +++ b/Library/Homebrew/test/cmd/uses_spec.rb @@ -1,5 +1,6 @@ # frozen_string_literal: true +require "cli/named_args" require "cmd/shared_examples/args_parse" require "cmd/uses" require "fileutils" @@ -44,4 +45,22 @@ .and not_to_output.to_stderr .and be_a_success end + + it "handles unavailable formula", :integration_test do + setup_test_formula "foo" + setup_test_formula "bar" + setup_test_formula "optional", <<~RUBY + url "https://brew.sh/optional-1.0" + depends_on "bar" => :optional + RUBY + + expect_any_instance_of(Homebrew::CLI::NamedArgs) + .to receive(:to_formulae) + .and_raise(FormulaUnavailableError, "foo") + cmd = described_class.new(%w[foo --eval-all --include-optional --recursive]) + expect { cmd.run } + .to output(/^(bar\noptional|optional\nbar)$/).to_stdout + .and output(/Error: Missing formulae should not have dependents!\n/).to_stderr + .and raise_error SystemExit + end end From cb1c49e06bf1b3f1b3c65f34f0926ce63c24a415 Mon Sep 17 00:00:00 2001 From: Douglas Eichelberger Date: Sat, 23 Nov 2024 10:25:45 -0800 Subject: [PATCH 2/2] Fix sigs --- Library/Homebrew/cmd/uses.rb | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/Library/Homebrew/cmd/uses.rb b/Library/Homebrew/cmd/uses.rb index 6bba12442667c..5305925ffe72d 100644 --- a/Library/Homebrew/cmd/uses.rb +++ b/Library/Homebrew/cmd/uses.rb @@ -88,7 +88,10 @@ def run private - sig { params(use_runtime_dependents: T::Boolean, used_formulae: T::Array[Formula]).returns(T::Array[Formula]) } + sig { + params(use_runtime_dependents: T::Boolean, used_formulae: T::Array[T.any(Formula, UnavailableFormula)]) + .returns(T::Array[Formula]) + } def intersection_of_dependents(use_runtime_dependents, used_formulae) recursive = args.recursive? show_formulae_and_casks = !args.formula? && !args.cask? @@ -96,6 +99,8 @@ def intersection_of_dependents(use_runtime_dependents, used_formulae) deps = [] if use_runtime_dependents + # We can only get here if `used_formulae_missing` is false, thus there are no UnavailableFormula. + used_formulae = T.cast(used_formulae, T::Array[Formula]) if show_formulae_and_casks || args.formula? deps += used_formulae.map(&:runtime_installed_formula_dependents) .reduce(&:&) @@ -141,8 +146,8 @@ def intersection_of_dependents(use_runtime_dependents, used_formulae) sig { params( - dependents: T::Array[Formula], used_formulae: T::Array[Formula], recursive: T::Boolean, - includes: T::Array[Symbol], ignores: T::Array[Symbol] + dependents: T::Array[Formula], used_formulae: T::Array[T.any(Formula, UnavailableFormula)], + recursive: T::Boolean, includes: T::Array[Symbol], ignores: T::Array[Symbol] ).returns( T::Array[Formula], )