Explicitly mark non-private APIs.

This commit is contained in:
Markus Reiter 2024-04-22 21:05:48 +02:00
parent 401500e70a
commit 4b432c7ea4
No known key found for this signature in database
GPG Key ID: 245293B51702655B
19 changed files with 393 additions and 45 deletions

View File

@ -20,7 +20,17 @@ module Cask
extend APIHashable extend APIHashable
include Metadata include Metadata
attr_reader :token, :sourcefile_path, :source, :config, :default_config, :loader # The token of this {Cask}.
#
# @api public
attr_reader :token
# The configuration of this {Cask}.
#
# @api internal
attr_reader :config
attr_reader :sourcefile_path, :source, :default_config, :loader
attr_accessor :download, :allow_reassignment attr_accessor :download, :allow_reassignment
attr_predicate :loaded_from_api? attr_predicate :loaded_from_api?
@ -124,13 +134,21 @@ module Cask
.map { |p| p.split.map(&:to_s) } .map { |p| p.split.map(&:to_s) }
end end
def full_name # The fully-qualified token of this {Cask}.
#
# @api public
def full_token
return token if tap.nil? return token if tap.nil?
return token if tap.core_cask_tap? return token if tap.core_cask_tap?
"#{tap.name}/#{token}" "#{tap.name}/#{token}"
end end
# Alias for {#full_token}.
#
# @api internal
def full_name = full_token
sig { returns(T::Boolean) } sig { returns(T::Boolean) }
def installed? def installed?
installed_caskfile&.exist? || false installed_caskfile&.exist? || false
@ -226,6 +244,9 @@ module Cask
@caskroom_path ||= Caskroom.path.join(token) @caskroom_path ||= Caskroom.path.join(token)
end end
# Check if the installed cask is outdated.
#
# @api internal
def outdated?(greedy: false, greedy_latest: false, greedy_auto_updates: false) def outdated?(greedy: false, greedy_latest: false, greedy_auto_updates: false)
!outdated_version(greedy:, greedy_latest:, !outdated_version(greedy:, greedy_latest:,
greedy_auto_updates:).nil? greedy_auto_updates:).nil?
@ -304,9 +325,10 @@ module Cask
@ruby_source_checksum = { sha256: ruby_source_sha256 } @ruby_source_checksum = { sha256: ruby_source_sha256 }
end end
def to_s # Alias for {#token}.
@token #
end # @api public
def to_s = token
def inspect def inspect
"#<Cask #{token}#{sourcefile_path&.to_s&.prepend(" ")}>" "#<Cask #{token}#{sourcefile_path&.to_s&.prepend(" ")}>"

View File

@ -6,7 +6,7 @@ require "utils/user"
module Cask module Cask
# Helper functions for interacting with the `Caskroom` directory. # Helper functions for interacting with the `Caskroom` directory.
# #
# @api private # @api internal
module Caskroom module Caskroom
sig { returns(Pathname) } sig { returns(Pathname) }
def self.path def self.path
@ -50,6 +50,9 @@ module Cask
SystemCommand.run("/usr/bin/chgrp", args: ["admin", path], sudo:) SystemCommand.run("/usr/bin/chgrp", args: ["admin", path], sudo:)
end end
# Get all installed casks.
#
# @api internal
sig { params(config: T.nilable(Config)).returns(T::Array[Cask]) } sig { params(config: T.nilable(Config)).returns(T::Array[Cask]) }
def self.casks(config: nil) def self.casks(config: nil)
tokens.sort.filter_map do |token| tokens.sort.filter_map do |token|

View File

@ -10,7 +10,7 @@ require "extend/hash/keys"
module Cask module Cask
# Configuration for installing casks. # Configuration for installing casks.
# #
# @api private # @api internal
class Config class Config
DEFAULT_DIRS = { DEFAULT_DIRS = {
appdir: "/Applications", appdir: "/Applications",
@ -88,6 +88,9 @@ module Cask
end end
end end
# Get the explicit configuration.
#
# @api internal
sig { returns(T::Hash[Symbol, T.any(String, Pathname, T::Array[String])]) } sig { returns(T::Hash[Symbol, T.any(String, Pathname, T::Array[String])]) }
attr_accessor :explicit attr_accessor :explicit
@ -184,6 +187,11 @@ module Cask
self.class.new(explicit: other.explicit.merge(explicit)) self.class.new(explicit: other.explicit.merge(explicit))
end end
# Get explicit configuration as a string.
#
# @api internal
#
# TODO: This is only used by `homebrew/bundle`, so move it there.
sig { returns(String) } sig { returns(String) }
def explicit_s def explicit_s
explicit.map do |key, value| explicit.map do |key, value|

View File

@ -83,6 +83,9 @@ class DevelopmentTools
end end
end end
# Get the GCC version.
#
# @api internal
sig { params(cc: String).returns(Version) } sig { params(cc: String).returns(Version) }
def gcc_version(cc) def gcc_version(cc)
(@gcc_version ||= {}).fetch(cc) do (@gcc_version ||= {}).fetch(cc) do

View File

@ -6,7 +6,7 @@ require "set"
module Homebrew module Homebrew
# Helper module for querying Homebrew-specific environment variables. # Helper module for querying Homebrew-specific environment variables.
# #
# @api private # @api internal
module EnvConfig module EnvConfig
module_function module_function

View File

@ -5,6 +5,8 @@ require "shellwords"
require "utils" require "utils"
# Raised when a command is used wrong. # Raised when a command is used wrong.
#
# @api internal
class UsageError < RuntimeError class UsageError < RuntimeError
attr_reader :reason attr_reader :reason
@ -133,6 +135,8 @@ class TapFormulaOrCaskUnavailableError < FormulaOrCaskUnavailableError
end end
# Raised when a formula is not available. # Raised when a formula is not available.
#
# @api internal
class FormulaUnavailableError < FormulaOrCaskUnavailableError class FormulaUnavailableError < FormulaOrCaskUnavailableError
attr_accessor :dependent attr_accessor :dependent

View File

@ -58,31 +58,42 @@ module Kernel
puts oh1_title(title, truncate:) puts oh1_title(title, truncate:)
end end
# Print a message prefixed with "Warning" (do this rarely). # Print a warning message.
#
# @api public
def opoo(message) def opoo(message)
Tty.with($stderr) do |stderr| Tty.with($stderr) do |stderr|
stderr.puts Formatter.warning(message, label: "Warning") stderr.puts Formatter.warning(message, label: "Warning")
end end
end end
# Print a message prefixed with "Error". # Print an error message.
#
# @api public
def onoe(message) def onoe(message)
Tty.with($stderr) do |stderr| Tty.with($stderr) do |stderr|
stderr.puts Formatter.error(message, label: "Error") stderr.puts Formatter.error(message, label: "Error")
end end
end end
# Print an error message and fail at the end of the program.
#
# @api public
def ofail(error) def ofail(error)
onoe error onoe error
Homebrew.failed = true Homebrew.failed = true
end end
# Print an error message and fail immediately.
#
# @api public
sig { params(error: T.any(String, Exception)).returns(T.noreturn) } sig { params(error: T.any(String, Exception)).returns(T.noreturn) }
def odie(error) def odie(error)
onoe error onoe error
exit 1 exit 1
end end
# Output a deprecation warning/error message.
def odeprecated(method, replacement = nil, def odeprecated(method, replacement = nil,
disable: false, disable: false,
disable_on: nil, disable_on: nil,
@ -254,6 +265,9 @@ module Kernel
end end
end end
# Find a command.
#
# @api public
def which(cmd, path = ENV.fetch("PATH")) def which(cmd, path = ENV.fetch("PATH"))
PATH.new(path).each do |p| PATH.new(path).each do |p|
begin begin

View File

@ -72,6 +72,8 @@ class Formula
# The name of this {Formula}. # The name of this {Formula}.
# e.g. `this-formula` # e.g. `this-formula`
#
# @api public
sig { returns(String) } sig { returns(String) }
attr_reader :name attr_reader :name
@ -88,6 +90,8 @@ class Formula
# The fully-qualified name of this {Formula}. # The fully-qualified name of this {Formula}.
# For core formulae it's the same as {#name}. # For core formulae it's the same as {#name}.
# e.g. `homebrew/tap-name/this-formula` # e.g. `homebrew/tap-name/this-formula`
#
# @api public
sig { returns(String) } sig { returns(String) }
attr_reader :full_name attr_reader :full_name
@ -99,19 +103,23 @@ class Formula
# The full path to this {Formula}. # The full path to this {Formula}.
# e.g. `/usr/local/Library/Taps/homebrew/homebrew-core/Formula/t/this-formula.rb` # e.g. `/usr/local/Library/Taps/homebrew/homebrew-core/Formula/t/this-formula.rb`
#
# @api public
sig { returns(Pathname) } sig { returns(Pathname) }
attr_reader :path attr_reader :path
# The {Tap} instance associated with this {Formula}. # The {Tap} instance associated with this {Formula}.
# If it's `nil`, then this formula is loaded from a path or URL. # If it's `nil`, then this formula is loaded from a path or URL.
# @private #
# @api internal
sig { returns(T.nilable(Tap)) } sig { returns(T.nilable(Tap)) }
attr_reader :tap attr_reader :tap
# The stable (and default) {SoftwareSpec} for this {Formula}. # The stable (and default) {SoftwareSpec} for this {Formula}.
# This contains all the attributes (e.g. URL, checksum) that apply to the # This contains all the attributes (e.g. URL, checksum) that apply to the
# stable version of this formula. # stable version of this formula.
# @private #
# @api internal
sig { returns(T.nilable(SoftwareSpec)) } sig { returns(T.nilable(SoftwareSpec)) }
attr_reader :stable attr_reader :stable
@ -120,8 +128,10 @@ class Formula
# This is always installed with the version `HEAD` and taken from the latest # This is always installed with the version `HEAD` and taken from the latest
# commit in the version control system. # commit in the version control system.
# `nil` if there is no HEAD version. # `nil` if there is no HEAD version.
#
# @see #stable # @see #stable
# @private #
# @api private
sig { returns(T.nilable(SoftwareSpec)) } sig { returns(T.nilable(SoftwareSpec)) }
attr_reader :head attr_reader :head
@ -549,6 +559,8 @@ class Formula
end end
# Old names for the formula. # Old names for the formula.
#
# @api internal
sig { returns(T::Array[String]) } sig { returns(T::Array[String]) }
def oldnames def oldnames
@oldnames ||= if (tap = self.tap) @oldnames ||= if (tap = self.tap)
@ -560,6 +572,8 @@ class Formula
end end
# All aliases for the formula. # All aliases for the formula.
#
# @api internal
sig { returns(T::Array[String]) } sig { returns(T::Array[String]) }
def aliases def aliases
@aliases ||= tap&.alias_reverse_table&.dig(full_name)&.map { _1.split("/").last } || [] @aliases ||= tap&.alias_reverse_table&.dig(full_name)&.map { _1.split("/").last } || []
@ -570,6 +584,8 @@ class Formula
def_delegator :"active_spec.resources", :values, :resources def_delegator :"active_spec.resources", :values, :resources
# The {Dependency}s for the currently active {SoftwareSpec}. # The {Dependency}s for the currently active {SoftwareSpec}.
#
# @api internal
delegate deps: :active_spec delegate deps: :active_spec
# The declared {Dependency}s for the currently active {SoftwareSpec} (i.e. including those provided by macOS) # The declared {Dependency}s for the currently active {SoftwareSpec} (i.e. including those provided by macOS)
@ -627,9 +643,10 @@ class Formula
installed_prefixes.any? { |keg| (keg/Tab::FILENAME).file? } installed_prefixes.any? { |keg| (keg/Tab::FILENAME).file? }
end end
# @private
# The link status symlink directory for this {Formula}. # The link status symlink directory for this {Formula}.
# You probably want {#opt_prefix} instead. # You probably want {#opt_prefix} instead.
#
# @api internal
def linked_keg def linked_keg
linked_keg = possible_names.map { |name| HOMEBREW_LINKED_KEGS/name } linked_keg = possible_names.map { |name| HOMEBREW_LINKED_KEGS/name }
.find(&:directory?) .find(&:directory?)
@ -696,6 +713,8 @@ class Formula
end end
# Is the formula linked? # Is the formula linked?
#
# @api internal
sig { returns(T::Boolean) } sig { returns(T::Boolean) }
def linked? def linked?
linked_keg.symlink? linked_keg.symlink?
@ -754,6 +773,8 @@ class Formula
# #
# No `make install` available? # No `make install` available?
# <pre>bin.install "binary1"</pre> # <pre>bin.install "binary1"</pre>
#
# @api public
sig { returns(Pathname) } sig { returns(Pathname) }
def bin def bin
prefix/"bin" prefix/"bin"
@ -762,6 +783,8 @@ class Formula
# The directory where the formula's documentation should be installed. # The directory where the formula's documentation should be installed.
# This is symlinked into `HOMEBREW_PREFIX` after installation or with # This is symlinked into `HOMEBREW_PREFIX` after installation or with
# `brew link` for formulae that are not keg-only. # `brew link` for formulae that are not keg-only.
#
# @api public
sig { returns(Pathname) } sig { returns(Pathname) }
def doc def doc
share/"doc"/name share/"doc"/name
@ -773,6 +796,8 @@ class Formula
# #
# No `make install` available? # No `make install` available?
# <pre>include.install "example.h"</pre> # <pre>include.install "example.h"</pre>
#
# @api public
sig { returns(Pathname) } sig { returns(Pathname) }
def include def include
prefix/"include" prefix/"include"
@ -781,6 +806,8 @@ class Formula
# The directory where the formula's info files should be installed. # The directory where the formula's info files should be installed.
# This is symlinked into `HOMEBREW_PREFIX` after installation or with # This is symlinked into `HOMEBREW_PREFIX` after installation or with
# `brew link` for formulae that are not keg-only. # `brew link` for formulae that are not keg-only.
#
# @api public
sig { returns(Pathname) } sig { returns(Pathname) }
def info def info
share/"info" share/"info"
@ -792,6 +819,8 @@ class Formula
# #
# No `make install` available? # No `make install` available?
# <pre>lib.install "example.dylib"</pre> # <pre>lib.install "example.dylib"</pre>
#
# @api public
sig { returns(Pathname) } sig { returns(Pathname) }
def lib def lib
prefix/"lib" prefix/"lib"
@ -805,6 +834,8 @@ class Formula
# <pre>libexec.install "foo.jar" # <pre>libexec.install "foo.jar"
# bin.write_jar_script libexec/"foo.jar", "foo" # bin.write_jar_script libexec/"foo.jar", "foo"
# </pre> # </pre>
#
# @api public
sig { returns(Pathname) } sig { returns(Pathname) }
def libexec def libexec
prefix/"libexec" prefix/"libexec"
@ -815,6 +846,8 @@ class Formula
# `brew link` for formulae that are not keg-only. # `brew link` for formulae that are not keg-only.
# Often one of the more specific `man` functions should be used instead, # Often one of the more specific `man` functions should be used instead,
# e.g. {#man1}. # e.g. {#man1}.
#
# @api public
sig { returns(Pathname) } sig { returns(Pathname) }
def man def man
share/"man" share/"man"
@ -826,6 +859,8 @@ class Formula
# #
# No `make install` available? # No `make install` available?
# <pre>man1.install "example.1"</pre> # <pre>man1.install "example.1"</pre>
#
# @api public
sig { returns(Pathname) } sig { returns(Pathname) }
def man1 def man1
man/"man1" man/"man1"
@ -834,6 +869,8 @@ class Formula
# The directory where the formula's man2 pages should be installed. # The directory where the formula's man2 pages should be installed.
# This is symlinked into `HOMEBREW_PREFIX` after installation or with # This is symlinked into `HOMEBREW_PREFIX` after installation or with
# `brew link` for formulae that are not keg-only. # `brew link` for formulae that are not keg-only.
#
# @api public
sig { returns(Pathname) } sig { returns(Pathname) }
def man2 def man2
man/"man2" man/"man2"
@ -845,6 +882,8 @@ class Formula
# #
# No `make install` available? # No `make install` available?
# <pre>man3.install "man.3"</pre> # <pre>man3.install "man.3"</pre>
#
# @api public
sig { returns(Pathname) } sig { returns(Pathname) }
def man3 def man3
man/"man3" man/"man3"
@ -853,6 +892,8 @@ class Formula
# The directory where the formula's man4 pages should be installed. # The directory where the formula's man4 pages should be installed.
# This is symlinked into `HOMEBREW_PREFIX` after installation or with # This is symlinked into `HOMEBREW_PREFIX` after installation or with
# `brew link` for formulae that are not keg-only. # `brew link` for formulae that are not keg-only.
#
# @api public
sig { returns(Pathname) } sig { returns(Pathname) }
def man4 def man4
man/"man4" man/"man4"
@ -861,6 +902,8 @@ class Formula
# The directory where the formula's man5 pages should be installed. # The directory where the formula's man5 pages should be installed.
# This is symlinked into `HOMEBREW_PREFIX` after installation or with # This is symlinked into `HOMEBREW_PREFIX` after installation or with
# `brew link` for formulae that are not keg-only. # `brew link` for formulae that are not keg-only.
#
# @api public
sig { returns(Pathname) } sig { returns(Pathname) }
def man5 def man5
man/"man5" man/"man5"
@ -869,6 +912,8 @@ class Formula
# The directory where the formula's man6 pages should be installed. # The directory where the formula's man6 pages should be installed.
# This is symlinked into `HOMEBREW_PREFIX` after installation or with # This is symlinked into `HOMEBREW_PREFIX` after installation or with
# `brew link` for formulae that are not keg-only. # `brew link` for formulae that are not keg-only.
#
# @api public
sig { returns(Pathname) } sig { returns(Pathname) }
def man6 def man6
man/"man6" man/"man6"
@ -877,6 +922,8 @@ class Formula
# The directory where the formula's man7 pages should be installed. # The directory where the formula's man7 pages should be installed.
# This is symlinked into `HOMEBREW_PREFIX` after installation or with # This is symlinked into `HOMEBREW_PREFIX` after installation or with
# `brew link` for formulae that are not keg-only. # `brew link` for formulae that are not keg-only.
#
# @api public
sig { returns(Pathname) } sig { returns(Pathname) }
def man7 def man7
man/"man7" man/"man7"
@ -885,6 +932,8 @@ class Formula
# The directory where the formula's man8 pages should be installed. # The directory where the formula's man8 pages should be installed.
# This is symlinked into `HOMEBREW_PREFIX` after installation or with # This is symlinked into `HOMEBREW_PREFIX` after installation or with
# `brew link` for formulae that are not keg-only. # `brew link` for formulae that are not keg-only.
#
# @api public
sig { returns(Pathname) } sig { returns(Pathname) }
def man8 def man8
man/"man8" man/"man8"
@ -894,6 +943,8 @@ class Formula
# This is symlinked into `HOMEBREW_PREFIX` after installation or with # This is symlinked into `HOMEBREW_PREFIX` after installation or with
# `brew link` for formulae that are not keg-only. # `brew link` for formulae that are not keg-only.
# Generally we try to migrate these to {#bin} instead. # Generally we try to migrate these to {#bin} instead.
#
# @api public
sig { returns(Pathname) } sig { returns(Pathname) }
def sbin def sbin
prefix/"sbin" prefix/"sbin"
@ -914,6 +965,8 @@ class Formula
# #
# Install `./example_code/simple/ones` to `share/demos/examples`: # Install `./example_code/simple/ones` to `share/demos/examples`:
# <pre>(share/"demos").install "example_code/simple/ones" => "examples"</pre> # <pre>(share/"demos").install "example_code/simple/ones" => "examples"</pre>
#
# @api public
sig { returns(Pathname) } sig { returns(Pathname) }
def share def share
prefix/"share" prefix/"share"
@ -926,6 +979,8 @@ class Formula
# #
# No `make install` available? # No `make install` available?
# <pre>pkgshare.install "examples"</pre> # <pre>pkgshare.install "examples"</pre>
#
# @api public
sig { returns(Pathname) } sig { returns(Pathname) }
def pkgshare def pkgshare
prefix/"share"/name prefix/"share"/name
@ -936,6 +991,8 @@ class Formula
# #
# To install an Emacs mode included with a software package: # To install an Emacs mode included with a software package:
# <pre>elisp.install "contrib/emacs/example-mode.el"</pre> # <pre>elisp.install "contrib/emacs/example-mode.el"</pre>
#
# @api public
sig { returns(Pathname) } sig { returns(Pathname) }
def elisp def elisp
prefix/"share/emacs/site-lisp"/name prefix/"share/emacs/site-lisp"/name
@ -945,6 +1002,8 @@ class Formula
# This is symlinked into `HOMEBREW_PREFIX` after installation or with # This is symlinked into `HOMEBREW_PREFIX` after installation or with
# `brew link` for formulae that are not keg-only. # `brew link` for formulae that are not keg-only.
# This is not symlinked into `HOMEBREW_PREFIX`. # This is not symlinked into `HOMEBREW_PREFIX`.
#
# @api public
sig { returns(Pathname) } sig { returns(Pathname) }
def frameworks def frameworks
prefix/"Frameworks" prefix/"Frameworks"
@ -954,6 +1013,8 @@ class Formula
# This is symlinked into `HOMEBREW_PREFIX` after installation or with # This is symlinked into `HOMEBREW_PREFIX` after installation or with
# `brew link` for formulae that are not keg-only. # `brew link` for formulae that are not keg-only.
# This is not symlinked into `HOMEBREW_PREFIX`. # This is not symlinked into `HOMEBREW_PREFIX`.
#
# @api public
sig { returns(Pathname) } sig { returns(Pathname) }
def kext_prefix def kext_prefix
prefix/"Library/Extensions" prefix/"Library/Extensions"
@ -964,6 +1025,8 @@ class Formula
# but will write a new file named `*.default`. # but will write a new file named `*.default`.
# This directory is not inside the `HOMEBREW_CELLAR` so it persists # This directory is not inside the `HOMEBREW_CELLAR` so it persists
# across upgrades. # across upgrades.
#
# @api public
sig { returns(Pathname) } sig { returns(Pathname) }
def etc def etc
(HOMEBREW_PREFIX/"etc").extend(InstallRenamed) (HOMEBREW_PREFIX/"etc").extend(InstallRenamed)
@ -973,6 +1036,8 @@ class Formula
# e.g. `$HOMEBREW_PREFIX/etc/openssl@1.1` # e.g. `$HOMEBREW_PREFIX/etc/openssl@1.1`
# Anything using `pkgetc.install` will not overwrite other files on # Anything using `pkgetc.install` will not overwrite other files on
# e.g. upgrades but will write a new file named `*.default`. # e.g. upgrades but will write a new file named `*.default`.
#
# @api public
sig { returns(Pathname) } sig { returns(Pathname) }
def pkgetc def pkgetc
(HOMEBREW_PREFIX/"etc"/name).extend(InstallRenamed) (HOMEBREW_PREFIX/"etc"/name).extend(InstallRenamed)
@ -981,6 +1046,8 @@ class Formula
# The directory where the formula's variable files should be installed. # The directory where the formula's variable files should be installed.
# This directory is not inside the `HOMEBREW_CELLAR` so it persists # This directory is not inside the `HOMEBREW_CELLAR` so it persists
# across upgrades. # across upgrades.
#
# @api public
sig { returns(Pathname) } sig { returns(Pathname) }
def var def var
HOMEBREW_PREFIX/"var" HOMEBREW_PREFIX/"var"
@ -990,6 +1057,8 @@ class Formula
# installed. # installed.
# This is symlinked into `HOMEBREW_PREFIX` after installation or with # This is symlinked into `HOMEBREW_PREFIX` after installation or with
# `brew link` for formulae that are not keg-only. # `brew link` for formulae that are not keg-only.
#
# @api public
sig { returns(Pathname) } sig { returns(Pathname) }
def zsh_function def zsh_function
share/"zsh/site-functions" share/"zsh/site-functions"
@ -999,6 +1068,8 @@ class Formula
# installed. # installed.
# This is symlinked into `HOMEBREW_PREFIX` after installation or with # This is symlinked into `HOMEBREW_PREFIX` after installation or with
# `brew link` for formulae that are not keg-only. # `brew link` for formulae that are not keg-only.
#
# @api public
sig { returns(Pathname) } sig { returns(Pathname) }
def fish_function def fish_function
share/"fish/vendor_functions.d" share/"fish/vendor_functions.d"
@ -1008,6 +1079,8 @@ class Formula
# installed. # installed.
# This is symlinked into `HOMEBREW_PREFIX` after installation or with # This is symlinked into `HOMEBREW_PREFIX` after installation or with
# `brew link` for formulae that are not keg-only. # `brew link` for formulae that are not keg-only.
#
# @api public
sig { returns(Pathname) } sig { returns(Pathname) }
def bash_completion def bash_completion
prefix/"etc/bash_completion.d" prefix/"etc/bash_completion.d"
@ -1017,6 +1090,8 @@ class Formula
# installed. # installed.
# This is symlinked into `HOMEBREW_PREFIX` after installation or with # This is symlinked into `HOMEBREW_PREFIX` after installation or with
# `brew link` for formulae that are not keg-only. # `brew link` for formulae that are not keg-only.
#
# @api public
sig { returns(Pathname) } sig { returns(Pathname) }
def zsh_completion def zsh_completion
share/"zsh/site-functions" share/"zsh/site-functions"
@ -1026,6 +1101,8 @@ class Formula
# installed. # installed.
# This is symlinked into `HOMEBREW_PREFIX` after installation or with # This is symlinked into `HOMEBREW_PREFIX` after installation or with
# `brew link` for formulae that are not keg-only. # `brew link` for formulae that are not keg-only.
#
# @api public
sig { returns(Pathname) } sig { returns(Pathname) }
def fish_completion def fish_completion
share/"fish/vendor_completions.d" share/"fish/vendor_completions.d"
@ -1141,51 +1218,80 @@ class Formula
# This is the preferred way to refer to a formula in plists or from another # This is the preferred way to refer to a formula in plists or from another
# formula, as the path is stable even when the software is updated. # formula, as the path is stable even when the software is updated.
# <pre>args << "--with-readline=#{Formula["readline"].opt_prefix}" if build.with? "readline"</pre> # <pre>args << "--with-readline=#{Formula["readline"].opt_prefix}" if build.with? "readline"</pre>
#
# @api public
sig { returns(Pathname) } sig { returns(Pathname) }
def opt_prefix def opt_prefix
HOMEBREW_PREFIX/"opt"/name HOMEBREW_PREFIX/"opt"/name
end end
# Same as {#bin}, but relative to {#opt_prefix} instead of {#prefix}.
#
# @api public
sig { returns(Pathname) } sig { returns(Pathname) }
def opt_bin def opt_bin
opt_prefix/"bin" opt_prefix/"bin"
end end
# Same as {#include}, but relative to {#opt_prefix} instead of {#prefix}.
#
# @api public
sig { returns(Pathname) } sig { returns(Pathname) }
def opt_include def opt_include
opt_prefix/"include" opt_prefix/"include"
end end
# Same as {#lib}, but relative to {#opt_prefix} instead of {#prefix}.
#
# @api public
sig { returns(Pathname) } sig { returns(Pathname) }
def opt_lib def opt_lib
opt_prefix/"lib" opt_prefix/"lib"
end end
# Same as {#libexec}, but relative to {#opt_prefix} instead of {#prefix}.
#
# @api public
sig { returns(Pathname) } sig { returns(Pathname) }
def opt_libexec def opt_libexec
opt_prefix/"libexec" opt_prefix/"libexec"
end end
# Same as {#sbin}, but relative to {#opt_prefix} instead of {#prefix}.
#
# @api public
sig { returns(Pathname) } sig { returns(Pathname) }
def opt_sbin def opt_sbin
opt_prefix/"sbin" opt_prefix/"sbin"
end end
# Same as {#share}, but relative to {#opt_prefix} instead of {#prefix}.
#
# @api public
sig { returns(Pathname) } sig { returns(Pathname) }
def opt_share def opt_share
opt_prefix/"share" opt_prefix/"share"
end end
# Same as {#pkgshare}, but relative to {#opt_prefix} instead of {#prefix}.
#
# @api public
sig { returns(Pathname) } sig { returns(Pathname) }
def opt_pkgshare def opt_pkgshare
opt_prefix/"share"/name opt_prefix/"share"/name
end end
# Same as {#elisp}, but relative to {#opt_prefix} instead of {#prefix}.
#
# @api public
sig { returns(Pathname) } sig { returns(Pathname) }
def opt_elisp def opt_elisp
opt_prefix/"share/emacs/site-lisp"/name opt_prefix/"share/emacs/site-lisp"/name
end end
# Same as {#frameworks}, but relative to {#opt_prefix} instead of {#prefix}.
#
# @api public
sig { returns(Pathname) } sig { returns(Pathname) }
def opt_frameworks def opt_frameworks
opt_prefix/"Frameworks" opt_prefix/"Frameworks"
@ -1285,6 +1391,8 @@ class Formula
# Rarely, you don't want your library symlinked into the main prefix. # Rarely, you don't want your library symlinked into the main prefix.
# See `gettext.rb` for an example. # See `gettext.rb` for an example.
# @see .keg_only # @see .keg_only
#
# @api internal
sig { returns(T::Boolean) } sig { returns(T::Boolean) }
def keg_only? def keg_only?
return false unless keg_only_reason return false unless keg_only_reason
@ -1560,7 +1668,9 @@ class Formula
self.class.installed_with_alias_path(alias_path).reject { |f| f.name == name } self.class.installed_with_alias_path(alias_path).reject { |f| f.name == name }
end end
# @private # Check whether the installed formula is outdated.
#
# @api internal
sig { params(fetch_head: T::Boolean).returns(T::Boolean) } sig { params(fetch_head: T::Boolean).returns(T::Boolean) }
def outdated?(fetch_head: false) def outdated?(fetch_head: false)
!outdated_kegs(fetch_head:).empty? !outdated_kegs(fetch_head:).empty?
@ -1571,7 +1681,7 @@ class Formula
# @private # @private
delegate pinnable?: :@pin delegate pinnable?: :@pin
# @private # @api internal
delegate pinned?: :@pin delegate pinned?: :@pin
# @private # @private
@ -2069,19 +2179,21 @@ class Formula
# @private # @private
delegate env: :"self.class" delegate env: :"self.class"
# @private # @api internal
delegate conflicts: :"self.class" delegate conflicts: :"self.class"
# Returns a list of Dependency objects in an installable order, which # Returns a list of Dependency objects in an installable order, which
# means if a depends on b then b will be ordered before a in this list # means if a depends on b then b will be ordered before a in this list
# @private #
# @api internal
def recursive_dependencies(&block) def recursive_dependencies(&block)
cache_key = "Formula#recursive_dependencies" unless block cache_key = "Formula#recursive_dependencies" unless block
Dependency.expand(self, cache_key:, &block) Dependency.expand(self, cache_key:, &block)
end end
# The full set of Requirements for this formula's dependency tree. # The full set of Requirements for this formula's dependency tree.
# @private #
# @api internal
def recursive_requirements(&block) def recursive_requirements(&block)
cache_key = "Formula#recursive_requirements" unless block cache_key = "Formula#recursive_requirements" unless block
Requirement.expand(self, cache_key:, &block) Requirement.expand(self, cache_key:, &block)
@ -2097,6 +2209,10 @@ class Formula
end end
end end
# Get the path of any installed prefix.
#
# @api internal
sig { returns(T.nilable(Pathname)) }
def any_installed_prefix def any_installed_prefix
if optlinked? && opt_prefix.exist? if optlinked? && opt_prefix.exist?
opt_prefix opt_prefix
@ -2112,7 +2228,8 @@ class Formula
end end
# Returns a list of Dependency objects that are required at runtime. # Returns a list of Dependency objects that are required at runtime.
# @private #
# @api internal
def runtime_dependencies(read_from_tab: true, undeclared: true) def runtime_dependencies(read_from_tab: true, undeclared: true)
deps = if read_from_tab && undeclared && deps = if read_from_tab && undeclared &&
(tab_deps = any_installed_keg&.runtime_dependencies) (tab_deps = any_installed_keg&.runtime_dependencies)
@ -3069,6 +3186,8 @@ class Formula
# Shows when running `brew info`. # Shows when running `brew info`.
# #
# <pre>desc "Example formula"</pre> # <pre>desc "Example formula"</pre>
#
# @api public
attr_rw :desc attr_rw :desc
# @!attribute [w] license # @!attribute [w] license
@ -3094,6 +3213,8 @@ class Formula
# all_of: ["0BSD", "Zlib", "Artistic-1.0+"], # all_of: ["0BSD", "Zlib", "Artistic-1.0+"],
# "Apache-2.0" => { with: "LLVM-exception" }, # "Apache-2.0" => { with: "LLVM-exception" },
# ]</pre> # ]</pre>
#
# @api public
def license(args = nil) def license(args = nil)
if args.nil? if args.nil?
@licenses @licenses
@ -3109,6 +3230,8 @@ class Formula
# Can be opened with running `brew home`. # Can be opened with running `brew home`.
# #
# <pre>homepage "https://www.example.com"</pre> # <pre>homepage "https://www.example.com"</pre>
#
# @api public
attr_rw :homepage attr_rw :homepage
# Whether a livecheck specification is defined or not. # Whether a livecheck specification is defined or not.
@ -3149,6 +3272,8 @@ class Formula
# `0` if unset. # `0` if unset.
# #
# <pre>revision 1</pre> # <pre>revision 1</pre>
#
# @api public
attr_rw :revision attr_rw :revision
# @!attribute [w] version_scheme # @!attribute [w] version_scheme
@ -3161,6 +3286,8 @@ class Formula
# `0` if unset. # `0` if unset.
# #
# <pre>version_scheme 1</pre> # <pre>version_scheme 1</pre>
#
# @api public
attr_rw :version_scheme attr_rw :version_scheme
# @private # @private
@ -3191,6 +3318,8 @@ class Formula
# using: :git, # using: :git,
# tag: "1.2.3", # tag: "1.2.3",
# revision: "db8e4de5b2d6653f66aea53094624468caad15d2"</pre> # revision: "db8e4de5b2d6653f66aea53094624468caad15d2"</pre>
#
# @api public
def url(val, specs = {}) def url(val, specs = {})
stable.url(val, specs) stable.url(val, specs)
end end
@ -3201,6 +3330,8 @@ class Formula
# declared if it cannot be autodetected correctly. # declared if it cannot be autodetected correctly.
# #
# <pre>version "1.2-final"</pre> # <pre>version "1.2-final"</pre>
#
# @api public
def version(val = nil) def version(val = nil)
stable.version(val) stable.version(val)
end end
@ -3214,6 +3345,8 @@ class Formula
# #
# <pre>mirror "https://in.case.the.host.is.down.example.com" # <pre>mirror "https://in.case.the.host.is.down.example.com"
# mirror "https://in.case.the.mirror.is.down.example.com</pre> # mirror "https://in.case.the.mirror.is.down.example.com</pre>
#
# @api public
def mirror(val) def mirror(val)
stable.mirror(val) stable.mirror(val)
end end
@ -3226,6 +3359,8 @@ class Formula
# tell you the currently valid value. # tell you the currently valid value.
# #
# <pre>sha256 "2a2ba417eebaadcb4418ee7b12fe2998f26d6e6f7fda7983412ff66a741ab6f7"</pre> # <pre>sha256 "2a2ba417eebaadcb4418ee7b12fe2998f26d6e6f7fda7983412ff66a741ab6f7"</pre>
#
# @api public
def sha256(val) def sha256(val)
stable.sha256(val) stable.sha256(val)
end end
@ -3251,6 +3386,8 @@ class Formula
# end</pre> # end</pre>
# #
# Homebrew maintainers aim to bottle all formulae. # Homebrew maintainers aim to bottle all formulae.
#
# @api public
sig { params(block: T.proc.bind(BottleSpecification).void).void } sig { params(block: T.proc.bind(BottleSpecification).void).void }
def bottle(&block) def bottle(&block)
stable.bottle(&block) stable.bottle(&block)
@ -3283,6 +3420,8 @@ class Formula
# depends_on "libxml2" # depends_on "libxml2"
# depends_on "libffi" # depends_on "libffi"
# end</pre> # end</pre>
#
# @api public
def stable(&block) def stable(&block)
return @stable unless block return @stable unless block
@ -3318,12 +3457,15 @@ class Formula
# url "https://example.com/additional-stuff.tar.gz" # url "https://example.com/additional-stuff.tar.gz"
# sha256 "c6bc3f48ce8e797854c4b865f6a8ff969867bbcaebd648ae6fd825683e59fef2" # sha256 "c6bc3f48ce8e797854c4b865f6a8ff969867bbcaebd648ae6fd825683e59fef2"
# end</pre> # end</pre>
#
# @api public
def resource(name, klass = Resource, &block) def resource(name, klass = Resource, &block)
specs.each do |spec| specs.each do |spec|
spec.resource(name, klass, &block) unless spec.resource_defined?(name) spec.resource(name, klass, &block) unless spec.resource_defined?(name)
end end
end end
# @api public
def go_resource(name, &block) def go_resource(name, &block)
# odeprecated "Formula#go_resource", "Go modules" # odeprecated "Formula#go_resource", "Go modules"
specs.each { |spec| spec.go_resource(name, &block) } specs.each { |spec| spec.go_resource(name, &block) }
@ -3365,6 +3507,8 @@ class Formula
# It is possible to only depend on something if # It is possible to only depend on something if
# `build.with?` or `build.without? "another_formula"`: # `build.with?` or `build.without? "another_formula"`:
# <pre>depends_on "postgresql" if build.without? "sqlite"</pre> # <pre>depends_on "postgresql" if build.without? "sqlite"</pre>
#
# @api public
def depends_on(dep) def depends_on(dep)
specs.each { |spec| spec.depends_on(dep) } specs.each { |spec| spec.depends_on(dep) }
end end
@ -3373,6 +3517,8 @@ class Formula
# On macOS this is a no-op (as we use the provided system libraries) unless # On macOS this is a no-op (as we use the provided system libraries) unless
# `:since` specifies a minimum macOS version. # `:since` specifies a minimum macOS version.
# On Linux this will act as {.depends_on}. # On Linux this will act as {.depends_on}.
#
# @api public
sig { sig {
params( params(
dep: T.any(String, T::Hash[T.any(String, Symbol), T.any(Symbol, T::Array[Symbol])]), dep: T.any(String, T::Hash[T.any(String, Symbol), T.any(Symbol, T::Array[Symbol])]),
@ -3397,6 +3543,8 @@ class Formula
# <pre>option "with-spam", "The description goes here without a dot at the end"</pre> # <pre>option "with-spam", "The description goes here without a dot at the end"</pre>
# <pre>option "with-qt", "Text here overwrites what's autogenerated by 'depends_on "qt" => :optional'"</pre> # <pre>option "with-qt", "Text here overwrites what's autogenerated by 'depends_on "qt" => :optional'"</pre>
# <pre>option :universal</pre> # <pre>option :universal</pre>
#
# @api public
def option(name, description = "") def option(name, description = "")
specs.each { |spec| spec.option(name, description) } specs.each { |spec| spec.option(name, description) }
end end
@ -3406,6 +3554,8 @@ class Formula
# them to newer ones. They are mostly used for migrating non-`with` options # them to newer ones. They are mostly used for migrating non-`with` options
# (e.g. `enable-debug`) to `with` options (e.g. `with-debug`). # (e.g. `enable-debug`) to `with` options (e.g. `with-debug`).
# <pre>deprecated_option "enable-debug" => "with-debug"</pre> # <pre>deprecated_option "enable-debug" => "with-debug"</pre>
#
# @api public
def deprecated_option(hash) def deprecated_option(hash)
specs.each { |spec| spec.deprecated_option(hash) } specs.each { |spec| spec.deprecated_option(hash) }
end end
@ -3441,12 +3591,16 @@ class Formula
# conditional. # conditional.
# <pre>patch :p0, "..."</pre> # <pre>patch :p0, "..."</pre>
# @see https://docs.brew.sh/Formula-Cookbook#patches Patches # @see https://docs.brew.sh/Formula-Cookbook#patches Patches
#
# @api public
def patch(strip = :p1, src = nil, &block) def patch(strip = :p1, src = nil, &block)
specs.each { |spec| spec.patch(strip, src, &block) } specs.each { |spec| spec.patch(strip, src, &block) }
end end
# One or more formulae that conflict with this one and why. # One or more formulae that conflict with this one and why.
# <pre>conflicts_with "imagemagick", because: "both install `convert` binaries"</pre> # <pre>conflicts_with "imagemagick", because: "both install `convert` binaries"</pre>
#
# @api public
def conflicts_with(*names) def conflicts_with(*names)
opts = names.last.is_a?(Hash) ? names.pop : {} opts = names.last.is_a?(Hash) ? names.pop : {}
names.each { |name| conflicts << FormulaConflict.new(name, opts[:because]) } names.each { |name| conflicts << FormulaConflict.new(name, opts[:because]) }
@ -3459,6 +3613,8 @@ class Formula
# <pre>skip_clean "bin/foo", "lib/bar"</pre> # <pre>skip_clean "bin/foo", "lib/bar"</pre>
# Keep .la files with: # Keep .la files with:
# <pre>skip_clean :la</pre> # <pre>skip_clean :la</pre>
#
# @api public
def skip_clean(*paths) def skip_clean(*paths)
paths.flatten! paths.flatten!
# Specifying :all is deprecated and will become an error # Specifying :all is deprecated and will become an error
@ -3476,11 +3632,15 @@ class Formula
# <pre>keg_only :provided_by_macos</pre> # <pre>keg_only :provided_by_macos</pre>
# <pre>keg_only :versioned_formulae</pre> # <pre>keg_only :versioned_formulae</pre>
# <pre>keg_only "because I want it so"</pre> # <pre>keg_only "because I want it so"</pre>
#
# @api public
def keg_only(reason, explanation = "") def keg_only(reason, explanation = "")
@keg_only_reason = KegOnlyReason.new(reason, explanation) @keg_only_reason = KegOnlyReason.new(reason, explanation)
end end
# Pass `:skip` to this method to disable post-install stdlib checking. # Pass `:skip` to this method to disable post-install stdlib checking.
#
# @api public
def cxxstdlib_check(check_type) def cxxstdlib_check(check_type)
define_method(:skip_cxxstdlib_check?) { true } if check_type == :skip define_method(:skip_cxxstdlib_check?) { true } if check_type == :skip
end end
@ -3506,6 +3666,8 @@ class Formula
# <pre>fails_with :gcc => '7' do # <pre>fails_with :gcc => '7' do
# version '7.1' # version '7.1'
# end</pre> # end</pre>
#
# @api public
def fails_with(compiler, &block) def fails_with(compiler, &block)
specs.each { |spec| spec.fails_with(compiler, &block) } specs.each { |spec| spec.fails_with(compiler, &block) }
end end
@ -3519,6 +3681,8 @@ class Formula
# rather than implicitly finding a suitable compiler with `needs`. # rather than implicitly finding a suitable compiler with `needs`.
# #
# @see .fails_with # @see .fails_with
#
# @api public
def needs(*standards) def needs(*standards)
specs.each { |spec| spec.needs(*standards) } specs.each { |spec| spec.needs(*standards) }
end end
@ -3551,6 +3715,8 @@ class Formula
# #
# The test will fail if it returns false, or if an exception is raised. # The test will fail if it returns false, or if an exception is raised.
# Failed assertions and failed `system` commands will raise exceptions. # Failed assertions and failed `system` commands will raise exceptions.
#
# @api public
def test(&block) def test(&block)
define_method(:test, &block) define_method(:test, &block)
end end
@ -3567,6 +3733,8 @@ class Formula
# url "https://example.com/foo/releases" # url "https://example.com/foo/releases"
# regex /foo-(\d+(?:\.\d+)+)\.tar/ # regex /foo-(\d+(?:\.\d+)+)\.tar/
# end</pre> # end</pre>
#
# @api public
def livecheck(&block) def livecheck(&block)
return @livecheck unless block return @livecheck unless block
@ -3583,6 +3751,8 @@ class Formula
# <pre>service do # <pre>service do
# run [opt_bin/"foo"] # run [opt_bin/"foo"]
# end</pre> # end</pre>
#
# @api public
def service(&block) def service(&block)
return @service_block unless block return @service_block unless block
@ -3604,6 +3774,8 @@ class Formula
# #
# Alternatively, a preset reason can be passed as a symbol: # Alternatively, a preset reason can be passed as a symbol:
# <pre>pour_bottle? only_if: :clt_installed</pre> # <pre>pour_bottle? only_if: :clt_installed</pre>
#
# @api public
def pour_bottle?(only_if: nil, &block) def pour_bottle?(only_if: nil, &block)
@pour_bottle_check = PourBottleCheck.new(self) @pour_bottle_check = PourBottleCheck.new(self)
@pour_bottle_only_if = only_if @pour_bottle_only_if = only_if
@ -3650,6 +3822,8 @@ class Formula
# <pre>deprecate! date: "2020-08-27", because: "has been replaced by foo"</pre> # <pre>deprecate! date: "2020-08-27", because: "has been replaced by foo"</pre>
# @see https://docs.brew.sh/Deprecating-Disabling-and-Removing-Formulae # @see https://docs.brew.sh/Deprecating-Disabling-and-Removing-Formulae
# @see DeprecateDisable::FORMULA_DEPRECATE_DISABLE_REASONS # @see DeprecateDisable::FORMULA_DEPRECATE_DISABLE_REASONS
#
# @api public
def deprecate!(date:, because:) def deprecate!(date:, because:)
@deprecation_date = Date.parse(date) @deprecation_date = Date.parse(date)
return if @deprecation_date > Date.today return if @deprecation_date > Date.today
@ -3685,6 +3859,8 @@ class Formula
# <pre>disable! date: "2020-08-27", because: "has been replaced by foo"</pre> # <pre>disable! date: "2020-08-27", because: "has been replaced by foo"</pre>
# @see https://docs.brew.sh/Deprecating-Disabling-and-Removing-Formulae # @see https://docs.brew.sh/Deprecating-Disabling-and-Removing-Formulae
# @see DeprecateDisable::FORMULA_DEPRECATE_DISABLE_REASONS # @see DeprecateDisable::FORMULA_DEPRECATE_DISABLE_REASONS
#
# @api public
def disable!(date:, because:) def disable!(date:, because:)
@disable_date = Date.parse(date) @disable_date = Date.parse(date)

View File

@ -24,6 +24,9 @@ module Formulary
# :codesign and custom requirement classes are not supported # :codesign and custom requirement classes are not supported
API_SUPPORTED_REQUIREMENTS = [:arch, :linux, :macos, :maximum_macos, :xcode].freeze API_SUPPORTED_REQUIREMENTS = [:arch, :linux, :macos, :maximum_macos, :xcode].freeze
# Enable the factory cache.
#
# @api internal
sig { void } sig { void }
def self.enable_factory_cache! def self.enable_factory_cache!
@factory_cache = true @factory_cache = true
@ -927,6 +930,8 @@ module Formulary
# * a formula pathname # * a formula pathname
# * a formula URL # * a formula URL
# * a local bottle reference # * a local bottle reference
#
# @api internal
sig { sig {
params( params(
ref: T.any(Pathname, String), ref: T.any(Pathname, String),

View File

@ -84,6 +84,10 @@ module Homebrew
class << self class << self
attr_writer :failed, :raise_deprecation_exceptions, :auditing attr_writer :failed, :raise_deprecation_exceptions, :auditing
# Check whether Homebrew is using the default prefix.
#
# @api internal
sig { params(prefix: T.any(Pathname, String)).returns(T::Boolean) }
def default_prefix?(prefix = HOMEBREW_PREFIX) def default_prefix?(prefix = HOMEBREW_PREFIX)
prefix.to_s == DEFAULT_PREFIX prefix.to_s == DEFAULT_PREFIX
end end

View File

@ -144,6 +144,10 @@ module Hardware
ppc? && is_64_bit? && big_endian? ppc? && is_64_bit? && big_endian?
end end
# Check whether the CPU architecture is ARM.
#
# @api internal
sig { returns(T::Boolean) }
def arm? def arm?
type == :arm type == :arm
end end

View File

@ -7,7 +7,7 @@ require "version"
# #
# @api private # @api private
module OS module OS
# Check if the operating system is macOS. # Check whether the operating system is macOS.
# #
# @api public # @api public
sig { returns(T::Boolean) } sig { returns(T::Boolean) }
@ -17,7 +17,7 @@ module OS
RbConfig::CONFIG["host_os"].include? "darwin" RbConfig::CONFIG["host_os"].include? "darwin"
end end
# Check if the operating system is Linux. # Check whether the operating system is Linux.
# #
# @api public # @api public
sig { returns(T::Boolean) } sig { returns(T::Boolean) }

View File

@ -6,6 +6,9 @@ require "utils"
module OS module OS
# Helper module for querying system information on Linux. # Helper module for querying system information on Linux.
module Linux module Linux
# Get the OS version.
#
# @api internal
sig { returns(String) } sig { returns(String) }
def self.os_version def self.os_version
if which("lsb_release") if which("lsb_release")

View File

@ -22,6 +22,8 @@ module OS
# This can be compared to numerics, strings, or symbols # This can be compared to numerics, strings, or symbols
# using the standard Ruby Comparable methods. # using the standard Ruby Comparable methods.
#
# @api internal
sig { returns(MacOSVersion) } sig { returns(MacOSVersion) }
def self.version def self.version
odeprecated "`MacOS.version` on Linux" if Homebrew::SimulateSystem.simulating_or_running_on_linux? odeprecated "`MacOS.version` on Linux" if Homebrew::SimulateSystem.simulating_or_running_on_linux?
@ -30,6 +32,8 @@ module OS
# This can be compared to numerics, strings, or symbols # This can be compared to numerics, strings, or symbols
# using the standard Ruby Comparable methods. # using the standard Ruby Comparable methods.
#
# @api internal
sig { returns(MacOSVersion) } sig { returns(MacOSVersion) }
def self.full_version def self.full_version
odeprecated "`MacOS.full_version` on Linux" if Homebrew::SimulateSystem.simulating_or_running_on_linux? odeprecated "`MacOS.full_version` on Linux" if Homebrew::SimulateSystem.simulating_or_running_on_linux?

View File

@ -172,6 +172,9 @@ module OS
end end
end end
# Get the Xcode version.
#
# @api internal
sig { returns(::Version) } sig { returns(::Version) }
def self.version def self.version
odeprecated "`MacOS::Xcode.version` on Linux" if Homebrew::SimulateSystem.simulating_or_running_on_linux? odeprecated "`MacOS::Xcode.version` on Linux" if Homebrew::SimulateSystem.simulating_or_running_on_linux?
@ -406,6 +409,8 @@ module OS
# Version string (a pretty long one) of the CLT package. # Version string (a pretty long one) of the CLT package.
# Note that the different ways of installing the CLTs lead to different # Note that the different ways of installing the CLTs lead to different
# version numbers. # version numbers.
#
# @api internal
sig { returns(::Version) } sig { returns(::Version) }
def self.version def self.version
odeprecated "`MacOS::CLT.version` on Linux" if Homebrew::SimulateSystem.simulating_or_running_on_linux? odeprecated "`MacOS::CLT.version` on Linux" if Homebrew::SimulateSystem.simulating_or_running_on_linux?

View File

@ -13,10 +13,22 @@ class Tab
FILENAME = "INSTALL_RECEIPT.json" FILENAME = "INSTALL_RECEIPT.json"
attr_accessor :homebrew_version, :tabfile, :built_as_bottle, :installed_as_dependency, :installed_on_request, # @api internal
:changed_files, :poured_from_bottle, :loaded_from_api, :time, :stdlib, :aliases, :arch, :source, attr_accessor :installed_as_dependency
# @api internal
attr_accessor :installed_on_request
# @api internal
attr_accessor :poured_from_bottle
attr_accessor :homebrew_version, :tabfile, :built_as_bottle,
:changed_files, :loaded_from_api, :time, :stdlib, :aliases, :arch, :source,
:built_on :built_on
attr_writer :used_options, :unused_options, :compiler, :runtime_dependencies, :source_modified_time attr_writer :used_options, :unused_options, :compiler, :source_modified_time
# @api internal
attr_writer :runtime_dependencies
# Instantiates a {Tab} for a new installation of a formula. # Instantiates a {Tab} for a new installation of a formula.
def self.create(formula, compiler, stdlib) def self.create(formula, compiler, stdlib)
@ -116,6 +128,7 @@ class Tab
new(attributes) new(attributes)
end end
# @api internal
def self.for_keg(keg) def self.for_keg(keg)
path = keg/FILENAME path = keg/FILENAME
@ -265,6 +278,7 @@ class Tab
spec == :stable spec == :stable
end end
# @api internal
def used_options def used_options
Options.create(@used_options) Options.create(@used_options)
end end

View File

@ -19,15 +19,24 @@ class Tap
TAP_DIRECTORY = (HOMEBREW_LIBRARY/"Taps").freeze TAP_DIRECTORY = (HOMEBREW_LIBRARY/"Taps").freeze
HOMEBREW_TAP_CASK_RENAMES_FILE = "cask_renames.json" HOMEBREW_TAP_CASK_RENAMES_FILE = "cask_renames.json"
private_constant :HOMEBREW_TAP_CASK_RENAMES_FILE
HOMEBREW_TAP_FORMULA_RENAMES_FILE = "formula_renames.json" HOMEBREW_TAP_FORMULA_RENAMES_FILE = "formula_renames.json"
private_constant :HOMEBREW_TAP_FORMULA_RENAMES_FILE
HOMEBREW_TAP_MIGRATIONS_FILE = "tap_migrations.json" HOMEBREW_TAP_MIGRATIONS_FILE = "tap_migrations.json"
private_constant :HOMEBREW_TAP_MIGRATIONS_FILE
HOMEBREW_TAP_AUTOBUMP_FILE = ".github/autobump.txt" HOMEBREW_TAP_AUTOBUMP_FILE = ".github/autobump.txt"
private_constant :HOMEBREW_TAP_AUTOBUMP_FILE
HOMEBREW_TAP_PYPI_FORMULA_MAPPINGS_FILE = "pypi_formula_mappings.json" HOMEBREW_TAP_PYPI_FORMULA_MAPPINGS_FILE = "pypi_formula_mappings.json"
private_constant :HOMEBREW_TAP_PYPI_FORMULA_MAPPINGS_FILE
HOMEBREW_TAP_SYNCED_VERSIONS_FORMULAE_FILE = "synced_versions_formulae.json" HOMEBREW_TAP_SYNCED_VERSIONS_FORMULAE_FILE = "synced_versions_formulae.json"
private_constant :HOMEBREW_TAP_SYNCED_VERSIONS_FORMULAE_FILE
HOMEBREW_TAP_AUDIT_EXCEPTIONS_DIR = "audit_exceptions" HOMEBREW_TAP_AUDIT_EXCEPTIONS_DIR = "audit_exceptions"
private_constant :HOMEBREW_TAP_AUDIT_EXCEPTIONS_DIR
HOMEBREW_TAP_STYLE_EXCEPTIONS_DIR = "style_exceptions" HOMEBREW_TAP_STYLE_EXCEPTIONS_DIR = "style_exceptions"
private_constant :HOMEBREW_TAP_STYLE_EXCEPTIONS_DIR
TAP_MIGRATIONS_STALE_SECONDS = 86400 # 1 day TAP_MIGRATIONS_STALE_SECONDS = 86400 # 1 day
private_constant :TAP_MIGRATIONS_STALE_SECONDS
HOMEBREW_TAP_JSON_FILES = %W[ HOMEBREW_TAP_JSON_FILES = %W[
#{HOMEBREW_TAP_FORMULA_RENAMES_FILE} #{HOMEBREW_TAP_FORMULA_RENAMES_FILE}
@ -41,6 +50,9 @@ class Tap
class InvalidNameError < ArgumentError; end class InvalidNameError < ArgumentError; end
# Fetch a {Tap} by name.
#
# @api public
sig { params(user: String, repo: String).returns(Tap) } sig { params(user: String, repo: String).returns(Tap) }
def self.fetch(user, repo = T.unsafe(nil)) def self.fetch(user, repo = T.unsafe(nil))
user, repo = user.split("/", 2) if repo.nil? user, repo = user.split("/", 2) if repo.nil?
@ -63,6 +75,9 @@ class Tap
cache.fetch(cache_key) { |key| cache[key] = new(user, repo) } cache.fetch(cache_key) { |key| cache[key] = new(user, repo) }
end end
# Get a {Tap} from it's path or a path inside of it.
#
# @api public
def self.from_path(path) def self.from_path(path)
match = File.expand_path(path).match(HOMEBREW_TAP_PATH_REGEX) match = File.expand_path(path).match(HOMEBREW_TAP_PATH_REGEX)
@ -119,27 +134,43 @@ class Tap
false false
end end
# @api public
extend Enumerable extend Enumerable
# The user name of this {Tap}. Usually, it's the GitHub username of # The user name of this {Tap}. Usually, it's the GitHub username of
# this {Tap}'s remote repository. # this {Tap}'s remote repository.
#
# @api public
attr_reader :user attr_reader :user
# The repository name of this {Tap} without the leading `homebrew-`. # The repository name of this {Tap} without the leading `homebrew-`.
#
# @api public
attr_reader :repo attr_reader :repo
# The name of this {Tap}. It combines {#user} and {#repo} with a slash. # The name of this {Tap}. It combines {#user} and {#repo} with a slash.
# {#name} is always in lowercase. # {#name} is always in lowercase.
# e.g. `user/repo` # e.g. `user/repo`
#
# @api public
attr_reader :name attr_reader :name
# Alias for {#name}.
#
# @api public
def to_s = name
# The full name of this {Tap}, including the `homebrew-` prefix. # The full name of this {Tap}, including the `homebrew-` prefix.
# It combines {#user} and 'homebrew-'-prefixed {#repo} with a slash. # It combines {#user} and 'homebrew-'-prefixed {#repo} with a slash.
# e.g. `user/homebrew-repo` # e.g. `user/homebrew-repo`
#
# @api public
attr_reader :full_name attr_reader :full_name
# The local path to this {Tap}. # The local path to this {Tap}.
# e.g. `/usr/local/Library/Taps/user/homebrew-repo` # e.g. `/usr/local/Library/Taps/user/homebrew-repo`
#
# @api public
sig { returns(Pathname) } sig { returns(Pathname) }
attr_reader :path attr_reader :path
@ -211,6 +242,8 @@ class Tap
# The remote path to this {Tap}. # The remote path to this {Tap}.
# e.g. `https://github.com/user/homebrew-repo` # e.g. `https://github.com/user/homebrew-repo`
#
# @api public
def remote def remote
return default_remote unless installed? return default_remote unless installed?
@ -219,6 +252,8 @@ class Tap
# The remote repository name of this {Tap}. # The remote repository name of this {Tap}.
# e.g. `user/homebrew-repo` # e.g. `user/homebrew-repo`
#
# @api public
sig { returns(T.nilable(String)) } sig { returns(T.nilable(String)) }
def remote_repo def remote_repo
return unless (remote = self.remote) return unless (remote = self.remote)
@ -243,12 +278,16 @@ class Tap
.upcase .upcase
end end
# True if this {Tap} is a Git repository. # Check whether this {Tap} is a Git repository.
#
# @api public
def git? def git?
git_repo.git_repo? git_repo.git_repo?
end end
# Git branch for this {Tap}. # Git branch for this {Tap}.
#
# @api public
def git_branch def git_branch
raise TapUnavailableError, name unless installed? raise TapUnavailableError, name unless installed?
@ -256,6 +295,8 @@ class Tap
end end
# Git HEAD for this {Tap}. # Git HEAD for this {Tap}.
#
# @api public
def git_head def git_head
raise TapUnavailableError, name unless installed? raise TapUnavailableError, name unless installed?
@ -263,6 +304,8 @@ class Tap
end end
# Time since last git commit for this {Tap}. # Time since last git commit for this {Tap}.
#
# @api public
def git_last_commit def git_last_commit
raise TapUnavailableError, name unless installed? raise TapUnavailableError, name unless installed?
@ -271,6 +314,8 @@ class Tap
# The issues URL of this {Tap}. # The issues URL of this {Tap}.
# e.g. `https://github.com/user/homebrew-repo/issues` # e.g. `https://github.com/user/homebrew-repo/issues`
#
# @api public
sig { returns(T.nilable(String)) } sig { returns(T.nilable(String)) }
def issues_url def issues_url
return if !official? && custom_remote? return if !official? && custom_remote?
@ -278,16 +323,16 @@ class Tap
"#{default_remote}/issues" "#{default_remote}/issues"
end end
def to_s # Check whether this {Tap} is an official Homebrew tap.
name #
end # @api public
# True if this {Tap} is an official Homebrew tap.
def official? def official?
user == "Homebrew" user == "Homebrew"
end end
# Check whether the remote of this {Tap} is a private repository. # Check whether the remote of this {Tap} is a private repository.
#
# @api public
sig { returns(T::Boolean) } sig { returns(T::Boolean) }
def private? def private?
return @private if defined?(@private) return @private if defined?(@private)
@ -322,13 +367,15 @@ class Tap
end end
end end
# True if this {Tap} has been installed. # Check whether this {Tap} is installed.
#
# @api public
sig { returns(T::Boolean) } sig { returns(T::Boolean) }
def installed? def installed?
path.directory? path.directory?
end end
# True if this {Tap} is not a full clone. # Check whether this {Tap} is a shallow clone.
def shallow? def shallow?
(path/".git/shallow").exist? (path/".git/shallow").exist?
end end
@ -352,6 +399,8 @@ class Tap
# @param custom_remote [Boolean] If set, change the tap's remote if already installed. # @param custom_remote [Boolean] If set, change the tap's remote if already installed.
# @param verify [Boolean] If set, verify all the formula, casks and aliases in the tap are valid. # @param verify [Boolean] If set, verify all the formula, casks and aliases in the tap are valid.
# @param force [Boolean] If set, force core and cask taps to install even under API mode. # @param force [Boolean] If set, force core and cask taps to install even under API mode.
#
# @api public
def install(quiet: false, clone_target: nil, def install(quiet: false, clone_target: nil,
custom_remote: false, verify: false, force: false) custom_remote: false, verify: false, force: false)
require "descriptions" require "descriptions"
@ -514,6 +563,8 @@ class Tap
end end
# Uninstall this {Tap}. # Uninstall this {Tap}.
#
# @api public
def uninstall(manual: false) def uninstall(manual: false)
require "descriptions" require "descriptions"
raise TapUnavailableError, name unless installed? raise TapUnavailableError, name unless installed?
@ -550,7 +601,9 @@ class Tap
Homebrew::Settings.write :untapped, untapped.join(";") Homebrew::Settings.write :untapped, untapped.join(";")
end end
# True if the {#remote} of {Tap} is customized. # Check whether the {#remote} of {Tap} is customized.
#
# @api public
sig { returns(T::Boolean) } sig { returns(T::Boolean) }
def custom_remote? def custom_remote?
return true unless (remote = self.remote) return true unless (remote = self.remote)
@ -559,6 +612,8 @@ class Tap
end end
# Path to the directory of all {Formula} files for this {Tap}. # Path to the directory of all {Formula} files for this {Tap}.
#
# @api public
sig { returns(Pathname) } sig { returns(Pathname) }
def formula_dir def formula_dir
# Official formulae taps always use this directory, saves time to hardcode. # Official formulae taps always use this directory, saves time to hardcode.
@ -580,6 +635,8 @@ class Tap
end end
# Path to the directory of all {Cask} files for this {Tap}. # Path to the directory of all {Cask} files for this {Tap}.
#
# @api public
sig { returns(Pathname) } sig { returns(Pathname) }
def cask_dir def cask_dir
@cask_dir ||= path/"Casks" @cask_dir ||= path/"Casks"
@ -666,15 +723,15 @@ class Tap
end end
end end
# returns true if the file has a Ruby extension # Check whether the file has a Ruby extension.
# @private # @private
sig { params(file: Pathname).returns(T::Boolean) } sig { params(file: Pathname).returns(T::Boolean) }
def ruby_file?(file) def ruby_file?(file)
file.extname == ".rb" file.extname == ".rb"
end end
# returns true if given path would present a {Formula} file in this {Tap}. # Check whether the given path would present a {Formula} file in this {Tap}.
# accepts both absolute path and relative path (relative to this {Tap}'s path) # Accepts either an absolute path or a path relative to this {Tap}'s path.
# @private # @private
sig { params(file: T.any(String, Pathname)).returns(T::Boolean) } sig { params(file: T.any(String, Pathname)).returns(T::Boolean) }
def formula_file?(file) def formula_file?(file)
@ -686,8 +743,8 @@ class Tap
file.to_s.start_with?("#{formula_dir}/") file.to_s.start_with?("#{formula_dir}/")
end end
# returns true if given path would present a {Cask} file in this {Tap}. # Check whether the given path would present a {Cask} file in this {Tap}.
# accepts both absolute path and relative path (relative to this {Tap}'s path) # Accepts either an absolute path or a path relative to this {Tap}'s path.
# @private # @private
sig { params(file: T.any(String, Pathname)).returns(T::Boolean) } sig { params(file: T.any(String, Pathname)).returns(T::Boolean) }
def cask_file?(file) def cask_file?(file)
@ -716,26 +773,27 @@ class Tap
end end
# An array of all {Cask} tokens of this {Tap}. # An array of all {Cask} tokens of this {Tap}.
# @private
sig { returns(T::Array[String]) } sig { returns(T::Array[String]) }
def cask_tokens def cask_tokens
@cask_tokens ||= cask_files.map { formula_file_to_name(_1) } @cask_tokens ||= cask_files.map { formula_file_to_name(_1) }
end end
# path to the directory of all alias files for this {Tap}. # Path to the directory of all alias files for this {Tap}.
# @private # @private
sig { returns(Pathname) } sig { returns(Pathname) }
def alias_dir def alias_dir
@alias_dir ||= path/"Aliases" @alias_dir ||= path/"Aliases"
end end
# an array of all alias files of this {Tap}. # An array of all alias files of this {Tap}.
# @private # @private
sig { returns(T::Array[Pathname]) } sig { returns(T::Array[Pathname]) }
def alias_files def alias_files
@alias_files ||= Pathname.glob("#{alias_dir}/*").select(&:file?) @alias_files ||= Pathname.glob("#{alias_dir}/*").select(&:file?)
end end
# an array of all aliases of this {Tap}. # An array of all aliases of this {Tap}.
# @private # @private
sig { returns(T::Array[String]) } sig { returns(T::Array[String]) }
def aliases def aliases
@ -743,7 +801,6 @@ class Tap
end end
# Mapping from aliases to formula names. # Mapping from aliases to formula names.
#
# @private # @private
sig { returns(T::Hash[String, String]) } sig { returns(T::Hash[String, String]) }
def alias_table def alias_table
@ -943,6 +1000,8 @@ class Tap
end end
# All locally installed taps. # All locally installed taps.
#
# @api public
sig { returns(T::Array[Tap]) } sig { returns(T::Array[Tap]) }
def self.installed def self.installed
cache[:installed] ||= if TAP_DIRECTORY.directory? cache[:installed] ||= if TAP_DIRECTORY.directory?
@ -965,6 +1024,9 @@ class Tap
end end
end end
# Enumerate all available {Tap}s.
#
# @api public
def self.each(&block) def self.each(&block)
if Homebrew::EnvConfig.no_install_from_api? if Homebrew::EnvConfig.no_install_from_api?
installed.each(&block) installed.each(&block)
@ -1058,6 +1120,9 @@ class AbstractCoreTap < Tap
private_class_method :fetch private_class_method :fetch
# Get the singleton instance for this {Tap}.
#
# @api internal
sig { returns(T.attached_class) } sig { returns(T.attached_class) }
def self.instance def self.instance
@instance ||= T.unsafe(self).new @instance ||= T.unsafe(self).new

View File

@ -6,10 +6,12 @@ require "tab"
module Utils module Utils
# Helper functions for bottles. # Helper functions for bottles.
# #
# @api private # @api internal
module Bottles module Bottles
class << self class << self
# Gets the tag for the running OS. # Gets the tag for the running OS.
#
# @api internal
sig { params(tag: T.nilable(T.any(Symbol, Tag))).returns(Tag) } sig { params(tag: T.nilable(T.any(Symbol, Tag))).returns(Tag) }
def tag(tag = nil) def tag(tag = nil)
case tag case tag

View File

@ -5,7 +5,7 @@ require "utils/tty"
# Helper module for formatting output. # Helper module for formatting output.
# #
# @api private # @api internal
module Formatter module Formatter
def self.arrow(string, color: nil) def self.arrow(string, color: nil)
prefix("==>", string, color) prefix("==>", string, color)
@ -23,14 +23,23 @@ module Formatter
"#{Tty.bold}#{string}#{Tty.reset}" "#{Tty.bold}#{string}#{Tty.reset}"
end end
# Format a string as success, with an optional label.
#
# @api internal
def self.success(string, label: nil) def self.success(string, label: nil)
label(label, string, :green) label(label, string, :green)
end end
# Format a string as warning, with an optional label.
#
# @api internal
def self.warning(string, label: nil) def self.warning(string, label: nil)
label(label, string, :yellow) label(label, string, :yellow)
end end
# Format a string as error, with an optional label.
#
# @api internal
def self.error(string, label: nil) def self.error(string, label: nil)
label(label, string, :red) label(label, string, :red)
end end
@ -81,6 +90,9 @@ module Formatter
end end
private_class_method :prefix private_class_method :prefix
# Layout objects in columns that fit the current terminal width.
#
# @api internal
def self.columns(*objects, gap_size: 2) def self.columns(*objects, gap_size: 2)
objects = objects.flatten.map(&:to_s) objects = objects.flatten.map(&:to_s)