Class: Formula

Inherits:
Object
  • Object
show all
Extended by:
BuildEnvironment::DSL, Cachable, Enumerable, Forwardable, OnOS, Predicable, T::Sig
Includes:
Context, FileUtils, OnOS, Utils::Inreplace, Utils::Shebang, Utils::Shell
Defined in:
Library/Homebrew/formula.rb,
Library/Homebrew/extend/os/linux/formula.rb

Overview

typed: true frozen_string_literal: true

Constant Summary

Constants included from Utils::Shell

Utils::Shell::SHELL_PROFILE_MAP, Utils::Shell::UNSAFE_SHELL_CHAR

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from OnOS

on_linux, on_macos

Methods included from BuildEnvironment::DSL

env

Methods included from Predicable

attr_predicate

Methods included from Cachable

cache, clear_cache

Methods included from Context

current, current=, #debug?, #quiet?, #verbose?, #with_context

Methods included from Utils::Shell

csh_quote, export_value, from_path, parent, preferred, prepend_path_in_profile, profile, set_variable_in_profile, sh_quote

Methods included from Utils::Shebang

rewrite_shebang

Methods included from Utils::Inreplace

inreplace, inreplace_pairs

Class Attribute Details

.bottle(*args, &block) ⇒ Object

Adds a bottle SoftwareSpec. This provides a pre-built binary package built by the Homebrew maintainers for you. It will be installed automatically if there is a binary package for your platform and you haven't passed or previously used any options on this formula.

If you maintain your own repository, you can add your own bottle links. You can ignore this block entirely if submitting to Homebrew/homebrew-core. It'll be handled for you by the Brew Test Bot.

bottle do
  root_url "https://example.com" # Optional root to calculate bottle URLs.
  rebuild 1 # Marks the old bottle as outdated without bumping the version/revision of the formula.
  # Optionally specify the HOMEBREW_CELLAR in which the bottles were built.
  sha256 cellar: "/brew/Cellar", catalina:    "ef65c759c5097a36323fa9c77756468649e8d1980a3a4e05695c05e39568967c"
  sha256 cellar: :any,           mojave:      "28f4090610946a4eb207df102d841de23ced0d06ba31cb79e040d883906dcd4f"
  sha256                         high_sierra: "91dd0caca9bd3f38c439d5a7b6f68440c4274945615fae035ff0a369264b8a2f"
end

Homebrew maintainers aim to bottle all formulae that require compilation.

Formulae that can be installed without compilation should be tagged with:

bottle :unneeded

Formulae which should not be bottled should be tagged with:

bottle :disable, "reasons"

See Also:


2490
2491
2492
# File 'Library/Homebrew/formula.rb', line 2490

def bottle(*args, &block)
  stable.bottle(*args, &block)
end

.deprecated_option(hash) ⇒ Object

Deprecated options are used to rename options and migrate users who used them to newer ones. They are mostly used for migrating non-with options (e.g. enable-debug) to with options (e.g. with-debug).

deprecated_option "enable-debug" => "with-debug"

2638
2639
2640
# File 'Library/Homebrew/formula.rb', line 2638

def deprecated_option(hash)
  specs.each { |spec| spec.deprecated_option(hash) }
end

.deprecation_dateObject (readonly)

The date that this Formula was or becomes deprecated. Returns nil if no date is specified.

Returns:

  • Date

See Also:


2880
2881
2882
# File 'Library/Homebrew/formula.rb', line 2880

def deprecation_date
  @deprecation_date
end

.deprecation_reasonnil, ... (readonly)

The reason for deprecation of a Formula.

Returns:

  • (nil)

    if no reason was provided or the formula is not deprecated.

  • (String, Symbol)

See Also:


2886
2887
2888
# File 'Library/Homebrew/formula.rb', line 2886

def deprecation_reason
  @deprecation_reason
end

.desc=(value) ⇒ Object (writeonly)

A one-line description of the software. Used by users to get an overview of the software and Homebrew maintainers. Shows when running brew info.

desc "Example formula"

2319
# File 'Library/Homebrew/formula.rb', line 2319

attr_rw :desc

.disable_dateObject (readonly)

The date that this Formula was or becomes disabled. Returns nil if no date is specified.

Returns:

  • Date

See Also:


2923
2924
2925
# File 'Library/Homebrew/formula.rb', line 2923

def disable_date
  @disable_date
end

.disable_reasonString, Symbol (readonly)

The reason this Formula is disabled. Returns nil if no reason was provided or the formula is not disabled.

Returns:

See Also:


2929
2930
2931
# File 'Library/Homebrew/formula.rb', line 2929

def disable_reason
  @disable_reason
end

.head(val = nil, specs = {}, &block) ⇒ Object

Adds a head SoftwareSpec. This can be installed by passing the --HEAD option to allow installing software directly from a branch of a version-control repository. If called as a method this provides just the url for the SoftwareSpec. If a block is provided you can also add depends_on and Patches just to the head SoftwareSpec. The download strategies (e.g. :using =>) are the same as for url. master is the default branch and doesn't need stating with a branch: parameter.

head "https://we.prefer.https.over.git.example.com/.git"
head "https://example.com/.git", branch: "name_of_branch"

or (if autodetect fails):

head "https://hg.is.awesome.but.git.has.won.example.com/", using: :hg

2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
# File 'Library/Homebrew/formula.rb', line 2540

def head(val = nil, specs = {}, &block)
  @head ||= HeadSoftwareSpec.new(flags: build_flags)
  if block
    @head.instance_eval(&block)
  elsif val
    @head.url(val, specs)
  else
    @head
  end
end

.homepage=(value) ⇒ Object (writeonly)

The homepage for the software. Used by users to get more information about the software and Homebrew maintainers as a point of contact for e.g. submitting patches. Can be opened with running brew home.

homepage "https://www.example.com"

2359
# File 'Library/Homebrew/formula.rb', line 2359

attr_rw :homepage

.license(args = nil) ⇒ Object

The SPDX ID of the open-source license that the formula uses. Shows when running brew info. Use :any_of, :all_of or :with to describe complex license expressions. :any_of should be used when the user can choose which license to use. :all_of should be used when the user must use all licenses. :with should be used to specify a valid SPDX exception. Add + to an identifier to indicate that the formulae can be licensed under later versions of the same license.

license "BSD-2-Clause"
license "EPL-1.0+"
license any_of: ["MIT", "GPL-2.0-only"]
license all_of: ["MIT", "GPL-2.0-only"]
license "GPL-2.0-only" => { with: "LLVM-exception" }
license :public_domain
license any_of: [
  "MIT",
  :public_domain,
  all_of: ["0BSD", "Zlib", "Artistic-1.0+"],
  "Apache-2.0" => { with: "LLVM-exception" },
]

2344
2345
2346
2347
2348
2349
2350
# File 'Library/Homebrew/formula.rb', line 2344

def license(args = nil)
  if args.nil?
    @licenses
  else
    @licenses = args
  end
end

.livecheck(&block) ⇒ Object

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 object accordingly. This is used by brew livecheck to check for newer versions of the software.

livecheck do
  skip "Not maintained"
  url "https://example.com/foo/releases"
  regex /foo-(\d+(?:\.\d+)+)\.tar/
end

2824
2825
2826
2827
2828
2829
2830
# File 'Library/Homebrew/formula.rb', line 2824

def livecheck(&block)
  @livecheck ||= Livecheck.new(self)
  return @livecheck unless block

  @livecheckable = true
  @livecheck.instance_eval(&block)
end

.mirror(val) ⇒ Object

Additional URLs for the stable version of the formula. These are only used if the url fails to download. It's optional and there can be more than one. Generally we add them when the main url is unreliable. If url is really unreliable then we may swap the mirror and url.

mirror "https://in.case.the.host.is.down.example.com"
mirror "https://in.case.the.mirror.is.down.example.com

2447
2448
2449
# File 'Library/Homebrew/formula.rb', line 2447

def mirror(val)
  stable.mirror(val)
end

.option(name, description = "") ⇒ Object

Options can be used as arguments to brew install. To switch features on/off: "with-something" or "with-otherthing". To use other software: "with-other-software" or "without-foo". Note that for depends_on that are :optional or :recommended, options are generated automatically.

There are also some special options:

  • :universal: build a universal binary/library (e.g. on newer Intel Macs this means a combined x86_64/x86 binary/library).
    option "with-spam", "The description goes here without a dot at the end"
    option "with-qt", "Text here overwrites what's autogenerated by 'depends_on "qt" => :optional'"
    option :universal

2629
2630
2631
# File 'Library/Homebrew/formula.rb', line 2629

def option(name, description = "")
  specs.each { |spec| spec.option(name, description) }
end

.revision=(value) ⇒ Object (writeonly)

Used for creating new Homebrew versions of software without new upstream versions. For example, if we bump the major version of a library that this Formula depends_on then we may need to update the revision of this Formula to install a new version linked against the new library version. 0 if unset.

revision 1

2389
# File 'Library/Homebrew/formula.rb', line 2389

attr_rw :revision

.sha256(val) ⇒ Object

To verify the cached download's integrity and security we verify the SHA-256 hash matches what we've declared in the Formula. To quickly fill this value you can leave it blank and run brew fetch --force and it'll tell you the currently valid value.

sha256 "2a2ba417eebaadcb4418ee7b12fe2998f26d6e6f7fda7983412ff66a741ab6f7"

2459
2460
2461
# File 'Library/Homebrew/formula.rb', line 2459

def sha256(val)
  stable.sha256(val)
end

.stable(&block) ⇒ Object

Allows adding depends_on and Patches just to the stable SoftwareSpec. This is required instead of using a conditional. It is preferrable to also pull the url and sha256 into the block if one is added.

stable do
  url "https://example.com/foo-1.0.tar.gz"
  sha256 "2a2ba417eebaadcb4418ee7b12fe2998f26d6e6f7fda7983412ff66a741ab6f7"

  depends_on "libxml2"
  depends_on "libffi"
end

2521
2522
2523
2524
2525
2526
# File 'Library/Homebrew/formula.rb', line 2521

def stable(&block)
  @stable ||= SoftwareSpec.new(flags: build_flags)
  return @stable unless block

  @stable.instance_eval(&block)
end

.url(val, specs = {}) ⇒ Object

The URL used to download the source for the stable version of the formula. We prefer https for security and proxy reasons. If not inferrable, specify the download strategy with using: ....

  • :git, :hg, :svn, :bzr, :fossil, :cvs,
  • :curl (normal file download, will also extract)
  • :nounzip (without extracting)
  • :post (download via an HTTP POST)
url "https://packed.sources.and.we.prefer.https.example.com/archive-1.2.3.tar.bz2"
url "https://some.dont.provide.archives.example.com",
    using:    :git,
    tag:      "1.2.3",
    revision: "db8e4de5b2d6653f66aea53094624468caad15d2"

2424
2425
2426
# File 'Library/Homebrew/formula.rb', line 2424

def url(val, specs = {})
  stable.url(val, specs)
end

.version(val = nil) ⇒ Object

The version string for the stable version of the formula. The version is autodetected from the URL and/or tag so only needs to be declared if it cannot be autodetected correctly.

version "1.2-final"

2434
2435
2436
# File 'Library/Homebrew/formula.rb', line 2434

def version(val = nil)
  stable.version(val)
end

.version_scheme=(value) ⇒ Object (writeonly)

Used for creating new Homebrew version schemes. For example, if we want to change version scheme from one to another, then we may need to update version_scheme of this Formula to be able to use new version scheme, e.g. to move from 20151020 scheme to 1.0.0 we need to increment version_scheme. Without this, the prior scheme will always equate to a higher version. 0 if unset.

version_scheme 1

2401
# File 'Library/Homebrew/formula.rb', line 2401

attr_rw :version_scheme

Instance Attribute Details

#alias_nameObject (readonly)

The name of the alias that was used to identify this Formula. e.g. another-name-for-this-formula


83
84
85
# File 'Library/Homebrew/formula.rb', line 83

def alias_name
  @alias_name
end

#alias_pathObject (readonly)

The path to the alias that was used to identify this Formula. e.g. /usr/local/Library/Taps/homebrew/homebrew-core/Aliases/another-name-for-this-formula


79
80
81
# File 'Library/Homebrew/formula.rb', line 79

def alias_path
  @alias_path
end

#buildBuildOptions

The BuildOptions for this Formula. Lists the arguments passed and any options in the Formula. Note that these may differ at different times during the installation of a Formula. This is annoying but the result of state that we're trying to eliminate.

Returns:


168
169
170
# File 'Library/Homebrew/formula.rb', line 168

def build
  @build
end

#buildpathObject (readonly)

The current working directory during builds. Will only be non-nil inside #install.


147
148
149
# File 'Library/Homebrew/formula.rb', line 147

def buildpath
  @buildpath
end

#follow_installed_aliasBoolean Also known as: follow_installed_alias?

Whether this formula should be considered outdated if the target of the alias it was installed with has since changed. Defaults to true.

Returns:

  • (Boolean)

174
175
176
# File 'Library/Homebrew/formula.rb', line 174

def follow_installed_alias
  @follow_installed_alias
end

#full_alias_nameObject (readonly)

The fully-qualified alias referring to this Formula. For core formula it's the same as #alias_name. e.g. homebrew/tap-name/another-name-for-this-formula


93
94
95
# File 'Library/Homebrew/formula.rb', line 93

def full_alias_name
  @full_alias_name
end

#full_nameObject (readonly)

The fully-qualified name of this Formula. For core formula it's the same as #name. e.g. homebrew/tap-name/this-formula


88
89
90
# File 'Library/Homebrew/formula.rb', line 88

def full_name
  @full_name
end

#nameObject (readonly)

The name of this Formula. e.g. this-formula


75
76
77
# File 'Library/Homebrew/formula.rb', line 75

def name
  @name
end

#pathObject (readonly)

The full path to this Formula. e.g. /usr/local/Library/Taps/homebrew/homebrew-core/Formula/this-formula.rb


97
98
99
# File 'Library/Homebrew/formula.rb', line 97

def path
  @path
end

#revisionObject (readonly)

Used for creating new Homebrew versions of software without new upstream versions.

See Also:


139
140
141
# File 'Library/Homebrew/formula.rb', line 139

def revision
  @revision
end

#testpathObject (readonly)

The current working directory during tests. Will only be non-nil inside test.


151
152
153
# File 'Library/Homebrew/formula.rb', line 151

def testpath
  @testpath
end

#version_schemeObject (readonly)

Used to change version schemes for packages.

See Also:


143
144
145
# File 'Library/Homebrew/formula.rb', line 143

def version_scheme
  @version_scheme
end

Class Method Details

.[](name) ⇒ Object


1644
1645
1646
# File 'Library/Homebrew/formula.rb', line 1644

def self.[](name)
  Formulary.factory(name)
end

.conflicts_with(*names) ⇒ Object

One or more formulae that conflict with this one and why.

conflicts_with "imagemagick", because: "both install `convert` binaries"

2699
2700
2701
2702
# File 'Library/Homebrew/formula.rb', line 2699

def conflicts_with(*names)
  opts = names.last.is_a?(Hash) ? names.pop : {}
  names.each { |name| conflicts << FormulaConflict.new(name, opts[:because]) }
end

.cxxstdlib_check(check_type) ⇒ Object

Pass :skip to this method to disable post-install stdlib checking.


2738
2739
2740
# File 'Library/Homebrew/formula.rb', line 2738

def cxxstdlib_check(check_type)
  define_method(:skip_cxxstdlib_check?) { true } if check_type == :skip
end

.depends_on(dep) ⇒ Object

The dependencies for this formula. Use strings for the names of other formulae. Homebrew provides some :special Requirements 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
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"

2604
2605
2606
# File 'Library/Homebrew/formula.rb', line 2604

def depends_on(dep)
  specs.each { |spec| spec.depends_on(dep) }
end

.deprecate!(date: nil, because: nil) ⇒ Object

Deprecates a Formula (on a given date, if provided) so a warning is shown on each installation. If the date has not yet passed the formula will not be deprecated.

deprecate! date: "2020-08-27", because: :unmaintained
deprecate! date: "2020-08-27", because: "has been replaced by foo"

2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
# File 'Library/Homebrew/formula.rb', line 2856

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?

  @deprecation_date = Date.parse(date) if date.present?

  return if date.present? && Date.parse(date) > Date.today

  @deprecation_reason = because if because.present?
  @deprecated = true
end

.deprecated?Boolean

Whether this Formula is deprecated (i.e. warns on installation). Defaults to false.

Returns:

  • (Boolean)

See Also:


2872
2873
2874
# File 'Library/Homebrew/formula.rb', line 2872

def deprecated?
  @deprecated == true
end

.disable!(date: nil, because: nil) ⇒ Object

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"

2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
# File 'Library/Homebrew/formula.rb', line 2895

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?

  @disable_date = Date.parse(date) if date.present?

  if @disable_date && @disable_date > Date.today
    @deprecation_reason = because if because.present?
    @deprecated = true
    return
  end

  @disable_reason = because if because.present?
  @disabled = true
end

.disabled?Boolean

Whether this Formula is disabled (i.e. cannot be installed). Defaults to false.

Returns:

  • (Boolean)

See Also:


2915
2916
2917
# File 'Library/Homebrew/formula.rb', line 2915

def disabled?
  @disabled == true
end

.fails_with(compiler, &block) ⇒ Object

Marks the Formula as failing with a particular compiler so it will fall back to others. For Apple compilers, this should be in the format:

fails_with :clang do
  build 600
  cause "multiple configure and compile errors"
end

The block may be omitted, and if present the build may be omitted; if so, then the compiler will not be allowed for all versions.

major_version should be the major release number only, for instance '7' for the GCC 7 series (7.0, 7.1, etc.). If version or the block is omitted, then the compiler will not be allowed for all compilers in that series.

For example, if a bug is only triggered on GCC 7.1 but is not encountered on 7.2:

fails_with :gcc => '7' do
  version '7.1'
end

2763
2764
2765
# File 'Library/Homebrew/formula.rb', line 2763

def fails_with(compiler, &block)
  specs.each { |spec| spec.fails_with(compiler, &block) }
end

.go_resource(name, &block) ⇒ Object


2564
2565
2566
# File 'Library/Homebrew/formula.rb', line 2564

def go_resource(name, &block)
  specs.each { |spec| spec.go_resource(name, &block) }
end

.ignore_missing_libraries(*libs) ⇒ Object

Permit links to certain libraries that don't exist. Available on Linux only.


2948
2949
2950
# File 'Library/Homebrew/formula.rb', line 2948

def ignore_missing_libraries(*)
  raise FormulaSpecificationError, "#{__method__} is available on Linux only"
end

.installed_with_alias_path(alias_path) ⇒ Object


1596
1597
1598
1599
1600
# File 'Library/Homebrew/formula.rb', line 1596

def self.installed_with_alias_path(alias_path)
  return [] if alias_path.nil?

  installed.select { |f| f.installed_alias_path == alias_path }
end

.keg_only(reason, explanation = "") ⇒ Object

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"

2733
2734
2735
# File 'Library/Homebrew/formula.rb', line 2733

def keg_only(reason, explanation = "")
  @keg_only_reason = KegOnlyReason.new(reason, explanation)
end

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-*"

2937
2938
2939
2940
# File 'Library/Homebrew/formula.rb', line 2937

def link_overwrite(*paths)
  paths.flatten!
  link_overwrite_paths.merge(paths)
end

.livecheckable?Boolean

Whether a livecheck specification is defined or not. It returns true when a livecheck block is present in the Formula and false otherwise, and is used by livecheck.

Returns:

  • (Boolean)

2364
2365
2366
# File 'Library/Homebrew/formula.rb', line 2364

def livecheckable?
  @livecheckable == true
end

.needs(*standards) ⇒ Object

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 Also:

  • #fails_with

2776
2777
2778
# File 'Library/Homebrew/formula.rb', line 2776

def needs(*standards)
  specs.each { |spec| spec.needs(*standards) }
end

.patch(strip = :p1, src = nil, &block) ⇒ Object

External patches can be declared using resource-style blocks.

patch do
  url "https://example.com/example_patch.diff"
  sha256 "c6bc3f48ce8e797854c4b865f6a8ff969867bbcaebd648ae6fd825683e59fef2"
end

A strip level of -p1 is assumed. It can be overridden using a symbol argument:

patch :p0 do
  url "https://example.com/example_patch.diff"
  sha256 "c6bc3f48ce8e797854c4b865f6a8ff969867bbcaebd648ae6fd825683e59fef2"
end

Patches can be declared in stable and head blocks. This form is preferred over using conditionals.

stable do
  patch do
    url "https://example.com/example_patch.diff"
    sha256 "c6bc3f48ce8e797854c4b865f6a8ff969867bbcaebd648ae6fd825683e59fef2"
  end
end

Embedded (__END__) patches are declared like so:

patch :DATA
patch :p0, :DATA

Patches can also be embedded by passing a string. This makes it possible to provide multiple embedded patches while making only some of them conditional.

patch :p0, "..."

See Also:


2673
2674
2675
# File 'Library/Homebrew/formula.rb', line 2673

def patch(strip = :p1, src = nil, &block)
  specs.each { |spec| spec.patch(strip, src, &block) }
end

.plist_options(options) ⇒ Object

Defines launchd plist handling.

Does your plist need to be loaded at startup?

plist_options startup: true

Or only when necessary or desired by the user?

plist_options manual: "foo"

Or perhaps you'd like to give the user a choice? Ooh fancy.

plist_options startup: true, manual: "foo start"

2687
2688
2689
2690
# File 'Library/Homebrew/formula.rb', line 2687

def plist_options(options)
  @plist_startup = options[:startup]
  @plist_manual = options[:manual]
end

.pour_bottle?(&block) ⇒ Boolean

Defines whether the Formula's bottle can be used on the given Homebrew installation.

For example, if the bottle requires the Xcode CLT to be installed a Formula would declare:

pour_bottle? do
  reason "The bottle needs the Xcode CLT to be installed."
  satisfy { MacOS::CLT.installed? }
end

If satisfy returns false then a bottle will not be used and instead the Formula will be built from source and reason will be printed.

Returns:

  • (Boolean)

2844
2845
2846
2847
# File 'Library/Homebrew/formula.rb', line 2844

def pour_bottle?(&block)
  @pour_bottle_check = PourBottleCheck.new(self)
  @pour_bottle_check.instance_eval(&block)
end

.resource(name, klass = Resource, &block) ⇒ Object

Additional downloads can be defined as resources and accessed in the install method. Resources can also be defined inside a stable or head block. This mechanism replaces ad-hoc "subformula" classes.

resource "additional_files" do
  url "https://example.com/additional-stuff.tar.gz"
  sha256 "c6bc3f48ce8e797854c4b865f6a8ff969867bbcaebd648ae6fd825683e59fef2"
end

2558
2559
2560
2561
2562
# File 'Library/Homebrew/formula.rb', line 2558

def resource(name, klass = Resource, &block)
  specs.each do |spec|
    spec.resource(name, klass, &block) unless spec.resource_defined?(name)
  end
end

.skip_clean(*paths) ⇒ Object

Skip cleaning paths in a formula.

Sometimes the formula cleaner breaks things. Preserve cleaned paths with:

skip_clean "bin/foo", "lib/bar"

Keep .la files with:

skip_clean :la

2711
2712
2713
2714
2715
# File 'Library/Homebrew/formula.rb', line 2711

def skip_clean(*paths)
  paths.flatten!
  # Specifying :all is deprecated and will become an error
  skip_clean_paths.merge(paths)
end

.test(&block) ⇒ Boolean

A test is required for new formulae and makes us happy. The block will create, run in and delete a temporary directory.

We want tests that don't require any user input and test the basic functionality of the application. For example, foo build-foo input.foo is a good test and foo --version or foo --help are bad tests. However, a bad test is better than no test at all.

(testpath/"test.file").write <<~EOS
  writing some test file, if you need to
EOS
assert_equal "OK", shell_output("test_command test.file").strip

Need complete control over stdin, stdout?

require "open3"
Open3.popen3("#{bin}/example", "argument") do |stdin, stdout, _|
  stdin.write("some text")
  stdin.close
  assert_equal "result", stdout.read
end

The test will fail if it returns false, or if an exception is raised. Failed assertions and failed system commands will raise exceptions.

Returns:

  • (Boolean)

See Also:


2808
2809
2810
# File 'Library/Homebrew/formula.rb', line 2808

def test(&block)
  define_method(:test, &block)
end

.uses_from_macos(dep, bounds = {}) ⇒ Object

Indicates use of dependencies provided by macOS. On macOS this is a no-op (as we use the provided system libraries). On Linux this will act as depends_on.


2611
2612
2613
# File 'Library/Homebrew/formula.rb', line 2611

def uses_from_macos(dep, bounds = {})
  specs.each { |spec| spec.uses_from_macos(dep, bounds) }
end

Instance Method Details

#active_log_prefixObject


906
907
908
909
910
911
912
# File 'Library/Homebrew/formula.rb', line 906

def active_log_prefix
  if active_log_type
    "#{active_log_type}."
  else
    ""
  end
end

#alias_changed?Boolean

Has the alias used to install the formula changed, or are different formulae already installed with this alias?

Returns:

  • (Boolean)

1343
1344
1345
# File 'Library/Homebrew/formula.rb', line 1343

def alias_changed?
  installed_alias_target_changed? || supersedes_an_installed_formula?
end

#aliasesObject

All aliases for the formula.


455
456
457
458
459
460
461
462
463
# File 'Library/Homebrew/formula.rb', line 455

def aliases
  @aliases ||= if tap
    tap.alias_reverse_table[full_name].to_a.map do |a|
      a.split("/").last
    end
  else
    []
  end
end

#any_installed_prefixObject


1701
1702
1703
1704
1705
1706
1707
# File 'Library/Homebrew/formula.rb', line 1701

def any_installed_prefix
  if optlinked? && opt_prefix.exist?
    opt_prefix
  elsif (latest_installed_prefix = installed_prefixes.last)
    latest_installed_prefix
  end
end

#any_installed_versionObject

Returns the PkgVersion for this formula if it is installed. If not, return nil.


1711
1712
1713
# File 'Library/Homebrew/formula.rb', line 1711

def any_installed_version
  any_installed_keg&.version
end

#bash_completionObject

The directory where the formula's Bash completion files should be installed. This is symlinked into HOMEBREW_PREFIX after installation or with brew link for formulae that are not keg-only.


870
871
872
# File 'Library/Homebrew/formula.rb', line 870

def bash_completion
  prefix/"etc/bash_completion.d"
end

#binObject

The directory where the formula's binaries should be installed. This is symlinked into HOMEBREW_PREFIX after installation or with brew link for formulae that are not keg-only.

Need to install into the #bin but the makefile doesn't mkdir -p prefix/bin?

bin.mkpath

No make install available?

bin.install "binary1"

642
643
644
# File 'Library/Homebrew/formula.rb', line 642

def bin
  prefix/"bin"
end

#bottleObject


365
366
367
# File 'Library/Homebrew/formula.rb', line 365

def bottle
  Bottle.new(self, bottle_specification) if bottled?
end

#bottle_hashObject

Returns the bottle information for a formula


1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
# File 'Library/Homebrew/formula.rb', line 1882

def bottle_hash
  bottle_spec = stable.bottle_specification
  hash = {
    "rebuild"  => bottle_spec.rebuild,
    "cellar"   => (cellar = bottle_spec.cellar).is_a?(Symbol) ? cellar.inspect : cellar,
    "prefix"   => bottle_spec.prefix,
    "root_url" => bottle_spec.root_url,
    "files"    => {},
  }
  bottle_spec.collector.each_key do |os|
    bottle_url = "#{bottle_spec.root_url}/#{Bottle::Filename.create(self, os, bottle_spec.rebuild).bintray}"
    checksum = bottle_spec.collector[os][:checksum]
    hash["files"][os] = {
      "url"    => bottle_url,
      "sha256" => checksum.hexdigest,
    }
  end
  hash
end

#caveatsObject


1105
1106
1107
# File 'Library/Homebrew/formula.rb', line 1105

def caveats
  nil
end

#current_installed_alias_targetObject


1323
1324
1325
# File 'Library/Homebrew/formula.rb', line 1323

def current_installed_alias_target
  Formulary.factory(installed_alias_path) if installed_alias_path
end

#deprecated?Boolean

Whether this Formula is deprecated (i.e. warns on installation). Defaults to false.

Returns:

  • (Boolean)

See Also:


1172
# File 'Library/Homebrew/formula.rb', line 1172

delegate deprecated?: :"self.class"

#deprecation_dateObject

The date that this Formula was or becomes deprecated. Returns nil if no date is specified.

Returns:

  • Date

See Also:


1179
# File 'Library/Homebrew/formula.rb', line 1179

delegate deprecation_date: :"self.class"

#deprecation_reasonString, Symbol

The reason this Formula is deprecated. Returns nil if no reason is specified or the formula is not deprecated.

Returns:

See Also:


1186
# File 'Library/Homebrew/formula.rb', line 1186

delegate deprecation_reason: :"self.class"

#descObject

The description of the software.

See Also:


372
# File 'Library/Homebrew/formula.rb', line 372

delegate desc: :"self.class"

#disable_dateObject

The date that this Formula was or becomes disabled. Returns nil if no date is specified.

Returns:

  • Date

See Also:


1200
# File 'Library/Homebrew/formula.rb', line 1200

delegate disable_date: :"self.class"

#disable_reasonString, Symbol

The reason this Formula is disabled. Returns nil if no reason is specified or the formula is not disabled.

Returns:

See Also:


1207
# File 'Library/Homebrew/formula.rb', line 1207

delegate disable_reason: :"self.class"

#disabled?Boolean

Whether this Formula is disabled (i.e. cannot be installed). Defaults to false.

Returns:

  • (Boolean)

See Also:


1193
# File 'Library/Homebrew/formula.rb', line 1193

delegate disabled?: :"self.class"

#docObject

The directory where the formula's documentation should be installed. This is symlinked into HOMEBREW_PREFIX after installation or with brew link for formulae that are not keg-only.


649
650
651
# File 'Library/Homebrew/formula.rb', line 649

def doc
  share/"doc"/name
end

#elispObject

The directory where Emacs Lisp files should be installed, with the formula name appended to avoid linking conflicts.

To install an Emacs mode included with a software package:

elisp.install "contrib/emacs/example-mode.el"

806
807
808
# File 'Library/Homebrew/formula.rb', line 806

def elisp
  prefix/"share/emacs/site-lisp"/name
end

#etcObject

The directory where the formula's configuration files should be installed. Anything using etc.install will not overwrite other files on e.g. upgrades but will write a new file named *.default. This directory is not inside the HOMEBREW_CELLAR so it persists across upgrades.


831
832
833
# File 'Library/Homebrew/formula.rb', line 831

def etc
  (HOMEBREW_PREFIX/"etc").extend(InstallRenamed)
end

#fetch_patchesObject


2207
2208
2209
# File 'Library/Homebrew/formula.rb', line 2207

def fetch_patches
  patchlist.select(&:external?).each(&:fetch)
end

#fish_completionObject

The directory where the formula's fish completion files should be installed. This is symlinked into HOMEBREW_PREFIX after installation or with brew link for formulae that are not keg-only.


886
887
888
# File 'Library/Homebrew/formula.rb', line 886

def fish_completion
  share/"fish/vendor_completions.d"
end

#fish_functionObject

The directory where the formula's fish function files should be installed. This is symlinked into HOMEBREW_PREFIX after installation or with brew link for formulae that are not keg-only.


862
863
864
# File 'Library/Homebrew/formula.rb', line 862

def fish_function
  share/"fish/vendor_functions.d"
end

#frameworksObject

The directory where the formula's Frameworks should be installed. This is symlinked into HOMEBREW_PREFIX after installation or with brew link for formulae that are not keg-only. This is not symlinked into HOMEBREW_PREFIX.


814
815
816
# File 'Library/Homebrew/formula.rb', line 814

def frameworks
  prefix/"Frameworks"
end

#full_installed_alias_nameObject


304
305
306
# File 'Library/Homebrew/formula.rb', line 304

def full_installed_alias_name
  full_name_with_optional_tap(installed_alias_name)
end

#full_installed_specified_nameObject

The name (including tap) specified to install this formula.


329
330
331
# File 'Library/Homebrew/formula.rb', line 329

def full_installed_specified_name
  full_installed_alias_name || full_name
end

#full_specified_nameObject

The name (including tap) specified to find this formula.


319
320
321
# File 'Library/Homebrew/formula.rb', line 319

def full_specified_name
  full_alias_name || full_name
end

#head_version_outdated?(version, fetch_head: false) ⇒ Boolean

Returns:

  • (Boolean)

544
545
546
547
548
549
550
551
552
553
554
555
556
557
# File 'Library/Homebrew/formula.rb', line 544

def head_version_outdated?(version, fetch_head: false)
  tab = Tab.for_keg(prefix(version))

  return true if tab.version_scheme < version_scheme
  return true if stable && tab.stable_version && tab.stable_version < stable.version
  return false unless fetch_head
  return false unless head&.downloader.is_a?(VCSDownloadStrategy)

  downloader = head.downloader

  with_context quiet: true do
    downloader.commit_outdated?(version.version.commit)
  end
end

#homepageObject

The homepage for the software.

See Also:


382
# File 'Library/Homebrew/formula.rb', line 382

delegate homepage: :"self.class"

#includeObject

The directory where the formula's headers should be installed. This is symlinked into HOMEBREW_PREFIX after installation or with brew link for formulae that are not keg-only.

No make install available?

include.install "example.h"

659
660
661
# File 'Library/Homebrew/formula.rb', line 659

def include
  prefix/"include"
end

#infoObject

The directory where the formula's info files should be installed. This is symlinked into HOMEBREW_PREFIX after installation or with brew link for formulae that are not keg-only.


666
667
668
# File 'Library/Homebrew/formula.rb', line 666

def info
  share/"info"
end

#inreplace(paths, before = nil, after = nil) ⇒ Object


# File 'Library/Homebrew/formula.rb', line 70

#inspectObject


1415
1416
1417
# File 'Library/Homebrew/formula.rb', line 1415

def inspect
  "#<Formula #{name} (#{active_spec_sym}) #{path}>"
end

#installObject

This method is overridden in Formula subclasses to provide the installation instructions. The sources (from url) are downloaded, hash-checked and then Homebrew changes into a temporary directory where the archive is unpacked or repository cloned.

def install
  system "./configure", "--prefix=#{prefix}"
  system "make", "install"
end

1972
# File 'Library/Homebrew/formula.rb', line 1972

def install; end

#installed_alias_nameObject


300
301
302
# File 'Library/Homebrew/formula.rb', line 300

def installed_alias_name
  File.basename(installed_alias_path) if installed_alias_path
end

#installed_alias_pathObject

The alias path that was used to install this formula, if it exists. Can differ from #alias_path, which is the alias used to find the formula, and is specified to this instance.


291
292
293
294
295
296
297
# File 'Library/Homebrew/formula.rb', line 291

def installed_alias_path
  path = build.source["path"] if build.is_a?(Tab)
  return unless path&.match?(%r{#{HOMEBREW_TAP_DIR_REGEX}/Aliases}o)
  return unless File.symlink?(path)

  path
end

#installed_alias_target_changed?Boolean

Has the target of the alias used to install this formula changed? Returns false if the formula wasn't installed with an alias.

Returns:

  • (Boolean)

1329
1330
1331
1332
1333
1334
# File 'Library/Homebrew/formula.rb', line 1329

def installed_alias_target_changed?
  target = current_installed_alias_target
  return false unless target

  target.name != name
end

#installed_specified_nameObject

The name specified to install this formula.


324
325
326
# File 'Library/Homebrew/formula.rb', line 324

def installed_specified_name
  installed_alias_name || name
end

#keg_only?Boolean

Rarely, you don't want your library symlinked into the main prefix. See gettext.rb for an example.

Returns:

  • (Boolean)

See Also:


1112
1113
1114
1115
1116
# File 'Library/Homebrew/formula.rb', line 1112

def keg_only?
  return false unless keg_only_reason

  keg_only_reason.applicable?
end

#kext_prefixObject

The directory where the formula's kernel extensions should be installed. This is symlinked into HOMEBREW_PREFIX after installation or with brew link for formulae that are not keg-only. This is not symlinked into HOMEBREW_PREFIX.


822
823
824
# File 'Library/Homebrew/formula.rb', line 822

def kext_prefix
  prefix/"Library/Extensions"
end

#latest_formulaObject

If the alias has changed value, return the new formula. Otherwise, return self.


1349
1350
1351
# File 'Library/Homebrew/formula.rb', line 1349

def latest_formula
  installed_alias_target_changed? ? current_installed_alias_target : self
end

#latest_head_prefixObject


539
540
541
542
# File 'Library/Homebrew/formula.rb', line 539

def latest_head_prefix
  head_version = latest_head_version
  prefix(head_version) if head_version
end

#latest_head_versionObject


528
529
530
531
532
533
534
535
536
537
# File 'Library/Homebrew/formula.rb', line 528

def latest_head_version
  head_versions = installed_prefixes.map do |pn|
    pn_pkgversion = PkgVersion.parse(pn.basename.to_s)
    pn_pkgversion if pn_pkgversion.head?
  end.compact

  head_versions.max_by do |pn_pkgversion|
    [Tab.for_keg(prefix(pn_pkgversion)).source_modified_time, pn_pkgversion.revision]
  end
end

#libObject

The directory where the formula's libraries should be installed. This is symlinked into HOMEBREW_PREFIX after installation or with brew link for formulae that are not keg-only.

No make install available?

lib.install "example.dylib"

676
677
678
# File 'Library/Homebrew/formula.rb', line 676

def lib
  prefix/"lib"
end

#libexecObject

The directory where the formula's binaries should be installed. This is not symlinked into HOMEBREW_PREFIX. 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"

688
689
690
# File 'Library/Homebrew/formula.rb', line 688

def libexec
  prefix/"libexec"
end

#licenseObject

The SPDX ID of the software license.

See Also:


377
# File 'Library/Homebrew/formula.rb', line 377

delegate license: :"self.class"

#linked?Boolean

Is the formula linked?

Returns:

  • (Boolean)

586
587
588
# File 'Library/Homebrew/formula.rb', line 586

def linked?
  linked_keg.symlink?
end

#linked_versionObject


604
605
606
607
608
# File 'Library/Homebrew/formula.rb', line 604

def linked_version
  return unless linked?

  Keg.for(linked_keg).version
end

#livecheckObject

The livecheck specification for the software.

See Also:


387
# File 'Library/Homebrew/formula.rb', line 387

delegate livecheck: :"self.class"

#livecheckable?Object

Is a livecheck specification defined for the software?

See Also:


392
# File 'Library/Homebrew/formula.rb', line 392

delegate livecheckable?: :"self.class"

#manObject

The root directory where the formula's manual pages should be installed. This is symlinked into HOMEBREW_PREFIX after installation or with brew link for formulae that are not keg-only. Often one of the more specific man functions should be used instead, e.g. #man1.


697
698
699
# File 'Library/Homebrew/formula.rb', line 697

def man
  share/"man"
end

#man1Object

The directory where the formula's man1 pages should be installed. This is symlinked into HOMEBREW_PREFIX after installation or with brew link for formulae that are not keg-only.

No make install available?

man1.install "example.1"

707
708
709
# File 'Library/Homebrew/formula.rb', line 707

def man1
  man/"man1"
end

#man2Object

The directory where the formula's man2 pages should be installed. This is symlinked into HOMEBREW_PREFIX after installation or with brew link for formulae that are not keg-only.


714
715
716
# File 'Library/Homebrew/formula.rb', line 714

def man2
  man/"man2"
end

#man3Object

The directory where the formula's man3 pages should be installed. This is symlinked into HOMEBREW_PREFIX after installation or with brew link for formulae that are not keg-only.

No make install available?

man3.install "man.3"

724
725
726
# File 'Library/Homebrew/formula.rb', line 724

def man3
  man/"man3"
end

#man4Object

The directory where the formula's man4 pages should be installed. This is symlinked into HOMEBREW_PREFIX after installation or with brew link for formulae that are not keg-only.


731
732
733
# File 'Library/Homebrew/formula.rb', line 731

def man4
  man/"man4"
end

#man5Object

The directory where the formula's man5 pages should be installed. This is symlinked into HOMEBREW_PREFIX after installation or with brew link for formulae that are not keg-only.


738
739
740
# File 'Library/Homebrew/formula.rb', line 738

def man5
  man/"man5"
end

#man6Object

The directory where the formula's man6 pages should be installed. This is symlinked into HOMEBREW_PREFIX after installation or with brew link for formulae that are not keg-only.


745
746
747
# File 'Library/Homebrew/formula.rb', line 745

def man6
  man/"man6"
end

#man7Object

The directory where the formula's man7 pages should be installed. This is symlinked into HOMEBREW_PREFIX after installation or with brew link for formulae that are not keg-only.


752
753
754
# File 'Library/Homebrew/formula.rb', line 752

def man7
  man/"man7"
end

#man8Object

The directory where the formula's man8 pages should be installed. This is symlinked into HOMEBREW_PREFIX after installation or with brew link for formulae that are not keg-only.


759
760
761
# File 'Library/Homebrew/formula.rb', line 759

def man8
  man/"man8"
end

#migration_needed?Boolean

Returns:

  • (Boolean)

1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
# File 'Library/Homebrew/formula.rb', line 1271

def migration_needed?
  return false unless oldname
  return false if rack.exist?

  old_rack = HOMEBREW_CELLAR/oldname
  return false unless old_rack.directory?
  return false if old_rack.subdirs.empty?

  tap == Tab.for_keg(old_rack.subdirs.min).tap
end

#missing_dependencies(hide: nil) ⇒ Object

Returns a list of formulae depended on by this formula that aren't installed.


1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
# File 'Library/Homebrew/formula.rb', line 1772

def missing_dependencies(hide: nil)
  hide ||= []
  runtime_formula_dependencies.select do |f|
    hide.include?(f.name) || f.installed_prefixes.empty?
  end
# If we're still getting unavailable formulae at this stage the best we can
# do is just return no results.
rescue FormulaUnavailableError
  []
end

#mkdir(name, &block) ⇒ Object

A version of FileUtils.mkdir that also changes to that folder in a block.


2188
2189
2190
2191
2192
2193
# File 'Library/Homebrew/formula.rb', line 2188

def mkdir(name, &block)
  result = FileUtils.mkdir_p(name)
  return result unless block

  FileUtils.chdir(name, &block)
end

#mktemp(prefix = name, opts = {}, &block) ⇒ Object

Create a temporary directory then yield. When the block returns, recursively delete the temporary directory. Passing opts[:retain] or calling do |staging| ... staging.retain! in the block will skip the deletion and retain the temporary directory's contents.


2182
2183
2184
# File 'Library/Homebrew/formula.rb', line 2182

def mktemp(prefix = name, opts = {}, &block)
  Mktemp.new(prefix, opts).run(&block)
end

#new_formula_available?Boolean

Returns:

  • (Boolean)

1319
1320
1321
# File 'Library/Homebrew/formula.rb', line 1319

def new_formula_available?
  installed_alias_target_changed? && !latest_formula.latest_version_installed?
end

#old_installed_formulaeObject


1353
1354
1355
1356
1357
1358
1359
1360
# File 'Library/Homebrew/formula.rb', line 1353

def old_installed_formulae
  # If this formula isn't the current target of the alias,
  # it doesn't make sense to say that other formulae are older versions of it
  # because we don't know which came first.
  return [] if alias_path.nil? || installed_alias_target_changed?

  self.class.installed_with_alias_path(alias_path).reject { |f| f.name == name }
end

#oldnameObject

An old name for the formula.


447
448
449
450
451
452
# File 'Library/Homebrew/formula.rb', line 447

def oldname
  @oldname ||= if tap
    formula_renames = tap.formula_renames
    formula_renames.to_a.rassoc(name).first if formula_renames.value?(name)
  end
end

#opt_binObject


984
985
986
# File 'Library/Homebrew/formula.rb', line 984

def opt_bin
  opt_prefix/"bin"
end

#opt_elispObject


1019
1020
1021
# File 'Library/Homebrew/formula.rb', line 1019

def opt_elisp
  opt_prefix/"share/emacs/site-lisp"/name
end

#opt_frameworksObject


1024
1025
1026
# File 'Library/Homebrew/formula.rb', line 1024

def opt_frameworks
  opt_prefix/"Frameworks"
end

#opt_includeObject


989
990
991
# File 'Library/Homebrew/formula.rb', line 989

def opt_include
  opt_prefix/"include"
end

#opt_libObject


994
995
996
# File 'Library/Homebrew/formula.rb', line 994

def opt_lib
  opt_prefix/"lib"
end

#opt_libexecObject


999
1000
1001
# File 'Library/Homebrew/formula.rb', line 999

def opt_libexec
  opt_prefix/"libexec"
end

#opt_pkgshareObject


1014
1015
1016
# File 'Library/Homebrew/formula.rb', line 1014

def opt_pkgshare
  opt_prefix/"share"/name
end

#opt_prefixObject


979
980
981
# File 'Library/Homebrew/formula.rb', line 979

def opt_prefix
  HOMEBREW_PREFIX/"opt"/name
end

#opt_sbinObject


1004
1005
1006
# File 'Library/Homebrew/formula.rb', line 1004

def opt_sbin
  opt_prefix/"sbin"
end

#opt_shareObject


1009
1010
1011
# File 'Library/Homebrew/formula.rb', line 1009

def opt_share
  opt_prefix/"share"
end

#option_defined?Object

If a named option is defined for the currently active SoftwareSpec.


498
# File 'Library/Homebrew/formula.rb', line 498

delegate option_defined?: :active_spec

#optlinked?Boolean

Is the formula linked to opt?

Returns:

  • (Boolean)

591
592
593
# File 'Library/Homebrew/formula.rb', line 591

def optlinked?
  opt_prefix.symlink?
end

#pkg_versionObject


419
420
421
# File 'Library/Homebrew/formula.rb', line 419

def pkg_version
  PkgVersion.new(version, revision)
end

#pkgetcObject

A subdirectory of etc with the formula name suffixed. e.g. $HOMEBREW_PREFIX/etc/[email protected] Anything using pkgetc.install will not overwrite other files on e.g. upgrades but will write a new file named *.default.


839
840
841
# File 'Library/Homebrew/formula.rb', line 839

def pkgetc
  (HOMEBREW_PREFIX/"etc"/name).extend(InstallRenamed)
end

#pkgshareObject

The directory where the formula's shared files should be installed, with the name of the formula appended to avoid linking conflicts. This is symlinked into HOMEBREW_PREFIX after installation or with brew link for formulae that are not keg-only.

No make install available?

pkgshare.install "examples"

797
798
799
# File 'Library/Homebrew/formula.rb', line 797

def pkgshare
  prefix/"share"/name
end

#plistObject

This method can be overridden to provide a plist.

def plist; <<~EOS
  <?xml version="1.0" encoding="UTF-8"?>
  <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  <plist version="1.0">
  <dict>
    <key>Label</key>
      <string>#{plist_name}</string>
    <key>ProgramArguments</key>
    <array>
      <string>#{opt_bin}/example</string>
      <string>--do-this</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>KeepAlive</key>
    <true/>
    <key>StandardErrorPath</key>
    <string>/dev/null</string>
    <key>StandardOutPath</key>
    <string>/dev/null</string>
  </dict>
  </plist>
  EOS
end

949
950
951
# File 'Library/Homebrew/formula.rb', line 949

def plist
  nil
end

#plist_nameObject


955
956
957
# File 'Library/Homebrew/formula.rb', line 955

def plist_name
  "homebrew.mxcl.#{name}"
end

#plist_pathObject


961
962
963
# File 'Library/Homebrew/formula.rb', line 961

def plist_path
  prefix/"#{plist_name}.plist"
end

#post_installObject


1044
# File 'Library/Homebrew/formula.rb', line 1044

def post_install; end

#pour_bottle?Boolean

Returns:

  • (Boolean)

1035
1036
1037
# File 'Library/Homebrew/formula.rb', line 1035

def pour_bottle?
  true
end

#prefix(v = pkg_version) ⇒ Object

The directory in the cellar that the formula is installed to. This directory points to #opt_prefix if it exists and if ##prefix is not called from within the same formula's #install or #post_install methods. Otherwise, return the full path to the formula's versioned cellar.


575
576
577
578
579
580
581
582
583
# File 'Library/Homebrew/formula.rb', line 575

def prefix(v = pkg_version)
  versioned_prefix = versioned_prefix(v)
  if !@prefix_returns_versioned_prefix && v == pkg_version &&
     versioned_prefix.directory? && Keg.new(versioned_prefix).optlinked?
    opt_prefix
  else
    versioned_prefix
  end
end

#prefix_linked?(v = pkg_version) ⇒ Boolean

If a formula's linked keg points to the prefix.

Returns:

  • (Boolean)

596
597
598
599
600
# File 'Library/Homebrew/formula.rb', line 596

def prefix_linked?(v = pkg_version)
  return false unless linked?

  linked_keg.resolved_path == versioned_prefix(v)
end

#rackObject


614
615
616
# File 'Library/Homebrew/formula.rb', line 614

def rack
  HOMEBREW_CELLAR/name
end

#require_universal_deps?Boolean

Returns:

  • (Boolean)

1216
1217
1218
# File 'Library/Homebrew/formula.rb', line 1216

def require_universal_deps?
  false
end

#resourceObject

A named Resource for the currently active SoftwareSpec. Additional downloads can be defined as #resources. Resource#stage will create a temporary directory and yield to a block.

resource("additional_files").stage { bin.install "my/extra/tool" }

444
# File 'Library/Homebrew/formula.rb', line 444

delegate resource: :active_spec

#resourcesObject

The Resources for the currently active SoftwareSpec.


467
# File 'Library/Homebrew/formula.rb', line 467

def_delegator :"active_spec.resources", :values, :resources

#run_post_installObject


1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
# File 'Library/Homebrew/formula.rb', line 1048

def run_post_install
  @prefix_returns_versioned_prefix = true
  build = self.build

  begin
    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"],
    }

    with_env(new_env) do
      ENV.clear_sensitive_environment!
      ENV.activate_extensions!

      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
end

#runtime_installed_formula_dependentsObject


1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
# File 'Library/Homebrew/formula.rb', line 1753

def runtime_installed_formula_dependents
  # `any_installed_keg` and `runtime_dependencies` `select`s ensure
  # that we don't end up with something `Formula#runtime_dependencies` can't
  # read from a `Tab`.
  Formula.cache[:runtime_installed_formula_dependents] = {}
  Formula.cache[:runtime_installed_formula_dependents][full_name] ||= Formula.installed
                                                                             .select(&:any_installed_keg)
                                                                             .select(&:runtime_dependencies)
                                                                             .select do |f|
    f.runtime_formula_dependencies.any? do |dep|
      full_name == dep.full_name
    rescue
      name == dep.name
    end
  end
end

#sbinObject

The directory where the formula's sbin binaries should be installed. This is symlinked into HOMEBREW_PREFIX after installation or with brew link for formulae that are not keg-only. Generally we try to migrate these to #bin instead.


767
768
769
# File 'Library/Homebrew/formula.rb', line 767

def sbin
  prefix/"sbin"
end

#shareObject

The directory where the formula's shared files should be installed. This is symlinked into HOMEBREW_PREFIX after installation or with brew link for formulae that are not keg-only.

Need a custom directory?

(share/"concept").mkpath

Installing something into another custom directory?

(share/"concept2").install "ducks.txt"

Install ./example_code/simple/ones to share/demos:

(share/"demos").install "example_code/simple/ones"

Install ./example_code/simple/ones to share/demos/examples:

(share/"demos").install "example_code/simple/ones" => "examples"

786
787
788
# File 'Library/Homebrew/formula.rb', line 786

def share
  prefix/"share"
end

#shared_library(name, version = nil) ⇒ Object


1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
# File 'Library/Homebrew/formula.rb', line 1501

def shared_library(name, version = nil)
  return "*.dylib" if name == "*" && (version.blank? || version == "*")

  infix = if version == "*"
    "{,.*}"
  elsif version.present?
    ".#{version}"
  end
  "#{name}#{infix}.dylib"
end

#skip_clean?(path) ⇒ Boolean

Returns:

  • (Boolean)

1124
1125
1126
1127
1128
1129
# File 'Library/Homebrew/formula.rb', line 1124

def skip_clean?(path)
  return true if path.extname == ".la" && self.class.skip_clean_paths.include?(:la)

  to_check = path.relative_path_from(prefix).to_s
  self.class.skip_clean_paths.include? to_check
end

#skip_cxxstdlib_check?Boolean

Returns:

  • (Boolean)

1210
1211
1212
# File 'Library/Homebrew/formula.rb', line 1210

def skip_cxxstdlib_check?
  false
end

#specified_nameObject

The name specified to find this formula.


314
315
316
# File 'Library/Homebrew/formula.rb', line 314

def specified_name
  alias_name || name
end

#specified_pathObject

The path that was specified to find this formula.


309
310
311
# File 'Library/Homebrew/formula.rb', line 309

def specified_path
  alias_path || path
end

#std_cabal_v2_argsObject


1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
# File 'Library/Homebrew/formula.rb', line 1469

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}"]
end

#std_cargo_argsObject


1427
1428
1429
# File 'Library/Homebrew/formula.rb', line 1427

def std_cargo_args
  ["--locked", "--root", prefix, "--path", "."]
end

#std_cmake_argsObject


1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
# File 'Library/Homebrew/formula.rb', line 1437

def std_cmake_args
  args = %W[
    -DCMAKE_C_FLAGS_RELEASE=-DNDEBUG
    -DCMAKE_CXX_FLAGS_RELEASE=-DNDEBUG
    -DCMAKE_INSTALL_PREFIX=#{prefix}
    -DCMAKE_INSTALL_LIBDIR=lib
    -DCMAKE_BUILD_TYPE=Release
    -DCMAKE_FIND_FRAMEWORK=LAST
    -DCMAKE_VERBOSE_MAKEFILE=ON
    -Wno-dev
  ]

  # Avoid false positives for clock_gettime support on 10.11.
  # CMake cache entries for other weak symbols may be added here as needed.
  args << "-DHAVE_CLOCK_GETTIME:INTERNAL=0" if MacOS.version == "10.11" && MacOS::Xcode.version >= "8.0"

  # Ensure CMake is using the same SDK we are using.
  args << "-DCMAKE_OSX_SYSROOT=#{MacOS.sdk_for_formula(self).path}" if MacOS.sdk_root_needed?

  args
end

#std_configure_argsObject


1421
1422
1423
# File 'Library/Homebrew/formula.rb', line 1421

def std_configure_args
  ["--disable-debug", "--disable-dependency-tracking", "--prefix=#{prefix}", "--libdir=#{lib}"]
end

#std_go_args(ldflags: nil) ⇒ Object


1461
1462
1463
1464
1465
# File 'Library/Homebrew/formula.rb', line 1461

def std_go_args(ldflags: nil)
  args = ["-trimpath", "-o=#{bin/name}"]
  args += ["-ldflags=#{ldflags}"] if ldflags
  args
end

#std_meson_argsObject


1483
1484
1485
# File 'Library/Homebrew/formula.rb', line 1483

def std_meson_args
  ["--prefix=#{prefix}", "--libdir=#{lib}", "--buildtype=release", "--wrap-mode=nofallback"]
end

#supersedes_an_installed_formula?Boolean

Is this formula the target of an alias used to install an old formula?

Returns:

  • (Boolean)

1337
1338
1339
# File 'Library/Homebrew/formula.rb', line 1337

def supersedes_an_installed_formula?
  old_installed_formulae.any?
end

#system(cmd, *args) ⇒ Object


2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
# File 'Library/Homebrew/formula.rb', line 2040

def system(cmd, *args)
  verbose_using_dots = Homebrew::EnvConfig.verbose_using_dots?

  # remove "boring" arguments so that the important ones are more likely to
  # be shown considering that we trim long ohai lines to the terminal width
  pretty_args = args.dup
  unless verbose?
    case cmd
    when "./configure"
      pretty_args -= %w[--disable-dependency-tracking --disable-debug --disable-silent-rules]
    when "cargo"
      pretty_args -= std_cargo_args
    when "cmake"
      pretty_args -= std_cmake_args
    when "go"
      pretty_args -= std_go_args
    end
  end
  pretty_args.each_index do |i|
    pretty_args[i] = "import setuptools..." if pretty_args[i].to_s.start_with? "import setuptools"
  end
  ohai "#{cmd} #{pretty_args * " "}".strip

  @exec_count ||= 0
  @exec_count += 1
  logfn = format("#{logs}/#{active_log_prefix}%02<exec_count>d.%<cmd_base>s",
                 exec_count: @exec_count,
                 cmd_base:   File.basename(cmd).split.first)
  logs.mkpath

  File.open(logfn, "w") do |log|
    log.puts Time.now, "", cmd, args, ""
    log.flush

    if verbose?
      rd, wr = IO.pipe
      begin
        pid = fork do
          rd.close
          log.close
          exec_cmd(cmd, args, wr, logfn)
        end
        wr.close

        if verbose_using_dots
          last_dot = Time.at(0)
          while (buf = rd.gets)
            log.puts buf
            # make sure dots printed with interval of at least 1 min.
            next unless (Time.now - last_dot) > 60

            print "."
            $stdout.flush
            last_dot = Time.now
          end
          puts
        else
          while (buf = rd.gets)
            log.puts buf
            puts buf
          end
        end
      ensure
        rd.close
      end
    else
      pid = fork do
        exec_cmd(cmd, args, log, logfn)
      end
    end

    Process.wait(T.must(pid))

    $stdout.flush

    unless $CHILD_STATUS.success?
      log_lines = Homebrew::EnvConfig.fail_log_lines

      log.flush
      if !verbose? || verbose_using_dots
        puts "Last #{log_lines} lines from #{logfn}:"
        Kernel.system "/usr/bin/tail", "-n", log_lines, logfn
      end
      log.puts

      require "system_config"
      require "build_environment"

      env = ENV.to_hash

      SystemConfig.dump_verbose_config(log)
      log.puts
      BuildEnvironment.dump env, log

      raise BuildError.new(self, cmd, args, env)
    end
  end
end

#test_defined?Boolean

Returns:

  • (Boolean)

1952
1953
1954
# File 'Library/Homebrew/formula.rb', line 1952

def test_defined?
  false
end

#to_sObject


1409
1410
1411
# File 'Library/Homebrew/formula.rb', line 1409

def to_s
  name
end

#update_head_versionObject


401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
# File 'Library/Homebrew/formula.rb', line 401

def update_head_version
  return unless head?
  return unless head.downloader.is_a?(VCSDownloadStrategy)
  return unless head.downloader.cached_location.exist?

  path = if ENV["HOMEBREW_ENV"]
    ENV["PATH"]
  else
    ENV["HOMEBREW_PATH"]
  end

  with_env(PATH: path) do
    head.version.update_commit(head.downloader.last_commit)
  end
end

#varObject

The directory where the formula's variable files should be installed. This directory is not inside the HOMEBREW_CELLAR so it persists across upgrades.


846
847
848
# File 'Library/Homebrew/formula.rb', line 846

def var
  HOMEBREW_PREFIX/"var"
end

#versionObject

The version for the currently active SoftwareSpec. The version is autodetected from the URL and/or tag so only needs to be declared if it cannot be autodetected correctly.

See Also:


399
# File 'Library/Homebrew/formula.rb', line 399

delegate version: :active_spec

#versioned_formula?Boolean

If this is a @-versioned formula.

Returns:

  • (Boolean)

424
425
426
# File 'Library/Homebrew/formula.rb', line 424

def versioned_formula?
  name.include?("@")
end

#versioned_formulaeObject

Returns any @-versioned formulae for any formula (including versioned formulae).


429
430
431
432
433
434
435
436
437
# File 'Library/Homebrew/formula.rb', line 429

def versioned_formulae
  Pathname.glob(path.to_s.gsub(/(@[\d.]+)?\.rb$/, "@*.rb")).map do |versioned_path|
    next if versioned_path == path

    Formula[versioned_path.basename(".rb").to_s]
  rescue FormulaUnavailableError
    nil
  end.compact.sort_by(&:version).reverse
end

#with_logging(log_type) ⇒ Object

Runs a block with the given log type in effect for its duration.


915
916
917
918
919
920
921
# File 'Library/Homebrew/formula.rb', line 915

def with_logging(log_type)
  old_log_type = @active_log_type
  @active_log_type = log_type
  yield
ensure
  @active_log_type = old_log_type
end

#xcodebuild(*args) ⇒ Object


2197
2198
2199
2200
2201
2202
2203
2204
2205
# File 'Library/Homebrew/formula.rb', line 2197

def xcodebuild(*args)
  removed = ENV.remove_cc_etc

  begin
    T.unsafe(self).system("xcodebuild", *args)
  ensure
    ENV.update(removed)
  end
end

#zsh_completionObject

The directory where the formula's zsh completion files should be installed. This is symlinked into HOMEBREW_PREFIX after installation or with brew link for formulae that are not keg-only.


878
879
880
# File 'Library/Homebrew/formula.rb', line 878

def zsh_completion
  share/"zsh/site-functions"
end

#zsh_functionObject

The directory where the formula's zsh function files should be installed. This is symlinked into HOMEBREW_PREFIX after installation or with brew link for formulae that are not keg-only.


854
855
856
# File 'Library/Homebrew/formula.rb', line 854

def zsh_function
  share/"zsh/site-functions"
end