Merge pull request #9276 from reitermarkus/formula-types
Add types for `Formula`.
This commit is contained in:
		
						commit
						038b3b713c
					
				@ -10,7 +10,7 @@ class PATH
 | 
			
		||||
  include Enumerable
 | 
			
		||||
  extend Forwardable
 | 
			
		||||
 | 
			
		||||
  def_delegator :@paths, :each
 | 
			
		||||
  delegate each: :@paths
 | 
			
		||||
 | 
			
		||||
  # FIXME: Enable cop again when https://github.com/sorbet/sorbet/issues/3532 is fixed.
 | 
			
		||||
  # rubocop:disable Style/MutableConstant
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
# typed: false
 | 
			
		||||
# typed: true
 | 
			
		||||
# frozen_string_literal: true
 | 
			
		||||
 | 
			
		||||
require "cache_store"
 | 
			
		||||
@ -124,6 +124,7 @@ class Formula
 | 
			
		||||
 | 
			
		||||
  # The currently active {SoftwareSpec}.
 | 
			
		||||
  # @see #determine_active_spec
 | 
			
		||||
  sig { returns(SoftwareSpec) }
 | 
			
		||||
  attr_reader :active_spec
 | 
			
		||||
 | 
			
		||||
  protected :active_spec
 | 
			
		||||
@ -939,6 +940,7 @@ class Formula
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  # The generated launchd {.plist} file path.
 | 
			
		||||
  sig { returns(Pathname) }
 | 
			
		||||
  def plist_path
 | 
			
		||||
    prefix/"#{plist_name}.plist"
 | 
			
		||||
  end
 | 
			
		||||
@ -961,38 +963,47 @@ class Formula
 | 
			
		||||
    HOMEBREW_PREFIX/"opt"/name
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  sig { returns(Pathname) }
 | 
			
		||||
  def opt_bin
 | 
			
		||||
    opt_prefix/"bin"
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  sig { returns(Pathname) }
 | 
			
		||||
  def opt_include
 | 
			
		||||
    opt_prefix/"include"
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  sig { returns(Pathname) }
 | 
			
		||||
  def opt_lib
 | 
			
		||||
    opt_prefix/"lib"
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  sig { returns(Pathname) }
 | 
			
		||||
  def opt_libexec
 | 
			
		||||
    opt_prefix/"libexec"
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  sig { returns(Pathname) }
 | 
			
		||||
  def opt_sbin
 | 
			
		||||
    opt_prefix/"sbin"
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  sig { returns(Pathname) }
 | 
			
		||||
  def opt_share
 | 
			
		||||
    opt_prefix/"share"
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  sig { returns(Pathname) }
 | 
			
		||||
  def opt_pkgshare
 | 
			
		||||
    opt_prefix/"share"/name
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  sig { returns(Pathname) }
 | 
			
		||||
  def opt_elisp
 | 
			
		||||
    opt_prefix/"share/emacs/site-lisp"/name
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  sig { returns(Pathname) }
 | 
			
		||||
  def opt_frameworks
 | 
			
		||||
    opt_prefix/"Frameworks"
 | 
			
		||||
  end
 | 
			
		||||
@ -1012,40 +1023,45 @@ class Formula
 | 
			
		||||
  delegate pour_bottle_check_unsatisfied_reason: :"self.class"
 | 
			
		||||
 | 
			
		||||
  # Can be overridden to run commands on both source and bottle installation.
 | 
			
		||||
  sig { overridable.void }
 | 
			
		||||
  def post_install; end
 | 
			
		||||
 | 
			
		||||
  # @private
 | 
			
		||||
  sig { void }
 | 
			
		||||
  def run_post_install
 | 
			
		||||
    @prefix_returns_versioned_prefix = true
 | 
			
		||||
    build = self.build
 | 
			
		||||
    self.build = Tab.for_formula(self)
 | 
			
		||||
 | 
			
		||||
    new_env = {
 | 
			
		||||
      TMPDIR:        HOMEBREW_TEMP,
 | 
			
		||||
      TEMP:          HOMEBREW_TEMP,
 | 
			
		||||
      TMP:           HOMEBREW_TEMP,
 | 
			
		||||
      _JAVA_OPTIONS: "-Djava.io.tmpdir=#{HOMEBREW_TEMP}",
 | 
			
		||||
      HOMEBREW_PATH: nil,
 | 
			
		||||
      PATH:          ENV["HOMEBREW_PATH"],
 | 
			
		||||
    }
 | 
			
		||||
    begin
 | 
			
		||||
      self.build = Tab.for_formula(self)
 | 
			
		||||
 | 
			
		||||
    with_env(new_env) do
 | 
			
		||||
      ENV.clear_sensitive_environment!
 | 
			
		||||
      new_env = {
 | 
			
		||||
        TMPDIR:        HOMEBREW_TEMP,
 | 
			
		||||
        TEMP:          HOMEBREW_TEMP,
 | 
			
		||||
        TMP:           HOMEBREW_TEMP,
 | 
			
		||||
        _JAVA_OPTIONS: "-Djava.io.tmpdir=#{HOMEBREW_TEMP}",
 | 
			
		||||
        HOMEBREW_PATH: nil,
 | 
			
		||||
        PATH:          ENV["HOMEBREW_PATH"],
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      etc_var_dirs = [bottle_prefix/"etc", bottle_prefix/"var"]
 | 
			
		||||
      Find.find(*etc_var_dirs.select(&:directory?)) do |path|
 | 
			
		||||
        path = Pathname.new(path)
 | 
			
		||||
        path.extend(InstallRenamed)
 | 
			
		||||
        path.cp_path_sub(bottle_prefix, HOMEBREW_PREFIX)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      with_logging("post_install") do
 | 
			
		||||
        post_install
 | 
			
		||||
      with_env(new_env) do
 | 
			
		||||
        ENV.clear_sensitive_environment!
 | 
			
		||||
 | 
			
		||||
        etc_var_dirs = [bottle_prefix/"etc", bottle_prefix/"var"]
 | 
			
		||||
        T.unsafe(Find).find(*etc_var_dirs.select(&:directory?)) do |path|
 | 
			
		||||
          path = Pathname.new(path)
 | 
			
		||||
          path.extend(InstallRenamed)
 | 
			
		||||
          path.cp_path_sub(bottle_prefix, HOMEBREW_PREFIX)
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        with_logging("post_install") do
 | 
			
		||||
          post_install
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
    ensure
 | 
			
		||||
      self.build = build
 | 
			
		||||
      @prefix_returns_versioned_prefix = false
 | 
			
		||||
    end
 | 
			
		||||
  ensure
 | 
			
		||||
    self.build = build
 | 
			
		||||
    @prefix_returns_versioned_prefix = false
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  # Warn the user about any Homebrew-specific issues or quirks for this package.
 | 
			
		||||
@ -1067,6 +1083,7 @@ class Formula
 | 
			
		||||
  #   s += "Some issue only on older systems" if MacOS.version < :el_capitan
 | 
			
		||||
  #   s
 | 
			
		||||
  # end</pre>
 | 
			
		||||
  sig { overridable.returns(T.nilable(String)) }
 | 
			
		||||
  def caveats
 | 
			
		||||
    nil
 | 
			
		||||
  end
 | 
			
		||||
@ -1089,6 +1106,8 @@ class Formula
 | 
			
		||||
  # keep .la files with:
 | 
			
		||||
  #   skip_clean :la
 | 
			
		||||
  # @private
 | 
			
		||||
  sig { params(path: Pathname).returns(T::Boolean) }
 | 
			
		||||
 | 
			
		||||
  def skip_clean?(path)
 | 
			
		||||
    return true if path.extname == ".la" && self.class.skip_clean_paths.include?(:la)
 | 
			
		||||
 | 
			
		||||
@ -1241,7 +1260,7 @@ class Formula
 | 
			
		||||
    Formula.cache[:outdated_kegs] ||= {}
 | 
			
		||||
    Formula.cache[:outdated_kegs][cache_key] ||= begin
 | 
			
		||||
      all_kegs = []
 | 
			
		||||
      current_version = false
 | 
			
		||||
      current_version = T.let(false, T::Boolean)
 | 
			
		||||
 | 
			
		||||
      installed_kegs.each do |keg|
 | 
			
		||||
        all_kegs << keg
 | 
			
		||||
@ -1427,13 +1446,15 @@ class Formula
 | 
			
		||||
  # Standard parameters for cabal-v2 builds.
 | 
			
		||||
  sig { returns(T::Array[String]) }
 | 
			
		||||
  def std_cabal_v2_args
 | 
			
		||||
    env = T.cast(ENV, T.any(Stdenv, Superenv))
 | 
			
		||||
 | 
			
		||||
    # cabal-install's dependency-resolution backtracking strategy can
 | 
			
		||||
    # easily need more than the default 2,000 maximum number of
 | 
			
		||||
    # "backjumps," since Hackage is a fast-moving, rolling-release
 | 
			
		||||
    # target. The highest known needed value by a formula was 43,478
 | 
			
		||||
    # for git-annex, so 100,000 should be enough to avoid most
 | 
			
		||||
    # gratuitous backjumps build failures.
 | 
			
		||||
    ["--jobs=#{ENV.make_jobs}", "--max-backjumps=100000", "--install-method=copy", "--installdir=#{bin}"]
 | 
			
		||||
    ["--jobs=#{env.make_jobs}", "--max-backjumps=100000", "--install-method=copy", "--installdir=#{bin}"]
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  # Standard parameters for meson builds.
 | 
			
		||||
@ -1960,6 +1981,7 @@ class Formula
 | 
			
		||||
  #
 | 
			
		||||
  # # If there is a "make install" available, please use it!
 | 
			
		||||
  # system "make", "install"</pre>
 | 
			
		||||
  sig { params(cmd: T.any(String, Pathname), args: T.any(String, Pathname)).void }
 | 
			
		||||
  def system(cmd, *args)
 | 
			
		||||
    verbose_using_dots = Homebrew::EnvConfig.verbose_using_dots?
 | 
			
		||||
 | 
			
		||||
@ -2026,10 +2048,12 @@ class Formula
 | 
			
		||||
          rd.close
 | 
			
		||||
        end
 | 
			
		||||
      else
 | 
			
		||||
        pid = fork { exec_cmd(cmd, args, log, logfn) }
 | 
			
		||||
        pid = fork do
 | 
			
		||||
          exec_cmd(cmd, args, log, logfn)
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      Process.wait(pid)
 | 
			
		||||
      Process.wait(T.must(pid))
 | 
			
		||||
 | 
			
		||||
      $stdout.flush
 | 
			
		||||
 | 
			
		||||
@ -2114,11 +2138,15 @@ class Formula
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  # Runs `xcodebuild` without Homebrew's compiler environment variables set.
 | 
			
		||||
  sig { params(args: T.any(String, Pathname)).void }
 | 
			
		||||
  def xcodebuild(*args)
 | 
			
		||||
    removed = ENV.remove_cc_etc
 | 
			
		||||
    system "xcodebuild", *args
 | 
			
		||||
  ensure
 | 
			
		||||
    ENV.update(removed)
 | 
			
		||||
 | 
			
		||||
    begin
 | 
			
		||||
      T.unsafe(self).system("xcodebuild", *args)
 | 
			
		||||
    ensure
 | 
			
		||||
      ENV.update(removed)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def fetch_patches
 | 
			
		||||
@ -2148,7 +2176,8 @@ class Formula
 | 
			
		||||
    if cmd == "python"
 | 
			
		||||
      setup_py_in_args = %w[setup.py build.py].include?(args.first)
 | 
			
		||||
      setuptools_shim_in_args = args.any? { |a| a.to_s.start_with? "import setuptools" }
 | 
			
		||||
      ENV.refurbish_args if setup_py_in_args || setuptools_shim_in_args
 | 
			
		||||
      env = T.cast(ENV, T.any(Stdenv, Superenv))
 | 
			
		||||
      env.refurbish_args if setup_py_in_args || setuptools_shim_in_args
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    $stdout.reopen(out)
 | 
			
		||||
@ -2156,7 +2185,7 @@ class Formula
 | 
			
		||||
    out.close
 | 
			
		||||
    args.map!(&:to_s)
 | 
			
		||||
    begin
 | 
			
		||||
      exec(cmd, *args)
 | 
			
		||||
      T.unsafe(Kernel).exec(cmd, *args)
 | 
			
		||||
    rescue
 | 
			
		||||
      nil
 | 
			
		||||
    end
 | 
			
		||||
@ -2420,7 +2449,7 @@ class Formula
 | 
			
		||||
    # Get the `BUILD_FLAGS` from the formula's namespace set in `Formulary::load_formula`.
 | 
			
		||||
    # @private
 | 
			
		||||
    def build_flags
 | 
			
		||||
      namespace = to_s.split("::")[0..-2].join("::")
 | 
			
		||||
      namespace = T.must(to_s.split("::")[0..-2]).join("::")
 | 
			
		||||
      return [] if namespace.empty?
 | 
			
		||||
 | 
			
		||||
      mod = const_get(namespace)
 | 
			
		||||
 | 
			
		||||
@ -12,6 +12,8 @@ require "mktemp"
 | 
			
		||||
#
 | 
			
		||||
# @api private
 | 
			
		||||
class Resource
 | 
			
		||||
  extend T::Sig
 | 
			
		||||
 | 
			
		||||
  include Context
 | 
			
		||||
  include FileUtils
 | 
			
		||||
 | 
			
		||||
@ -221,8 +223,8 @@ class Resource
 | 
			
		||||
 | 
			
		||||
  # A resource containing a Go package.
 | 
			
		||||
  class Go < Resource
 | 
			
		||||
    def stage(target)
 | 
			
		||||
      super(target/name)
 | 
			
		||||
    def stage(target, &block)
 | 
			
		||||
      super(target/name, &block)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -29,7 +29,9 @@ class SoftwareSpec
 | 
			
		||||
 | 
			
		||||
  def_delegators :@resource, :stage, :fetch, :verify_download_integrity, :source_modified_time, :download_name,
 | 
			
		||||
                 :cached_download, :clear_cache, :checksum, :mirrors, :specs, :using, :version, :mirror,
 | 
			
		||||
                 :downloader, *Checksum::TYPES
 | 
			
		||||
                 :downloader
 | 
			
		||||
 | 
			
		||||
  def_delegators :@resource, *Checksum::TYPES
 | 
			
		||||
 | 
			
		||||
  def initialize(flags: [])
 | 
			
		||||
    @resource = Resource.new
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										13
									
								
								Library/Homebrew/sorbet/plugins/attr_rw.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								Library/Homebrew/sorbet/plugins/attr_rw.rb
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,13 @@
 | 
			
		||||
# typed: strict
 | 
			
		||||
# frozen_string_literal: true
 | 
			
		||||
 | 
			
		||||
source = ARGV[5]
 | 
			
		||||
 | 
			
		||||
source.scan(/:([^\s,]+)/).flatten.each do |method|
 | 
			
		||||
  puts <<~RUBY
 | 
			
		||||
    # typed: strict
 | 
			
		||||
 | 
			
		||||
    sig { params(arg: T.untyped).returns(T.untyped) }
 | 
			
		||||
    def #{method}(arg = T.unsafe(nil)); end
 | 
			
		||||
  RUBY
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										17
									
								
								Library/Homebrew/sorbet/plugins/def_delegator.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								Library/Homebrew/sorbet/plugins/def_delegator.rb
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,17 @@
 | 
			
		||||
# typed: strict
 | 
			
		||||
# frozen_string_literal: true
 | 
			
		||||
 | 
			
		||||
source = ARGV[5]
 | 
			
		||||
 | 
			
		||||
match = source.match(/\s*def_delegator\s+.*:(?<method>[^:]+)\s*\Z/m)
 | 
			
		||||
 | 
			
		||||
raise if match.nil?
 | 
			
		||||
 | 
			
		||||
method = match[:method]
 | 
			
		||||
 | 
			
		||||
puts <<~RUBY
 | 
			
		||||
  # typed: strict
 | 
			
		||||
 | 
			
		||||
  sig {params(arg0: T.untyped, blk: T.untyped).returns(T.untyped)}
 | 
			
		||||
  def #{method}(*arg0, &blk); end
 | 
			
		||||
RUBY
 | 
			
		||||
							
								
								
									
										17
									
								
								Library/Homebrew/sorbet/plugins/def_delegators.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								Library/Homebrew/sorbet/plugins/def_delegators.rb
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,17 @@
 | 
			
		||||
# typed: strict
 | 
			
		||||
# frozen_string_literal: true
 | 
			
		||||
 | 
			
		||||
source = ARGV[5]
 | 
			
		||||
 | 
			
		||||
symbols = source.scan(/:[^\s,]+/)
 | 
			
		||||
 | 
			
		||||
_, *methods = symbols.map { |s| s.delete_prefix(":") }
 | 
			
		||||
 | 
			
		||||
methods.each do |method|
 | 
			
		||||
  puts <<~RUBY
 | 
			
		||||
    # typed: strict
 | 
			
		||||
 | 
			
		||||
    sig {params(arg0: T.untyped, blk: T.untyped).returns(T.untyped)}
 | 
			
		||||
    def #{method}(*arg0, &blk); end
 | 
			
		||||
  RUBY
 | 
			
		||||
end
 | 
			
		||||
@ -15,7 +15,7 @@ methods.each do |method|
 | 
			
		||||
  puts <<~RUBY
 | 
			
		||||
    # typed: strict
 | 
			
		||||
 | 
			
		||||
    sig {params(arg0: T.untyped).returns(T.untyped)}
 | 
			
		||||
    def #{method}(*arg0); end
 | 
			
		||||
    sig {params(arg0: T.untyped, blk: T.untyped).returns(T.untyped)}
 | 
			
		||||
    def #{method}(*arg0, &blk); end
 | 
			
		||||
  RUBY
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
@ -9,3 +9,48 @@ class Pathname
 | 
			
		||||
  sig { params(with_directory: T::Boolean).returns(T::Array[Pathname]) }
 | 
			
		||||
  def children(with_directory = true); end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
module FileUtils
 | 
			
		||||
  # https://github.com/sorbet/sorbet/pull/3730
 | 
			
		||||
  module_function
 | 
			
		||||
 | 
			
		||||
  sig do
 | 
			
		||||
    params(
 | 
			
		||||
      src: T.untyped,
 | 
			
		||||
      dest: T.untyped,
 | 
			
		||||
      preserve: T.nilable(T::Boolean),
 | 
			
		||||
      noop: T.nilable(T::Boolean),
 | 
			
		||||
      verbose: T.nilable(T::Boolean)
 | 
			
		||||
    ).returns(T.untyped)
 | 
			
		||||
  end
 | 
			
		||||
  def cp(src, dest, preserve: nil, noop: nil, verbose: nil); end
 | 
			
		||||
 | 
			
		||||
  sig do
 | 
			
		||||
    params(
 | 
			
		||||
      list: T.any(String, Pathname),
 | 
			
		||||
      mode: T.nilable(Integer),
 | 
			
		||||
      noop: T.nilable(T::Boolean),
 | 
			
		||||
      verbose: T.nilable(T::Boolean)
 | 
			
		||||
    ).returns(T::Array[String])
 | 
			
		||||
  end
 | 
			
		||||
  def mkdir_p(list, mode: nil, noop: nil, verbose: nil); end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
class Module
 | 
			
		||||
  # https://github.com/sorbet/sorbet/pull/3732
 | 
			
		||||
  sig do
 | 
			
		||||
    params(
 | 
			
		||||
        arg0: T.any(Symbol, String),
 | 
			
		||||
        arg1: T.any(Proc, Method, UnboundMethod)
 | 
			
		||||
    )
 | 
			
		||||
    .returns(Symbol)
 | 
			
		||||
  end
 | 
			
		||||
  sig do
 | 
			
		||||
    params(
 | 
			
		||||
        arg0: T.any(Symbol, String),
 | 
			
		||||
        blk: T.proc.bind(T.untyped).returns(T.untyped),
 | 
			
		||||
    )
 | 
			
		||||
    .returns(Symbol)
 | 
			
		||||
  end
 | 
			
		||||
  def define_method(arg0, arg1=T.unsafe(nil), &blk); end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
@ -4,4 +4,7 @@ ruby_extra_args:
 | 
			
		||||
triggers:
 | 
			
		||||
  using: sorbet/plugins/using.rb
 | 
			
		||||
  attr_predicate: sorbet/plugins/attr_predicate.rb
 | 
			
		||||
  attr_rw: sorbet/plugins/attr_rw.rb
 | 
			
		||||
  def_delegator: sorbet/plugins/def_delegator.rb
 | 
			
		||||
  def_delegators: sorbet/plugins/def_delegators.rb
 | 
			
		||||
  delegate: sorbet/plugins/delegate.rb
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user