diff --git a/Library/Homebrew/formula.rb b/Library/Homebrew/formula.rb index 347a211271..37c08fb136 100644 --- a/Library/Homebrew/formula.rb +++ b/Library/Homebrew/formula.rb @@ -67,15 +67,6 @@ class Formula extend Predicable # @!method inreplace(paths, before = nil, after = nil) - # Actually implemented in {Utils::Inreplace.inreplace}. - # Sometimes we have to change a bit before we install. Mostly we - # prefer a patch but if you need the `prefix` of this formula in the - # patch you have to resort to `inreplace`, because in the patch - # you don't have access to any variable defined by the formula. Only - # `HOMEBREW_PREFIX` is available in the embedded patch. - # - # `inreplace` supports regular expressions: - #
inreplace "somefile.cfg", /look[for]what?/, "replace by #{bin}/tool"
# @see Utils::Inreplace.inreplace
# The name of this {Formula}.
@@ -590,6 +581,7 @@ class Formula
end
# {PkgVersion} of the linked keg for the formula.
+ sig { returns(T.nilable(PkgVersion)) }
def linked_version
return unless linked?
@@ -668,9 +660,12 @@ class Formula
# The directory where the formula's binaries should be installed.
# This is not symlinked into `HOMEBREW_PREFIX`.
- # It is also commonly used to install files that we do not wish to be
+ # It is commonly used to install files that we do not wish to be
# symlinked into `HOMEBREW_PREFIX` from one of the other directories and
# instead manually create symlinks or wrapper scripts into e.g. {#bin}.
+ # libexec.install "foo.jar" + # bin.write_jar_script libexec/"foo.jar", "foo" + #def libexec prefix/"libexec" end @@ -1104,14 +1099,9 @@ class Formula # @private delegate keg_only_reason: :"self.class" - # sometimes the formula cleaner breaks things - # skip cleaning paths in a formula with a class method like this: - # skip_clean "bin/foo", "lib/bar" - # keep .la files with: - # skip_clean :la + # @see .skip_clean # @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) @@ -1119,11 +1109,7 @@ class Formula self.class.skip_clean_paths.include? to_check end - # Sometimes we accidentally install files outside prefix. After we fix that, - # users will get nasty link conflict error. So we create an allowlist here to - # allow overwriting certain files. e.g. - # link_overwrite "bin/foo", "lib/bar" - # link_overwrite "share/man/man1/baz-*" + # @see .link_overwrite # @private def link_overwrite?(path) # Don't overwrite files not created by Homebrew. @@ -1163,36 +1149,42 @@ class Formula # Defaults to false. # @!method deprecated? # @return [Boolean] + # @see .deprecate! delegate deprecated?: :"self.class" # The date that this {Formula} was or becomes deprecated. # Returns `nil` if no date is specified. # @!method deprecation_date # @return Date + # @see .deprecate! delegate deprecation_date: :"self.class" # The reason this {Formula} is deprecated. # Returns `nil` if no reason is specified or the formula is not deprecated. # @!method deprecation_reason # @return [String, Symbol] + # @see .deprecate! delegate deprecation_reason: :"self.class" # Whether this {Formula} is disabled (i.e. cannot be installed). # Defaults to false. # @!method disabled? # @return [Boolean] + # @see .disable! delegate disabled?: :"self.class" # The date that this {Formula} was or becomes disabled. # Returns `nil` if no date is specified. # @!method disable_date # @return Date + # @see .disable! delegate disable_date: :"self.class" # The reason this {Formula} is disabled. # Returns `nil` if no reason is specified or the formula is not disabled. # @!method disable_reason # @return [String, Symbol] + # @see .disable! delegate disable_reason: :"self.class" sig { returns(T::Boolean) } @@ -1406,21 +1398,22 @@ class Formula end # Standard parameters for configure builds. + sig { returns(T::Array[String]) } def std_configure_args ["--disable-debug", "--disable-dependency-tracking", "--prefix=#{prefix}", "--libdir=#{lib}"] end # Standard parameters for cargo builds. + sig { returns(T::Array[T.any(String, Pathname)]) } def std_cargo_args ["--locked", "--root", prefix, "--path", "."] end # Standard parameters for CMake builds. + # # Setting `CMAKE_FIND_FRAMEWORK` to "LAST" tells CMake to search for our # libraries before trying to utilize Frameworks, many of which will be from # 3rd party installs. - # Note that there isn't a std_autotools variant because autotools is a lot - # less consistent and the standard parameters are more memorable. sig { returns(T::Array[String]) } def std_cmake_args args = %W[ @@ -1445,6 +1438,7 @@ class Formula end # Standard parameters for Go builds. + sig { returns(T::Array[T.any(String, Pathname)]) } def std_go_args ["-trimpath", "-o", bin/name] end @@ -1469,6 +1463,20 @@ class Formula ["--prefix=#{prefix}", "--libdir=#{lib}", "--buildtype=release", "--wrap-mode=nofallback"] end + # Shared library names according to platform conventions. + # + # Optionally specify a `version` to restrict the shared library to a specific + # version. The special string "*" matches any version. + # + # If `name` is specified as "*", match any shared library of any version. + # + #
+ # shared_library("foo") #=> foo.dylib
+ # shared_library("foo", 1) #=> foo.1.dylib
+ # shared_library("foo", "*") #=> foo.2.dylib, foo.1.dylib, foo.dylib
+ # shared_library("*") #=> foo.dylib, bar.dylib
+ #
+ sig { params(name: String, version: T.nilable(T.any(String, Integer))).returns(String) }
def shared_library(name, version = nil)
return "*.dylib" if name == "*" && (version.blank? || version == "*")
@@ -1675,6 +1683,8 @@ class Formula
end
end
+ # Returns the {PkgVersion} for this formula if it is installed.
+ # If not, return `nil`.
def any_installed_version
any_installed_keg&.version
end
@@ -1981,7 +1991,8 @@ class Formula
# has to be opened first.
# system "./bootstrap.sh", "--arg1", "--prefix=#{prefix}"
#
- # For CMake we have some necessary defaults in {#std_cmake_args}:
+ # For CMake and other build systems we have some necessary defaults in e.g.
+ # {#std_cmake_args}:
# system "cmake", ".", *std_cmake_args# # If the arguments given to `configure` (or `make` or `cmake`) are depending @@ -2435,7 +2446,6 @@ class Formula # #
bottle do
# root_url "https://example.com" # Optional root to calculate bottle URLs.
- # prefix "/opt/homebrew" # Optional HOMEBREW_PREFIX in which the bottles were built.
# cellar "/opt/homebrew/Cellar" # Optional HOMEBREW_CELLAR in which the bottles were built.
# rebuild 1 # Marks the old bottle as outdated without bumping the version/revision of the formula.
# sha256 "ef65c759c5097a36323fa9c77756468649e8d1980a3a4e05695c05e39568967c" => :catalina
@@ -2443,16 +2453,12 @@ class Formula
# sha256 "91dd0caca9bd3f38c439d5a7b6f68440c4274945615fae035ff0a369264b8a2f" => :high_sierra
# end
#
- # Only formulae where the upstream URL breaks or moves frequently, require compiling
- # or have a reasonable amount of patches/resources should be bottled.
- # Formulae which do not meet the above requirements should not be bottled.
+ # Homebrew maintainers aim to bottle all formulae that require compilation.
#
- # Formulae which should not be bottled and can be installed without any compile
- # required should be tagged with:
+ # Formulae that can be installed without compilation should be tagged with:
# bottle :unneeded# - # Otherwise formulae which do not meet the above requirements and should not - # be bottled should be tagged with: + # Formulae which should not be bottled should be tagged with: #
bottle :disable, "reasons"def bottle(*args, &block) stable.bottle(*args, &block) @@ -2533,32 +2539,41 @@ class Formula end # The dependencies for this formula. Use strings for the names of other - # formulae. Homebrew provides some :special dependencies for stuff that - # requires certain extra handling (often changing some ENV vars or - # deciding if to use the system provided version or not). - #
# `:build` means this dep is only needed during build. - # depends_on "cmake" => :build- #
# `:recommended` dependencies are built by default. - # # But a `--without-...` option is generated to opt-out. - # depends_on "readline" => :recommended- #
# `:optional` dependencies are NOT built by default unless the - # # auto-generated `--with-...` option is passed. - # depends_on "glib" => :optional- #
# If you need to specify that another formula has to be built with/out
- # # certain options (note, no `--` needed before the option):
- # depends_on "zeromq" => "with-pgm"
+ # formulae. Homebrew provides some `:special` {Requirement}s for stuff
+ # that needs extra handling (often changing some ENV vars or
+ # deciding whether to use the system provided version).
+ #
+ # `:build` means this dependency is only needed during build.
+ # depends_on "cmake" => :build
+ #
+ # `:test` means this dependency is only needed during testing.
+ # depends_on "node" => :test
+ #
+ # `:recommended` dependencies are built by default.
+ # But a `--without-...` option is generated to opt-out.
+ # depends_on "readline" => :recommended
+ #
+ # `:optional` dependencies are NOT built by default unless the
+ # auto-generated `--with-...` option is passed.
+ # depends_on "glib" => :optional
+ #
+ # If you need to specify that another formula has to be built with/out
+ # certain options (note, no `--` needed before the option):
+ # depends_on "zeromq" => "with-pgm"
# depends_on "qt" => ["with-qtdbus", "developer"] # Multiple options.
- # # Optional and enforce that "boost" is built with `--with-c++11`.
- # depends_on "boost" => [:optional, "with-c++11"]
- # # If a dependency is only needed in certain cases:
- # depends_on "sqlite" if MacOS.version >= :catalina
+ #
+ # Optional and enforce that "boost" is built with `--with-c++11`.
+ # depends_on "boost" => [:optional, "with-c++11"]
+ #
+ # If a dependency is only needed in certain cases:
+ # depends_on "sqlite" if MacOS.version >= :catalina
# depends_on xcode: :build # If the formula really needs full Xcode to compile.
# depends_on macos: :mojave # Needs at least macOS Mojave (10.14) to run.
- # # It is possible to only depend on something if
- # # `build.with?` or `build.without? "another_formula"`:
- # depends_on "postgresql" if build.without? "sqlite"
- # # Require Python if `--with-python` is passed to `brew install example`:
- # depends_on "python" => :optional
+ #
+ #
+ # It is possible to only depend on something if
+ # `build.with?` or `build.without? "another_formula"`:
+ # depends_on "postgresql" if build.without? "sqlite"
def depends_on(dep)
specs.each { |spec| spec.depends_on(dep) }
end
@@ -2659,6 +2674,13 @@ class Formula
names.each { |name| conflicts << FormulaConflict.new(name, opts[:because]) }
end
+ # Skip cleaning paths in a formula.
+ #
+ # Sometimes the formula {Cleaner cleaner} breaks things.
+ # Preserve cleaned paths with:
+ # skip_clean "bin/foo", "lib/bar"
+ # Keep .la files with:
+ # skip_clean :la
def skip_clean(*paths)
paths.flatten!
# Specifying :all is deprecated and will become an error
@@ -2670,13 +2692,16 @@ class Formula
@skip_clean_paths ||= Set.new
end
- # Software that will not be symlinked into the `brew --prefix` will only
- # live in its Cellar. Other formulae can depend on it and then brew will
- # add the necessary includes and libs (etc.) during the brewing of that
- # other formula. But generally, keg-only formulae are not in your PATH
- # and not seen by compilers if you build your own software outside of
- # Homebrew. This way, we don't shadow software provided by macOS.
+ # Software that will not be symlinked into the `brew --prefix` and will
+ # only live in its Cellar. Other formulae can depend on it and Homebrew
+ # will add the necessary includes, libraries, and other paths while
+ # building that other formula.
+ #
+ # Keg-only formulae are not in your PATH and are not seen by compilers
+ # if you build your own software outside of Homebrew. This way, we
+ # don't shadow software provided by macOS.
# keg_only :provided_by_macos
+ # keg_only :versioned_formulae
# keg_only "because I want it so"
def keg_only(reason, explanation = "")
@keg_only_reason = KegOnlyReason.new(reason, explanation)
@@ -2712,6 +2737,15 @@ class Formula
specs.each { |spec| spec.fails_with(compiler, &block) }
end
+ # Marks the {Formula} as needing a certain standard, so Homebrew
+ # will fall back to other compilers if the default compiler
+ # does not implement that standard.
+ #
+ # We generally prefer to {.depends_on} a desired compiler and to
+ # explicitly use that compiler in a formula's {#install} block,
+ # rather than implicitly finding a suitable compiler with `needs`.
+ #
+ # @see #fails_with
def needs(*standards)
specs.each { |spec| spec.needs(*standards) }
end
@@ -2749,9 +2783,9 @@ class Formula
end
# @!attribute [w] livecheck
- # Livecheck can be used to check for newer versions of the software.
+ # {Livecheck} can be used to check for newer versions of the software.
# This method evaluates the DSL specified in the livecheck block of the
- # {Formula} (if it exists) and sets the instance variables of a Livecheck
+ # {Formula} (if it exists) and sets the instance variables of a {Livecheck}
# object accordingly. This is used by `brew livecheck` to check for newer
# versions of the software.
#
@@ -2790,6 +2824,8 @@ class Formula
# will not be deprecated.
# deprecate! date: "2020-08-27", because: :unmaintained
# deprecate! date: "2020-08-27", because: "has been replaced by foo"
+ # @see https://docs.brew.sh/Deprecating-Disabling-and-Removing-Formulae
+ # @see DeprecateDisable::DEPRECATE_DISABLE_REASONS
def deprecate!(date: nil, because: nil)
odeprecated "`deprecate!` without a reason", "`deprecate! because: \"reason\"`" if because.blank?
odeprecated "`deprecate!` without a date", "`deprecate! date: \"#{Date.today}\"`" if date.blank?
@@ -2805,6 +2841,7 @@ class Formula
# Whether this {Formula} is deprecated (i.e. warns on installation).
# Defaults to false.
# @return [Boolean]
+ # @see .deprecate!
def deprecated?
@deprecated == true
end
@@ -2812,18 +2849,22 @@ class Formula
# The date that this {Formula} was or becomes deprecated.
# Returns `nil` if no date is specified.
# @return Date
+ # @see .deprecate!
attr_reader :deprecation_date
# The reason for deprecation of a {Formula}.
# @return [nil] if no reason was provided or the formula is not deprecated.
# @return [String, Symbol]
+ # @see .deprecate!
attr_reader :deprecation_reason
- # Disables a {Formula} (on a given date, if provided) so it cannot be
+ # Disables a {Formula} (on a given date, if provided) so it cannot be
# installed. If the date has not yet passed the formula
# will be deprecated instead of disabled.
# disable! date: "2020-08-27", because: :does_not_build
# disable! date: "2020-08-27", because: "has been replaced by foo"
+ # @see https://docs.brew.sh/Deprecating-Disabling-and-Removing-Formulae
+ # @see DeprecateDisable::DEPRECATE_DISABLE_REASONS
def disable!(date: nil, because: nil)
odeprecated "`disable!` without a reason", "`disable! because: \"reason\"`" if because.blank?
odeprecated "`disable!` without a date", "`disable! date: \"#{Date.today}\"`" if date.blank?
@@ -2843,6 +2884,7 @@ class Formula
# Whether this {Formula} is disabled (i.e. cannot be installed).
# Defaults to false.
# @return [Boolean]
+ # @see .disable!
def disabled?
@disabled == true
end
@@ -2850,14 +2892,21 @@ class Formula
# The date that this {Formula} was or becomes disabled.
# Returns `nil` if no date is specified.
# @return Date
+ # @see .disable!
attr_reader :disable_date
# The reason this {Formula} is disabled.
# Returns `nil` if no reason was provided or the formula is not disabled.
# @return [String, Symbol]
+ # @see .disable!
attr_reader :disable_reason
- # @private
+ # Permit overwriting certain files while linking.
+ #
+ # Sometimes we accidentally install files outside prefix. Once we fix that,
+ # users will get a link conflict error. Overwrite those files with:
+ # link_overwrite "bin/foo", "lib/bar"
+ # link_overwrite "share/man/man1/baz-*"
def link_overwrite(*paths)
paths.flatten!
link_overwrite_paths.merge(paths)
@@ -2868,6 +2917,7 @@ class Formula
@link_overwrite_paths ||= Set.new
end
+ # Permit links to certain libraries that don't exist. Available on Linux only.
def ignore_missing_libraries(*)
raise FormulaSpecificationError, "#{__method__} is available on Linux only"
end
diff --git a/Library/Homebrew/utils/inreplace.rb b/Library/Homebrew/utils/inreplace.rb
index 951b55148c..95a19aeaa6 100644
--- a/Library/Homebrew/utils/inreplace.rb
+++ b/Library/Homebrew/utils/inreplace.rb
@@ -23,14 +23,22 @@ module Utils
module_function
# Sometimes we have to change a bit before we install. Mostly we
- # prefer a patch but if you need the `prefix` of this formula in the
- # patch you have to resort to `inreplace`, because in the patch
- # you don't have access to any var defined by the formula. Only
- # `HOMEBREW_PREFIX` is available in the embedded patch.
+ # prefer a patch, but if you need the {Formula#prefix prefix} of
+ # this formula in the patch you have to resort to `inreplace`,
+ # because in the patch you don't have access to any variables
+ # defined by the formula, as only `HOMEBREW_PREFIX` is available
+ # in the {DATAPatch embedded patch}.
#
# `inreplace` supports regular expressions:
# inreplace "somefile.cfg", /look[for]what?/, "replace by #{bin}/tool"
#
+ # `inreplace` supports blocks:
+ # inreplace "Makefile" do |s|
+ # s.gsub! "/usr/local", HOMEBREW_PREFIX.to_s
+ # end
+ #
+ #
+ # @see StringInreplaceExtension
# @api public
sig do
params(
@@ -65,6 +73,7 @@ module Utils
raise Error, errors unless errors.empty?
end
+ # @api private
def inreplace_pairs(path, replacement_pairs, read_only_run: false, silent: false)
str = File.open(path, "rb", &:read) || ""
contents = StringInreplaceExtension.new(str)
diff --git a/docs/Bottles.md b/docs/Bottles.md
index 4b1d4fa332..c7de6e026a 100644
--- a/docs/Bottles.md
+++ b/docs/Bottles.md
@@ -33,7 +33,6 @@ A full example:
```ruby
bottle do
root_url "https://example.com"
- prefix "/opt/homebrew"
cellar "/opt/homebrew/Cellar"
rebuild 4
sha256 "4921af80137af9cc3d38fd17c9120da882448a090b0a8a3a19af3199b415bfca" => :sierra
@@ -50,10 +49,6 @@ By default this is omitted and the Homebrew default bottle URL root is used. Thi
Optionally contains the value of `HOMEBREW_CELLAR` in which the bottles were built.
Most compiled software contains references to its compiled location so cannot be simply relocated anywhere on disk. If this value is `:any` or `:any_skip_relocation` this means that the bottle can be safely installed in any Cellar as it did not contain any references to its installation Cellar. This can be omitted if a bottle is compiled (as all default Homebrew ones are) for the default `HOMEBREW_CELLAR` of `/usr/local/Cellar`.
-### Prefix (`prefix`)
-Optionally contains the value of `HOMEBREW_PREFIX` in which the bottles were built.
-See description of `cellar`. When `cellar` is `:any` or `:any_skip_relocation` the prefix should be omitted.
-
### Rebuild version (`rebuild`)
Optionally contains the rebuild version of the bottle.
Sometimes bottles may need be updated without bumping the version of the formula, e.g. a new patch was applied. In that case the rebuild will have a value of 1 or more.