Enable strict typing in DependenciesHelpers
This commit is contained in:
		
							parent
							
								
									673f19086b
								
							
						
					
					
						commit
						0037b1f626
					
				@ -1,11 +1,9 @@
 | 
				
			|||||||
# typed: true # rubocop:todo Sorbet/StrictSigil
 | 
					# typed: strict
 | 
				
			||||||
# frozen_string_literal: true
 | 
					# frozen_string_literal: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
module OS
 | 
					module OS
 | 
				
			||||||
  module Mac
 | 
					  module Mac
 | 
				
			||||||
    module_function
 | 
					    SYSTEM_DIRS = T.let([
 | 
				
			||||||
 | 
					 | 
				
			||||||
    SYSTEM_DIRS = [
 | 
					 | 
				
			||||||
      "/",
 | 
					      "/",
 | 
				
			||||||
      "/Applications",
 | 
					      "/Applications",
 | 
				
			||||||
      "/Applications/Utilities",
 | 
					      "/Applications/Utilities",
 | 
				
			||||||
@ -234,14 +232,13 @@ module OS
 | 
				
			|||||||
      "/var/spool/mail",
 | 
					      "/var/spool/mail",
 | 
				
			||||||
      "/var/tmp",
 | 
					      "/var/tmp",
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
                  .map(&method(:Pathname))
 | 
					                  .to_set { Pathname(_1) }
 | 
				
			||||||
                  .to_set
 | 
					                  .freeze, T::Set[Pathname])
 | 
				
			||||||
                  .freeze
 | 
					 | 
				
			||||||
    private_constant :SYSTEM_DIRS
 | 
					    private_constant :SYSTEM_DIRS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # TODO: There should be a way to specify a containing
 | 
					    # TODO: There should be a way to specify a containing
 | 
				
			||||||
    #       directory under which nothing can be deleted.
 | 
					    #       directory under which nothing can be deleted.
 | 
				
			||||||
    UNDELETABLE_PATHS = [
 | 
					    UNDELETABLE_PATHS = T.let([
 | 
				
			||||||
      "~/",
 | 
					      "~/",
 | 
				
			||||||
      "~/Applications",
 | 
					      "~/Applications",
 | 
				
			||||||
      "~/Applications/.localized",
 | 
					      "~/Applications/.localized",
 | 
				
			||||||
@ -378,14 +375,16 @@ module OS
 | 
				
			|||||||
    ]
 | 
					    ]
 | 
				
			||||||
                        .to_set { |path| Pathname(path.sub(%r{^~(?=(/|$))}, Dir.home)).expand_path }
 | 
					                        .to_set { |path| Pathname(path.sub(%r{^~(?=(/|$))}, Dir.home)).expand_path }
 | 
				
			||||||
                        .union(SYSTEM_DIRS)
 | 
					                        .union(SYSTEM_DIRS)
 | 
				
			||||||
                        .freeze
 | 
					                        .freeze, T::Set[Pathname])
 | 
				
			||||||
    private_constant :UNDELETABLE_PATHS
 | 
					    private_constant :UNDELETABLE_PATHS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def system_dir?(dir)
 | 
					    sig { params(dir: T.any(Pathname, String)).returns(T::Boolean) }
 | 
				
			||||||
 | 
					    def self.system_dir?(dir)
 | 
				
			||||||
      SYSTEM_DIRS.include?(Pathname.new(dir).expand_path)
 | 
					      SYSTEM_DIRS.include?(Pathname.new(dir).expand_path)
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def undeletable?(path)
 | 
					    sig { params(path: T.any(Pathname, String)).returns(T::Boolean) }
 | 
				
			||||||
 | 
					    def self.undeletable?(path)
 | 
				
			||||||
      UNDELETABLE_PATHS.include?(Pathname.new(path).expand_path)
 | 
					      UNDELETABLE_PATHS.include?(Pathname.new(path).expand_path)
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
				
			|||||||
@ -70,26 +70,29 @@ module Homebrew
 | 
				
			|||||||
          method:             T.nilable(Symbol),
 | 
					          method:             T.nilable(Symbol),
 | 
				
			||||||
          uniq:               T::Boolean,
 | 
					          uniq:               T::Boolean,
 | 
				
			||||||
          warn:               T::Boolean,
 | 
					          warn:               T::Boolean,
 | 
				
			||||||
        ).returns(T::Array[T.any(Formula, Keg, Cask::Cask)])
 | 
					        ).returns(T::Array[T.any(Formula, Cask::Cask)])
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      def to_formulae_and_casks(
 | 
					      def to_formulae_and_casks(
 | 
				
			||||||
        only: parent.only_formula_or_cask, ignore_unavailable: false, method: nil, uniq: true, warn: false
 | 
					        only: parent.only_formula_or_cask, ignore_unavailable: false, method: nil, uniq: true, warn: false
 | 
				
			||||||
      )
 | 
					      )
 | 
				
			||||||
        @to_formulae_and_casks ||= T.let(
 | 
					        @to_formulae_and_casks ||= T.let(
 | 
				
			||||||
          {}, T.nilable(T::Hash[T.nilable(Symbol), T::Array[T.any(Formula, Keg, Cask::Cask)]])
 | 
					          {}, T.nilable(T::Hash[T.nilable(Symbol), T::Array[T.any(Formula, Cask::Cask)]])
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        @to_formulae_and_casks[only] ||= T.cast(
 | 
				
			||||||
 | 
					          downcased_unique_named.flat_map do |name|
 | 
				
			||||||
 | 
					            options = { warn: }.compact
 | 
				
			||||||
 | 
					            load_formula_or_cask(name, only:, method:, **options)
 | 
				
			||||||
 | 
					          rescue FormulaUnreadableError, FormulaClassUnavailableError,
 | 
				
			||||||
 | 
					                 TapFormulaUnreadableError, TapFormulaClassUnavailableError,
 | 
				
			||||||
 | 
					                 Cask::CaskUnreadableError
 | 
				
			||||||
 | 
					            # Need to rescue before `*UnavailableError` (superclass of this)
 | 
				
			||||||
 | 
					            # The formula/cask was found, but there's a problem with its implementation
 | 
				
			||||||
 | 
					            raise
 | 
				
			||||||
 | 
					          rescue NoSuchKegError, FormulaUnavailableError, Cask::CaskUnavailableError, FormulaOrCaskUnavailableError
 | 
				
			||||||
 | 
					            ignore_unavailable ? [] : raise
 | 
				
			||||||
 | 
					          end.freeze,
 | 
				
			||||||
 | 
					          T::Array[T.any(Formula, Cask::Cask)],
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        @to_formulae_and_casks[only] ||= downcased_unique_named.flat_map do |name|
 | 
					 | 
				
			||||||
          options = { warn: }.compact
 | 
					 | 
				
			||||||
          load_formula_or_cask(name, only:, method:, **options)
 | 
					 | 
				
			||||||
        rescue FormulaUnreadableError, FormulaClassUnavailableError,
 | 
					 | 
				
			||||||
               TapFormulaUnreadableError, TapFormulaClassUnavailableError,
 | 
					 | 
				
			||||||
               Cask::CaskUnreadableError
 | 
					 | 
				
			||||||
          # Need to rescue before `*UnavailableError` (superclass of this)
 | 
					 | 
				
			||||||
          # The formula/cask was found, but there's a problem with its implementation
 | 
					 | 
				
			||||||
          raise
 | 
					 | 
				
			||||||
        rescue NoSuchKegError, FormulaUnavailableError, Cask::CaskUnavailableError, FormulaOrCaskUnavailableError
 | 
					 | 
				
			||||||
          ignore_unavailable ? [] : raise
 | 
					 | 
				
			||||||
        end.freeze
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if uniq
 | 
					        if uniq
 | 
				
			||||||
          @to_formulae_and_casks.fetch(only).uniq.freeze
 | 
					          @to_formulae_and_casks.fetch(only).uniq.freeze
 | 
				
			||||||
@ -120,7 +123,7 @@ module Homebrew
 | 
				
			|||||||
      def to_formulae_and_casks_with_taps
 | 
					      def to_formulae_and_casks_with_taps
 | 
				
			||||||
        formulae_and_casks_with_taps, formulae_and_casks_without_taps =
 | 
					        formulae_and_casks_with_taps, formulae_and_casks_without_taps =
 | 
				
			||||||
          to_formulae_and_casks.partition do |formula_or_cask|
 | 
					          to_formulae_and_casks.partition do |formula_or_cask|
 | 
				
			||||||
            T.cast(formula_or_cask, T.any(Formula, Cask::Cask)).tap&.installed?
 | 
					            formula_or_cask.tap&.installed?
 | 
				
			||||||
          end
 | 
					          end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return formulae_and_casks_with_taps if formulae_and_casks_without_taps.empty?
 | 
					        return formulae_and_casks_with_taps if formulae_and_casks_without_taps.empty?
 | 
				
			||||||
 | 
				
			|||||||
@ -81,7 +81,7 @@ module Homebrew
 | 
				
			|||||||
              end
 | 
					              end
 | 
				
			||||||
            end
 | 
					            end
 | 
				
			||||||
          else
 | 
					          else
 | 
				
			||||||
            raise "Invalid type: #{formula_or_cask.class}"
 | 
					            T.absurd(formula_or_cask)
 | 
				
			||||||
          end
 | 
					          end
 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
 | 
				
			|||||||
@ -221,8 +221,8 @@ module Homebrew
 | 
				
			|||||||
        deps = dependency.runtime_dependencies if @use_runtime_dependencies
 | 
					        deps = dependency.runtime_dependencies if @use_runtime_dependencies
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if recursive
 | 
					        if recursive
 | 
				
			||||||
          deps ||= recursive_includes(Dependency, dependency, includes, ignores)
 | 
					          deps ||= recursive_dep_includes(dependency, includes, ignores)
 | 
				
			||||||
          reqs   = recursive_includes(Requirement, dependency, includes, ignores)
 | 
					          reqs   = recursive_req_includes(dependency, includes, ignores)
 | 
				
			||||||
        else
 | 
					        else
 | 
				
			||||||
          deps ||= select_includes(dependency.deps, ignores, includes)
 | 
					          deps ||= select_includes(dependency.deps, ignores, includes)
 | 
				
			||||||
          reqs   = select_includes(dependency.requirements, ignores, includes)
 | 
					          reqs   = select_includes(dependency.requirements, ignores, includes)
 | 
				
			||||||
 | 
				
			|||||||
@ -65,7 +65,7 @@ module Homebrew
 | 
				
			|||||||
            description = formula_or_cask.desc.presence || Formatter.warning("[no description]")
 | 
					            description = formula_or_cask.desc.presence || Formatter.warning("[no description]")
 | 
				
			||||||
            desc[formula_or_cask.full_name] = "(#{formula_or_cask.name.join(", ")}) #{description}"
 | 
					            desc[formula_or_cask.full_name] = "(#{formula_or_cask.name.join(", ")}) #{description}"
 | 
				
			||||||
          else
 | 
					          else
 | 
				
			||||||
            raise TypeError, "Unsupported formula_or_cask type: #{formula_or_cask.class}"
 | 
					            T.absurd(formula_or_cask)
 | 
				
			||||||
          end
 | 
					          end
 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
        Descriptions.new(desc).print
 | 
					        Descriptions.new(desc).print
 | 
				
			||||||
 | 
				
			|||||||
@ -29,8 +29,7 @@ module Homebrew
 | 
				
			|||||||
          return
 | 
					          return
 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # to_formulae_and_casks is typed to possibly return Kegs (but won't without explicitly asking)
 | 
					        formulae_or_casks = args.named.to_formulae_and_casks
 | 
				
			||||||
        formulae_or_casks = T.cast(args.named.to_formulae_and_casks, T::Array[T.any(Formula, Cask::Cask)])
 | 
					 | 
				
			||||||
        homepages = formulae_or_casks.map do |formula_or_cask|
 | 
					        homepages = formulae_or_casks.map do |formula_or_cask|
 | 
				
			||||||
          puts "Opening homepage for #{name_of(formula_or_cask)}"
 | 
					          puts "Opening homepage for #{name_of(formula_or_cask)}"
 | 
				
			||||||
          formula_or_cask.homepage
 | 
					          formula_or_cask.homepage
 | 
				
			||||||
 | 
				
			|||||||
@ -99,9 +99,7 @@ module Homebrew
 | 
				
			|||||||
            else
 | 
					            else
 | 
				
			||||||
              args.named.to_formulae_and_casks(only: :cask, method: :resolve)
 | 
					              args.named.to_formulae_and_casks(only: :cask, method: :resolve)
 | 
				
			||||||
            end
 | 
					            end
 | 
				
			||||||
            # The cast is because `Keg`` does not define `full_name`
 | 
					            full_cask_names = cask_names.map(&:full_name).sort(&tap_and_name_comparison)
 | 
				
			||||||
            full_cask_names = T.cast(cask_names, T::Array[T.any(Formula, Cask::Cask)])
 | 
					 | 
				
			||||||
                               .map(&:full_name).sort(&tap_and_name_comparison)
 | 
					 | 
				
			||||||
            full_cask_names = Formatter.columns(full_cask_names) unless args.public_send(:"1?")
 | 
					            full_cask_names = Formatter.columns(full_cask_names) unless args.public_send(:"1?")
 | 
				
			||||||
            puts full_cask_names if full_cask_names.present?
 | 
					            puts full_cask_names if full_cask_names.present?
 | 
				
			||||||
          end
 | 
					          end
 | 
				
			||||||
 | 
				
			|||||||
@ -94,7 +94,7 @@ module Homebrew
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      sig {
 | 
					      sig {
 | 
				
			||||||
        params(use_runtime_dependents: T::Boolean, used_formulae: T::Array[T.any(Formula, UnavailableFormula)])
 | 
					        params(use_runtime_dependents: T::Boolean, used_formulae: T::Array[T.any(Formula, UnavailableFormula)])
 | 
				
			||||||
          .returns(T::Array[Formula])
 | 
					          .returns(T::Array[T.any(Formula, CaskDependent)])
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      def intersection_of_dependents(use_runtime_dependents, used_formulae)
 | 
					      def intersection_of_dependents(use_runtime_dependents, used_formulae)
 | 
				
			||||||
        recursive = args.recursive?
 | 
					        recursive = args.recursive?
 | 
				
			||||||
@ -150,26 +150,30 @@ module Homebrew
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      sig {
 | 
					      sig {
 | 
				
			||||||
        params(
 | 
					        params(
 | 
				
			||||||
          dependents: T::Array[Formula], used_formulae: T::Array[T.any(Formula, UnavailableFormula)],
 | 
					          dependents:    T::Array[T.any(Formula, CaskDependent)],
 | 
				
			||||||
          recursive: T::Boolean, includes: T::Array[Symbol], ignores: T::Array[Symbol]
 | 
					          used_formulae: T::Array[T.any(Formula, UnavailableFormula)],
 | 
				
			||||||
        ).returns(
 | 
					          recursive:     T::Boolean,
 | 
				
			||||||
          T::Array[Formula],
 | 
					          includes:      T::Array[Symbol],
 | 
				
			||||||
        )
 | 
					          ignores:       T::Array[Symbol],
 | 
				
			||||||
 | 
					        ).returns(T::Array[T.any(Formula, CaskDependent)])
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      def select_used_dependents(dependents, used_formulae, recursive, includes, ignores)
 | 
					      def select_used_dependents(dependents, used_formulae, recursive, includes, ignores)
 | 
				
			||||||
        dependents.select do |d|
 | 
					        dependents.select do |d|
 | 
				
			||||||
          deps = if recursive
 | 
					          deps = if recursive
 | 
				
			||||||
            recursive_includes(Dependency, d, includes, ignores)
 | 
					            recursive_dep_includes(d, includes, ignores)
 | 
				
			||||||
          else
 | 
					          else
 | 
				
			||||||
            select_includes(d.deps, ignores, includes)
 | 
					            select_includes(d.deps, ignores, includes)
 | 
				
			||||||
          end
 | 
					          end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          used_formulae.all? do |ff|
 | 
					          used_formulae.all? do |ff|
 | 
				
			||||||
            deps.any? do |dep|
 | 
					            deps.any? do |dep|
 | 
				
			||||||
              match = begin
 | 
					              match = case dep
 | 
				
			||||||
 | 
					              when Dependency
 | 
				
			||||||
                dep.to_formula.full_name == ff.full_name if dep.name.include?("/")
 | 
					                dep.to_formula.full_name == ff.full_name if dep.name.include?("/")
 | 
				
			||||||
              rescue
 | 
					              when CaskDependent, Formula
 | 
				
			||||||
                nil
 | 
					                nil
 | 
				
			||||||
 | 
					              else
 | 
				
			||||||
 | 
					                T.absurd(dep)
 | 
				
			||||||
              end
 | 
					              end
 | 
				
			||||||
              next match unless match.nil?
 | 
					              next match unless match.nil?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -39,11 +39,6 @@ class Dependencies < SimpleDelegator
 | 
				
			|||||||
  def inspect
 | 
					  def inspect
 | 
				
			||||||
    "#<#{self.class.name}: #{__getobj__}>"
 | 
					    "#<#{self.class.name}: #{__getobj__}>"
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					 | 
				
			||||||
  sig { returns(T::Array[Dependency]) }
 | 
					 | 
				
			||||||
  def to_a
 | 
					 | 
				
			||||||
    __getobj__.to_a
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# A collection of requirements.
 | 
					# A collection of requirements.
 | 
				
			||||||
 | 
				
			|||||||
@ -1,13 +1,24 @@
 | 
				
			|||||||
# typed: strict
 | 
					# typed: strict
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Dependencies < SimpleDelegator
 | 
					class Dependencies < SimpleDelegator
 | 
				
			||||||
 | 
					  include Enumerable
 | 
				
			||||||
  include Kernel
 | 
					  include Kernel
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # This is a workaround to enable `alias eql? ==`
 | 
					  # This is a workaround to enable `alias eql? ==`
 | 
				
			||||||
  # @see https://github.com/sorbet/sorbet/issues/2378#issuecomment-569474238
 | 
					  # @see https://github.com/sorbet/sorbet/issues/2378#issuecomment-569474238
 | 
				
			||||||
  sig { params(other: BasicObject).returns(T::Boolean) }
 | 
					  sig { params(other: BasicObject).returns(T::Boolean) }
 | 
				
			||||||
  def ==(other); end
 | 
					  def ==(other); end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  sig { params(blk: T.proc.params(arg0: Dependency).void).returns(T.self_type) }
 | 
				
			||||||
 | 
					  sig { returns(T::Enumerator[Dependency]) }
 | 
				
			||||||
 | 
					  def each(&blk); end
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Requirements < SimpleDelegator
 | 
					class Requirements < SimpleDelegator
 | 
				
			||||||
 | 
					  include Enumerable
 | 
				
			||||||
  include Kernel
 | 
					  include Kernel
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  sig { params(blk: T.proc.params(arg0: Requirement).void).returns(T.self_type) }
 | 
				
			||||||
 | 
					  sig { returns(T::Enumerator[Requirement]) }
 | 
				
			||||||
 | 
					  def each(&blk); end
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
				
			|||||||
@ -1,14 +1,10 @@
 | 
				
			|||||||
# typed: true # rubocop:todo Sorbet/StrictSigil
 | 
					# typed: strict
 | 
				
			||||||
# frozen_string_literal: true
 | 
					# frozen_string_literal: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
require "cask_dependent"
 | 
					require "cask_dependent"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Helper functions for dependencies.
 | 
					# Helper functions for dependencies.
 | 
				
			||||||
module DependenciesHelpers
 | 
					module DependenciesHelpers
 | 
				
			||||||
  extend T::Helpers
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  requires_ancestor { Kernel }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  def args_includes_ignores(args)
 | 
					  def args_includes_ignores(args)
 | 
				
			||||||
    includes = [:required?, :recommended?] # included by default
 | 
					    includes = [:required?, :recommended?] # included by default
 | 
				
			||||||
    includes << :implicit? if args.include_implicit?
 | 
					    includes << :implicit? if args.include_implicit?
 | 
				
			||||||
@ -23,9 +19,35 @@ module DependenciesHelpers
 | 
				
			|||||||
    [includes, ignores]
 | 
					    [includes, ignores]
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def recursive_includes(klass, root_dependent, includes, ignores)
 | 
					  sig {
 | 
				
			||||||
    raise ArgumentError, "Invalid class argument: #{klass}" if klass != Dependency && klass != Requirement
 | 
					    params(root_dependent: T.any(Formula, CaskDependent), includes: T::Array[Symbol], ignores: T::Array[Symbol])
 | 
				
			||||||
 | 
					      .returns(T::Array[Dependency])
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  def recursive_dep_includes(root_dependent, includes, ignores)
 | 
				
			||||||
 | 
					    # The use of T.unsafe is recommended by the Sorbet docs:
 | 
				
			||||||
 | 
					    #   https://sorbet.org/docs/overloads#multiple-methods-but-sharing-a-common-implementation
 | 
				
			||||||
 | 
					    T.unsafe(recursive_includes(Dependency, root_dependent, includes, ignores))
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  sig {
 | 
				
			||||||
 | 
					    params(root_dependent: T.any(Formula, CaskDependent), includes: T::Array[Symbol], ignores: T::Array[Symbol])
 | 
				
			||||||
 | 
					      .returns(Requirements)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  def recursive_req_includes(root_dependent, includes, ignores)
 | 
				
			||||||
 | 
					    # The use of T.unsafe is recommended by the Sorbet docs:
 | 
				
			||||||
 | 
					    #   https://sorbet.org/docs/overloads#multiple-methods-but-sharing-a-common-implementation
 | 
				
			||||||
 | 
					    T.unsafe(recursive_includes(Requirement, root_dependent, includes, ignores))
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  sig {
 | 
				
			||||||
 | 
					    params(
 | 
				
			||||||
 | 
					      klass:          T.any(T.class_of(Dependency), T.class_of(Requirement)),
 | 
				
			||||||
 | 
					      root_dependent: T.any(Formula, CaskDependent),
 | 
				
			||||||
 | 
					      includes:       T::Array[Symbol],
 | 
				
			||||||
 | 
					      ignores:        T::Array[Symbol],
 | 
				
			||||||
 | 
					    ).returns(T.any(T::Array[Dependency], Requirements))
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  def recursive_includes(klass, root_dependent, includes, ignores)
 | 
				
			||||||
    cache_key = "recursive_includes_#{includes}_#{ignores}"
 | 
					    cache_key = "recursive_includes_#{includes}_#{ignores}"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    klass.expand(root_dependent, cache_key:) do |dependent, dep|
 | 
					    klass.expand(root_dependent, cache_key:) do |dependent, dep|
 | 
				
			||||||
@ -43,6 +65,11 @@ module DependenciesHelpers
 | 
				
			|||||||
    end
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  sig {
 | 
				
			||||||
 | 
					    params(dependables: T::Array[T.any(Formula, CaskDependent)], ignores: T::Array[Symbol],
 | 
				
			||||||
 | 
					           includes: T::Array[Symbol])
 | 
				
			||||||
 | 
					      .returns(T::Array[T.any(Formula, CaskDependent)])
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
  def select_includes(dependables, ignores, includes)
 | 
					  def select_includes(dependables, ignores, includes)
 | 
				
			||||||
    dependables.select do |dep|
 | 
					    dependables.select do |dep|
 | 
				
			||||||
      next false if ignores.any? { |ignore| dep.public_send(ignore) }
 | 
					      next false if ignores.any? { |ignore| dep.public_send(ignore) }
 | 
				
			||||||
@ -51,6 +78,9 @@ module DependenciesHelpers
 | 
				
			|||||||
    end
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  sig {
 | 
				
			||||||
 | 
					    params(formulae_or_casks: T::Array[T.any(Formula, Cask::Cask)]).returns(T::Array[T.any(Formula, CaskDependent)])
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
  def dependents(formulae_or_casks)
 | 
					  def dependents(formulae_or_casks)
 | 
				
			||||||
    formulae_or_casks.map do |formula_or_cask|
 | 
					    formulae_or_casks.map do |formula_or_cask|
 | 
				
			||||||
      if formula_or_cask.is_a?(Formula)
 | 
					      if formula_or_cask.is_a?(Formula)
 | 
				
			||||||
@ -60,5 +90,4 @@ module DependenciesHelpers
 | 
				
			|||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
  module_function :dependents
 | 
					 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										12
									
								
								Library/Homebrew/dependencies_helpers.rbi
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								Library/Homebrew/dependencies_helpers.rbi
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,12 @@
 | 
				
			|||||||
 | 
					# typed: strict
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					module DependenciesHelpers
 | 
				
			||||||
 | 
					  include Kernel
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # This sig is in an RBI to avoid both circular dependencies and unnecessary requires
 | 
				
			||||||
 | 
					  sig {
 | 
				
			||||||
 | 
					    params(args: T.any(Homebrew::Cmd::Deps::Args, Homebrew::Cmd::Uses::Args))
 | 
				
			||||||
 | 
					      .returns([T::Array[Symbol], T::Array[Symbol]])
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  def args_includes_ignores(args); end
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
@ -35,7 +35,7 @@ RSpec.describe DependenciesHelpers do
 | 
				
			|||||||
      :any_version_installed?,
 | 
					      :any_version_installed?,
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    dependents = described_class.dependents([foo, foo_cask, bar, bar_cask])
 | 
					    dependents = Class.new.extend(described_class).dependents([foo, foo_cask, bar, bar_cask])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    dependents.each do |dependent|
 | 
					    dependents.each do |dependent|
 | 
				
			||||||
      methods.each do |method|
 | 
					      methods.each do |method|
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user